blob: 519dec9774fd6bab9df4bb6df202cb7072db9561 [file] [log] [blame]
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001/**
2 * OV519 driver
3 *
4 * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr)
Hans de Goedeb46aaa02009-10-12 10:07:57 -03005 * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03006 *
Romain Beauxis2961e8752008-12-05 06:25:26 -03007 * This module is adapted from the ov51x-jpeg package, which itself
8 * was adapted from the ov511 driver.
9 *
10 * Original copyright for the ov511 driver is:
11 *
Hans de Goedeb46aaa02009-10-12 10:07:57 -030012 * Copyright (c) 1999-2006 Mark W. McClelland
Romain Beauxis2961e8752008-12-05 06:25:26 -030013 * Support for OV519, OV8610 Copyright (c) 2003 Joerg Heckenbach
Hans de Goedeb46aaa02009-10-12 10:07:57 -030014 * Many improvements by Bret Wallach <bwallac1@san.rr.com>
15 * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
16 * OV7620 fixes by Charl P. Botha <cpbotha@ieee.org>
17 * Changes by Claudio Matsuoka <claudio@conectiva.com>
Romain Beauxis2961e8752008-12-05 06:25:26 -030018 *
19 * ov51x-jpeg original copyright is:
20 *
21 * Copyright (c) 2004-2007 Romain Beauxis <toots@rastageeks.org>
22 * Support for OV7670 sensors was contributed by Sam Skipsey <aoanla@yahoo.com>
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030023 *
24 * This program is free software; you can redistribute it and/or modify
25 * it under the terms of the GNU General Public License as published by
26 * the Free Software Foundation; either version 2 of the License, or
27 * any later version.
28 *
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
33 *
34 * You should have received a copy of the GNU General Public License
35 * along with this program; if not, write to the Free Software
36 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37 *
38 */
39#define MODULE_NAME "ov519"
40
Hans de Goede417a4d22010-02-19 07:37:08 -030041#include <linux/input.h>
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030042#include "gspca.h"
43
Jean-François Moine9a731a32010-06-04 05:26:42 -030044/* The jpeg_hdr is used by w996Xcf only */
45/* The CONEX_CAM define for jpeg.h needs renaming, now its used here too */
46#define CONEX_CAM
47#include "jpeg.h"
48
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030049MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
50MODULE_DESCRIPTION("OV519 USB Camera Driver");
51MODULE_LICENSE("GPL");
52
53/* global parameters */
54static int frame_rate;
55
56/* Number of times to retry a failed I2C transaction. Increase this if you
57 * are getting "Failed to read sensor ID..." */
58static int i2c_detect_tries = 10;
59
Jean-François Moine62833ac2010-10-02 04:27:02 -030060/* controls */
61enum e_ctrl {
62 BRIGHTNESS,
63 CONTRAST,
64 COLORS,
65 HFLIP,
66 VFLIP,
67 AUTOBRIGHT,
68 FREQ,
69 NCTRL /* number of controls */
70};
71
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030072/* ov519 device descriptor */
73struct sd {
74 struct gspca_dev gspca_dev; /* !! must be the first item */
75
Jean-François Moine62833ac2010-10-02 04:27:02 -030076 struct gspca_ctrl ctrls[NCTRL];
77
Jean-François Moine9d1593a2010-11-11 08:04:06 -030078 u8 packet_nr;
Hans de Goede92918a52009-06-14 06:21:35 -030079
Hans de Goede49809d62009-06-07 12:10:39 -030080 char bridge;
81#define BRIDGE_OV511 0
82#define BRIDGE_OV511PLUS 1
83#define BRIDGE_OV518 2
84#define BRIDGE_OV518PLUS 3
85#define BRIDGE_OV519 4
Hans de Goede635118d2009-10-11 09:49:03 -030086#define BRIDGE_OVFX2 5
Hans de Goedea511ba92009-10-16 07:13:07 -030087#define BRIDGE_W9968CF 6
Hans de Goede9e4d8252009-06-14 06:25:06 -030088#define BRIDGE_MASK 7
89
90 char invert_led;
91#define BRIDGE_INVERT_LED 8
Hans de Goede49809d62009-06-07 12:10:39 -030092
Hans de Goede417a4d22010-02-19 07:37:08 -030093 char snapshot_pressed;
94 char snapshot_needs_reset;
95
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030096 /* Determined by sensor type */
Jean-François Moine9d1593a2010-11-11 08:04:06 -030097 u8 sif;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030098
Jean-François Moine9d1593a2010-11-11 08:04:06 -030099 u8 quality;
Hans de Goede79b35902009-10-19 06:08:01 -0300100#define QUALITY_MIN 50
101#define QUALITY_MAX 70
102#define QUALITY_DEF 50
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300103
Jean-François Moine9d1593a2010-11-11 08:04:06 -0300104 u8 stopped; /* Streaming is temporarily paused */
105 u8 first_frame;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300106
Jean-François Moine9d1593a2010-11-11 08:04:06 -0300107 u8 frame_rate; /* current Framerate */
108 u8 clockdiv; /* clockdiv override */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300109
Jean-François Moine7bbe6b82010-11-11 08:27:24 -0300110 s8 sensor; /* Type of image sensor chip (SEN_*) */
Hans de Goedea511ba92009-10-16 07:13:07 -0300111
112 u8 sensor_addr;
Jean-François Moined6fa6632010-11-11 08:05:50 -0300113 u16 sensor_width;
114 u16 sensor_height;
115 s16 sensor_reg_cache[256];
Hans de Goede79b35902009-10-19 06:08:01 -0300116
Jean-François Moine9a731a32010-06-04 05:26:42 -0300117 u8 jpeg_hdr[JPEG_HDR_SZ];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300118};
Jean-François Moine7bbe6b82010-11-11 08:27:24 -0300119enum sensors {
120 SEN_OV2610,
121 SEN_OV3610,
122 SEN_OV6620,
123 SEN_OV6630,
124 SEN_OV66308AF,
125 SEN_OV7610,
126 SEN_OV7620,
127 SEN_OV7620AE,
128 SEN_OV7640,
129 SEN_OV7648,
130 SEN_OV7670,
131 SEN_OV76BE,
132 SEN_OV8610,
133};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300134
Hans de Goedea511ba92009-10-16 07:13:07 -0300135/* Note this is a bit of a hack, but the w9968cf driver needs the code for all
136 the ov sensors which is already present here. When we have the time we
137 really should move the sensor drivers to v4l2 sub drivers. */
138#include "w996Xcf.c"
139
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300140/* V4L2 controls supported by the driver */
Hans de Goede49809d62009-06-07 12:10:39 -0300141static void setbrightness(struct gspca_dev *gspca_dev);
142static void setcontrast(struct gspca_dev *gspca_dev);
143static void setcolors(struct gspca_dev *gspca_dev);
Jean-François Moine62833ac2010-10-02 04:27:02 -0300144static void sethvflip(struct gspca_dev *gspca_dev);
145static void setautobright(struct gspca_dev *gspca_dev);
146static void setfreq(struct gspca_dev *gspca_dev);
147static void setfreq_i(struct sd *sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300148
Hans de Goede02ab18b2009-06-14 04:32:04 -0300149static const struct ctrl sd_ctrls[] = {
Jean-François Moine62833ac2010-10-02 04:27:02 -0300150[BRIGHTNESS] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300151 {
152 .id = V4L2_CID_BRIGHTNESS,
153 .type = V4L2_CTRL_TYPE_INTEGER,
154 .name = "Brightness",
155 .minimum = 0,
156 .maximum = 255,
157 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300158 .default_value = 127,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300159 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300160 .set_control = setbrightness,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300161 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300162[CONTRAST] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300163 {
164 .id = V4L2_CID_CONTRAST,
165 .type = V4L2_CTRL_TYPE_INTEGER,
166 .name = "Contrast",
167 .minimum = 0,
168 .maximum = 255,
169 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300170 .default_value = 127,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300171 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300172 .set_control = setcontrast,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300173 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300174[COLORS] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300175 {
176 .id = V4L2_CID_SATURATION,
177 .type = V4L2_CTRL_TYPE_INTEGER,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300178 .name = "Color",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300179 .minimum = 0,
180 .maximum = 255,
181 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300182 .default_value = 127,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300183 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300184 .set_control = setcolors,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300185 },
Hans de Goede02ab18b2009-06-14 04:32:04 -0300186/* The flip controls work with ov7670 only */
Jean-François Moine62833ac2010-10-02 04:27:02 -0300187[HFLIP] = {
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300188 {
189 .id = V4L2_CID_HFLIP,
190 .type = V4L2_CTRL_TYPE_BOOLEAN,
191 .name = "Mirror",
192 .minimum = 0,
193 .maximum = 1,
194 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300195 .default_value = 0,
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300196 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300197 .set_control = sethvflip,
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300198 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300199[VFLIP] = {
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300200 {
201 .id = V4L2_CID_VFLIP,
202 .type = V4L2_CTRL_TYPE_BOOLEAN,
203 .name = "Vflip",
204 .minimum = 0,
205 .maximum = 1,
206 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300207 .default_value = 0,
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300208 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300209 .set_control = sethvflip,
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300210 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300211[AUTOBRIGHT] = {
Hans de Goede02ab18b2009-06-14 04:32:04 -0300212 {
213 .id = V4L2_CID_AUTOBRIGHTNESS,
214 .type = V4L2_CTRL_TYPE_BOOLEAN,
215 .name = "Auto Brightness",
216 .minimum = 0,
217 .maximum = 1,
218 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300219 .default_value = 1,
Hans de Goede02ab18b2009-06-14 04:32:04 -0300220 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300221 .set_control = setautobright,
Hans de Goede02ab18b2009-06-14 04:32:04 -0300222 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300223[FREQ] = {
Hans de Goede02ab18b2009-06-14 04:32:04 -0300224 {
225 .id = V4L2_CID_POWER_LINE_FREQUENCY,
226 .type = V4L2_CTRL_TYPE_MENU,
227 .name = "Light frequency filter",
228 .minimum = 0,
Jean-François Moine87bae742010-11-12 05:31:34 -0300229 .maximum = 2, /* 0: no flicker, 1: 50Hz, 2:60Hz, 3: auto */
Hans de Goede02ab18b2009-06-14 04:32:04 -0300230 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300231 .default_value = 0,
Hans de Goede02ab18b2009-06-14 04:32:04 -0300232 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300233 .set_control = setfreq,
Hans de Goede02ab18b2009-06-14 04:32:04 -0300234 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300235};
236
Hans de Goede49809d62009-06-07 12:10:39 -0300237static const struct v4l2_pix_format ov519_vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300238 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
239 .bytesperline = 320,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300240 .sizeimage = 320 * 240 * 3 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300241 .colorspace = V4L2_COLORSPACE_JPEG,
242 .priv = 1},
243 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
244 .bytesperline = 640,
245 .sizeimage = 640 * 480 * 3 / 8 + 590,
246 .colorspace = V4L2_COLORSPACE_JPEG,
247 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300248};
Hans de Goede49809d62009-06-07 12:10:39 -0300249static const struct v4l2_pix_format ov519_sif_mode[] = {
Hans de Goede124cc9c2009-06-14 05:48:00 -0300250 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
251 .bytesperline = 160,
252 .sizeimage = 160 * 120 * 3 / 8 + 590,
253 .colorspace = V4L2_COLORSPACE_JPEG,
254 .priv = 3},
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300255 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
256 .bytesperline = 176,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300257 .sizeimage = 176 * 144 * 3 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300258 .colorspace = V4L2_COLORSPACE_JPEG,
259 .priv = 1},
Hans de Goede124cc9c2009-06-14 05:48:00 -0300260 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
261 .bytesperline = 320,
262 .sizeimage = 320 * 240 * 3 / 8 + 590,
263 .colorspace = V4L2_COLORSPACE_JPEG,
264 .priv = 2},
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300265 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
266 .bytesperline = 352,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300267 .sizeimage = 352 * 288 * 3 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300268 .colorspace = V4L2_COLORSPACE_JPEG,
269 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300270};
271
Hans de Goedeb282d872009-06-14 19:10:40 -0300272/* Note some of the sizeimage values for the ov511 / ov518 may seem
273 larger then necessary, however they need to be this big as the ov511 /
274 ov518 always fills the entire isoc frame, using 0 padding bytes when
275 it doesn't have any data. So with low framerates the amount of data
276 transfered can become quite large (libv4l will remove all the 0 padding
277 in userspace). */
Hans de Goede49809d62009-06-07 12:10:39 -0300278static const struct v4l2_pix_format ov518_vga_mode[] = {
279 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
280 .bytesperline = 320,
Hans de Goedeb282d872009-06-14 19:10:40 -0300281 .sizeimage = 320 * 240 * 3,
Hans de Goede49809d62009-06-07 12:10:39 -0300282 .colorspace = V4L2_COLORSPACE_JPEG,
283 .priv = 1},
284 {640, 480, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
285 .bytesperline = 640,
Hans de Goedeb282d872009-06-14 19:10:40 -0300286 .sizeimage = 640 * 480 * 2,
Hans de Goede49809d62009-06-07 12:10:39 -0300287 .colorspace = V4L2_COLORSPACE_JPEG,
288 .priv = 0},
289};
290static const struct v4l2_pix_format ov518_sif_mode[] = {
Hans de Goede124cc9c2009-06-14 05:48:00 -0300291 {160, 120, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
292 .bytesperline = 160,
Hans de Goedeb282d872009-06-14 19:10:40 -0300293 .sizeimage = 70000,
Hans de Goede124cc9c2009-06-14 05:48:00 -0300294 .colorspace = V4L2_COLORSPACE_JPEG,
295 .priv = 3},
Hans de Goede49809d62009-06-07 12:10:39 -0300296 {176, 144, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
297 .bytesperline = 176,
Hans de Goedeb282d872009-06-14 19:10:40 -0300298 .sizeimage = 70000,
Hans de Goede49809d62009-06-07 12:10:39 -0300299 .colorspace = V4L2_COLORSPACE_JPEG,
300 .priv = 1},
Hans de Goede124cc9c2009-06-14 05:48:00 -0300301 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
302 .bytesperline = 320,
Hans de Goedeb282d872009-06-14 19:10:40 -0300303 .sizeimage = 320 * 240 * 3,
Hans de Goede124cc9c2009-06-14 05:48:00 -0300304 .colorspace = V4L2_COLORSPACE_JPEG,
305 .priv = 2},
Hans de Goede49809d62009-06-07 12:10:39 -0300306 {352, 288, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
307 .bytesperline = 352,
Hans de Goedeb282d872009-06-14 19:10:40 -0300308 .sizeimage = 352 * 288 * 3,
Hans de Goede49809d62009-06-07 12:10:39 -0300309 .colorspace = V4L2_COLORSPACE_JPEG,
310 .priv = 0},
311};
312
Hans de Goede1876bb92009-06-14 06:45:50 -0300313static const struct v4l2_pix_format ov511_vga_mode[] = {
314 {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
315 .bytesperline = 320,
316 .sizeimage = 320 * 240 * 3,
317 .colorspace = V4L2_COLORSPACE_JPEG,
318 .priv = 1},
319 {640, 480, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
320 .bytesperline = 640,
321 .sizeimage = 640 * 480 * 2,
322 .colorspace = V4L2_COLORSPACE_JPEG,
323 .priv = 0},
324};
325static const struct v4l2_pix_format ov511_sif_mode[] = {
326 {160, 120, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
327 .bytesperline = 160,
Hans de Goedeb282d872009-06-14 19:10:40 -0300328 .sizeimage = 70000,
Hans de Goede1876bb92009-06-14 06:45:50 -0300329 .colorspace = V4L2_COLORSPACE_JPEG,
330 .priv = 3},
331 {176, 144, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
332 .bytesperline = 176,
Hans de Goedeb282d872009-06-14 19:10:40 -0300333 .sizeimage = 70000,
Hans de Goede1876bb92009-06-14 06:45:50 -0300334 .colorspace = V4L2_COLORSPACE_JPEG,
335 .priv = 1},
336 {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
337 .bytesperline = 320,
338 .sizeimage = 320 * 240 * 3,
339 .colorspace = V4L2_COLORSPACE_JPEG,
340 .priv = 2},
341 {352, 288, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
342 .bytesperline = 352,
343 .sizeimage = 352 * 288 * 3,
344 .colorspace = V4L2_COLORSPACE_JPEG,
345 .priv = 0},
346};
Hans de Goede49809d62009-06-07 12:10:39 -0300347
Hans de Goede635118d2009-10-11 09:49:03 -0300348static const struct v4l2_pix_format ovfx2_vga_mode[] = {
349 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
350 .bytesperline = 320,
351 .sizeimage = 320 * 240,
352 .colorspace = V4L2_COLORSPACE_SRGB,
353 .priv = 1},
354 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
355 .bytesperline = 640,
356 .sizeimage = 640 * 480,
357 .colorspace = V4L2_COLORSPACE_SRGB,
358 .priv = 0},
359};
360static const struct v4l2_pix_format ovfx2_cif_mode[] = {
361 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
362 .bytesperline = 160,
363 .sizeimage = 160 * 120,
364 .colorspace = V4L2_COLORSPACE_SRGB,
365 .priv = 3},
366 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
367 .bytesperline = 176,
368 .sizeimage = 176 * 144,
369 .colorspace = V4L2_COLORSPACE_SRGB,
370 .priv = 1},
371 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
372 .bytesperline = 320,
373 .sizeimage = 320 * 240,
374 .colorspace = V4L2_COLORSPACE_SRGB,
375 .priv = 2},
376 {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
377 .bytesperline = 352,
378 .sizeimage = 352 * 288,
379 .colorspace = V4L2_COLORSPACE_SRGB,
380 .priv = 0},
381};
382static const struct v4l2_pix_format ovfx2_ov2610_mode[] = {
383 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
384 .bytesperline = 1600,
385 .sizeimage = 1600 * 1200,
386 .colorspace = V4L2_COLORSPACE_SRGB},
387};
388static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
Hans de Goede635118d2009-10-11 09:49:03 -0300389 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
390 .bytesperline = 640,
391 .sizeimage = 640 * 480,
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300392 .colorspace = V4L2_COLORSPACE_SRGB,
393 .priv = 1},
394 {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
395 .bytesperline = 800,
396 .sizeimage = 800 * 600,
397 .colorspace = V4L2_COLORSPACE_SRGB,
398 .priv = 1},
399 {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
400 .bytesperline = 1024,
401 .sizeimage = 1024 * 768,
402 .colorspace = V4L2_COLORSPACE_SRGB,
403 .priv = 1},
404 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
405 .bytesperline = 1600,
406 .sizeimage = 1600 * 1200,
407 .colorspace = V4L2_COLORSPACE_SRGB,
408 .priv = 0},
409 {2048, 1536, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
410 .bytesperline = 2048,
411 .sizeimage = 2048 * 1536,
412 .colorspace = V4L2_COLORSPACE_SRGB,
413 .priv = 0},
Hans de Goede635118d2009-10-11 09:49:03 -0300414};
415
Hans de Goede49809d62009-06-07 12:10:39 -0300416/* Registers common to OV511 / OV518 */
Hans de Goede1876bb92009-06-14 06:45:50 -0300417#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */
Jean-François Moine780e3122010-10-19 04:29:10 -0300418#define R51x_SYS_RESET 0x50
Hans de Goede1876bb92009-06-14 06:45:50 -0300419 /* Reset type flags */
420 #define OV511_RESET_OMNICE 0x08
Jean-François Moine780e3122010-10-19 04:29:10 -0300421#define R51x_SYS_INIT 0x53
Hans de Goede49809d62009-06-07 12:10:39 -0300422#define R51x_SYS_SNAP 0x52
Jean-François Moine87bae742010-11-12 05:31:34 -0300423#define R51x_SYS_CUST_ID 0x5f
Hans de Goede49809d62009-06-07 12:10:39 -0300424#define R51x_COMP_LUT_BEGIN 0x80
425
426/* OV511 Camera interface register numbers */
Hans de Goede1876bb92009-06-14 06:45:50 -0300427#define R511_CAM_DELAY 0x10
428#define R511_CAM_EDGE 0x11
429#define R511_CAM_PXCNT 0x12
430#define R511_CAM_LNCNT 0x13
431#define R511_CAM_PXDIV 0x14
432#define R511_CAM_LNDIV 0x15
433#define R511_CAM_UV_EN 0x16
434#define R511_CAM_LINE_MODE 0x17
435#define R511_CAM_OPTS 0x18
436
437#define R511_SNAP_FRAME 0x19
Jean-François Moine87bae742010-11-12 05:31:34 -0300438#define R511_SNAP_PXCNT 0x1a
439#define R511_SNAP_LNCNT 0x1b
440#define R511_SNAP_PXDIV 0x1c
441#define R511_SNAP_LNDIV 0x1d
442#define R511_SNAP_UV_EN 0x1e
443#define R511_SNAP_UV_EN 0x1e
444#define R511_SNAP_OPTS 0x1f
Hans de Goede1876bb92009-06-14 06:45:50 -0300445
446#define R511_DRAM_FLOW_CTL 0x20
447#define R511_FIFO_OPTS 0x31
448#define R511_I2C_CTL 0x40
Hans de Goede49809d62009-06-07 12:10:39 -0300449#define R511_SYS_LED_CTL 0x55 /* OV511+ only */
Hans de Goede1876bb92009-06-14 06:45:50 -0300450#define R511_COMP_EN 0x78
451#define R511_COMP_LUT_EN 0x79
Hans de Goede49809d62009-06-07 12:10:39 -0300452
453/* OV518 Camera interface register numbers */
454#define R518_GPIO_OUT 0x56 /* OV518(+) only */
455#define R518_GPIO_CTL 0x57 /* OV518(+) only */
456
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300457/* OV519 Camera interface register numbers */
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -0300458#define OV519_R10_H_SIZE 0x10
459#define OV519_R11_V_SIZE 0x11
460#define OV519_R12_X_OFFSETL 0x12
461#define OV519_R13_X_OFFSETH 0x13
462#define OV519_R14_Y_OFFSETL 0x14
463#define OV519_R15_Y_OFFSETH 0x15
464#define OV519_R16_DIVIDER 0x16
465#define OV519_R20_DFR 0x20
466#define OV519_R25_FORMAT 0x25
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300467
468/* OV519 System Controller register numbers */
Jean-François Moine21867802010-11-12 06:12:09 -0300469#define OV519_R51_RESET1 0x51
470#define OV519_R54_EN_CLK1 0x54
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300471
472#define OV519_GPIO_DATA_OUT0 0x71
473#define OV519_GPIO_IO_CTRL0 0x72
474
Jean-François Moine87bae742010-11-12 05:31:34 -0300475/*#define OV511_ENDPOINT_ADDRESS 1 * Isoc endpoint number */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300476
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300477/*
478 * The FX2 chip does not give us a zero length read at end of frame.
479 * It does, however, give a short read at the end of a frame, if
Daniel Mack3ad2f3f2010-02-03 08:01:28 +0800480 * necessary, rather than run two frames together.
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300481 *
482 * By choosing the right bulk transfer size, we are guaranteed to always
483 * get a short read for the last read of each frame. Frame sizes are
484 * always a composite number (width * height, or a multiple) so if we
485 * choose a prime number, we are guaranteed that the last read of a
486 * frame will be short.
487 *
488 * But it isn't that easy: the 2.6 kernel requires a multiple of 4KB,
489 * otherwise EOVERFLOW "babbling" errors occur. I have not been able
490 * to figure out why. [PMiller]
491 *
492 * The constant (13 * 4096) is the largest "prime enough" number less than 64KB.
493 *
494 * It isn't enough to know the number of bytes per frame, in case we
495 * have data dropouts or buffer overruns (even though the FX2 double
496 * buffers, there are some pretty strict real time constraints for
497 * isochronous transfer for larger frame sizes).
498 */
499#define OVFX2_BULK_SIZE (13 * 4096)
500
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300501/* I2C registers */
502#define R51x_I2C_W_SID 0x41
503#define R51x_I2C_SADDR_3 0x42
504#define R51x_I2C_SADDR_2 0x43
505#define R51x_I2C_R_SID 0x44
506#define R51x_I2C_DATA 0x45
507#define R518_I2C_CTL 0x47 /* OV518(+) only */
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300508#define OVFX2_I2C_ADDR 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300509
510/* I2C ADDRESSES */
511#define OV7xx0_SID 0x42
Hans de Goede229bb7d2009-10-11 07:41:46 -0300512#define OV_HIRES_SID 0x60 /* OV9xxx / OV2xxx / OV3xxx */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300513#define OV8xx0_SID 0xa0
514#define OV6xx0_SID 0xc0
515
516/* OV7610 registers */
517#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */
Hans de Goede49809d62009-06-07 12:10:39 -0300518#define OV7610_REG_BLUE 0x01 /* blue channel balance */
519#define OV7610_REG_RED 0x02 /* red channel balance */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300520#define OV7610_REG_SAT 0x03 /* saturation */
521#define OV8610_REG_HUE 0x04 /* 04 reserved */
522#define OV7610_REG_CNT 0x05 /* Y contrast */
523#define OV7610_REG_BRT 0x06 /* Y brightness */
524#define OV7610_REG_COM_C 0x14 /* misc common regs */
525#define OV7610_REG_ID_HIGH 0x1c /* manufacturer ID MSB */
526#define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */
527#define OV7610_REG_COM_I 0x29 /* misc settings */
528
529/* OV7670 registers */
Jean-François Moine21867802010-11-12 06:12:09 -0300530#define OV7670_R00_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */
531#define OV7670_R01_BLUE 0x01 /* blue gain */
532#define OV7670_R02_RED 0x02 /* red gain */
533#define OV7670_R03_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */
534#define OV7670_R04_COM1 0x04 /* Control 1 */
535/*#define OV7670_R07_AECHH 0x07 * AEC MS 5 bits */
536#define OV7670_R0C_COM3 0x0c /* Control 3 */
537#define OV7670_R0D_COM4 0x0d /* Control 4 */
538#define OV7670_R0E_COM5 0x0e /* All "reserved" */
539#define OV7670_R0F_COM6 0x0f /* Control 6 */
540#define OV7670_R10_AECH 0x10 /* More bits of AEC value */
541#define OV7670_R11_CLKRC 0x11 /* Clock control */
542#define OV7670_R12_COM7 0x12 /* Control 7 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300543#define OV7670_COM7_FMT_VGA 0x00
544/*#define OV7670_COM7_YUV 0x00 * YUV */
545#define OV7670_COM7_FMT_QVGA 0x10 /* QVGA format */
546#define OV7670_COM7_FMT_MASK 0x38
547#define OV7670_COM7_RESET 0x80 /* Register reset */
Jean-François Moine21867802010-11-12 06:12:09 -0300548#define OV7670_R13_COM8 0x13 /* Control 8 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300549#define OV7670_COM8_AEC 0x01 /* Auto exposure enable */
550#define OV7670_COM8_AWB 0x02 /* White balance enable */
551#define OV7670_COM8_AGC 0x04 /* Auto gain enable */
552#define OV7670_COM8_BFILT 0x20 /* Band filter enable */
553#define OV7670_COM8_AECSTEP 0x40 /* Unlimited AEC step size */
554#define OV7670_COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */
Jean-François Moine21867802010-11-12 06:12:09 -0300555#define OV7670_R14_COM9 0x14 /* Control 9 - gain ceiling */
556#define OV7670_R15_COM10 0x15 /* Control 10 */
557#define OV7670_R17_HSTART 0x17 /* Horiz start high bits */
558#define OV7670_R18_HSTOP 0x18 /* Horiz stop high bits */
559#define OV7670_R19_VSTART 0x19 /* Vert start high bits */
560#define OV7670_R1A_VSTOP 0x1a /* Vert stop high bits */
561#define OV7670_R1E_MVFP 0x1e /* Mirror / vflip */
Jean-François Moine87bae742010-11-12 05:31:34 -0300562#define OV7670_MVFP_VFLIP 0x10 /* vertical flip */
563#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */
Jean-François Moine21867802010-11-12 06:12:09 -0300564#define OV7670_R24_AEW 0x24 /* AGC upper limit */
565#define OV7670_R25_AEB 0x25 /* AGC lower limit */
566#define OV7670_R26_VPT 0x26 /* AGC/AEC fast mode op region */
567#define OV7670_R32_HREF 0x32 /* HREF pieces */
568#define OV7670_R3A_TSLB 0x3a /* lots of stuff */
569#define OV7670_R3B_COM11 0x3b /* Control 11 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300570#define OV7670_COM11_EXP 0x02
571#define OV7670_COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */
Jean-François Moine21867802010-11-12 06:12:09 -0300572#define OV7670_R3C_COM12 0x3c /* Control 12 */
573#define OV7670_R3D_COM13 0x3d /* Control 13 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300574#define OV7670_COM13_GAMMA 0x80 /* Gamma enable */
575#define OV7670_COM13_UVSAT 0x40 /* UV saturation auto adjustment */
Jean-François Moine21867802010-11-12 06:12:09 -0300576#define OV7670_R3E_COM14 0x3e /* Control 14 */
577#define OV7670_R3F_EDGE 0x3f /* Edge enhancement factor */
578#define OV7670_R40_COM15 0x40 /* Control 15 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300579/*#define OV7670_COM15_R00FF 0xc0 * 00 to FF */
Jean-François Moine21867802010-11-12 06:12:09 -0300580#define OV7670_R41_COM16 0x41 /* Control 16 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300581#define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */
Jean-François Moine21867802010-11-12 06:12:09 -0300582#define OV7670_R55_BRIGHT 0x55 /* Brightness */
583#define OV7670_R56_CONTRAS 0x56 /* Contrast control */
584#define OV7670_R69_GFIX 0x69 /* Fix gain control */
585/*#define OV7670_R8C_RGB444 0x8c * RGB 444 control */
586#define OV7670_R9F_HAECC1 0x9f /* Hist AEC/AGC control 1 */
587#define OV7670_RA0_HAECC2 0xa0 /* Hist AEC/AGC control 2 */
588#define OV7670_RA5_BD50MAX 0xa5 /* 50hz banding step limit */
589#define OV7670_RA6_HAECC3 0xa6 /* Hist AEC/AGC control 3 */
590#define OV7670_RA7_HAECC4 0xa7 /* Hist AEC/AGC control 4 */
591#define OV7670_RA8_HAECC5 0xa8 /* Hist AEC/AGC control 5 */
592#define OV7670_RA9_HAECC6 0xa9 /* Hist AEC/AGC control 6 */
593#define OV7670_RAA_HAECC7 0xaa /* Hist AEC/AGC control 7 */
594#define OV7670_RAB_BD60MAX 0xab /* 60hz banding step limit */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300595
Jean-Francois Moine4202f712008-09-03 17:12:15 -0300596struct ov_regvals {
Jean-François Moine9d1593a2010-11-11 08:04:06 -0300597 u8 reg;
598 u8 val;
Jean-Francois Moine4202f712008-09-03 17:12:15 -0300599};
600struct ov_i2c_regvals {
Jean-François Moine9d1593a2010-11-11 08:04:06 -0300601 u8 reg;
602 u8 val;
Jean-Francois Moine4202f712008-09-03 17:12:15 -0300603};
604
Hans de Goede635118d2009-10-11 09:49:03 -0300605/* Settings for OV2610 camera chip */
Jean-François Moine780e3122010-10-19 04:29:10 -0300606static const struct ov_i2c_regvals norm_2610[] = {
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300607 { 0x12, 0x80 }, /* reset */
Hans de Goede635118d2009-10-11 09:49:03 -0300608};
609
Jean-François Moine780e3122010-10-19 04:29:10 -0300610static const struct ov_i2c_regvals norm_3620b[] = {
Hans de Goede635118d2009-10-11 09:49:03 -0300611 /*
612 * From the datasheet: "Note that after writing to register COMH
613 * (0x12) to change the sensor mode, registers related to the
614 * sensor’s cropping window will be reset back to their default
615 * values."
616 *
617 * "wait 4096 external clock ... to make sure the sensor is
618 * stable and ready to access registers" i.e. 160us at 24MHz
619 */
Hans de Goede635118d2009-10-11 09:49:03 -0300620 { 0x12, 0x80 }, /* COMH reset */
621 { 0x12, 0x00 }, /* QXGA, master */
622
623 /*
624 * 11 CLKRC "Clock Rate Control"
625 * [7] internal frequency doublers: on
626 * [6] video port mode: master
627 * [5:0] clock divider: 1
628 */
629 { 0x11, 0x80 },
630
631 /*
632 * 13 COMI "Common Control I"
633 * = 192 (0xC0) 11000000
634 * COMI[7] "AEC speed selection"
635 * = 1 (0x01) 1....... "Faster AEC correction"
636 * COMI[6] "AEC speed step selection"
637 * = 1 (0x01) .1...... "Big steps, fast"
638 * COMI[5] "Banding filter on off"
639 * = 0 (0x00) ..0..... "Off"
640 * COMI[4] "Banding filter option"
641 * = 0 (0x00) ...0.... "Main clock is 48 MHz and
642 * the PLL is ON"
643 * COMI[3] "Reserved"
644 * = 0 (0x00) ....0...
645 * COMI[2] "AGC auto manual control selection"
646 * = 0 (0x00) .....0.. "Manual"
647 * COMI[1] "AWB auto manual control selection"
648 * = 0 (0x00) ......0. "Manual"
649 * COMI[0] "Exposure control"
650 * = 0 (0x00) .......0 "Manual"
651 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300652 { 0x13, 0xc0 },
Hans de Goede635118d2009-10-11 09:49:03 -0300653
654 /*
655 * 09 COMC "Common Control C"
656 * = 8 (0x08) 00001000
657 * COMC[7:5] "Reserved"
658 * = 0 (0x00) 000.....
659 * COMC[4] "Sleep Mode Enable"
660 * = 0 (0x00) ...0.... "Normal mode"
661 * COMC[3:2] "Sensor sampling reset timing selection"
662 * = 2 (0x02) ....10.. "Longer reset time"
663 * COMC[1:0] "Output drive current select"
664 * = 0 (0x00) ......00 "Weakest"
665 */
666 { 0x09, 0x08 },
667
668 /*
669 * 0C COMD "Common Control D"
670 * = 8 (0x08) 00001000
671 * COMD[7] "Reserved"
672 * = 0 (0x00) 0.......
673 * COMD[6] "Swap MSB and LSB at the output port"
674 * = 0 (0x00) .0...... "False"
675 * COMD[5:3] "Reserved"
676 * = 1 (0x01) ..001...
677 * COMD[2] "Output Average On Off"
678 * = 0 (0x00) .....0.. "Output Normal"
679 * COMD[1] "Sensor precharge voltage selection"
680 * = 0 (0x00) ......0. "Selects internal
681 * reference precharge
682 * voltage"
683 * COMD[0] "Snapshot option"
684 * = 0 (0x00) .......0 "Enable live video output
685 * after snapshot sequence"
686 */
687 { 0x0c, 0x08 },
688
689 /*
690 * 0D COME "Common Control E"
691 * = 161 (0xA1) 10100001
692 * COME[7] "Output average option"
693 * = 1 (0x01) 1....... "Output average of 4 pixels"
694 * COME[6] "Anti-blooming control"
695 * = 0 (0x00) .0...... "Off"
696 * COME[5:3] "Reserved"
697 * = 4 (0x04) ..100...
698 * COME[2] "Clock output power down pin status"
699 * = 0 (0x00) .....0.. "Tri-state data output pin
700 * on power down"
701 * COME[1] "Data output pin status selection at power down"
702 * = 0 (0x00) ......0. "Tri-state VSYNC, PCLK,
703 * HREF, and CHSYNC pins on
704 * power down"
705 * COME[0] "Auto zero circuit select"
706 * = 1 (0x01) .......1 "On"
707 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300708 { 0x0d, 0xa1 },
Hans de Goede635118d2009-10-11 09:49:03 -0300709
710 /*
711 * 0E COMF "Common Control F"
712 * = 112 (0x70) 01110000
713 * COMF[7] "System clock selection"
714 * = 0 (0x00) 0....... "Use 24 MHz system clock"
715 * COMF[6:4] "Reserved"
716 * = 7 (0x07) .111....
717 * COMF[3] "Manual auto negative offset canceling selection"
718 * = 0 (0x00) ....0... "Auto detect negative
719 * offset and cancel it"
720 * COMF[2:0] "Reserved"
721 * = 0 (0x00) .....000
722 */
723 { 0x0e, 0x70 },
724
725 /*
726 * 0F COMG "Common Control G"
727 * = 66 (0x42) 01000010
728 * COMG[7] "Optical black output selection"
729 * = 0 (0x00) 0....... "Disable"
730 * COMG[6] "Black level calibrate selection"
731 * = 1 (0x01) .1...... "Use optical black pixels
732 * to calibrate"
733 * COMG[5:4] "Reserved"
734 * = 0 (0x00) ..00....
735 * COMG[3] "Channel offset adjustment"
736 * = 0 (0x00) ....0... "Disable offset adjustment"
737 * COMG[2] "ADC black level calibration option"
738 * = 0 (0x00) .....0.. "Use B/G line and G/R
739 * line to calibrate each
740 * channel's black level"
741 * COMG[1] "Reserved"
742 * = 1 (0x01) ......1.
743 * COMG[0] "ADC black level calibration enable"
744 * = 0 (0x00) .......0 "Disable"
745 */
746 { 0x0f, 0x42 },
747
748 /*
749 * 14 COMJ "Common Control J"
750 * = 198 (0xC6) 11000110
751 * COMJ[7:6] "AGC gain ceiling"
752 * = 3 (0x03) 11...... "8x"
753 * COMJ[5:4] "Reserved"
754 * = 0 (0x00) ..00....
755 * COMJ[3] "Auto banding filter"
756 * = 0 (0x00) ....0... "Banding filter is always
757 * on off depending on
758 * COMI[5] setting"
759 * COMJ[2] "VSYNC drop option"
760 * = 1 (0x01) .....1.. "SYNC is dropped if frame
761 * data is dropped"
762 * COMJ[1] "Frame data drop"
763 * = 1 (0x01) ......1. "Drop frame data if
764 * exposure is not within
765 * tolerance. In AEC mode,
766 * data is normally dropped
767 * when data is out of
768 * range."
769 * COMJ[0] "Reserved"
770 * = 0 (0x00) .......0
771 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300772 { 0x14, 0xc6 },
Hans de Goede635118d2009-10-11 09:49:03 -0300773
774 /*
775 * 15 COMK "Common Control K"
776 * = 2 (0x02) 00000010
777 * COMK[7] "CHSYNC pin output swap"
778 * = 0 (0x00) 0....... "CHSYNC"
779 * COMK[6] "HREF pin output swap"
780 * = 0 (0x00) .0...... "HREF"
781 * COMK[5] "PCLK output selection"
782 * = 0 (0x00) ..0..... "PCLK always output"
783 * COMK[4] "PCLK edge selection"
784 * = 0 (0x00) ...0.... "Data valid on falling edge"
785 * COMK[3] "HREF output polarity"
786 * = 0 (0x00) ....0... "positive"
787 * COMK[2] "Reserved"
788 * = 0 (0x00) .....0..
789 * COMK[1] "VSYNC polarity"
790 * = 1 (0x01) ......1. "negative"
791 * COMK[0] "HSYNC polarity"
792 * = 0 (0x00) .......0 "positive"
793 */
794 { 0x15, 0x02 },
795
796 /*
797 * 33 CHLF "Current Control"
798 * = 9 (0x09) 00001001
799 * CHLF[7:6] "Sensor current control"
800 * = 0 (0x00) 00......
801 * CHLF[5] "Sensor current range control"
802 * = 0 (0x00) ..0..... "normal range"
803 * CHLF[4] "Sensor current"
804 * = 0 (0x00) ...0.... "normal current"
805 * CHLF[3] "Sensor buffer current control"
806 * = 1 (0x01) ....1... "half current"
807 * CHLF[2] "Column buffer current control"
808 * = 0 (0x00) .....0.. "normal current"
809 * CHLF[1] "Analog DSP current control"
810 * = 0 (0x00) ......0. "normal current"
811 * CHLF[1] "ADC current control"
812 * = 0 (0x00) ......0. "normal current"
813 */
814 { 0x33, 0x09 },
815
816 /*
817 * 34 VBLM "Blooming Control"
818 * = 80 (0x50) 01010000
819 * VBLM[7] "Hard soft reset switch"
820 * = 0 (0x00) 0....... "Hard reset"
821 * VBLM[6:4] "Blooming voltage selection"
822 * = 5 (0x05) .101....
823 * VBLM[3:0] "Sensor current control"
824 * = 0 (0x00) ....0000
825 */
826 { 0x34, 0x50 },
827
828 /*
829 * 36 VCHG "Sensor Precharge Voltage Control"
830 * = 0 (0x00) 00000000
831 * VCHG[7] "Reserved"
832 * = 0 (0x00) 0.......
833 * VCHG[6:4] "Sensor precharge voltage control"
834 * = 0 (0x00) .000....
835 * VCHG[3:0] "Sensor array common reference"
836 * = 0 (0x00) ....0000
837 */
838 { 0x36, 0x00 },
839
840 /*
841 * 37 ADC "ADC Reference Control"
842 * = 4 (0x04) 00000100
843 * ADC[7:4] "Reserved"
844 * = 0 (0x00) 0000....
845 * ADC[3] "ADC input signal range"
846 * = 0 (0x00) ....0... "Input signal 1.0x"
847 * ADC[2:0] "ADC range control"
848 * = 4 (0x04) .....100
849 */
850 { 0x37, 0x04 },
851
852 /*
853 * 38 ACOM "Analog Common Ground"
854 * = 82 (0x52) 01010010
855 * ACOM[7] "Analog gain control"
856 * = 0 (0x00) 0....... "Gain 1x"
857 * ACOM[6] "Analog black level calibration"
858 * = 1 (0x01) .1...... "On"
859 * ACOM[5:0] "Reserved"
860 * = 18 (0x12) ..010010
861 */
862 { 0x38, 0x52 },
863
864 /*
865 * 3A FREFA "Internal Reference Adjustment"
866 * = 0 (0x00) 00000000
867 * FREFA[7:0] "Range"
868 * = 0 (0x00) 00000000
869 */
870 { 0x3a, 0x00 },
871
872 /*
873 * 3C FVOPT "Internal Reference Adjustment"
874 * = 31 (0x1F) 00011111
875 * FVOPT[7:0] "Range"
876 * = 31 (0x1F) 00011111
877 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300878 { 0x3c, 0x1f },
Hans de Goede635118d2009-10-11 09:49:03 -0300879
880 /*
881 * 44 Undocumented = 0 (0x00) 00000000
882 * 44[7:0] "It's a secret"
883 * = 0 (0x00) 00000000
884 */
885 { 0x44, 0x00 },
886
887 /*
888 * 40 Undocumented = 0 (0x00) 00000000
889 * 40[7:0] "It's a secret"
890 * = 0 (0x00) 00000000
891 */
892 { 0x40, 0x00 },
893
894 /*
895 * 41 Undocumented = 0 (0x00) 00000000
896 * 41[7:0] "It's a secret"
897 * = 0 (0x00) 00000000
898 */
899 { 0x41, 0x00 },
900
901 /*
902 * 42 Undocumented = 0 (0x00) 00000000
903 * 42[7:0] "It's a secret"
904 * = 0 (0x00) 00000000
905 */
906 { 0x42, 0x00 },
907
908 /*
909 * 43 Undocumented = 0 (0x00) 00000000
910 * 43[7:0] "It's a secret"
911 * = 0 (0x00) 00000000
912 */
913 { 0x43, 0x00 },
914
915 /*
916 * 45 Undocumented = 128 (0x80) 10000000
917 * 45[7:0] "It's a secret"
918 * = 128 (0x80) 10000000
919 */
920 { 0x45, 0x80 },
921
922 /*
923 * 48 Undocumented = 192 (0xC0) 11000000
924 * 48[7:0] "It's a secret"
925 * = 192 (0xC0) 11000000
926 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300927 { 0x48, 0xc0 },
Hans de Goede635118d2009-10-11 09:49:03 -0300928
929 /*
930 * 49 Undocumented = 25 (0x19) 00011001
931 * 49[7:0] "It's a secret"
932 * = 25 (0x19) 00011001
933 */
934 { 0x49, 0x19 },
935
936 /*
937 * 4B Undocumented = 128 (0x80) 10000000
938 * 4B[7:0] "It's a secret"
939 * = 128 (0x80) 10000000
940 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300941 { 0x4b, 0x80 },
Hans de Goede635118d2009-10-11 09:49:03 -0300942
943 /*
944 * 4D Undocumented = 196 (0xC4) 11000100
945 * 4D[7:0] "It's a secret"
946 * = 196 (0xC4) 11000100
947 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300948 { 0x4d, 0xc4 },
Hans de Goede635118d2009-10-11 09:49:03 -0300949
950 /*
951 * 35 VREF "Reference Voltage Control"
Jean-François Moine87bae742010-11-12 05:31:34 -0300952 * = 76 (0x4c) 01001100
Hans de Goede635118d2009-10-11 09:49:03 -0300953 * VREF[7:5] "Column high reference control"
954 * = 2 (0x02) 010..... "higher voltage"
955 * VREF[4:2] "Column low reference control"
956 * = 3 (0x03) ...011.. "Highest voltage"
957 * VREF[1:0] "Reserved"
958 * = 0 (0x00) ......00
959 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300960 { 0x35, 0x4c },
Hans de Goede635118d2009-10-11 09:49:03 -0300961
962 /*
963 * 3D Undocumented = 0 (0x00) 00000000
964 * 3D[7:0] "It's a secret"
965 * = 0 (0x00) 00000000
966 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300967 { 0x3d, 0x00 },
Hans de Goede635118d2009-10-11 09:49:03 -0300968
969 /*
970 * 3E Undocumented = 0 (0x00) 00000000
971 * 3E[7:0] "It's a secret"
972 * = 0 (0x00) 00000000
973 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300974 { 0x3e, 0x00 },
Hans de Goede635118d2009-10-11 09:49:03 -0300975
976 /*
977 * 3B FREFB "Internal Reference Adjustment"
978 * = 24 (0x18) 00011000
979 * FREFB[7:0] "Range"
980 * = 24 (0x18) 00011000
981 */
982 { 0x3b, 0x18 },
983
984 /*
985 * 33 CHLF "Current Control"
986 * = 25 (0x19) 00011001
987 * CHLF[7:6] "Sensor current control"
988 * = 0 (0x00) 00......
989 * CHLF[5] "Sensor current range control"
990 * = 0 (0x00) ..0..... "normal range"
991 * CHLF[4] "Sensor current"
992 * = 1 (0x01) ...1.... "double current"
993 * CHLF[3] "Sensor buffer current control"
994 * = 1 (0x01) ....1... "half current"
995 * CHLF[2] "Column buffer current control"
996 * = 0 (0x00) .....0.. "normal current"
997 * CHLF[1] "Analog DSP current control"
998 * = 0 (0x00) ......0. "normal current"
999 * CHLF[1] "ADC current control"
1000 * = 0 (0x00) ......0. "normal current"
1001 */
1002 { 0x33, 0x19 },
1003
1004 /*
1005 * 34 VBLM "Blooming Control"
1006 * = 90 (0x5A) 01011010
1007 * VBLM[7] "Hard soft reset switch"
1008 * = 0 (0x00) 0....... "Hard reset"
1009 * VBLM[6:4] "Blooming voltage selection"
1010 * = 5 (0x05) .101....
1011 * VBLM[3:0] "Sensor current control"
1012 * = 10 (0x0A) ....1010
1013 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001014 { 0x34, 0x5a },
Hans de Goede635118d2009-10-11 09:49:03 -03001015
1016 /*
1017 * 3B FREFB "Internal Reference Adjustment"
1018 * = 0 (0x00) 00000000
1019 * FREFB[7:0] "Range"
1020 * = 0 (0x00) 00000000
1021 */
1022 { 0x3b, 0x00 },
1023
1024 /*
1025 * 33 CHLF "Current Control"
1026 * = 9 (0x09) 00001001
1027 * CHLF[7:6] "Sensor current control"
1028 * = 0 (0x00) 00......
1029 * CHLF[5] "Sensor current range control"
1030 * = 0 (0x00) ..0..... "normal range"
1031 * CHLF[4] "Sensor current"
1032 * = 0 (0x00) ...0.... "normal current"
1033 * CHLF[3] "Sensor buffer current control"
1034 * = 1 (0x01) ....1... "half current"
1035 * CHLF[2] "Column buffer current control"
1036 * = 0 (0x00) .....0.. "normal current"
1037 * CHLF[1] "Analog DSP current control"
1038 * = 0 (0x00) ......0. "normal current"
1039 * CHLF[1] "ADC current control"
1040 * = 0 (0x00) ......0. "normal current"
1041 */
1042 { 0x33, 0x09 },
1043
1044 /*
1045 * 34 VBLM "Blooming Control"
1046 * = 80 (0x50) 01010000
1047 * VBLM[7] "Hard soft reset switch"
1048 * = 0 (0x00) 0....... "Hard reset"
1049 * VBLM[6:4] "Blooming voltage selection"
1050 * = 5 (0x05) .101....
1051 * VBLM[3:0] "Sensor current control"
1052 * = 0 (0x00) ....0000
1053 */
1054 { 0x34, 0x50 },
1055
1056 /*
1057 * 12 COMH "Common Control H"
1058 * = 64 (0x40) 01000000
1059 * COMH[7] "SRST"
1060 * = 0 (0x00) 0....... "No-op"
1061 * COMH[6:4] "Resolution selection"
1062 * = 4 (0x04) .100.... "XGA"
1063 * COMH[3] "Master slave selection"
1064 * = 0 (0x00) ....0... "Master mode"
1065 * COMH[2] "Internal B/R channel option"
1066 * = 0 (0x00) .....0.. "B/R use same channel"
1067 * COMH[1] "Color bar test pattern"
1068 * = 0 (0x00) ......0. "Off"
1069 * COMH[0] "Reserved"
1070 * = 0 (0x00) .......0
1071 */
1072 { 0x12, 0x40 },
1073
1074 /*
1075 * 17 HREFST "Horizontal window start"
1076 * = 31 (0x1F) 00011111
1077 * HREFST[7:0] "Horizontal window start, 8 MSBs"
1078 * = 31 (0x1F) 00011111
1079 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001080 { 0x17, 0x1f },
Hans de Goede635118d2009-10-11 09:49:03 -03001081
1082 /*
1083 * 18 HREFEND "Horizontal window end"
1084 * = 95 (0x5F) 01011111
1085 * HREFEND[7:0] "Horizontal Window End, 8 MSBs"
1086 * = 95 (0x5F) 01011111
1087 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001088 { 0x18, 0x5f },
Hans de Goede635118d2009-10-11 09:49:03 -03001089
1090 /*
1091 * 19 VSTRT "Vertical window start"
1092 * = 0 (0x00) 00000000
1093 * VSTRT[7:0] "Vertical Window Start, 8 MSBs"
1094 * = 0 (0x00) 00000000
1095 */
1096 { 0x19, 0x00 },
1097
1098 /*
1099 * 1A VEND "Vertical window end"
1100 * = 96 (0x60) 01100000
1101 * VEND[7:0] "Vertical Window End, 8 MSBs"
1102 * = 96 (0x60) 01100000
1103 */
1104 { 0x1a, 0x60 },
1105
1106 /*
1107 * 32 COMM "Common Control M"
1108 * = 18 (0x12) 00010010
1109 * COMM[7:6] "Pixel clock divide option"
1110 * = 0 (0x00) 00...... "/1"
1111 * COMM[5:3] "Horizontal window end position, 3 LSBs"
1112 * = 2 (0x02) ..010...
1113 * COMM[2:0] "Horizontal window start position, 3 LSBs"
1114 * = 2 (0x02) .....010
1115 */
1116 { 0x32, 0x12 },
1117
1118 /*
1119 * 03 COMA "Common Control A"
1120 * = 74 (0x4A) 01001010
1121 * COMA[7:4] "AWB Update Threshold"
1122 * = 4 (0x04) 0100....
1123 * COMA[3:2] "Vertical window end line control 2 LSBs"
1124 * = 2 (0x02) ....10..
1125 * COMA[1:0] "Vertical window start line control 2 LSBs"
1126 * = 2 (0x02) ......10
1127 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001128 { 0x03, 0x4a },
Hans de Goede635118d2009-10-11 09:49:03 -03001129
1130 /*
1131 * 11 CLKRC "Clock Rate Control"
1132 * = 128 (0x80) 10000000
1133 * CLKRC[7] "Internal frequency doublers on off seclection"
1134 * = 1 (0x01) 1....... "On"
1135 * CLKRC[6] "Digital video master slave selection"
1136 * = 0 (0x00) .0...... "Master mode, sensor
1137 * provides PCLK"
1138 * CLKRC[5:0] "Clock divider { CLK = PCLK/(1+CLKRC[5:0]) }"
1139 * = 0 (0x00) ..000000
1140 */
1141 { 0x11, 0x80 },
1142
1143 /*
1144 * 12 COMH "Common Control H"
1145 * = 0 (0x00) 00000000
1146 * COMH[7] "SRST"
1147 * = 0 (0x00) 0....... "No-op"
1148 * COMH[6:4] "Resolution selection"
1149 * = 0 (0x00) .000.... "QXGA"
1150 * COMH[3] "Master slave selection"
1151 * = 0 (0x00) ....0... "Master mode"
1152 * COMH[2] "Internal B/R channel option"
1153 * = 0 (0x00) .....0.. "B/R use same channel"
1154 * COMH[1] "Color bar test pattern"
1155 * = 0 (0x00) ......0. "Off"
1156 * COMH[0] "Reserved"
1157 * = 0 (0x00) .......0
1158 */
1159 { 0x12, 0x00 },
1160
1161 /*
1162 * 12 COMH "Common Control H"
1163 * = 64 (0x40) 01000000
1164 * COMH[7] "SRST"
1165 * = 0 (0x00) 0....... "No-op"
1166 * COMH[6:4] "Resolution selection"
1167 * = 4 (0x04) .100.... "XGA"
1168 * COMH[3] "Master slave selection"
1169 * = 0 (0x00) ....0... "Master mode"
1170 * COMH[2] "Internal B/R channel option"
1171 * = 0 (0x00) .....0.. "B/R use same channel"
1172 * COMH[1] "Color bar test pattern"
1173 * = 0 (0x00) ......0. "Off"
1174 * COMH[0] "Reserved"
1175 * = 0 (0x00) .......0
1176 */
1177 { 0x12, 0x40 },
1178
1179 /*
1180 * 17 HREFST "Horizontal window start"
1181 * = 31 (0x1F) 00011111
1182 * HREFST[7:0] "Horizontal window start, 8 MSBs"
1183 * = 31 (0x1F) 00011111
1184 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001185 { 0x17, 0x1f },
Hans de Goede635118d2009-10-11 09:49:03 -03001186
1187 /*
1188 * 18 HREFEND "Horizontal window end"
1189 * = 95 (0x5F) 01011111
1190 * HREFEND[7:0] "Horizontal Window End, 8 MSBs"
1191 * = 95 (0x5F) 01011111
1192 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001193 { 0x18, 0x5f },
Hans de Goede635118d2009-10-11 09:49:03 -03001194
1195 /*
1196 * 19 VSTRT "Vertical window start"
1197 * = 0 (0x00) 00000000
1198 * VSTRT[7:0] "Vertical Window Start, 8 MSBs"
1199 * = 0 (0x00) 00000000
1200 */
1201 { 0x19, 0x00 },
1202
1203 /*
1204 * 1A VEND "Vertical window end"
1205 * = 96 (0x60) 01100000
1206 * VEND[7:0] "Vertical Window End, 8 MSBs"
1207 * = 96 (0x60) 01100000
1208 */
1209 { 0x1a, 0x60 },
1210
1211 /*
1212 * 32 COMM "Common Control M"
1213 * = 18 (0x12) 00010010
1214 * COMM[7:6] "Pixel clock divide option"
1215 * = 0 (0x00) 00...... "/1"
1216 * COMM[5:3] "Horizontal window end position, 3 LSBs"
1217 * = 2 (0x02) ..010...
1218 * COMM[2:0] "Horizontal window start position, 3 LSBs"
1219 * = 2 (0x02) .....010
1220 */
1221 { 0x32, 0x12 },
1222
1223 /*
1224 * 03 COMA "Common Control A"
1225 * = 74 (0x4A) 01001010
1226 * COMA[7:4] "AWB Update Threshold"
1227 * = 4 (0x04) 0100....
1228 * COMA[3:2] "Vertical window end line control 2 LSBs"
1229 * = 2 (0x02) ....10..
1230 * COMA[1:0] "Vertical window start line control 2 LSBs"
1231 * = 2 (0x02) ......10
1232 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001233 { 0x03, 0x4a },
Hans de Goede635118d2009-10-11 09:49:03 -03001234
1235 /*
1236 * 02 RED "Red Gain Control"
1237 * = 175 (0xAF) 10101111
1238 * RED[7] "Action"
1239 * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
1240 * RED[6:0] "Value"
1241 * = 47 (0x2F) .0101111
1242 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001243 { 0x02, 0xaf },
Hans de Goede635118d2009-10-11 09:49:03 -03001244
1245 /*
1246 * 2D ADDVSL "VSYNC Pulse Width"
1247 * = 210 (0xD2) 11010010
1248 * ADDVSL[7:0] "VSYNC pulse width, LSB"
1249 * = 210 (0xD2) 11010010
1250 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001251 { 0x2d, 0xd2 },
Hans de Goede635118d2009-10-11 09:49:03 -03001252
1253 /*
1254 * 00 GAIN = 24 (0x18) 00011000
1255 * GAIN[7:6] "Reserved"
1256 * = 0 (0x00) 00......
1257 * GAIN[5] "Double"
1258 * = 0 (0x00) ..0..... "False"
1259 * GAIN[4] "Double"
1260 * = 1 (0x01) ...1.... "True"
1261 * GAIN[3:0] "Range"
1262 * = 8 (0x08) ....1000
1263 */
1264 { 0x00, 0x18 },
1265
1266 /*
1267 * 01 BLUE "Blue Gain Control"
1268 * = 240 (0xF0) 11110000
1269 * BLUE[7] "Action"
1270 * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
1271 * BLUE[6:0] "Value"
1272 * = 112 (0x70) .1110000
1273 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001274 { 0x01, 0xf0 },
Hans de Goede635118d2009-10-11 09:49:03 -03001275
1276 /*
1277 * 10 AEC "Automatic Exposure Control"
1278 * = 10 (0x0A) 00001010
1279 * AEC[7:0] "Automatic Exposure Control, 8 MSBs"
1280 * = 10 (0x0A) 00001010
1281 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001282 { 0x10, 0x0a },
Hans de Goede635118d2009-10-11 09:49:03 -03001283
Jean-François Moine87bae742010-11-12 05:31:34 -03001284 { 0xe1, 0x67 },
1285 { 0xe3, 0x03 },
1286 { 0xe4, 0x26 },
1287 { 0xe5, 0x3e },
1288 { 0xf8, 0x01 },
1289 { 0xff, 0x01 },
Hans de Goede635118d2009-10-11 09:49:03 -03001290};
1291
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001292static const struct ov_i2c_regvals norm_6x20[] = {
1293 { 0x12, 0x80 }, /* reset */
1294 { 0x11, 0x01 },
1295 { 0x03, 0x60 },
1296 { 0x05, 0x7f }, /* For when autoadjust is off */
1297 { 0x07, 0xa8 },
Jean-François Moine87bae742010-11-12 05:31:34 -03001298 /* The ratio of 0x0c and 0x0d controls the white point */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001299 { 0x0c, 0x24 },
1300 { 0x0d, 0x24 },
1301 { 0x0f, 0x15 }, /* COMS */
1302 { 0x10, 0x75 }, /* AEC Exposure time */
1303 { 0x12, 0x24 }, /* Enable AGC */
1304 { 0x14, 0x04 },
1305 /* 0x16: 0x06 helps frame stability with moving objects */
1306 { 0x16, 0x06 },
1307/* { 0x20, 0x30 }, * Aperture correction enable */
1308 { 0x26, 0xb2 }, /* BLC enable */
1309 /* 0x28: 0x05 Selects RGB format if RGB on */
1310 { 0x28, 0x05 },
1311 { 0x2a, 0x04 }, /* Disable framerate adjust */
1312/* { 0x2b, 0xac }, * Framerate; Set 2a[7] first */
Hans de Goedeae49c402009-06-14 19:15:07 -03001313 { 0x2d, 0x85 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001314 { 0x33, 0xa0 }, /* Color Processing Parameter */
1315 { 0x34, 0xd2 }, /* Max A/D range */
1316 { 0x38, 0x8b },
1317 { 0x39, 0x40 },
1318
1319 { 0x3c, 0x39 }, /* Enable AEC mode changing */
1320 { 0x3c, 0x3c }, /* Change AEC mode */
1321 { 0x3c, 0x24 }, /* Disable AEC mode changing */
1322
1323 { 0x3d, 0x80 },
1324 /* These next two registers (0x4a, 0x4b) are undocumented.
1325 * They control the color balance */
1326 { 0x4a, 0x80 },
1327 { 0x4b, 0x80 },
1328 { 0x4d, 0xd2 }, /* This reduces noise a bit */
1329 { 0x4e, 0xc1 },
1330 { 0x4f, 0x04 },
1331/* Do 50-53 have any effect? */
1332/* Toggle 0x12[2] off and on here? */
1333};
1334
1335static const struct ov_i2c_regvals norm_6x30[] = {
1336 { 0x12, 0x80 }, /* Reset */
1337 { 0x00, 0x1f }, /* Gain */
1338 { 0x01, 0x99 }, /* Blue gain */
1339 { 0x02, 0x7c }, /* Red gain */
1340 { 0x03, 0xc0 }, /* Saturation */
1341 { 0x05, 0x0a }, /* Contrast */
1342 { 0x06, 0x95 }, /* Brightness */
1343 { 0x07, 0x2d }, /* Sharpness */
1344 { 0x0c, 0x20 },
1345 { 0x0d, 0x20 },
Hans de Goede02ab18b2009-06-14 04:32:04 -03001346 { 0x0e, 0xa0 }, /* Was 0x20, bit7 enables a 2x gain which we need */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001347 { 0x0f, 0x05 },
1348 { 0x10, 0x9a },
1349 { 0x11, 0x00 }, /* Pixel clock = fastest */
1350 { 0x12, 0x24 }, /* Enable AGC and AWB */
1351 { 0x13, 0x21 },
1352 { 0x14, 0x80 },
1353 { 0x15, 0x01 },
1354 { 0x16, 0x03 },
1355 { 0x17, 0x38 },
1356 { 0x18, 0xea },
1357 { 0x19, 0x04 },
1358 { 0x1a, 0x93 },
1359 { 0x1b, 0x00 },
1360 { 0x1e, 0xc4 },
1361 { 0x1f, 0x04 },
1362 { 0x20, 0x20 },
1363 { 0x21, 0x10 },
1364 { 0x22, 0x88 },
1365 { 0x23, 0xc0 }, /* Crystal circuit power level */
1366 { 0x25, 0x9a }, /* Increase AEC black ratio */
1367 { 0x26, 0xb2 }, /* BLC enable */
1368 { 0x27, 0xa2 },
1369 { 0x28, 0x00 },
1370 { 0x29, 0x00 },
1371 { 0x2a, 0x84 }, /* 60 Hz power */
1372 { 0x2b, 0xa8 }, /* 60 Hz power */
1373 { 0x2c, 0xa0 },
1374 { 0x2d, 0x95 }, /* Enable auto-brightness */
1375 { 0x2e, 0x88 },
1376 { 0x33, 0x26 },
1377 { 0x34, 0x03 },
1378 { 0x36, 0x8f },
1379 { 0x37, 0x80 },
1380 { 0x38, 0x83 },
1381 { 0x39, 0x80 },
1382 { 0x3a, 0x0f },
1383 { 0x3b, 0x3c },
1384 { 0x3c, 0x1a },
1385 { 0x3d, 0x80 },
1386 { 0x3e, 0x80 },
1387 { 0x3f, 0x0e },
1388 { 0x40, 0x00 }, /* White bal */
1389 { 0x41, 0x00 }, /* White bal */
1390 { 0x42, 0x80 },
1391 { 0x43, 0x3f }, /* White bal */
1392 { 0x44, 0x80 },
1393 { 0x45, 0x20 },
1394 { 0x46, 0x20 },
1395 { 0x47, 0x80 },
1396 { 0x48, 0x7f },
1397 { 0x49, 0x00 },
1398 { 0x4a, 0x00 },
1399 { 0x4b, 0x80 },
1400 { 0x4c, 0xd0 },
1401 { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
1402 { 0x4e, 0x40 },
1403 { 0x4f, 0x07 }, /* UV avg., col. killer: max */
1404 { 0x50, 0xff },
1405 { 0x54, 0x23 }, /* Max AGC gain: 18dB */
1406 { 0x55, 0xff },
1407 { 0x56, 0x12 },
1408 { 0x57, 0x81 },
1409 { 0x58, 0x75 },
1410 { 0x59, 0x01 }, /* AGC dark current comp.: +1 */
1411 { 0x5a, 0x2c },
1412 { 0x5b, 0x0f }, /* AWB chrominance levels */
1413 { 0x5c, 0x10 },
1414 { 0x3d, 0x80 },
1415 { 0x27, 0xa6 },
1416 { 0x12, 0x20 }, /* Toggle AWB */
1417 { 0x12, 0x24 },
1418};
1419
1420/* Lawrence Glaister <lg@jfm.bc.ca> reports:
1421 *
1422 * Register 0x0f in the 7610 has the following effects:
1423 *
1424 * 0x85 (AEC method 1): Best overall, good contrast range
1425 * 0x45 (AEC method 2): Very overexposed
1426 * 0xa5 (spec sheet default): Ok, but the black level is
1427 * shifted resulting in loss of contrast
1428 * 0x05 (old driver setting): very overexposed, too much
1429 * contrast
1430 */
1431static const struct ov_i2c_regvals norm_7610[] = {
1432 { 0x10, 0xff },
1433 { 0x16, 0x06 },
1434 { 0x28, 0x24 },
1435 { 0x2b, 0xac },
1436 { 0x12, 0x00 },
1437 { 0x38, 0x81 },
1438 { 0x28, 0x24 }, /* 0c */
1439 { 0x0f, 0x85 }, /* lg's setting */
1440 { 0x15, 0x01 },
1441 { 0x20, 0x1c },
1442 { 0x23, 0x2a },
1443 { 0x24, 0x10 },
1444 { 0x25, 0x8a },
1445 { 0x26, 0xa2 },
1446 { 0x27, 0xc2 },
1447 { 0x2a, 0x04 },
1448 { 0x2c, 0xfe },
1449 { 0x2d, 0x93 },
1450 { 0x30, 0x71 },
1451 { 0x31, 0x60 },
1452 { 0x32, 0x26 },
1453 { 0x33, 0x20 },
1454 { 0x34, 0x48 },
1455 { 0x12, 0x24 },
1456 { 0x11, 0x01 },
1457 { 0x0c, 0x24 },
1458 { 0x0d, 0x24 },
1459};
1460
1461static const struct ov_i2c_regvals norm_7620[] = {
Hans de Goedea511ba92009-10-16 07:13:07 -03001462 { 0x12, 0x80 }, /* reset */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001463 { 0x00, 0x00 }, /* gain */
1464 { 0x01, 0x80 }, /* blue gain */
1465 { 0x02, 0x80 }, /* red gain */
Jean-François Moine21867802010-11-12 06:12:09 -03001466 { 0x03, 0xc0 }, /* OV7670_R03_VREF */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001467 { 0x06, 0x60 },
1468 { 0x07, 0x00 },
1469 { 0x0c, 0x24 },
1470 { 0x0c, 0x24 },
1471 { 0x0d, 0x24 },
1472 { 0x11, 0x01 },
1473 { 0x12, 0x24 },
1474 { 0x13, 0x01 },
1475 { 0x14, 0x84 },
1476 { 0x15, 0x01 },
1477 { 0x16, 0x03 },
1478 { 0x17, 0x2f },
1479 { 0x18, 0xcf },
1480 { 0x19, 0x06 },
1481 { 0x1a, 0xf5 },
1482 { 0x1b, 0x00 },
1483 { 0x20, 0x18 },
1484 { 0x21, 0x80 },
1485 { 0x22, 0x80 },
1486 { 0x23, 0x00 },
1487 { 0x26, 0xa2 },
1488 { 0x27, 0xea },
Hans de Goedeb282d872009-06-14 19:10:40 -03001489 { 0x28, 0x22 }, /* Was 0x20, bit1 enables a 2x gain which we need */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001490 { 0x29, 0x00 },
1491 { 0x2a, 0x10 },
1492 { 0x2b, 0x00 },
1493 { 0x2c, 0x88 },
1494 { 0x2d, 0x91 },
1495 { 0x2e, 0x80 },
1496 { 0x2f, 0x44 },
1497 { 0x60, 0x27 },
1498 { 0x61, 0x02 },
1499 { 0x62, 0x5f },
1500 { 0x63, 0xd5 },
1501 { 0x64, 0x57 },
1502 { 0x65, 0x83 },
1503 { 0x66, 0x55 },
1504 { 0x67, 0x92 },
1505 { 0x68, 0xcf },
1506 { 0x69, 0x76 },
1507 { 0x6a, 0x22 },
1508 { 0x6b, 0x00 },
1509 { 0x6c, 0x02 },
1510 { 0x6d, 0x44 },
1511 { 0x6e, 0x80 },
1512 { 0x6f, 0x1d },
1513 { 0x70, 0x8b },
1514 { 0x71, 0x00 },
1515 { 0x72, 0x14 },
1516 { 0x73, 0x54 },
1517 { 0x74, 0x00 },
1518 { 0x75, 0x8e },
1519 { 0x76, 0x00 },
1520 { 0x77, 0xff },
1521 { 0x78, 0x80 },
1522 { 0x79, 0x80 },
1523 { 0x7a, 0x80 },
1524 { 0x7b, 0xe2 },
1525 { 0x7c, 0x00 },
1526};
1527
1528/* 7640 and 7648. The defaults should be OK for most registers. */
1529static const struct ov_i2c_regvals norm_7640[] = {
1530 { 0x12, 0x80 },
1531 { 0x12, 0x14 },
1532};
1533
1534/* 7670. Defaults taken from OmniVision provided data,
1535* as provided by Jonathan Corbet of OLPC */
1536static const struct ov_i2c_regvals norm_7670[] = {
Jean-François Moine21867802010-11-12 06:12:09 -03001537 { OV7670_R12_COM7, OV7670_COM7_RESET },
1538 { OV7670_R3A_TSLB, 0x04 }, /* OV */
1539 { OV7670_R12_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
1540 { OV7670_R11_CLKRC, 0x01 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001541/*
1542 * Set the hardware window. These values from OV don't entirely
1543 * make sense - hstop is less than hstart. But they work...
1544 */
Jean-François Moine21867802010-11-12 06:12:09 -03001545 { OV7670_R17_HSTART, 0x13 },
1546 { OV7670_R18_HSTOP, 0x01 },
1547 { OV7670_R32_HREF, 0xb6 },
1548 { OV7670_R19_VSTART, 0x02 },
1549 { OV7670_R1A_VSTOP, 0x7a },
1550 { OV7670_R03_VREF, 0x0a },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001551
Jean-François Moine21867802010-11-12 06:12:09 -03001552 { OV7670_R0C_COM3, 0x00 },
1553 { OV7670_R3E_COM14, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001554/* Mystery scaling numbers */
1555 { 0x70, 0x3a },
1556 { 0x71, 0x35 },
1557 { 0x72, 0x11 },
1558 { 0x73, 0xf0 },
1559 { 0xa2, 0x02 },
Jean-François Moine21867802010-11-12 06:12:09 -03001560/* { OV7670_R15_COM10, 0x0 }, */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001561
1562/* Gamma curve values */
1563 { 0x7a, 0x20 },
1564 { 0x7b, 0x10 },
1565 { 0x7c, 0x1e },
1566 { 0x7d, 0x35 },
1567 { 0x7e, 0x5a },
1568 { 0x7f, 0x69 },
1569 { 0x80, 0x76 },
1570 { 0x81, 0x80 },
1571 { 0x82, 0x88 },
1572 { 0x83, 0x8f },
1573 { 0x84, 0x96 },
1574 { 0x85, 0xa3 },
1575 { 0x86, 0xaf },
1576 { 0x87, 0xc4 },
1577 { 0x88, 0xd7 },
1578 { 0x89, 0xe8 },
1579
1580/* AGC and AEC parameters. Note we start by disabling those features,
1581 then turn them only after tweaking the values. */
Jean-François Moine21867802010-11-12 06:12:09 -03001582 { OV7670_R13_COM8, OV7670_COM8_FASTAEC
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001583 | OV7670_COM8_AECSTEP
1584 | OV7670_COM8_BFILT },
Jean-François Moine21867802010-11-12 06:12:09 -03001585 { OV7670_R00_GAIN, 0x00 },
1586 { OV7670_R10_AECH, 0x00 },
1587 { OV7670_R0D_COM4, 0x40 }, /* magic reserved bit */
1588 { OV7670_R14_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
1589 { OV7670_RA5_BD50MAX, 0x05 },
1590 { OV7670_RAB_BD60MAX, 0x07 },
1591 { OV7670_R24_AEW, 0x95 },
1592 { OV7670_R25_AEB, 0x33 },
1593 { OV7670_R26_VPT, 0xe3 },
1594 { OV7670_R9F_HAECC1, 0x78 },
1595 { OV7670_RA0_HAECC2, 0x68 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001596 { 0xa1, 0x03 }, /* magic */
Jean-François Moine21867802010-11-12 06:12:09 -03001597 { OV7670_RA6_HAECC3, 0xd8 },
1598 { OV7670_RA7_HAECC4, 0xd8 },
1599 { OV7670_RA8_HAECC5, 0xf0 },
1600 { OV7670_RA9_HAECC6, 0x90 },
1601 { OV7670_RAA_HAECC7, 0x94 },
1602 { OV7670_R13_COM8, OV7670_COM8_FASTAEC
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001603 | OV7670_COM8_AECSTEP
1604 | OV7670_COM8_BFILT
1605 | OV7670_COM8_AGC
1606 | OV7670_COM8_AEC },
1607
1608/* Almost all of these are magic "reserved" values. */
Jean-François Moine21867802010-11-12 06:12:09 -03001609 { OV7670_R0E_COM5, 0x61 },
1610 { OV7670_R0F_COM6, 0x4b },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001611 { 0x16, 0x02 },
Jean-François Moine21867802010-11-12 06:12:09 -03001612 { OV7670_R1E_MVFP, 0x07 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001613 { 0x21, 0x02 },
1614 { 0x22, 0x91 },
1615 { 0x29, 0x07 },
1616 { 0x33, 0x0b },
1617 { 0x35, 0x0b },
1618 { 0x37, 0x1d },
1619 { 0x38, 0x71 },
1620 { 0x39, 0x2a },
Jean-François Moine21867802010-11-12 06:12:09 -03001621 { OV7670_R3C_COM12, 0x78 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001622 { 0x4d, 0x40 },
1623 { 0x4e, 0x20 },
Jean-François Moine21867802010-11-12 06:12:09 -03001624 { OV7670_R69_GFIX, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001625 { 0x6b, 0x4a },
1626 { 0x74, 0x10 },
1627 { 0x8d, 0x4f },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001628 { 0x8e, 0x00 },
1629 { 0x8f, 0x00 },
1630 { 0x90, 0x00 },
1631 { 0x91, 0x00 },
1632 { 0x96, 0x00 },
1633 { 0x9a, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001634 { 0xb0, 0x84 },
1635 { 0xb1, 0x0c },
1636 { 0xb2, 0x0e },
1637 { 0xb3, 0x82 },
1638 { 0xb8, 0x0a },
1639
1640/* More reserved magic, some of which tweaks white balance */
1641 { 0x43, 0x0a },
1642 { 0x44, 0xf0 },
1643 { 0x45, 0x34 },
1644 { 0x46, 0x58 },
1645 { 0x47, 0x28 },
1646 { 0x48, 0x3a },
1647 { 0x59, 0x88 },
1648 { 0x5a, 0x88 },
1649 { 0x5b, 0x44 },
1650 { 0x5c, 0x67 },
1651 { 0x5d, 0x49 },
1652 { 0x5e, 0x0e },
1653 { 0x6c, 0x0a },
1654 { 0x6d, 0x55 },
1655 { 0x6e, 0x11 },
1656 { 0x6f, 0x9f },
1657 /* "9e for advance AWB" */
1658 { 0x6a, 0x40 },
Jean-François Moine21867802010-11-12 06:12:09 -03001659 { OV7670_R01_BLUE, 0x40 },
1660 { OV7670_R02_RED, 0x60 },
1661 { OV7670_R13_COM8, OV7670_COM8_FASTAEC
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001662 | OV7670_COM8_AECSTEP
1663 | OV7670_COM8_BFILT
1664 | OV7670_COM8_AGC
1665 | OV7670_COM8_AEC
1666 | OV7670_COM8_AWB },
1667
1668/* Matrix coefficients */
1669 { 0x4f, 0x80 },
1670 { 0x50, 0x80 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001671 { 0x51, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001672 { 0x52, 0x22 },
1673 { 0x53, 0x5e },
1674 { 0x54, 0x80 },
1675 { 0x58, 0x9e },
1676
Jean-François Moine21867802010-11-12 06:12:09 -03001677 { OV7670_R41_COM16, OV7670_COM16_AWBGAIN },
1678 { OV7670_R3F_EDGE, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001679 { 0x75, 0x05 },
1680 { 0x76, 0xe1 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001681 { 0x4c, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001682 { 0x77, 0x01 },
Jean-François Moine21867802010-11-12 06:12:09 -03001683 { OV7670_R3D_COM13, OV7670_COM13_GAMMA
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001684 | OV7670_COM13_UVSAT
1685 | 2}, /* was 3 */
1686 { 0x4b, 0x09 },
1687 { 0xc9, 0x60 },
Jean-François Moine21867802010-11-12 06:12:09 -03001688 { OV7670_R41_COM16, 0x38 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001689 { 0x56, 0x40 },
1690
1691 { 0x34, 0x11 },
Jean-François Moine21867802010-11-12 06:12:09 -03001692 { OV7670_R3B_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001693 { 0xa4, 0x88 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001694 { 0x96, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001695 { 0x97, 0x30 },
1696 { 0x98, 0x20 },
1697 { 0x99, 0x30 },
1698 { 0x9a, 0x84 },
1699 { 0x9b, 0x29 },
1700 { 0x9c, 0x03 },
1701 { 0x9d, 0x4c },
1702 { 0x9e, 0x3f },
1703 { 0x78, 0x04 },
1704
1705/* Extra-weird stuff. Some sort of multiplexor register */
1706 { 0x79, 0x01 },
1707 { 0xc8, 0xf0 },
1708 { 0x79, 0x0f },
1709 { 0xc8, 0x00 },
1710 { 0x79, 0x10 },
1711 { 0xc8, 0x7e },
1712 { 0x79, 0x0a },
1713 { 0xc8, 0x80 },
1714 { 0x79, 0x0b },
1715 { 0xc8, 0x01 },
1716 { 0x79, 0x0c },
1717 { 0xc8, 0x0f },
1718 { 0x79, 0x0d },
1719 { 0xc8, 0x20 },
1720 { 0x79, 0x09 },
1721 { 0xc8, 0x80 },
1722 { 0x79, 0x02 },
1723 { 0xc8, 0xc0 },
1724 { 0x79, 0x03 },
1725 { 0xc8, 0x40 },
1726 { 0x79, 0x05 },
1727 { 0xc8, 0x30 },
1728 { 0x79, 0x26 },
1729};
1730
1731static const struct ov_i2c_regvals norm_8610[] = {
1732 { 0x12, 0x80 },
1733 { 0x00, 0x00 },
1734 { 0x01, 0x80 },
1735 { 0x02, 0x80 },
1736 { 0x03, 0xc0 },
1737 { 0x04, 0x30 },
1738 { 0x05, 0x30 }, /* was 0x10, new from windrv 090403 */
1739 { 0x06, 0x70 }, /* was 0x80, new from windrv 090403 */
1740 { 0x0a, 0x86 },
1741 { 0x0b, 0xb0 },
1742 { 0x0c, 0x20 },
1743 { 0x0d, 0x20 },
1744 { 0x11, 0x01 },
1745 { 0x12, 0x25 },
1746 { 0x13, 0x01 },
1747 { 0x14, 0x04 },
1748 { 0x15, 0x01 }, /* Lin and Win think different about UV order */
1749 { 0x16, 0x03 },
1750 { 0x17, 0x38 }, /* was 0x2f, new from windrv 090403 */
1751 { 0x18, 0xea }, /* was 0xcf, new from windrv 090403 */
1752 { 0x19, 0x02 }, /* was 0x06, new from windrv 090403 */
1753 { 0x1a, 0xf5 },
1754 { 0x1b, 0x00 },
1755 { 0x20, 0xd0 }, /* was 0x90, new from windrv 090403 */
1756 { 0x23, 0xc0 }, /* was 0x00, new from windrv 090403 */
1757 { 0x24, 0x30 }, /* was 0x1d, new from windrv 090403 */
1758 { 0x25, 0x50 }, /* was 0x57, new from windrv 090403 */
1759 { 0x26, 0xa2 },
1760 { 0x27, 0xea },
1761 { 0x28, 0x00 },
1762 { 0x29, 0x00 },
1763 { 0x2a, 0x80 },
1764 { 0x2b, 0xc8 }, /* was 0xcc, new from windrv 090403 */
1765 { 0x2c, 0xac },
1766 { 0x2d, 0x45 }, /* was 0xd5, new from windrv 090403 */
1767 { 0x2e, 0x80 },
1768 { 0x2f, 0x14 }, /* was 0x01, new from windrv 090403 */
1769 { 0x4c, 0x00 },
1770 { 0x4d, 0x30 }, /* was 0x10, new from windrv 090403 */
1771 { 0x60, 0x02 }, /* was 0x01, new from windrv 090403 */
1772 { 0x61, 0x00 }, /* was 0x09, new from windrv 090403 */
1773 { 0x62, 0x5f }, /* was 0xd7, new from windrv 090403 */
1774 { 0x63, 0xff },
1775 { 0x64, 0x53 }, /* new windrv 090403 says 0x57,
1776 * maybe thats wrong */
1777 { 0x65, 0x00 },
1778 { 0x66, 0x55 },
1779 { 0x67, 0xb0 },
1780 { 0x68, 0xc0 }, /* was 0xaf, new from windrv 090403 */
1781 { 0x69, 0x02 },
1782 { 0x6a, 0x22 },
1783 { 0x6b, 0x00 },
1784 { 0x6c, 0x99 }, /* was 0x80, old windrv says 0x00, but
1785 * deleting bit7 colors the first images red */
1786 { 0x6d, 0x11 }, /* was 0x00, new from windrv 090403 */
1787 { 0x6e, 0x11 }, /* was 0x00, new from windrv 090403 */
1788 { 0x6f, 0x01 },
1789 { 0x70, 0x8b },
1790 { 0x71, 0x00 },
1791 { 0x72, 0x14 },
1792 { 0x73, 0x54 },
1793 { 0x74, 0x00 },/* 0x60? - was 0x00, new from windrv 090403 */
1794 { 0x75, 0x0e },
1795 { 0x76, 0x02 }, /* was 0x02, new from windrv 090403 */
1796 { 0x77, 0xff },
1797 { 0x78, 0x80 },
1798 { 0x79, 0x80 },
1799 { 0x7a, 0x80 },
1800 { 0x7b, 0x10 }, /* was 0x13, new from windrv 090403 */
1801 { 0x7c, 0x00 },
1802 { 0x7d, 0x08 }, /* was 0x09, new from windrv 090403 */
1803 { 0x7e, 0x08 }, /* was 0xc0, new from windrv 090403 */
1804 { 0x7f, 0xfb },
1805 { 0x80, 0x28 },
1806 { 0x81, 0x00 },
1807 { 0x82, 0x23 },
1808 { 0x83, 0x0b },
1809 { 0x84, 0x00 },
1810 { 0x85, 0x62 }, /* was 0x61, new from windrv 090403 */
1811 { 0x86, 0xc9 },
1812 { 0x87, 0x00 },
1813 { 0x88, 0x00 },
1814 { 0x89, 0x01 },
1815 { 0x12, 0x20 },
1816 { 0x12, 0x25 }, /* was 0x24, new from windrv 090403 */
1817};
1818
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001819static unsigned char ov7670_abs_to_sm(unsigned char v)
1820{
1821 if (v > 127)
1822 return v & 0x7f;
1823 return (128 - v) | 0x80;
1824}
1825
1826/* Write a OV519 register */
Jean-François Moine9d1593a2010-11-11 08:04:06 -03001827static int reg_w(struct sd *sd, u16 index, u16 value)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001828{
Hans de Goedea511ba92009-10-16 07:13:07 -03001829 int ret, req = 0;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001830
1831 switch (sd->bridge) {
1832 case BRIDGE_OV511:
1833 case BRIDGE_OV511PLUS:
1834 req = 2;
1835 break;
1836 case BRIDGE_OVFX2:
Hans de Goedea511ba92009-10-16 07:13:07 -03001837 req = 0x0a;
1838 /* fall through */
1839 case BRIDGE_W9968CF:
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001840 ret = usb_control_msg(sd->gspca_dev.dev,
1841 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
Hans de Goedea511ba92009-10-16 07:13:07 -03001842 req,
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001843 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Hans de Goedea511ba92009-10-16 07:13:07 -03001844 value, index, NULL, 0, 500);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001845 goto leave;
1846 default:
1847 req = 1;
1848 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001849
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001850 sd->gspca_dev.usb_buf[0] = value;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001851 ret = usb_control_msg(sd->gspca_dev.dev,
1852 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
Hans de Goede49809d62009-06-07 12:10:39 -03001853 req,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001854 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1855 0, index,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001856 sd->gspca_dev.usb_buf, 1, 500);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001857leave:
Hans de Goedea511ba92009-10-16 07:13:07 -03001858 if (ret < 0) {
Jean-François Moine0b656322010-09-13 05:19:58 -03001859 err("Write reg 0x%04x -> [0x%02x] failed",
Hans de Goedea511ba92009-10-16 07:13:07 -03001860 value, index);
1861 return ret;
1862 }
1863
1864 PDEBUG(D_USBO, "Write reg 0x%04x -> [0x%02x]", value, index);
1865 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001866}
1867
Hans de Goedea511ba92009-10-16 07:13:07 -03001868/* Read from a OV519 register, note not valid for the w9968cf!! */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001869/* returns: negative is error, pos or zero is data */
Jean-François Moine9d1593a2010-11-11 08:04:06 -03001870static int reg_r(struct sd *sd, u16 index)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001871{
1872 int ret;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001873 int req;
1874
1875 switch (sd->bridge) {
1876 case BRIDGE_OV511:
1877 case BRIDGE_OV511PLUS:
1878 req = 3;
1879 break;
1880 case BRIDGE_OVFX2:
1881 req = 0x0b;
1882 break;
1883 default:
1884 req = 1;
1885 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001886
1887 ret = usb_control_msg(sd->gspca_dev.dev,
1888 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
Hans de Goede49809d62009-06-07 12:10:39 -03001889 req,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001890 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001891 0, index, sd->gspca_dev.usb_buf, 1, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001892
Hans de Goedea511ba92009-10-16 07:13:07 -03001893 if (ret >= 0) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001894 ret = sd->gspca_dev.usb_buf[0];
Hans de Goedea511ba92009-10-16 07:13:07 -03001895 PDEBUG(D_USBI, "Read reg [0x%02X] -> 0x%04X", index, ret);
1896 } else
Jean-François Moine0b656322010-09-13 05:19:58 -03001897 err("Read reg [0x%02x] failed", index);
Hans de Goedea511ba92009-10-16 07:13:07 -03001898
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001899 return ret;
1900}
1901
1902/* Read 8 values from a OV519 register */
1903static int reg_r8(struct sd *sd,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03001904 u16 index)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001905{
1906 int ret;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001907
1908 ret = usb_control_msg(sd->gspca_dev.dev,
1909 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
1910 1, /* REQ_IO */
1911 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001912 0, index, sd->gspca_dev.usb_buf, 8, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001913
1914 if (ret >= 0)
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001915 ret = sd->gspca_dev.usb_buf[0];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001916 else
Jean-François Moine0b656322010-09-13 05:19:58 -03001917 err("Read reg 8 [0x%02x] failed", index);
Hans de Goedea511ba92009-10-16 07:13:07 -03001918
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001919 return ret;
1920}
1921
1922/*
1923 * Writes bits at positions specified by mask to an OV51x reg. Bits that are in
1924 * the same position as 1's in "mask" are cleared and set to "value". Bits
1925 * that are in the same position as 0's in "mask" are preserved, regardless
1926 * of their respective state in "value".
1927 */
1928static int reg_w_mask(struct sd *sd,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03001929 u16 index,
1930 u8 value,
1931 u8 mask)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001932{
1933 int ret;
Jean-François Moine9d1593a2010-11-11 08:04:06 -03001934 u8 oldval;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001935
1936 if (mask != 0xff) {
1937 value &= mask; /* Enforce mask on value */
1938 ret = reg_r(sd, index);
1939 if (ret < 0)
1940 return ret;
1941
1942 oldval = ret & ~mask; /* Clear the masked bits */
1943 value |= oldval; /* Set the desired bits */
1944 }
1945 return reg_w(sd, index, value);
1946}
1947
1948/*
Hans de Goede49809d62009-06-07 12:10:39 -03001949 * Writes multiple (n) byte value to a single register. Only valid with certain
1950 * registers (0x30 and 0xc4 - 0xce).
1951 */
Jean-François Moine9d1593a2010-11-11 08:04:06 -03001952static int ov518_reg_w32(struct sd *sd, u16 index, u32 value, int n)
Hans de Goede49809d62009-06-07 12:10:39 -03001953{
1954 int ret;
1955
Jean-Francois Moine83955552009-12-12 06:58:01 -03001956 *((__le32 *) sd->gspca_dev.usb_buf) = __cpu_to_le32(value);
Hans de Goede49809d62009-06-07 12:10:39 -03001957
1958 ret = usb_control_msg(sd->gspca_dev.dev,
1959 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
1960 1 /* REG_IO */,
1961 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1962 0, index,
1963 sd->gspca_dev.usb_buf, n, 500);
Hans de Goedea511ba92009-10-16 07:13:07 -03001964 if (ret < 0) {
Jean-François Moine0b656322010-09-13 05:19:58 -03001965 err("Write reg32 [%02x] %08x failed", index, value);
Hans de Goedea511ba92009-10-16 07:13:07 -03001966 return ret;
1967 }
1968
1969 return 0;
Hans de Goede49809d62009-06-07 12:10:39 -03001970}
1971
Jean-François Moine9d1593a2010-11-11 08:04:06 -03001972static int ov511_i2c_w(struct sd *sd, u8 reg, u8 value)
Hans de Goede1876bb92009-06-14 06:45:50 -03001973{
1974 int rc, retries;
1975
1976 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
1977
1978 /* Three byte write cycle */
1979 for (retries = 6; ; ) {
1980 /* Select camera register */
1981 rc = reg_w(sd, R51x_I2C_SADDR_3, reg);
1982 if (rc < 0)
1983 return rc;
1984
1985 /* Write "value" to I2C data port of OV511 */
1986 rc = reg_w(sd, R51x_I2C_DATA, value);
1987 if (rc < 0)
1988 return rc;
1989
1990 /* Initiate 3-byte write cycle */
1991 rc = reg_w(sd, R511_I2C_CTL, 0x01);
1992 if (rc < 0)
1993 return rc;
1994
Jean-Francois Moine83955552009-12-12 06:58:01 -03001995 do {
Hans de Goede1876bb92009-06-14 06:45:50 -03001996 rc = reg_r(sd, R511_I2C_CTL);
Jean-Francois Moine83955552009-12-12 06:58:01 -03001997 } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
Hans de Goede1876bb92009-06-14 06:45:50 -03001998
1999 if (rc < 0)
2000 return rc;
2001
2002 if ((rc & 2) == 0) /* Ack? */
2003 break;
2004 if (--retries < 0) {
2005 PDEBUG(D_USBO, "i2c write retries exhausted");
2006 return -1;
2007 }
2008 }
2009
2010 return 0;
2011}
2012
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002013static int ov511_i2c_r(struct sd *sd, u8 reg)
Hans de Goede1876bb92009-06-14 06:45:50 -03002014{
2015 int rc, value, retries;
2016
2017 /* Two byte write cycle */
2018 for (retries = 6; ; ) {
2019 /* Select camera register */
2020 rc = reg_w(sd, R51x_I2C_SADDR_2, reg);
2021 if (rc < 0)
2022 return rc;
2023
2024 /* Initiate 2-byte write cycle */
2025 rc = reg_w(sd, R511_I2C_CTL, 0x03);
2026 if (rc < 0)
2027 return rc;
2028
Jean-Francois Moine83955552009-12-12 06:58:01 -03002029 do {
Hans de Goede1876bb92009-06-14 06:45:50 -03002030 rc = reg_r(sd, R511_I2C_CTL);
Jean-Francois Moine83955552009-12-12 06:58:01 -03002031 } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
Hans de Goede1876bb92009-06-14 06:45:50 -03002032
2033 if (rc < 0)
2034 return rc;
2035
2036 if ((rc & 2) == 0) /* Ack? */
2037 break;
2038
2039 /* I2C abort */
2040 reg_w(sd, R511_I2C_CTL, 0x10);
2041
2042 if (--retries < 0) {
2043 PDEBUG(D_USBI, "i2c write retries exhausted");
2044 return -1;
2045 }
2046 }
2047
2048 /* Two byte read cycle */
2049 for (retries = 6; ; ) {
2050 /* Initiate 2-byte read cycle */
2051 rc = reg_w(sd, R511_I2C_CTL, 0x05);
2052 if (rc < 0)
2053 return rc;
2054
Jean-Francois Moine83955552009-12-12 06:58:01 -03002055 do {
Hans de Goede1876bb92009-06-14 06:45:50 -03002056 rc = reg_r(sd, R511_I2C_CTL);
Jean-Francois Moine83955552009-12-12 06:58:01 -03002057 } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
Hans de Goede1876bb92009-06-14 06:45:50 -03002058
2059 if (rc < 0)
2060 return rc;
2061
2062 if ((rc & 2) == 0) /* Ack? */
2063 break;
2064
2065 /* I2C abort */
2066 rc = reg_w(sd, R511_I2C_CTL, 0x10);
2067 if (rc < 0)
2068 return rc;
2069
2070 if (--retries < 0) {
2071 PDEBUG(D_USBI, "i2c read retries exhausted");
2072 return -1;
2073 }
2074 }
2075
2076 value = reg_r(sd, R51x_I2C_DATA);
2077
2078 PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
2079
2080 /* This is needed to make i2c_w() work */
2081 rc = reg_w(sd, R511_I2C_CTL, 0x05);
2082 if (rc < 0)
2083 return rc;
2084
2085 return value;
2086}
Hans de Goede49809d62009-06-07 12:10:39 -03002087
2088/*
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002089 * The OV518 I2C I/O procedure is different, hence, this function.
2090 * This is normally only called from i2c_w(). Note that this function
2091 * always succeeds regardless of whether the sensor is present and working.
2092 */
Hans de Goede1876bb92009-06-14 06:45:50 -03002093static int ov518_i2c_w(struct sd *sd,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002094 u8 reg,
2095 u8 value)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002096{
2097 int rc;
2098
2099 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
2100
2101 /* Select camera register */
2102 rc = reg_w(sd, R51x_I2C_SADDR_3, reg);
2103 if (rc < 0)
2104 return rc;
2105
2106 /* Write "value" to I2C data port of OV511 */
2107 rc = reg_w(sd, R51x_I2C_DATA, value);
2108 if (rc < 0)
2109 return rc;
2110
2111 /* Initiate 3-byte write cycle */
2112 rc = reg_w(sd, R518_I2C_CTL, 0x01);
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002113 if (rc < 0)
2114 return rc;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002115
2116 /* wait for write complete */
2117 msleep(4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002118 return reg_r8(sd, R518_I2C_CTL);
2119}
2120
2121/*
2122 * returns: negative is error, pos or zero is data
2123 *
2124 * The OV518 I2C I/O procedure is different, hence, this function.
2125 * This is normally only called from i2c_r(). Note that this function
2126 * always succeeds regardless of whether the sensor is present and working.
2127 */
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002128static int ov518_i2c_r(struct sd *sd, u8 reg)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002129{
2130 int rc, value;
2131
2132 /* Select camera register */
2133 rc = reg_w(sd, R51x_I2C_SADDR_2, reg);
2134 if (rc < 0)
2135 return rc;
2136
2137 /* Initiate 2-byte write cycle */
2138 rc = reg_w(sd, R518_I2C_CTL, 0x03);
2139 if (rc < 0)
2140 return rc;
2141
2142 /* Initiate 2-byte read cycle */
2143 rc = reg_w(sd, R518_I2C_CTL, 0x05);
2144 if (rc < 0)
2145 return rc;
2146 value = reg_r(sd, R51x_I2C_DATA);
2147 PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
2148 return value;
2149}
2150
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002151static int ovfx2_i2c_w(struct sd *sd, u8 reg, u8 value)
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002152{
2153 int ret;
2154
2155 ret = usb_control_msg(sd->gspca_dev.dev,
2156 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
2157 0x02,
2158 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002159 (u16) value, (u16) reg, NULL, 0, 500);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002160
Hans de Goedea511ba92009-10-16 07:13:07 -03002161 if (ret < 0) {
Jean-François Moine0b656322010-09-13 05:19:58 -03002162 err("i2c 0x%02x -> [0x%02x] failed", value, reg);
Hans de Goedea511ba92009-10-16 07:13:07 -03002163 return ret;
2164 }
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002165
Hans de Goedea511ba92009-10-16 07:13:07 -03002166 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
2167 return 0;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002168}
2169
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002170static int ovfx2_i2c_r(struct sd *sd, u8 reg)
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002171{
2172 int ret;
2173
2174 ret = usb_control_msg(sd->gspca_dev.dev,
2175 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
2176 0x03,
2177 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002178 0, (u16) reg, sd->gspca_dev.usb_buf, 1, 500);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002179
2180 if (ret >= 0) {
2181 ret = sd->gspca_dev.usb_buf[0];
2182 PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, ret);
2183 } else
Jean-François Moine0b656322010-09-13 05:19:58 -03002184 err("i2c read [0x%02x] failed", reg);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002185
2186 return ret;
2187}
2188
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002189static int i2c_w(struct sd *sd, u8 reg, u8 value)
Hans de Goede1876bb92009-06-14 06:45:50 -03002190{
Hans de Goedefb1f9022009-10-16 07:42:53 -03002191 int ret = -1;
2192
2193 if (sd->sensor_reg_cache[reg] == value)
2194 return 0;
2195
Hans de Goede1876bb92009-06-14 06:45:50 -03002196 switch (sd->bridge) {
2197 case BRIDGE_OV511:
2198 case BRIDGE_OV511PLUS:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002199 ret = ov511_i2c_w(sd, reg, value);
2200 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002201 case BRIDGE_OV518:
2202 case BRIDGE_OV518PLUS:
2203 case BRIDGE_OV519:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002204 ret = ov518_i2c_w(sd, reg, value);
2205 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002206 case BRIDGE_OVFX2:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002207 ret = ovfx2_i2c_w(sd, reg, value);
2208 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03002209 case BRIDGE_W9968CF:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002210 ret = w9968cf_i2c_w(sd, reg, value);
2211 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002212 }
Hans de Goedefb1f9022009-10-16 07:42:53 -03002213
2214 if (ret >= 0) {
2215 /* Up on sensor reset empty the register cache */
2216 if (reg == 0x12 && (value & 0x80))
2217 memset(sd->sensor_reg_cache, -1,
Jean-François Moine87bae742010-11-12 05:31:34 -03002218 sizeof(sd->sensor_reg_cache));
Hans de Goedefb1f9022009-10-16 07:42:53 -03002219 else
2220 sd->sensor_reg_cache[reg] = value;
2221 }
2222
2223 return ret;
Hans de Goede1876bb92009-06-14 06:45:50 -03002224}
2225
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002226static int i2c_r(struct sd *sd, u8 reg)
Hans de Goede1876bb92009-06-14 06:45:50 -03002227{
Hans de Goede8394bcf2009-10-16 11:26:22 -03002228 int ret = -1;
Hans de Goedefb1f9022009-10-16 07:42:53 -03002229
2230 if (sd->sensor_reg_cache[reg] != -1)
2231 return sd->sensor_reg_cache[reg];
2232
Hans de Goede1876bb92009-06-14 06:45:50 -03002233 switch (sd->bridge) {
2234 case BRIDGE_OV511:
2235 case BRIDGE_OV511PLUS:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002236 ret = ov511_i2c_r(sd, reg);
2237 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002238 case BRIDGE_OV518:
2239 case BRIDGE_OV518PLUS:
2240 case BRIDGE_OV519:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002241 ret = ov518_i2c_r(sd, reg);
2242 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002243 case BRIDGE_OVFX2:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002244 ret = ovfx2_i2c_r(sd, reg);
2245 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03002246 case BRIDGE_W9968CF:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002247 ret = w9968cf_i2c_r(sd, reg);
2248 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002249 }
Hans de Goedefb1f9022009-10-16 07:42:53 -03002250
2251 if (ret >= 0)
2252 sd->sensor_reg_cache[reg] = ret;
2253
2254 return ret;
Hans de Goede1876bb92009-06-14 06:45:50 -03002255}
2256
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002257/* Writes bits at positions specified by mask to an I2C reg. Bits that are in
2258 * the same position as 1's in "mask" are cleared and set to "value". Bits
2259 * that are in the same position as 0's in "mask" are preserved, regardless
2260 * of their respective state in "value".
2261 */
2262static int i2c_w_mask(struct sd *sd,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002263 u8 reg,
2264 u8 value,
2265 u8 mask)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002266{
2267 int rc;
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002268 u8 oldval;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002269
2270 value &= mask; /* Enforce mask on value */
2271 rc = i2c_r(sd, reg);
2272 if (rc < 0)
2273 return rc;
2274 oldval = rc & ~mask; /* Clear the masked bits */
2275 value |= oldval; /* Set the desired bits */
2276 return i2c_w(sd, reg, value);
2277}
2278
2279/* Temporarily stops OV511 from functioning. Must do this before changing
2280 * registers while the camera is streaming */
2281static inline int ov51x_stop(struct sd *sd)
2282{
2283 PDEBUG(D_STREAM, "stopping");
2284 sd->stopped = 1;
Hans de Goede49809d62009-06-07 12:10:39 -03002285 switch (sd->bridge) {
2286 case BRIDGE_OV511:
2287 case BRIDGE_OV511PLUS:
2288 return reg_w(sd, R51x_SYS_RESET, 0x3d);
2289 case BRIDGE_OV518:
2290 case BRIDGE_OV518PLUS:
2291 return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
2292 case BRIDGE_OV519:
Jean-François Moine21867802010-11-12 06:12:09 -03002293 return reg_w(sd, OV519_R51_RESET1, 0x0f);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002294 case BRIDGE_OVFX2:
2295 return reg_w_mask(sd, 0x0f, 0x00, 0x02);
Hans de Goedea511ba92009-10-16 07:13:07 -03002296 case BRIDGE_W9968CF:
Hans de Goede79b35902009-10-19 06:08:01 -03002297 return reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */
Hans de Goede49809d62009-06-07 12:10:39 -03002298 }
2299
2300 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002301}
2302
2303/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
2304 * actually stopped (for performance). */
2305static inline int ov51x_restart(struct sd *sd)
2306{
Hans de Goede49809d62009-06-07 12:10:39 -03002307 int rc;
2308
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002309 PDEBUG(D_STREAM, "restarting");
2310 if (!sd->stopped)
2311 return 0;
2312 sd->stopped = 0;
2313
2314 /* Reinitialize the stream */
Hans de Goede49809d62009-06-07 12:10:39 -03002315 switch (sd->bridge) {
2316 case BRIDGE_OV511:
2317 case BRIDGE_OV511PLUS:
2318 return reg_w(sd, R51x_SYS_RESET, 0x00);
2319 case BRIDGE_OV518:
2320 case BRIDGE_OV518PLUS:
2321 rc = reg_w(sd, 0x2f, 0x80);
2322 if (rc < 0)
2323 return rc;
2324 return reg_w(sd, R51x_SYS_RESET, 0x00);
2325 case BRIDGE_OV519:
Jean-François Moine21867802010-11-12 06:12:09 -03002326 return reg_w(sd, OV519_R51_RESET1, 0x00);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002327 case BRIDGE_OVFX2:
2328 return reg_w_mask(sd, 0x0f, 0x02, 0x02);
Hans de Goedea511ba92009-10-16 07:13:07 -03002329 case BRIDGE_W9968CF:
2330 return reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */
Hans de Goede49809d62009-06-07 12:10:39 -03002331 }
2332
2333 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002334}
2335
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002336static int ov51x_set_slave_ids(struct sd *sd, u8 slave);
Hans de Goede229bb7d2009-10-11 07:41:46 -03002337
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002338/* This does an initial reset of an OmniVision sensor and ensures that I2C
2339 * is synchronized. Returns <0 on failure.
2340 */
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002341static int init_ov_sensor(struct sd *sd, u8 slave)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002342{
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002343 int i;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002344
Hans de Goede229bb7d2009-10-11 07:41:46 -03002345 if (ov51x_set_slave_ids(sd, slave) < 0)
2346 return -EIO;
2347
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002348 /* Reset the sensor */
2349 if (i2c_w(sd, 0x12, 0x80) < 0)
2350 return -EIO;
2351
2352 /* Wait for it to initialize */
2353 msleep(150);
2354
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002355 for (i = 0; i < i2c_detect_tries; i++) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002356 if (i2c_r(sd, OV7610_REG_ID_HIGH) == 0x7f &&
2357 i2c_r(sd, OV7610_REG_ID_LOW) == 0xa2) {
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002358 PDEBUG(D_PROBE, "I2C synced in %d attempt(s)", i);
2359 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002360 }
2361
2362 /* Reset the sensor */
2363 if (i2c_w(sd, 0x12, 0x80) < 0)
2364 return -EIO;
2365 /* Wait for it to initialize */
2366 msleep(150);
Jean-François Moine87bae742010-11-12 05:31:34 -03002367
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002368 /* Dummy read to sync I2C */
2369 if (i2c_r(sd, 0x00) < 0)
2370 return -EIO;
2371 }
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002372 return -EIO;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002373}
2374
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002375/* Set the read and write slave IDs. The "slave" argument is the write slave,
2376 * and the read slave will be set to (slave + 1).
2377 * This should not be called from outside the i2c I/O functions.
2378 * Sets I2C read and write slave IDs. Returns <0 for error
2379 */
2380static int ov51x_set_slave_ids(struct sd *sd,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002381 u8 slave)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002382{
2383 int rc;
2384
Hans de Goedea511ba92009-10-16 07:13:07 -03002385 switch (sd->bridge) {
2386 case BRIDGE_OVFX2:
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002387 return reg_w(sd, OVFX2_I2C_ADDR, slave);
Hans de Goedea511ba92009-10-16 07:13:07 -03002388 case BRIDGE_W9968CF:
2389 sd->sensor_addr = slave;
2390 return 0;
2391 }
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002392
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002393 rc = reg_w(sd, R51x_I2C_W_SID, slave);
2394 if (rc < 0)
2395 return rc;
2396 return reg_w(sd, R51x_I2C_R_SID, slave + 1);
2397}
2398
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002399static int write_regvals(struct sd *sd,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002400 const struct ov_regvals *regvals,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002401 int n)
2402{
2403 int rc;
2404
2405 while (--n >= 0) {
2406 rc = reg_w(sd, regvals->reg, regvals->val);
2407 if (rc < 0)
2408 return rc;
2409 regvals++;
2410 }
2411 return 0;
2412}
2413
2414static int write_i2c_regvals(struct sd *sd,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002415 const struct ov_i2c_regvals *regvals,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002416 int n)
2417{
2418 int rc;
2419
2420 while (--n >= 0) {
2421 rc = i2c_w(sd, regvals->reg, regvals->val);
2422 if (rc < 0)
2423 return rc;
2424 regvals++;
2425 }
2426 return 0;
2427}
2428
2429/****************************************************************************
2430 *
2431 * OV511 and sensor configuration
2432 *
2433 ***************************************************************************/
2434
Hans de Goede635118d2009-10-11 09:49:03 -03002435/* This initializes the OV2x10 / OV3610 / OV3620 */
2436static int ov_hires_configure(struct sd *sd)
2437{
2438 int high, low;
2439
2440 if (sd->bridge != BRIDGE_OVFX2) {
Jean-François Moine0b656322010-09-13 05:19:58 -03002441 err("error hires sensors only supported with ovfx2");
Hans de Goede635118d2009-10-11 09:49:03 -03002442 return -1;
2443 }
2444
2445 PDEBUG(D_PROBE, "starting ov hires configuration");
2446
2447 /* Detect sensor (sub)type */
2448 high = i2c_r(sd, 0x0a);
2449 low = i2c_r(sd, 0x0b);
2450 /* info("%x, %x", high, low); */
2451 if (high == 0x96 && low == 0x40) {
2452 PDEBUG(D_PROBE, "Sensor is an OV2610");
2453 sd->sensor = SEN_OV2610;
2454 } else if (high == 0x36 && (low & 0x0f) == 0x00) {
2455 PDEBUG(D_PROBE, "Sensor is an OV3610");
2456 sd->sensor = SEN_OV3610;
2457 } else {
Jean-François Moine0b656322010-09-13 05:19:58 -03002458 err("Error unknown sensor type: 0x%02x%02x",
Jean-François Moine87bae742010-11-12 05:31:34 -03002459 high, low);
Hans de Goede635118d2009-10-11 09:49:03 -03002460 return -1;
2461 }
2462
2463 /* Set sensor-specific vars */
2464 return 0;
2465}
2466
2467
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002468/* This initializes the OV8110, OV8610 sensor. The OV8110 uses
2469 * the same register settings as the OV8610, since they are very similar.
2470 */
2471static int ov8xx0_configure(struct sd *sd)
2472{
2473 int rc;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002474
2475 PDEBUG(D_PROBE, "starting ov8xx0 configuration");
2476
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002477 /* Detect sensor (sub)type */
2478 rc = i2c_r(sd, OV7610_REG_COM_I);
2479 if (rc < 0) {
2480 PDEBUG(D_ERR, "Error detecting sensor type");
2481 return -1;
2482 }
2483 if ((rc & 3) == 1) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002484 sd->sensor = SEN_OV8610;
2485 } else {
Jean-François Moine0b656322010-09-13 05:19:58 -03002486 err("Unknown image sensor version: %d", rc & 3);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002487 return -1;
2488 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002489
2490 /* Set sensor-specific vars */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002491 return 0;
2492}
2493
2494/* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses
2495 * the same register settings as the OV7610, since they are very similar.
2496 */
2497static int ov7xx0_configure(struct sd *sd)
2498{
2499 int rc, high, low;
2500
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002501 PDEBUG(D_PROBE, "starting OV7xx0 configuration");
2502
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002503 /* Detect sensor (sub)type */
2504 rc = i2c_r(sd, OV7610_REG_COM_I);
2505
2506 /* add OV7670 here
2507 * it appears to be wrongly detected as a 7610 by default */
2508 if (rc < 0) {
2509 PDEBUG(D_ERR, "Error detecting sensor type");
2510 return -1;
2511 }
2512 if ((rc & 3) == 3) {
2513 /* quick hack to make OV7670s work */
2514 high = i2c_r(sd, 0x0a);
2515 low = i2c_r(sd, 0x0b);
2516 /* info("%x, %x", high, low); */
2517 if (high == 0x76 && low == 0x73) {
2518 PDEBUG(D_PROBE, "Sensor is an OV7670");
2519 sd->sensor = SEN_OV7670;
2520 } else {
2521 PDEBUG(D_PROBE, "Sensor is an OV7610");
2522 sd->sensor = SEN_OV7610;
2523 }
2524 } else if ((rc & 3) == 1) {
2525 /* I don't know what's different about the 76BE yet. */
Hans de Goedeb282d872009-06-14 19:10:40 -03002526 if (i2c_r(sd, 0x15) & 1) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002527 PDEBUG(D_PROBE, "Sensor is an OV7620AE");
Hans de Goede859cc472010-01-07 15:42:35 -03002528 sd->sensor = SEN_OV7620AE;
Hans de Goedeb282d872009-06-14 19:10:40 -03002529 } else {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002530 PDEBUG(D_PROBE, "Sensor is an OV76BE");
Hans de Goedeb282d872009-06-14 19:10:40 -03002531 sd->sensor = SEN_OV76BE;
2532 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002533 } else if ((rc & 3) == 0) {
2534 /* try to read product id registers */
2535 high = i2c_r(sd, 0x0a);
2536 if (high < 0) {
2537 PDEBUG(D_ERR, "Error detecting camera chip PID");
2538 return high;
2539 }
2540 low = i2c_r(sd, 0x0b);
2541 if (low < 0) {
2542 PDEBUG(D_ERR, "Error detecting camera chip VER");
2543 return low;
2544 }
2545 if (high == 0x76) {
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002546 switch (low) {
2547 case 0x30:
Jean-François Moine0b656322010-09-13 05:19:58 -03002548 err("Sensor is an OV7630/OV7635");
2549 err("7630 is not supported by this driver");
Jean-Francois Moine4202f712008-09-03 17:12:15 -03002550 return -1;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002551 case 0x40:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002552 PDEBUG(D_PROBE, "Sensor is an OV7645");
2553 sd->sensor = SEN_OV7640; /* FIXME */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002554 break;
2555 case 0x45:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002556 PDEBUG(D_PROBE, "Sensor is an OV7645B");
2557 sd->sensor = SEN_OV7640; /* FIXME */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002558 break;
2559 case 0x48:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002560 PDEBUG(D_PROBE, "Sensor is an OV7648");
Hans de Goede035d3a32010-01-09 08:14:43 -03002561 sd->sensor = SEN_OV7648;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002562 break;
2563 default:
2564 PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002565 return -1;
2566 }
2567 } else {
2568 PDEBUG(D_PROBE, "Sensor is an OV7620");
2569 sd->sensor = SEN_OV7620;
2570 }
2571 } else {
Jean-François Moine0b656322010-09-13 05:19:58 -03002572 err("Unknown image sensor version: %d", rc & 3);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002573 return -1;
2574 }
2575
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002576 /* Set sensor-specific vars */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002577 return 0;
2578}
2579
2580/* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */
2581static int ov6xx0_configure(struct sd *sd)
2582{
2583 int rc;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03002584 PDEBUG(D_PROBE, "starting OV6xx0 configuration");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002585
2586 /* Detect sensor (sub)type */
2587 rc = i2c_r(sd, OV7610_REG_COM_I);
2588 if (rc < 0) {
2589 PDEBUG(D_ERR, "Error detecting sensor type");
2590 return -1;
2591 }
2592
2593 /* Ugh. The first two bits are the version bits, but
2594 * the entire register value must be used. I guess OVT
2595 * underestimated how many variants they would make. */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002596 switch (rc) {
2597 case 0x00:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002598 sd->sensor = SEN_OV6630;
Jean-François Moine0b656322010-09-13 05:19:58 -03002599 warn("WARNING: Sensor is an OV66308. Your camera may have");
2600 warn("been misdetected in previous driver versions.");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002601 break;
2602 case 0x01:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002603 sd->sensor = SEN_OV6620;
Hans de Goede7d971372009-06-14 05:28:17 -03002604 PDEBUG(D_PROBE, "Sensor is an OV6620");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002605 break;
2606 case 0x02:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002607 sd->sensor = SEN_OV6630;
2608 PDEBUG(D_PROBE, "Sensor is an OV66308AE");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002609 break;
2610 case 0x03:
Hans de Goede7d971372009-06-14 05:28:17 -03002611 sd->sensor = SEN_OV66308AF;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002612 PDEBUG(D_PROBE, "Sensor is an OV66308AF");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002613 break;
2614 case 0x90:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002615 sd->sensor = SEN_OV6630;
Jean-François Moine0b656322010-09-13 05:19:58 -03002616 warn("WARNING: Sensor is an OV66307. Your camera may have");
2617 warn("been misdetected in previous driver versions.");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002618 break;
2619 default:
Jean-François Moine0b656322010-09-13 05:19:58 -03002620 err("FATAL: Unknown sensor version: 0x%02x", rc);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002621 return -1;
2622 }
2623
2624 /* Set sensor-specific vars */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002625 sd->sif = 1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002626
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002627 return 0;
2628}
2629
2630/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
2631static void ov51x_led_control(struct sd *sd, int on)
2632{
Hans de Goede9e4d8252009-06-14 06:25:06 -03002633 if (sd->invert_led)
2634 on = !on;
2635
Hans de Goede49809d62009-06-07 12:10:39 -03002636 switch (sd->bridge) {
2637 /* OV511 has no LED control */
2638 case BRIDGE_OV511PLUS:
2639 reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0);
2640 break;
2641 case BRIDGE_OV518:
2642 case BRIDGE_OV518PLUS:
2643 reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02);
2644 break;
2645 case BRIDGE_OV519:
2646 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */
2647 break;
2648 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002649}
2650
Hans de Goede417a4d22010-02-19 07:37:08 -03002651static void sd_reset_snapshot(struct gspca_dev *gspca_dev)
2652{
2653 struct sd *sd = (struct sd *) gspca_dev;
2654
2655 if (!sd->snapshot_needs_reset)
2656 return;
2657
2658 /* Note it is important that we clear sd->snapshot_needs_reset,
2659 before actually clearing the snapshot state in the bridge
2660 otherwise we might race with the pkt_scan interrupt handler */
2661 sd->snapshot_needs_reset = 0;
2662
2663 switch (sd->bridge) {
Hans de Goede88e8d202010-02-20 04:45:49 -03002664 case BRIDGE_OV511:
2665 case BRIDGE_OV511PLUS:
2666 reg_w(sd, R51x_SYS_SNAP, 0x02);
2667 reg_w(sd, R51x_SYS_SNAP, 0x00);
2668 break;
Hans de Goede92e232a2010-02-20 04:30:45 -03002669 case BRIDGE_OV518:
2670 case BRIDGE_OV518PLUS:
2671 reg_w(sd, R51x_SYS_SNAP, 0x02); /* Reset */
2672 reg_w(sd, R51x_SYS_SNAP, 0x01); /* Enable */
2673 break;
Hans de Goede417a4d22010-02-19 07:37:08 -03002674 case BRIDGE_OV519:
2675 reg_w(sd, R51x_SYS_RESET, 0x40);
2676 reg_w(sd, R51x_SYS_RESET, 0x00);
2677 break;
2678 }
2679}
2680
Hans de Goede1876bb92009-06-14 06:45:50 -03002681static int ov51x_upload_quan_tables(struct sd *sd)
Hans de Goede49809d62009-06-07 12:10:39 -03002682{
Hans de Goede1876bb92009-06-14 06:45:50 -03002683 const unsigned char yQuanTable511[] = {
2684 0, 1, 1, 2, 2, 3, 3, 4,
2685 1, 1, 1, 2, 2, 3, 4, 4,
2686 1, 1, 2, 2, 3, 4, 4, 4,
2687 2, 2, 2, 3, 4, 4, 4, 4,
2688 2, 2, 3, 4, 4, 5, 5, 5,
2689 3, 3, 4, 4, 5, 5, 5, 5,
2690 3, 4, 4, 4, 5, 5, 5, 5,
2691 4, 4, 4, 4, 5, 5, 5, 5
2692 };
2693
2694 const unsigned char uvQuanTable511[] = {
2695 0, 2, 2, 3, 4, 4, 4, 4,
2696 2, 2, 2, 4, 4, 4, 4, 4,
2697 2, 2, 3, 4, 4, 4, 4, 4,
2698 3, 4, 4, 4, 4, 4, 4, 4,
2699 4, 4, 4, 4, 4, 4, 4, 4,
2700 4, 4, 4, 4, 4, 4, 4, 4,
2701 4, 4, 4, 4, 4, 4, 4, 4,
2702 4, 4, 4, 4, 4, 4, 4, 4
2703 };
2704
2705 /* OV518 quantization tables are 8x4 (instead of 8x8) */
Hans de Goede49809d62009-06-07 12:10:39 -03002706 const unsigned char yQuanTable518[] = {
2707 5, 4, 5, 6, 6, 7, 7, 7,
2708 5, 5, 5, 5, 6, 7, 7, 7,
2709 6, 6, 6, 6, 7, 7, 7, 8,
2710 7, 7, 6, 7, 7, 7, 8, 8
2711 };
Hans de Goede49809d62009-06-07 12:10:39 -03002712 const unsigned char uvQuanTable518[] = {
2713 6, 6, 6, 7, 7, 7, 7, 7,
2714 6, 6, 6, 7, 7, 7, 7, 7,
2715 6, 6, 6, 7, 7, 7, 7, 8,
2716 7, 7, 7, 7, 7, 7, 8, 8
2717 };
2718
Hans de Goede1876bb92009-06-14 06:45:50 -03002719 const unsigned char *pYTable, *pUVTable;
Hans de Goede49809d62009-06-07 12:10:39 -03002720 unsigned char val0, val1;
Hans de Goede1876bb92009-06-14 06:45:50 -03002721 int i, size, rc, reg = R51x_COMP_LUT_BEGIN;
Hans de Goede49809d62009-06-07 12:10:39 -03002722
2723 PDEBUG(D_PROBE, "Uploading quantization tables");
2724
Hans de Goede1876bb92009-06-14 06:45:50 -03002725 if (sd->bridge == BRIDGE_OV511 || sd->bridge == BRIDGE_OV511PLUS) {
2726 pYTable = yQuanTable511;
2727 pUVTable = uvQuanTable511;
Jean-François Moine87bae742010-11-12 05:31:34 -03002728 size = 32;
Hans de Goede1876bb92009-06-14 06:45:50 -03002729 } else {
2730 pYTable = yQuanTable518;
2731 pUVTable = uvQuanTable518;
Jean-François Moine87bae742010-11-12 05:31:34 -03002732 size = 16;
Hans de Goede1876bb92009-06-14 06:45:50 -03002733 }
2734
2735 for (i = 0; i < size; i++) {
Hans de Goede49809d62009-06-07 12:10:39 -03002736 val0 = *pYTable++;
2737 val1 = *pYTable++;
2738 val0 &= 0x0f;
2739 val1 &= 0x0f;
2740 val0 |= val1 << 4;
2741 rc = reg_w(sd, reg, val0);
2742 if (rc < 0)
2743 return rc;
2744
2745 val0 = *pUVTable++;
2746 val1 = *pUVTable++;
2747 val0 &= 0x0f;
2748 val1 &= 0x0f;
2749 val0 |= val1 << 4;
Hans de Goede1876bb92009-06-14 06:45:50 -03002750 rc = reg_w(sd, reg + size, val0);
Hans de Goede49809d62009-06-07 12:10:39 -03002751 if (rc < 0)
2752 return rc;
2753
2754 reg++;
2755 }
2756
2757 return 0;
2758}
2759
Hans de Goede1876bb92009-06-14 06:45:50 -03002760/* This initializes the OV511/OV511+ and the sensor */
2761static int ov511_configure(struct gspca_dev *gspca_dev)
2762{
2763 struct sd *sd = (struct sd *) gspca_dev;
2764 int rc;
2765
2766 /* For 511 and 511+ */
2767 const struct ov_regvals init_511[] = {
2768 { R51x_SYS_RESET, 0x7f },
2769 { R51x_SYS_INIT, 0x01 },
2770 { R51x_SYS_RESET, 0x7f },
2771 { R51x_SYS_INIT, 0x01 },
2772 { R51x_SYS_RESET, 0x3f },
2773 { R51x_SYS_INIT, 0x01 },
2774 { R51x_SYS_RESET, 0x3d },
2775 };
2776
2777 const struct ov_regvals norm_511[] = {
Jean-François Moine780e3122010-10-19 04:29:10 -03002778 { R511_DRAM_FLOW_CTL, 0x01 },
Hans de Goede1876bb92009-06-14 06:45:50 -03002779 { R51x_SYS_SNAP, 0x00 },
2780 { R51x_SYS_SNAP, 0x02 },
2781 { R51x_SYS_SNAP, 0x00 },
2782 { R511_FIFO_OPTS, 0x1f },
2783 { R511_COMP_EN, 0x00 },
2784 { R511_COMP_LUT_EN, 0x03 },
2785 };
2786
2787 const struct ov_regvals norm_511_p[] = {
2788 { R511_DRAM_FLOW_CTL, 0xff },
2789 { R51x_SYS_SNAP, 0x00 },
2790 { R51x_SYS_SNAP, 0x02 },
2791 { R51x_SYS_SNAP, 0x00 },
2792 { R511_FIFO_OPTS, 0xff },
2793 { R511_COMP_EN, 0x00 },
2794 { R511_COMP_LUT_EN, 0x03 },
2795 };
2796
2797 const struct ov_regvals compress_511[] = {
2798 { 0x70, 0x1f },
2799 { 0x71, 0x05 },
2800 { 0x72, 0x06 },
2801 { 0x73, 0x06 },
2802 { 0x74, 0x14 },
2803 { 0x75, 0x03 },
2804 { 0x76, 0x04 },
2805 { 0x77, 0x04 },
2806 };
2807
2808 PDEBUG(D_PROBE, "Device custom id %x", reg_r(sd, R51x_SYS_CUST_ID));
2809
2810 rc = write_regvals(sd, init_511, ARRAY_SIZE(init_511));
2811 if (rc < 0)
2812 return rc;
2813
2814 switch (sd->bridge) {
2815 case BRIDGE_OV511:
2816 rc = write_regvals(sd, norm_511, ARRAY_SIZE(norm_511));
2817 if (rc < 0)
2818 return rc;
2819 break;
2820 case BRIDGE_OV511PLUS:
2821 rc = write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p));
2822 if (rc < 0)
2823 return rc;
2824 break;
2825 }
2826
2827 /* Init compression */
2828 rc = write_regvals(sd, compress_511, ARRAY_SIZE(compress_511));
2829 if (rc < 0)
2830 return rc;
2831
2832 rc = ov51x_upload_quan_tables(sd);
2833 if (rc < 0) {
2834 PDEBUG(D_ERR, "Error uploading quantization tables");
2835 return rc;
2836 }
2837
2838 return 0;
2839}
2840
Hans de Goede49809d62009-06-07 12:10:39 -03002841/* This initializes the OV518/OV518+ and the sensor */
2842static int ov518_configure(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002843{
2844 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goede49809d62009-06-07 12:10:39 -03002845 int rc;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002846
Hans de Goede49809d62009-06-07 12:10:39 -03002847 /* For 518 and 518+ */
Hans de Goedee080fcd2009-06-18 05:03:16 -03002848 const struct ov_regvals init_518[] = {
Hans de Goede49809d62009-06-07 12:10:39 -03002849 { R51x_SYS_RESET, 0x40 },
2850 { R51x_SYS_INIT, 0xe1 },
2851 { R51x_SYS_RESET, 0x3e },
2852 { R51x_SYS_INIT, 0xe1 },
2853 { R51x_SYS_RESET, 0x00 },
2854 { R51x_SYS_INIT, 0xe1 },
2855 { 0x46, 0x00 },
2856 { 0x5d, 0x03 },
2857 };
2858
Hans de Goedee080fcd2009-06-18 05:03:16 -03002859 const struct ov_regvals norm_518[] = {
Hans de Goede49809d62009-06-07 12:10:39 -03002860 { R51x_SYS_SNAP, 0x02 }, /* Reset */
2861 { R51x_SYS_SNAP, 0x01 }, /* Enable */
Jean-François Moine780e3122010-10-19 04:29:10 -03002862 { 0x31, 0x0f },
Hans de Goede49809d62009-06-07 12:10:39 -03002863 { 0x5d, 0x03 },
2864 { 0x24, 0x9f },
2865 { 0x25, 0x90 },
2866 { 0x20, 0x00 },
2867 { 0x51, 0x04 },
2868 { 0x71, 0x19 },
2869 { 0x2f, 0x80 },
2870 };
2871
Hans de Goedee080fcd2009-06-18 05:03:16 -03002872 const struct ov_regvals norm_518_p[] = {
Hans de Goede49809d62009-06-07 12:10:39 -03002873 { R51x_SYS_SNAP, 0x02 }, /* Reset */
2874 { R51x_SYS_SNAP, 0x01 }, /* Enable */
Jean-François Moine780e3122010-10-19 04:29:10 -03002875 { 0x31, 0x0f },
Hans de Goede49809d62009-06-07 12:10:39 -03002876 { 0x5d, 0x03 },
2877 { 0x24, 0x9f },
2878 { 0x25, 0x90 },
2879 { 0x20, 0x60 },
2880 { 0x51, 0x02 },
2881 { 0x71, 0x19 },
2882 { 0x40, 0xff },
2883 { 0x41, 0x42 },
2884 { 0x46, 0x00 },
2885 { 0x33, 0x04 },
2886 { 0x21, 0x19 },
2887 { 0x3f, 0x10 },
2888 { 0x2f, 0x80 },
2889 };
2890
2891 /* First 5 bits of custom ID reg are a revision ID on OV518 */
2892 PDEBUG(D_PROBE, "Device revision %d",
Jean-François Moine87bae742010-11-12 05:31:34 -03002893 0x1f & reg_r(sd, R51x_SYS_CUST_ID));
Hans de Goede49809d62009-06-07 12:10:39 -03002894
2895 rc = write_regvals(sd, init_518, ARRAY_SIZE(init_518));
2896 if (rc < 0)
2897 return rc;
2898
2899 /* Set LED GPIO pin to output mode */
2900 rc = reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02);
2901 if (rc < 0)
2902 return rc;
2903
2904 switch (sd->bridge) {
2905 case BRIDGE_OV518:
2906 rc = write_regvals(sd, norm_518, ARRAY_SIZE(norm_518));
2907 if (rc < 0)
2908 return rc;
2909 break;
2910 case BRIDGE_OV518PLUS:
2911 rc = write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p));
2912 if (rc < 0)
2913 return rc;
2914 break;
2915 }
2916
Hans de Goede1876bb92009-06-14 06:45:50 -03002917 rc = ov51x_upload_quan_tables(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03002918 if (rc < 0) {
2919 PDEBUG(D_ERR, "Error uploading quantization tables");
2920 return rc;
2921 }
2922
2923 rc = reg_w(sd, 0x2f, 0x80);
2924 if (rc < 0)
2925 return rc;
2926
2927 return 0;
2928}
2929
2930static int ov519_configure(struct sd *sd)
2931{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002932 static const struct ov_regvals init_519[] = {
Jean-François Moine87bae742010-11-12 05:31:34 -03002933 { 0x5a, 0x6d }, /* EnableSystem */
2934 { 0x53, 0x9b },
Jean-François Moine21867802010-11-12 06:12:09 -03002935 { OV519_R54_EN_CLK1, 0xff }, /* set bit2 to enable jpeg */
Jean-François Moine87bae742010-11-12 05:31:34 -03002936 { 0x5d, 0x03 },
2937 { 0x49, 0x01 },
2938 { 0x48, 0x00 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002939 /* Set LED pin to output mode. Bit 4 must be cleared or sensor
2940 * detection will fail. This deserves further investigation. */
2941 { OV519_GPIO_IO_CTRL0, 0xee },
Jean-François Moine21867802010-11-12 06:12:09 -03002942 { OV519_R51_RESET1, 0x0f },
2943 { OV519_R51_RESET1, 0x00 },
Jean-François Moine87bae742010-11-12 05:31:34 -03002944 { 0x22, 0x00 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002945 /* windows reads 0x55 at this point*/
2946 };
2947
Hans de Goede49809d62009-06-07 12:10:39 -03002948 return write_regvals(sd, init_519, ARRAY_SIZE(init_519));
2949}
2950
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002951static int ovfx2_configure(struct sd *sd)
2952{
2953 static const struct ov_regvals init_fx2[] = {
2954 { 0x00, 0x60 },
2955 { 0x02, 0x01 },
2956 { 0x0f, 0x1d },
2957 { 0xe9, 0x82 },
2958 { 0xea, 0xc7 },
2959 { 0xeb, 0x10 },
2960 { 0xec, 0xf6 },
2961 };
2962
2963 sd->stopped = 1;
2964
2965 return write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
2966}
2967
Hans de Goede49809d62009-06-07 12:10:39 -03002968/* this function is called at probe time */
2969static int sd_config(struct gspca_dev *gspca_dev,
2970 const struct usb_device_id *id)
2971{
2972 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002973 struct cam *cam = &gspca_dev->cam;
Hans de Goede49809d62009-06-07 12:10:39 -03002974 int ret = 0;
2975
Hans de Goede9e4d8252009-06-14 06:25:06 -03002976 sd->bridge = id->driver_info & BRIDGE_MASK;
2977 sd->invert_led = id->driver_info & BRIDGE_INVERT_LED;
Hans de Goede49809d62009-06-07 12:10:39 -03002978
2979 switch (sd->bridge) {
Hans de Goede1876bb92009-06-14 06:45:50 -03002980 case BRIDGE_OV511:
2981 case BRIDGE_OV511PLUS:
2982 ret = ov511_configure(gspca_dev);
2983 break;
Hans de Goede49809d62009-06-07 12:10:39 -03002984 case BRIDGE_OV518:
2985 case BRIDGE_OV518PLUS:
2986 ret = ov518_configure(gspca_dev);
2987 break;
2988 case BRIDGE_OV519:
2989 ret = ov519_configure(sd);
2990 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002991 case BRIDGE_OVFX2:
2992 ret = ovfx2_configure(sd);
2993 cam->bulk_size = OVFX2_BULK_SIZE;
2994 cam->bulk_nurbs = MAX_NURBS;
2995 cam->bulk = 1;
2996 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03002997 case BRIDGE_W9968CF:
2998 ret = w9968cf_configure(sd);
2999 cam->reverse_alts = 1;
3000 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003001 }
3002
3003 if (ret)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003004 goto error;
Hans de Goede49809d62009-06-07 12:10:39 -03003005
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003006 ov51x_led_control(sd, 0); /* turn LED off */
3007
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003008 /* The OV519 must be more aggressive about sensor detection since
3009 * I2C write will never fail if the sensor is not present. We have
3010 * to try to initialize the sensor to detect its presence */
Jean-François Moine7bbe6b82010-11-11 08:27:24 -03003011 sd->sensor = -1;
Hans de Goede229bb7d2009-10-11 07:41:46 -03003012
3013 /* Test for 76xx */
3014 if (init_ov_sensor(sd, OV7xx0_SID) >= 0) {
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003015 if (ov7xx0_configure(sd) < 0) {
3016 PDEBUG(D_ERR, "Failed to configure OV7xx0");
3017 goto error;
3018 }
Hans de Goede229bb7d2009-10-11 07:41:46 -03003019 /* Test for 6xx0 */
3020 } else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) {
3021 if (ov6xx0_configure(sd) < 0) {
3022 PDEBUG(D_ERR, "Failed to configure OV6xx0");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003023 goto error;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003024 }
Hans de Goede229bb7d2009-10-11 07:41:46 -03003025 /* Test for 8xx0 */
3026 } else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) {
3027 if (ov8xx0_configure(sd) < 0) {
3028 PDEBUG(D_ERR, "Failed to configure OV8xx0");
3029 goto error;
3030 }
Hans de Goede635118d2009-10-11 09:49:03 -03003031 /* Test for 3xxx / 2xxx */
3032 } else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) {
3033 if (ov_hires_configure(sd) < 0) {
3034 PDEBUG(D_ERR, "Failed to configure high res OV");
3035 goto error;
3036 }
Hans de Goede229bb7d2009-10-11 07:41:46 -03003037 } else {
Jean-François Moine0b656322010-09-13 05:19:58 -03003038 err("Can't determine sensor slave IDs");
Hans de Goede229bb7d2009-10-11 07:41:46 -03003039 goto error;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003040 }
3041
Jean-François Moine7bbe6b82010-11-11 08:27:24 -03003042 if (sd->sensor < 0)
3043 goto error;
3044
Hans de Goede49809d62009-06-07 12:10:39 -03003045 switch (sd->bridge) {
Hans de Goede1876bb92009-06-14 06:45:50 -03003046 case BRIDGE_OV511:
3047 case BRIDGE_OV511PLUS:
3048 if (!sd->sif) {
3049 cam->cam_mode = ov511_vga_mode;
3050 cam->nmodes = ARRAY_SIZE(ov511_vga_mode);
3051 } else {
3052 cam->cam_mode = ov511_sif_mode;
3053 cam->nmodes = ARRAY_SIZE(ov511_sif_mode);
3054 }
3055 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003056 case BRIDGE_OV518:
3057 case BRIDGE_OV518PLUS:
3058 if (!sd->sif) {
3059 cam->cam_mode = ov518_vga_mode;
3060 cam->nmodes = ARRAY_SIZE(ov518_vga_mode);
3061 } else {
3062 cam->cam_mode = ov518_sif_mode;
3063 cam->nmodes = ARRAY_SIZE(ov518_sif_mode);
3064 }
3065 break;
3066 case BRIDGE_OV519:
3067 if (!sd->sif) {
3068 cam->cam_mode = ov519_vga_mode;
3069 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
3070 } else {
3071 cam->cam_mode = ov519_sif_mode;
3072 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3073 }
3074 break;
Hans de Goede635118d2009-10-11 09:49:03 -03003075 case BRIDGE_OVFX2:
3076 if (sd->sensor == SEN_OV2610) {
3077 cam->cam_mode = ovfx2_ov2610_mode;
3078 cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode);
3079 } else if (sd->sensor == SEN_OV3610) {
3080 cam->cam_mode = ovfx2_ov3610_mode;
3081 cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode);
3082 } else if (!sd->sif) {
3083 cam->cam_mode = ov519_vga_mode;
3084 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
3085 } else {
3086 cam->cam_mode = ov519_sif_mode;
3087 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3088 }
3089 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03003090 case BRIDGE_W9968CF:
3091 cam->cam_mode = w9968cf_vga_mode;
3092 cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
Hans de Goede79b35902009-10-19 06:08:01 -03003093 if (sd->sif)
3094 cam->nmodes--;
Hans de Goedea511ba92009-10-16 07:13:07 -03003095
3096 /* w9968cf needs initialisation once the sensor is known */
3097 if (w9968cf_init(sd) < 0)
3098 goto error;
3099 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003100 }
Jean-François Moine62833ac2010-10-02 04:27:02 -03003101 gspca_dev->cam.ctrls = sd->ctrls;
3102 if (sd->sensor == SEN_OV7670)
3103 gspca_dev->ctrl_dis = 1 << COLORS;
Hans de Goedef5cee952009-06-14 06:32:52 -03003104 else
Jean-François Moine62833ac2010-10-02 04:27:02 -03003105 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
Hans de Goede79b35902009-10-19 06:08:01 -03003106 sd->quality = QUALITY_DEF;
Hans de Goede035d3a32010-01-09 08:14:43 -03003107 if (sd->sensor == SEN_OV7640 ||
Hans de Goeded02134d2010-01-09 19:22:34 -03003108 sd->sensor == SEN_OV7648)
Jean-François Moine62833ac2010-10-02 04:27:02 -03003109 gspca_dev->ctrl_dis |= (1 << AUTOBRIGHT) | (1 << CONTRAST);
Hans de Goeded02134d2010-01-09 19:22:34 -03003110 if (sd->sensor == SEN_OV7670)
Jean-François Moine62833ac2010-10-02 04:27:02 -03003111 gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT;
Hans de Goede02ab18b2009-06-14 04:32:04 -03003112 /* OV8610 Frequency filter control should work but needs testing */
3113 if (sd->sensor == SEN_OV8610)
Jean-François Moine62833ac2010-10-02 04:27:02 -03003114 gspca_dev->ctrl_dis |= 1 << FREQ;
Hans de Goede635118d2009-10-11 09:49:03 -03003115 /* No controls for the OV2610/OV3610 */
3116 if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
Jean-François Moine62833ac2010-10-02 04:27:02 -03003117 gspca_dev->ctrl_dis |= (1 << NCTRL) - 1;
Hans de Goede02ab18b2009-06-14 04:32:04 -03003118
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003119 return 0;
3120error:
3121 PDEBUG(D_ERR, "OV519 Config failed");
Jean-François Moine7bbe6b82010-11-11 08:27:24 -03003122 return -EINVAL;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003123}
3124
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03003125/* this function is called at probe and resume time */
3126static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003127{
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003128 struct sd *sd = (struct sd *) gspca_dev;
3129
3130 /* initialize the sensor */
3131 switch (sd->sensor) {
Hans de Goede635118d2009-10-11 09:49:03 -03003132 case SEN_OV2610:
3133 if (write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610)))
3134 return -EIO;
3135 /* Enable autogain, autoexpo, awb, bandfilter */
3136 if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
3137 return -EIO;
3138 break;
3139 case SEN_OV3610:
3140 if (write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b)))
3141 return -EIO;
3142 /* Enable autogain, autoexpo, awb, bandfilter */
3143 if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
3144 return -EIO;
3145 break;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003146 case SEN_OV6620:
3147 if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)))
3148 return -EIO;
3149 break;
3150 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03003151 case SEN_OV66308AF:
Jean-François Moine62833ac2010-10-02 04:27:02 -03003152 sd->ctrls[CONTRAST].def = 200;
3153 /* The default is too low for the ov6630 */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003154 if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)))
3155 return -EIO;
3156 break;
3157 default:
3158/* case SEN_OV7610: */
3159/* case SEN_OV76BE: */
3160 if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610)))
3161 return -EIO;
Hans de Goedeae49c402009-06-14 19:15:07 -03003162 if (i2c_w_mask(sd, 0x0e, 0x00, 0x40))
3163 return -EIO;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003164 break;
3165 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03003166 case SEN_OV7620AE:
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003167 if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)))
3168 return -EIO;
3169 break;
3170 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003171 case SEN_OV7648:
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003172 if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)))
3173 return -EIO;
3174 break;
3175 case SEN_OV7670:
Jean-François Moine62833ac2010-10-02 04:27:02 -03003176 sd->ctrls[FREQ].max = 3; /* auto */
3177 sd->ctrls[FREQ].def = 3;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003178 if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)))
3179 return -EIO;
3180 break;
3181 case SEN_OV8610:
3182 if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610)))
3183 return -EIO;
3184 break;
3185 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003186 return 0;
3187}
3188
Hans de Goede1876bb92009-06-14 06:45:50 -03003189/* Set up the OV511/OV511+ with the given image parameters.
3190 *
3191 * Do not put any sensor-specific code in here (including I2C I/O functions)
3192 */
3193static int ov511_mode_init_regs(struct sd *sd)
3194{
3195 int hsegs, vsegs, packet_size, fps, needed;
3196 int interlaced = 0;
3197 struct usb_host_interface *alt;
3198 struct usb_interface *intf;
3199
3200 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
3201 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
3202 if (!alt) {
Jean-François Moine0b656322010-09-13 05:19:58 -03003203 err("Couldn't get altsetting");
Hans de Goede1876bb92009-06-14 06:45:50 -03003204 return -EIO;
3205 }
3206
3207 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
3208 reg_w(sd, R51x_FIFO_PSIZE, packet_size >> 5);
3209
3210 reg_w(sd, R511_CAM_UV_EN, 0x01);
3211 reg_w(sd, R511_SNAP_UV_EN, 0x01);
3212 reg_w(sd, R511_SNAP_OPTS, 0x03);
3213
3214 /* Here I'm assuming that snapshot size == image size.
3215 * I hope that's always true. --claudio
3216 */
3217 hsegs = (sd->gspca_dev.width >> 3) - 1;
3218 vsegs = (sd->gspca_dev.height >> 3) - 1;
3219
3220 reg_w(sd, R511_CAM_PXCNT, hsegs);
3221 reg_w(sd, R511_CAM_LNCNT, vsegs);
3222 reg_w(sd, R511_CAM_PXDIV, 0x00);
3223 reg_w(sd, R511_CAM_LNDIV, 0x00);
3224
3225 /* YUV420, low pass filter on */
3226 reg_w(sd, R511_CAM_OPTS, 0x03);
3227
3228 /* Snapshot additions */
3229 reg_w(sd, R511_SNAP_PXCNT, hsegs);
3230 reg_w(sd, R511_SNAP_LNCNT, vsegs);
3231 reg_w(sd, R511_SNAP_PXDIV, 0x00);
3232 reg_w(sd, R511_SNAP_LNDIV, 0x00);
3233
3234 /******** Set the framerate ********/
3235 if (frame_rate > 0)
3236 sd->frame_rate = frame_rate;
3237
3238 switch (sd->sensor) {
3239 case SEN_OV6620:
3240 /* No framerate control, doesn't like higher rates yet */
3241 sd->clockdiv = 3;
3242 break;
3243
3244 /* Note once the FIXME's in mode_init_ov_sensor_regs() are fixed
3245 for more sensors we need to do this for them too */
3246 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03003247 case SEN_OV7620AE:
Hans de Goede1876bb92009-06-14 06:45:50 -03003248 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003249 case SEN_OV7648:
Hans de Goedeb282d872009-06-14 19:10:40 -03003250 case SEN_OV76BE:
Hans de Goede1876bb92009-06-14 06:45:50 -03003251 if (sd->gspca_dev.width == 320)
3252 interlaced = 1;
3253 /* Fall through */
3254 case SEN_OV6630:
Hans de Goede1876bb92009-06-14 06:45:50 -03003255 case SEN_OV7610:
3256 case SEN_OV7670:
3257 switch (sd->frame_rate) {
3258 case 30:
3259 case 25:
3260 /* Not enough bandwidth to do 640x480 @ 30 fps */
3261 if (sd->gspca_dev.width != 640) {
3262 sd->clockdiv = 0;
3263 break;
3264 }
3265 /* Fall through for 640x480 case */
3266 default:
3267/* case 20: */
3268/* case 15: */
3269 sd->clockdiv = 1;
3270 break;
3271 case 10:
3272 sd->clockdiv = 2;
3273 break;
3274 case 5:
3275 sd->clockdiv = 5;
3276 break;
3277 }
3278 if (interlaced) {
3279 sd->clockdiv = (sd->clockdiv + 1) * 2 - 1;
3280 /* Higher then 10 does not work */
3281 if (sd->clockdiv > 10)
3282 sd->clockdiv = 10;
3283 }
3284 break;
3285
3286 case SEN_OV8610:
3287 /* No framerate control ?? */
3288 sd->clockdiv = 0;
3289 break;
3290 }
3291
3292 /* Check if we have enough bandwidth to disable compression */
3293 fps = (interlaced ? 60 : 30) / (sd->clockdiv + 1) + 1;
3294 needed = fps * sd->gspca_dev.width * sd->gspca_dev.height * 3 / 2;
3295 /* 1400 is a conservative estimate of the max nr of isoc packets/sec */
3296 if (needed > 1400 * packet_size) {
3297 /* Enable Y and UV quantization and compression */
3298 reg_w(sd, R511_COMP_EN, 0x07);
3299 reg_w(sd, R511_COMP_LUT_EN, 0x03);
3300 } else {
3301 reg_w(sd, R511_COMP_EN, 0x06);
3302 reg_w(sd, R511_COMP_LUT_EN, 0x00);
3303 }
3304
3305 reg_w(sd, R51x_SYS_RESET, OV511_RESET_OMNICE);
3306 reg_w(sd, R51x_SYS_RESET, 0);
3307
3308 return 0;
3309}
3310
Hans de Goede49809d62009-06-07 12:10:39 -03003311/* Sets up the OV518/OV518+ with the given image parameters
3312 *
3313 * OV518 needs a completely different approach, until we can figure out what
3314 * the individual registers do. Also, only 15 FPS is supported now.
3315 *
3316 * Do not put any sensor-specific code in here (including I2C I/O functions)
3317 */
3318static int ov518_mode_init_regs(struct sd *sd)
3319{
Hans de Goedeb282d872009-06-14 19:10:40 -03003320 int hsegs, vsegs, packet_size;
3321 struct usb_host_interface *alt;
3322 struct usb_interface *intf;
3323
3324 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
3325 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
3326 if (!alt) {
Jean-François Moine0b656322010-09-13 05:19:58 -03003327 err("Couldn't get altsetting");
Hans de Goedeb282d872009-06-14 19:10:40 -03003328 return -EIO;
3329 }
3330
3331 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
3332 ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2);
Hans de Goede49809d62009-06-07 12:10:39 -03003333
3334 /******** Set the mode ********/
Hans de Goede49809d62009-06-07 12:10:39 -03003335 reg_w(sd, 0x2b, 0);
3336 reg_w(sd, 0x2c, 0);
3337 reg_w(sd, 0x2d, 0);
3338 reg_w(sd, 0x2e, 0);
3339 reg_w(sd, 0x3b, 0);
3340 reg_w(sd, 0x3c, 0);
3341 reg_w(sd, 0x3d, 0);
3342 reg_w(sd, 0x3e, 0);
3343
3344 if (sd->bridge == BRIDGE_OV518) {
3345 /* Set 8-bit (YVYU) input format */
3346 reg_w_mask(sd, 0x20, 0x08, 0x08);
3347
3348 /* Set 12-bit (4:2:0) output format */
3349 reg_w_mask(sd, 0x28, 0x80, 0xf0);
3350 reg_w_mask(sd, 0x38, 0x80, 0xf0);
3351 } else {
3352 reg_w(sd, 0x28, 0x80);
3353 reg_w(sd, 0x38, 0x80);
3354 }
3355
3356 hsegs = sd->gspca_dev.width / 16;
3357 vsegs = sd->gspca_dev.height / 4;
3358
3359 reg_w(sd, 0x29, hsegs);
3360 reg_w(sd, 0x2a, vsegs);
3361
3362 reg_w(sd, 0x39, hsegs);
3363 reg_w(sd, 0x3a, vsegs);
3364
3365 /* Windows driver does this here; who knows why */
3366 reg_w(sd, 0x2f, 0x80);
3367
Jean-François Moine87bae742010-11-12 05:31:34 -03003368 /******** Set the framerate ********/
Hans de Goedeb282d872009-06-14 19:10:40 -03003369 sd->clockdiv = 1;
Hans de Goede49809d62009-06-07 12:10:39 -03003370
3371 /* Mode independent, but framerate dependent, regs */
Hans de Goedeb282d872009-06-14 19:10:40 -03003372 /* 0x51: Clock divider; Only works on some cams which use 2 crystals */
3373 reg_w(sd, 0x51, 0x04);
Hans de Goede49809d62009-06-07 12:10:39 -03003374 reg_w(sd, 0x22, 0x18);
3375 reg_w(sd, 0x23, 0xff);
3376
Hans de Goedeb282d872009-06-14 19:10:40 -03003377 if (sd->bridge == BRIDGE_OV518PLUS) {
3378 switch (sd->sensor) {
Hans de Goede859cc472010-01-07 15:42:35 -03003379 case SEN_OV7620AE:
Hans de Goedeb282d872009-06-14 19:10:40 -03003380 if (sd->gspca_dev.width == 320) {
3381 reg_w(sd, 0x20, 0x00);
3382 reg_w(sd, 0x21, 0x19);
3383 } else {
3384 reg_w(sd, 0x20, 0x60);
3385 reg_w(sd, 0x21, 0x1f);
3386 }
3387 break;
Hans de Goede859cc472010-01-07 15:42:35 -03003388 case SEN_OV7620:
3389 reg_w(sd, 0x20, 0x00);
3390 reg_w(sd, 0x21, 0x19);
3391 break;
Hans de Goedeb282d872009-06-14 19:10:40 -03003392 default:
3393 reg_w(sd, 0x21, 0x19);
3394 }
3395 } else
Hans de Goede49809d62009-06-07 12:10:39 -03003396 reg_w(sd, 0x71, 0x17); /* Compression-related? */
3397
3398 /* FIXME: Sensor-specific */
3399 /* Bit 5 is what matters here. Of course, it is "reserved" */
3400 i2c_w(sd, 0x54, 0x23);
3401
3402 reg_w(sd, 0x2f, 0x80);
3403
3404 if (sd->bridge == BRIDGE_OV518PLUS) {
3405 reg_w(sd, 0x24, 0x94);
3406 reg_w(sd, 0x25, 0x90);
3407 ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */
3408 ov518_reg_w32(sd, 0xc6, 540, 2); /* 21ch */
3409 ov518_reg_w32(sd, 0xc7, 540, 2); /* 21ch */
3410 ov518_reg_w32(sd, 0xc8, 108, 2); /* 6ch */
3411 ov518_reg_w32(sd, 0xca, 131098, 3); /* 2001ah */
3412 ov518_reg_w32(sd, 0xcb, 532, 2); /* 214h */
3413 ov518_reg_w32(sd, 0xcc, 2400, 2); /* 960h */
3414 ov518_reg_w32(sd, 0xcd, 32, 2); /* 20h */
3415 ov518_reg_w32(sd, 0xce, 608, 2); /* 260h */
3416 } else {
3417 reg_w(sd, 0x24, 0x9f);
3418 reg_w(sd, 0x25, 0x90);
3419 ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */
3420 ov518_reg_w32(sd, 0xc6, 381, 2); /* 17dh */
3421 ov518_reg_w32(sd, 0xc7, 381, 2); /* 17dh */
3422 ov518_reg_w32(sd, 0xc8, 128, 2); /* 80h */
3423 ov518_reg_w32(sd, 0xca, 183331, 3); /* 2cc23h */
3424 ov518_reg_w32(sd, 0xcb, 746, 2); /* 2eah */
3425 ov518_reg_w32(sd, 0xcc, 1750, 2); /* 6d6h */
3426 ov518_reg_w32(sd, 0xcd, 45, 2); /* 2dh */
3427 ov518_reg_w32(sd, 0xce, 851, 2); /* 353h */
3428 }
3429
3430 reg_w(sd, 0x2f, 0x80);
3431
3432 return 0;
3433}
3434
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003435/* Sets up the OV519 with the given image parameters
3436 *
3437 * OV519 needs a completely different approach, until we can figure out what
3438 * the individual registers do.
3439 *
3440 * Do not put any sensor-specific code in here (including I2C I/O functions)
3441 */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003442static int ov519_mode_init_regs(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003443{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003444 static const struct ov_regvals mode_init_519_ov7670[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003445 { 0x5d, 0x03 }, /* Turn off suspend mode */
3446 { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
Jean-François Moine21867802010-11-12 06:12:09 -03003447 { OV519_R54_EN_CLK1, 0x0f }, /* bit2 (jpeg enable) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003448 { 0xa2, 0x20 }, /* a2-a5 are undocumented */
3449 { 0xa3, 0x18 },
3450 { 0xa4, 0x04 },
3451 { 0xa5, 0x28 },
3452 { 0x37, 0x00 }, /* SetUsbInit */
3453 { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
3454 /* Enable both fields, YUV Input, disable defect comp (why?) */
3455 { 0x20, 0x0c },
3456 { 0x21, 0x38 },
3457 { 0x22, 0x1d },
3458 { 0x17, 0x50 }, /* undocumented */
3459 { 0x37, 0x00 }, /* undocumented */
3460 { 0x40, 0xff }, /* I2C timeout counter */
3461 { 0x46, 0x00 }, /* I2C clock prescaler */
3462 { 0x59, 0x04 }, /* new from windrv 090403 */
3463 { 0xff, 0x00 }, /* undocumented */
3464 /* windows reads 0x55 at this point, why? */
3465 };
3466
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003467 static const struct ov_regvals mode_init_519[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003468 { 0x5d, 0x03 }, /* Turn off suspend mode */
3469 { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
Jean-François Moine21867802010-11-12 06:12:09 -03003470 { OV519_R54_EN_CLK1, 0x0f }, /* bit2 (jpeg enable) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003471 { 0xa2, 0x20 }, /* a2-a5 are undocumented */
3472 { 0xa3, 0x18 },
3473 { 0xa4, 0x04 },
3474 { 0xa5, 0x28 },
3475 { 0x37, 0x00 }, /* SetUsbInit */
3476 { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
3477 /* Enable both fields, YUV Input, disable defect comp (why?) */
3478 { 0x22, 0x1d },
3479 { 0x17, 0x50 }, /* undocumented */
3480 { 0x37, 0x00 }, /* undocumented */
3481 { 0x40, 0xff }, /* I2C timeout counter */
3482 { 0x46, 0x00 }, /* I2C clock prescaler */
3483 { 0x59, 0x04 }, /* new from windrv 090403 */
3484 { 0xff, 0x00 }, /* undocumented */
3485 /* windows reads 0x55 at this point, why? */
3486 };
3487
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003488 /******** Set the mode ********/
3489 if (sd->sensor != SEN_OV7670) {
3490 if (write_regvals(sd, mode_init_519,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003491 ARRAY_SIZE(mode_init_519)))
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003492 return -EIO;
Hans de Goede035d3a32010-01-09 08:14:43 -03003493 if (sd->sensor == SEN_OV7640 ||
3494 sd->sensor == SEN_OV7648) {
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003495 /* Select 8-bit input mode */
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003496 reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10);
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003497 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003498 } else {
3499 if (write_regvals(sd, mode_init_519_ov7670,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003500 ARRAY_SIZE(mode_init_519_ov7670)))
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003501 return -EIO;
3502 }
3503
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003504 reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4);
3505 reg_w(sd, OV519_R11_V_SIZE, sd->gspca_dev.height >> 3);
Hans de Goede80142ef2009-06-14 06:26:49 -03003506 if (sd->sensor == SEN_OV7670 &&
3507 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
3508 reg_w(sd, OV519_R12_X_OFFSETL, 0x04);
Hans de Goede035d3a32010-01-09 08:14:43 -03003509 else if (sd->sensor == SEN_OV7648 &&
3510 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
3511 reg_w(sd, OV519_R12_X_OFFSETL, 0x01);
Hans de Goede80142ef2009-06-14 06:26:49 -03003512 else
3513 reg_w(sd, OV519_R12_X_OFFSETL, 0x00);
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003514 reg_w(sd, OV519_R13_X_OFFSETH, 0x00);
3515 reg_w(sd, OV519_R14_Y_OFFSETL, 0x00);
3516 reg_w(sd, OV519_R15_Y_OFFSETH, 0x00);
3517 reg_w(sd, OV519_R16_DIVIDER, 0x00);
3518 reg_w(sd, OV519_R25_FORMAT, 0x03); /* YUV422 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003519 reg_w(sd, 0x26, 0x00); /* Undocumented */
3520
3521 /******** Set the framerate ********/
3522 if (frame_rate > 0)
3523 sd->frame_rate = frame_rate;
3524
3525/* FIXME: These are only valid at the max resolution. */
3526 sd->clockdiv = 0;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003527 switch (sd->sensor) {
3528 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003529 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003530 switch (sd->frame_rate) {
Jean-Francois Moine53e74512008-11-08 06:10:19 -03003531 default:
3532/* case 30: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003533 reg_w(sd, 0xa4, 0x0c);
3534 reg_w(sd, 0x23, 0xff);
3535 break;
3536 case 25:
3537 reg_w(sd, 0xa4, 0x0c);
3538 reg_w(sd, 0x23, 0x1f);
3539 break;
3540 case 20:
3541 reg_w(sd, 0xa4, 0x0c);
3542 reg_w(sd, 0x23, 0x1b);
3543 break;
Jean-Francois Moine53e74512008-11-08 06:10:19 -03003544 case 15:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003545 reg_w(sd, 0xa4, 0x04);
3546 reg_w(sd, 0x23, 0xff);
3547 sd->clockdiv = 1;
3548 break;
3549 case 10:
3550 reg_w(sd, 0xa4, 0x04);
3551 reg_w(sd, 0x23, 0x1f);
3552 sd->clockdiv = 1;
3553 break;
3554 case 5:
3555 reg_w(sd, 0xa4, 0x04);
3556 reg_w(sd, 0x23, 0x1b);
3557 sd->clockdiv = 1;
3558 break;
3559 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003560 break;
3561 case SEN_OV8610:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003562 switch (sd->frame_rate) {
3563 default: /* 15 fps */
3564/* case 15: */
3565 reg_w(sd, 0xa4, 0x06);
3566 reg_w(sd, 0x23, 0xff);
3567 break;
3568 case 10:
3569 reg_w(sd, 0xa4, 0x06);
3570 reg_w(sd, 0x23, 0x1f);
3571 break;
3572 case 5:
3573 reg_w(sd, 0xa4, 0x06);
3574 reg_w(sd, 0x23, 0x1b);
3575 break;
3576 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003577 break;
3578 case SEN_OV7670: /* guesses, based on 7640 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003579 PDEBUG(D_STREAM, "Setting framerate to %d fps",
3580 (sd->frame_rate == 0) ? 15 : sd->frame_rate);
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003581 reg_w(sd, 0xa4, 0x10);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003582 switch (sd->frame_rate) {
3583 case 30:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003584 reg_w(sd, 0x23, 0xff);
3585 break;
3586 case 20:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003587 reg_w(sd, 0x23, 0x1b);
3588 break;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003589 default:
3590/* case 15: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003591 reg_w(sd, 0x23, 0xff);
3592 sd->clockdiv = 1;
3593 break;
3594 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003595 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003596 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003597 return 0;
3598}
3599
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003600static int mode_init_ov_sensor_regs(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003601{
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003602 struct gspca_dev *gspca_dev;
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003603 int qvga, xstart, xend, ystart, yend;
Jean-François Moine9d1593a2010-11-11 08:04:06 -03003604 u8 v;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003605
3606 gspca_dev = &sd->gspca_dev;
Jean-François Moine87bae742010-11-12 05:31:34 -03003607 qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003608
3609 /******** Mode (VGA/QVGA) and sensor specific regs ********/
3610 switch (sd->sensor) {
Hans de Goede635118d2009-10-11 09:49:03 -03003611 case SEN_OV2610:
3612 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3613 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
3614 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
3615 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
3616 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
3617 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
3618 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
3619 return 0;
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003620 case SEN_OV3610:
Hans de Goede635118d2009-10-11 09:49:03 -03003621 if (qvga) {
3622 xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003623 ystart = (776 - gspca_dev->height) / 2;
Hans de Goede635118d2009-10-11 09:49:03 -03003624 } else {
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003625 xstart = (2076 - gspca_dev->width) / 2 + (0x10 << 4);
Hans de Goede635118d2009-10-11 09:49:03 -03003626 ystart = (1544 - gspca_dev->height) / 2;
3627 }
3628 xend = xstart + gspca_dev->width;
3629 yend = ystart + gspca_dev->height;
3630 /* Writing to the COMH register resets the other windowing regs
3631 to their default values, so we must do this first. */
3632 i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0xf0);
3633 i2c_w_mask(sd, 0x32,
3634 (((xend >> 1) & 7) << 3) | ((xstart >> 1) & 7),
3635 0x3f);
3636 i2c_w_mask(sd, 0x03,
3637 (((yend >> 1) & 3) << 2) | ((ystart >> 1) & 3),
3638 0x0f);
3639 i2c_w(sd, 0x17, xstart >> 4);
3640 i2c_w(sd, 0x18, xend >> 4);
3641 i2c_w(sd, 0x19, ystart >> 3);
3642 i2c_w(sd, 0x1a, yend >> 3);
3643 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003644 case SEN_OV8610:
3645 /* For OV8610 qvga means qsvga */
3646 i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003647 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3648 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3649 i2c_w_mask(sd, 0x2d, 0x00, 0x40); /* from windrv 090403 */
3650 i2c_w_mask(sd, 0x28, 0x20, 0x20); /* progressive mode on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003651 break;
3652 case SEN_OV7610:
3653 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
Jean-François Moine780e3122010-10-19 04:29:10 -03003654 i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003655 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3656 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003657 break;
3658 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03003659 case SEN_OV7620AE:
Hans de Goedeb282d872009-06-14 19:10:40 -03003660 case SEN_OV76BE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003661 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3662 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
3663 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
3664 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
3665 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
Hans de Goedeb282d872009-06-14 19:10:40 -03003666 i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003667 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003668 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3669 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3670 if (sd->sensor == SEN_OV76BE)
3671 i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003672 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003673 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003674 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003675 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3676 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
Hans de Goede8d0082f2010-01-09 19:45:44 -03003677 /* Setting this undocumented bit in qvga mode removes a very
3678 annoying vertical shaking of the image */
Hans de Goede035d3a32010-01-09 08:14:43 -03003679 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
Hans de Goede8d0082f2010-01-09 19:45:44 -03003680 /* Unknown */
Hans de Goede035d3a32010-01-09 08:14:43 -03003681 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
Hans de Goede8d0082f2010-01-09 19:45:44 -03003682 /* Allow higher automatic gain (to allow higher framerates) */
Hans de Goede035d3a32010-01-09 08:14:43 -03003683 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003684 i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003685 break;
3686 case SEN_OV7670:
3687 /* set COM7_FMT_VGA or COM7_FMT_QVGA
3688 * do we need to set anything else?
3689 * HSTART etc are set in set_ov_sensor_window itself */
Jean-François Moine21867802010-11-12 06:12:09 -03003690 i2c_w_mask(sd, OV7670_R12_COM7,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003691 qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA,
3692 OV7670_COM7_FMT_MASK);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003693 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
Jean-François Moine21867802010-11-12 06:12:09 -03003694 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_AWB,
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003695 OV7670_COM8_AWB);
3696 if (qvga) { /* QVGA from ov7670.c by
3697 * Jonathan Corbet */
3698 xstart = 164;
3699 xend = 28;
3700 ystart = 14;
3701 yend = 494;
3702 } else { /* VGA */
3703 xstart = 158;
3704 xend = 14;
3705 ystart = 10;
3706 yend = 490;
3707 }
3708 /* OV7670 hardware window registers are split across
3709 * multiple locations */
Jean-François Moine21867802010-11-12 06:12:09 -03003710 i2c_w(sd, OV7670_R17_HSTART, xstart >> 3);
3711 i2c_w(sd, OV7670_R18_HSTOP, xend >> 3);
3712 v = i2c_r(sd, OV7670_R32_HREF);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003713 v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07);
3714 msleep(10); /* need to sleep between read and write to
3715 * same reg! */
Jean-François Moine21867802010-11-12 06:12:09 -03003716 i2c_w(sd, OV7670_R32_HREF, v);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003717
Jean-François Moine21867802010-11-12 06:12:09 -03003718 i2c_w(sd, OV7670_R19_VSTART, ystart >> 2);
3719 i2c_w(sd, OV7670_R1A_VSTOP, yend >> 2);
3720 v = i2c_r(sd, OV7670_R03_VREF);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003721 v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03);
3722 msleep(10); /* need to sleep between read and write to
3723 * same reg! */
Jean-François Moine21867802010-11-12 06:12:09 -03003724 i2c_w(sd, OV7670_R03_VREF, v);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003725 break;
3726 case SEN_OV6620:
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003727 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3728 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3729 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3730 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003731 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03003732 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003733 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003734 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003735 break;
3736 default:
3737 return -EINVAL;
3738 }
3739
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003740 /******** Clock programming ********/
Hans de Goedeae49c402009-06-14 19:15:07 -03003741 i2c_w(sd, 0x11, sd->clockdiv);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003742
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003743 return 0;
3744}
3745
Jean-François Moine62833ac2010-10-02 04:27:02 -03003746static void sethvflip(struct gspca_dev *gspca_dev)
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003747{
Jean-François Moine62833ac2010-10-02 04:27:02 -03003748 struct sd *sd = (struct sd *) gspca_dev;
3749
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003750 if (sd->sensor != SEN_OV7670)
3751 return;
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003752 if (sd->gspca_dev.streaming)
3753 ov51x_stop(sd);
Jean-François Moine21867802010-11-12 06:12:09 -03003754 i2c_w_mask(sd, OV7670_R1E_MVFP,
Jean-François Moine62833ac2010-10-02 04:27:02 -03003755 OV7670_MVFP_MIRROR * sd->ctrls[HFLIP].val
3756 | OV7670_MVFP_VFLIP * sd->ctrls[VFLIP].val,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003757 OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP);
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003758 if (sd->gspca_dev.streaming)
3759 ov51x_restart(sd);
3760}
3761
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003762static int set_ov_sensor_window(struct sd *sd)
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003763{
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003764 struct gspca_dev *gspca_dev;
Hans de Goede124cc9c2009-06-14 05:48:00 -03003765 int qvga, crop;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003766 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003767 int ret;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003768
Hans de Goede635118d2009-10-11 09:49:03 -03003769 /* mode setup is fully handled in mode_init_ov_sensor_regs for these */
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003770 if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610 ||
3771 sd->sensor == SEN_OV7670)
Hans de Goede635118d2009-10-11 09:49:03 -03003772 return mode_init_ov_sensor_regs(sd);
3773
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003774 gspca_dev = &sd->gspca_dev;
Jean-François Moine87bae742010-11-12 05:31:34 -03003775 qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
3776 crop = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 2;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003777
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003778 /* The different sensor ICs handle setting up of window differently.
3779 * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */
3780 switch (sd->sensor) {
3781 case SEN_OV8610:
3782 hwsbase = 0x1e;
3783 hwebase = 0x1e;
3784 vwsbase = 0x02;
3785 vwebase = 0x02;
3786 break;
3787 case SEN_OV7610:
3788 case SEN_OV76BE:
3789 hwsbase = 0x38;
3790 hwebase = 0x3a;
3791 vwsbase = vwebase = 0x05;
3792 break;
3793 case SEN_OV6620:
3794 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03003795 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003796 hwsbase = 0x38;
3797 hwebase = 0x3a;
3798 vwsbase = 0x05;
3799 vwebase = 0x06;
Hans de Goede7d971372009-06-14 05:28:17 -03003800 if (sd->sensor == SEN_OV66308AF && qvga)
Hans de Goede49809d62009-06-07 12:10:39 -03003801 /* HDG: this fixes U and V getting swapped */
Hans de Goede7d971372009-06-14 05:28:17 -03003802 hwsbase++;
Hans de Goede124cc9c2009-06-14 05:48:00 -03003803 if (crop) {
3804 hwsbase += 8;
3805 hwebase += 8;
3806 vwsbase += 11;
3807 vwebase += 11;
3808 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003809 break;
3810 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03003811 case SEN_OV7620AE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003812 hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */
3813 hwebase = 0x2f;
3814 vwsbase = vwebase = 0x05;
3815 break;
3816 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003817 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003818 hwsbase = 0x1a;
3819 hwebase = 0x1a;
3820 vwsbase = vwebase = 0x03;
3821 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003822 default:
3823 return -EINVAL;
3824 }
3825
3826 switch (sd->sensor) {
3827 case SEN_OV6620:
3828 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03003829 case SEN_OV66308AF:
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003830 if (qvga) { /* QCIF */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003831 hwscale = 0;
3832 vwscale = 0;
3833 } else { /* CIF */
3834 hwscale = 1;
3835 vwscale = 1; /* The datasheet says 0;
3836 * it's wrong */
3837 }
3838 break;
3839 case SEN_OV8610:
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003840 if (qvga) { /* QSVGA */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003841 hwscale = 1;
3842 vwscale = 1;
3843 } else { /* SVGA */
3844 hwscale = 2;
3845 vwscale = 2;
3846 }
3847 break;
3848 default: /* SEN_OV7xx0 */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003849 if (qvga) { /* QVGA */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003850 hwscale = 1;
3851 vwscale = 0;
3852 } else { /* VGA */
3853 hwscale = 2;
3854 vwscale = 1;
3855 }
3856 }
3857
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003858 ret = mode_init_ov_sensor_regs(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003859 if (ret < 0)
3860 return ret;
3861
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003862 i2c_w(sd, 0x17, hwsbase);
Hans de Goedea511ba92009-10-16 07:13:07 -03003863 i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale));
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003864 i2c_w(sd, 0x19, vwsbase);
Hans de Goedea511ba92009-10-16 07:13:07 -03003865 i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale));
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003866
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003867 return 0;
3868}
3869
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003870/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03003871static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003872{
3873 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goede49809d62009-06-07 12:10:39 -03003874 int ret = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003875
Hans de Goedea511ba92009-10-16 07:13:07 -03003876 /* Default for most bridges, allow bridge_mode_init_regs to override */
3877 sd->sensor_width = sd->gspca_dev.width;
3878 sd->sensor_height = sd->gspca_dev.height;
3879
Hans de Goede49809d62009-06-07 12:10:39 -03003880 switch (sd->bridge) {
Hans de Goede1876bb92009-06-14 06:45:50 -03003881 case BRIDGE_OV511:
3882 case BRIDGE_OV511PLUS:
3883 ret = ov511_mode_init_regs(sd);
3884 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003885 case BRIDGE_OV518:
3886 case BRIDGE_OV518PLUS:
3887 ret = ov518_mode_init_regs(sd);
3888 break;
3889 case BRIDGE_OV519:
3890 ret = ov519_mode_init_regs(sd);
3891 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003892 /* case BRIDGE_OVFX2: nothing to do */
Hans de Goedea511ba92009-10-16 07:13:07 -03003893 case BRIDGE_W9968CF:
3894 ret = w9968cf_mode_init_regs(sd);
3895 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003896 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003897 if (ret < 0)
3898 goto out;
Hans de Goede49809d62009-06-07 12:10:39 -03003899
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003900 ret = set_ov_sensor_window(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003901 if (ret < 0)
3902 goto out;
3903
Hans de Goede49809d62009-06-07 12:10:39 -03003904 setcontrast(gspca_dev);
3905 setbrightness(gspca_dev);
3906 setcolors(gspca_dev);
Jean-François Moine62833ac2010-10-02 04:27:02 -03003907 sethvflip(gspca_dev);
3908 setautobright(gspca_dev);
3909 setfreq_i(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03003910
Hans de Goede417a4d22010-02-19 07:37:08 -03003911 /* Force clear snapshot state in case the snapshot button was
3912 pressed while we weren't streaming */
3913 sd->snapshot_needs_reset = 1;
3914 sd_reset_snapshot(gspca_dev);
Hans de Goede417a4d22010-02-19 07:37:08 -03003915
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03003916 sd->first_frame = 3;
3917
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003918 ret = ov51x_restart(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003919 if (ret < 0)
3920 goto out;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003921 ov51x_led_control(sd, 1);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03003922 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003923out:
3924 PDEBUG(D_ERR, "camera start error:%d", ret);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03003925 return ret;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003926}
3927
3928static void sd_stopN(struct gspca_dev *gspca_dev)
3929{
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003930 struct sd *sd = (struct sd *) gspca_dev;
3931
3932 ov51x_stop(sd);
3933 ov51x_led_control(sd, 0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003934}
3935
Hans de Goede79b35902009-10-19 06:08:01 -03003936static void sd_stop0(struct gspca_dev *gspca_dev)
3937{
3938 struct sd *sd = (struct sd *) gspca_dev;
3939
Jean-François Moined65174c2010-11-11 06:20:42 -03003940 if (!sd->gspca_dev.present)
3941 return;
Hans de Goede79b35902009-10-19 06:08:01 -03003942 if (sd->bridge == BRIDGE_W9968CF)
3943 w9968cf_stop0(sd);
Hans de Goede614d0692010-10-27 07:42:28 -03003944
Jean-François Moine14653e62010-11-11 06:17:01 -03003945#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
Hans de Goede614d0692010-10-27 07:42:28 -03003946 /* If the last button state is pressed, release it now! */
3947 if (sd->snapshot_pressed) {
3948 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
3949 input_sync(gspca_dev->input_dev);
3950 sd->snapshot_pressed = 0;
3951 }
3952#endif
Hans de Goede79b35902009-10-19 06:08:01 -03003953}
3954
Hans de Goede92e232a2010-02-20 04:30:45 -03003955static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state)
3956{
3957 struct sd *sd = (struct sd *) gspca_dev;
3958
3959 if (sd->snapshot_pressed != state) {
Jean-François Moine28566432010-10-01 07:33:26 -03003960#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
Hans de Goede92e232a2010-02-20 04:30:45 -03003961 input_report_key(gspca_dev->input_dev, KEY_CAMERA, state);
3962 input_sync(gspca_dev->input_dev);
3963#endif
3964 if (state)
3965 sd->snapshot_needs_reset = 1;
3966
3967 sd->snapshot_pressed = state;
3968 } else {
Hans de Goede88e8d202010-02-20 04:45:49 -03003969 /* On the ov511 / ov519 we need to reset the button state
3970 multiple times, as resetting does not work as long as the
3971 button stays pressed */
3972 switch (sd->bridge) {
3973 case BRIDGE_OV511:
3974 case BRIDGE_OV511PLUS:
3975 case BRIDGE_OV519:
3976 if (state)
3977 sd->snapshot_needs_reset = 1;
3978 break;
3979 }
Hans de Goede92e232a2010-02-20 04:30:45 -03003980 }
3981}
3982
Hans de Goede1876bb92009-06-14 06:45:50 -03003983static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03003984 u8 *in, /* isoc packet */
3985 int len) /* iso packet length */
Hans de Goede1876bb92009-06-14 06:45:50 -03003986{
3987 struct sd *sd = (struct sd *) gspca_dev;
3988
3989 /* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th
3990 * byte non-zero. The EOF packet has image width/height in the
3991 * 10th and 11th bytes. The 9th byte is given as follows:
3992 *
3993 * bit 7: EOF
3994 * 6: compression enabled
3995 * 5: 422/420/400 modes
3996 * 4: 422/420/400 modes
3997 * 3: 1
3998 * 2: snapshot button on
3999 * 1: snapshot frame
4000 * 0: even/odd field
4001 */
4002 if (!(in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) &&
4003 (in[8] & 0x08)) {
Hans de Goede88e8d202010-02-20 04:45:49 -03004004 ov51x_handle_button(gspca_dev, (in[8] >> 2) & 1);
Hans de Goede1876bb92009-06-14 06:45:50 -03004005 if (in[8] & 0x80) {
4006 /* Frame end */
4007 if ((in[9] + 1) * 8 != gspca_dev->width ||
4008 (in[10] + 1) * 8 != gspca_dev->height) {
4009 PDEBUG(D_ERR, "Invalid frame size, got: %dx%d,"
4010 " requested: %dx%d\n",
4011 (in[9] + 1) * 8, (in[10] + 1) * 8,
4012 gspca_dev->width, gspca_dev->height);
4013 gspca_dev->last_packet_type = DISCARD_PACKET;
4014 return;
4015 }
4016 /* Add 11 byte footer to frame, might be usefull */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004017 gspca_frame_add(gspca_dev, LAST_PACKET, in, 11);
Hans de Goede1876bb92009-06-14 06:45:50 -03004018 return;
4019 } else {
4020 /* Frame start */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004021 gspca_frame_add(gspca_dev, FIRST_PACKET, in, 0);
Hans de Goede1876bb92009-06-14 06:45:50 -03004022 sd->packet_nr = 0;
4023 }
4024 }
4025
4026 /* Ignore the packet number */
4027 len--;
4028
4029 /* intermediate packet */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004030 gspca_frame_add(gspca_dev, INTER_PACKET, in, len);
Hans de Goede1876bb92009-06-14 06:45:50 -03004031}
4032
Hans de Goede49809d62009-06-07 12:10:39 -03004033static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004034 u8 *data, /* isoc packet */
Hans de Goede49809d62009-06-07 12:10:39 -03004035 int len) /* iso packet length */
4036{
Hans de Goede92918a52009-06-14 06:21:35 -03004037 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goede49809d62009-06-07 12:10:39 -03004038
4039 /* A false positive here is likely, until OVT gives me
4040 * the definitive SOF/EOF format */
4041 if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
Hans de Goede92e232a2010-02-20 04:30:45 -03004042 ov51x_handle_button(gspca_dev, (data[6] >> 1) & 1);
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004043 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
4044 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
Hans de Goede92918a52009-06-14 06:21:35 -03004045 sd->packet_nr = 0;
4046 }
4047
4048 if (gspca_dev->last_packet_type == DISCARD_PACKET)
4049 return;
4050
4051 /* Does this device use packet numbers ? */
4052 if (len & 7) {
4053 len--;
4054 if (sd->packet_nr == data[len])
4055 sd->packet_nr++;
4056 /* The last few packets of the frame (which are all 0's
4057 except that they may contain part of the footer), are
4058 numbered 0 */
4059 else if (sd->packet_nr == 0 || data[len]) {
4060 PDEBUG(D_ERR, "Invalid packet nr: %d (expect: %d)",
4061 (int)data[len], (int)sd->packet_nr);
4062 gspca_dev->last_packet_type = DISCARD_PACKET;
4063 return;
4064 }
Hans de Goede49809d62009-06-07 12:10:39 -03004065 }
4066
4067 /* intermediate packet */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004068 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004069}
4070
4071static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004072 u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004073 int len) /* iso packet length */
4074{
4075 /* Header of ov519 is 16 bytes:
4076 * Byte Value Description
4077 * 0 0xff magic
4078 * 1 0xff magic
4079 * 2 0xff magic
4080 * 3 0xXX 0x50 = SOF, 0x51 = EOF
4081 * 9 0xXX 0x01 initial frame without data,
4082 * 0x00 standard frame with image
4083 * 14 Lo in EOF: length of image data / 8
4084 * 15 Hi
4085 */
4086
4087 if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) {
4088 switch (data[3]) {
4089 case 0x50: /* start of frame */
Hans de Goede417a4d22010-02-19 07:37:08 -03004090 /* Don't check the button state here, as the state
4091 usually (always ?) changes at EOF and checking it
4092 here leads to unnecessary snapshot state resets. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004093#define HDRSZ 16
4094 data += HDRSZ;
4095 len -= HDRSZ;
4096#undef HDRSZ
4097 if (data[0] == 0xff || data[1] == 0xd8)
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004098 gspca_frame_add(gspca_dev, FIRST_PACKET,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004099 data, len);
4100 else
4101 gspca_dev->last_packet_type = DISCARD_PACKET;
4102 return;
4103 case 0x51: /* end of frame */
Hans de Goede92e232a2010-02-20 04:30:45 -03004104 ov51x_handle_button(gspca_dev, data[11] & 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004105 if (data[9] != 0)
4106 gspca_dev->last_packet_type = DISCARD_PACKET;
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004107 gspca_frame_add(gspca_dev, LAST_PACKET,
4108 NULL, 0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004109 return;
4110 }
4111 }
4112
4113 /* intermediate packet */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004114 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004115}
4116
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004117static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004118 u8 *data, /* isoc packet */
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004119 int len) /* iso packet length */
4120{
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03004121 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03004122
4123 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
4124
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004125 /* A short read signals EOF */
4126 if (len < OVFX2_BULK_SIZE) {
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03004127 /* If the frame is short, and it is one of the first ones
4128 the sensor and bridge are still syncing, so drop it. */
4129 if (sd->first_frame) {
4130 sd->first_frame--;
Jean-François Moineb192ca92010-06-27 03:08:19 -03004131 if (gspca_dev->image_len <
4132 sd->gspca_dev.width * sd->gspca_dev.height)
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03004133 gspca_dev->last_packet_type = DISCARD_PACKET;
4134 }
4135 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004136 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004137 }
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004138}
4139
Hans de Goede49809d62009-06-07 12:10:39 -03004140static void sd_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004141 u8 *data, /* isoc packet */
Hans de Goede49809d62009-06-07 12:10:39 -03004142 int len) /* iso packet length */
4143{
4144 struct sd *sd = (struct sd *) gspca_dev;
4145
4146 switch (sd->bridge) {
4147 case BRIDGE_OV511:
4148 case BRIDGE_OV511PLUS:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004149 ov511_pkt_scan(gspca_dev, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004150 break;
4151 case BRIDGE_OV518:
4152 case BRIDGE_OV518PLUS:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004153 ov518_pkt_scan(gspca_dev, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004154 break;
4155 case BRIDGE_OV519:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004156 ov519_pkt_scan(gspca_dev, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004157 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004158 case BRIDGE_OVFX2:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004159 ovfx2_pkt_scan(gspca_dev, data, len);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004160 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03004161 case BRIDGE_W9968CF:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004162 w9968cf_pkt_scan(gspca_dev, data, len);
Hans de Goedea511ba92009-10-16 07:13:07 -03004163 break;
Hans de Goede49809d62009-06-07 12:10:39 -03004164 }
4165}
4166
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004167/* -- management routines -- */
4168
4169static void setbrightness(struct gspca_dev *gspca_dev)
4170{
4171 struct sd *sd = (struct sd *) gspca_dev;
4172 int val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004173
Jean-François Moine62833ac2010-10-02 04:27:02 -03004174 val = sd->ctrls[BRIGHTNESS].val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004175 switch (sd->sensor) {
4176 case SEN_OV8610:
4177 case SEN_OV7610:
4178 case SEN_OV76BE:
4179 case SEN_OV6620:
4180 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004181 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004182 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03004183 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004184 i2c_w(sd, OV7610_REG_BRT, val);
4185 break;
4186 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03004187 case SEN_OV7620AE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004188 /* 7620 doesn't like manual changes when in auto mode */
Jean-François Moine62833ac2010-10-02 04:27:02 -03004189 if (!sd->ctrls[AUTOBRIGHT].val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004190 i2c_w(sd, OV7610_REG_BRT, val);
4191 break;
4192 case SEN_OV7670:
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004193/*win trace
Jean-François Moine21867802010-11-12 06:12:09 -03004194 * i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_AEC); */
4195 i2c_w(sd, OV7670_R55_BRIGHT, ov7670_abs_to_sm(val));
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004196 break;
4197 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004198}
4199
4200static void setcontrast(struct gspca_dev *gspca_dev)
4201{
4202 struct sd *sd = (struct sd *) gspca_dev;
4203 int val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004204
Jean-François Moine62833ac2010-10-02 04:27:02 -03004205 val = sd->ctrls[CONTRAST].val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004206 switch (sd->sensor) {
4207 case SEN_OV7610:
4208 case SEN_OV6620:
4209 i2c_w(sd, OV7610_REG_CNT, val);
4210 break;
4211 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004212 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004213 i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f);
Hans de Goede49809d62009-06-07 12:10:39 -03004214 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004215 case SEN_OV8610: {
Jean-François Moine9d1593a2010-11-11 08:04:06 -03004216 static const u8 ctab[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004217 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f
4218 };
4219
4220 /* Use Y gamma control instead. Bit 0 enables it. */
4221 i2c_w(sd, 0x64, ctab[val >> 5]);
4222 break;
4223 }
Hans de Goede859cc472010-01-07 15:42:35 -03004224 case SEN_OV7620:
4225 case SEN_OV7620AE: {
Jean-François Moine9d1593a2010-11-11 08:04:06 -03004226 static const u8 ctab[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004227 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
4228 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
4229 };
4230
4231 /* Use Y gamma control instead. Bit 0 enables it. */
4232 i2c_w(sd, 0x64, ctab[val >> 4]);
4233 break;
4234 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004235 case SEN_OV7670:
4236 /* check that this isn't just the same as ov7610 */
Jean-François Moine21867802010-11-12 06:12:09 -03004237 i2c_w(sd, OV7670_R56_CONTRAS, val >> 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004238 break;
4239 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004240}
4241
4242static void setcolors(struct gspca_dev *gspca_dev)
4243{
4244 struct sd *sd = (struct sd *) gspca_dev;
4245 int val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004246
Jean-François Moine62833ac2010-10-02 04:27:02 -03004247 val = sd->ctrls[COLORS].val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004248 switch (sd->sensor) {
4249 case SEN_OV8610:
4250 case SEN_OV7610:
4251 case SEN_OV76BE:
4252 case SEN_OV6620:
4253 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004254 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004255 i2c_w(sd, OV7610_REG_SAT, val);
4256 break;
4257 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03004258 case SEN_OV7620AE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004259 /* Use UV gamma control instead. Bits 0 & 7 are reserved. */
4260/* rc = ov_i2c_write(sd->dev, 0x62, (val >> 9) & 0x7e);
4261 if (rc < 0)
4262 goto out; */
4263 i2c_w(sd, OV7610_REG_SAT, val);
4264 break;
4265 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03004266 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004267 i2c_w(sd, OV7610_REG_SAT, val & 0xf0);
4268 break;
4269 case SEN_OV7670:
4270 /* supported later once I work out how to do it
4271 * transparently fail now! */
4272 /* set REG_COM13 values for UV sat auto mode */
4273 break;
4274 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004275}
4276
Jean-François Moine62833ac2010-10-02 04:27:02 -03004277static void setautobright(struct gspca_dev *gspca_dev)
Hans de Goede02ab18b2009-06-14 04:32:04 -03004278{
Jean-François Moine62833ac2010-10-02 04:27:02 -03004279 struct sd *sd = (struct sd *) gspca_dev;
4280
Hans de Goede035d3a32010-01-09 08:14:43 -03004281 if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7648 ||
4282 sd->sensor == SEN_OV7670 ||
Hans de Goede635118d2009-10-11 09:49:03 -03004283 sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
Hans de Goede02ab18b2009-06-14 04:32:04 -03004284 return;
4285
Jean-François Moine62833ac2010-10-02 04:27:02 -03004286 i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10);
Hans de Goede02ab18b2009-06-14 04:32:04 -03004287}
4288
Jean-François Moine62833ac2010-10-02 04:27:02 -03004289static void setfreq_i(struct sd *sd)
Hans de Goede02ab18b2009-06-14 04:32:04 -03004290{
Hans de Goede635118d2009-10-11 09:49:03 -03004291 if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
4292 return;
4293
Hans de Goede02ab18b2009-06-14 04:32:04 -03004294 if (sd->sensor == SEN_OV7670) {
Jean-François Moine62833ac2010-10-02 04:27:02 -03004295 switch (sd->ctrls[FREQ].val) {
Hans de Goede02ab18b2009-06-14 04:32:04 -03004296 case 0: /* Banding filter disabled */
Jean-François Moine21867802010-11-12 06:12:09 -03004297 i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_BFILT);
Hans de Goede02ab18b2009-06-14 04:32:04 -03004298 break;
4299 case 1: /* 50 hz */
Jean-François Moine21867802010-11-12 06:12:09 -03004300 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004301 OV7670_COM8_BFILT);
Jean-François Moine21867802010-11-12 06:12:09 -03004302 i2c_w_mask(sd, OV7670_R3B_COM11, 0x08, 0x18);
Hans de Goede02ab18b2009-06-14 04:32:04 -03004303 break;
4304 case 2: /* 60 hz */
Jean-François Moine21867802010-11-12 06:12:09 -03004305 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004306 OV7670_COM8_BFILT);
Jean-François Moine21867802010-11-12 06:12:09 -03004307 i2c_w_mask(sd, OV7670_R3B_COM11, 0x00, 0x18);
Hans de Goede02ab18b2009-06-14 04:32:04 -03004308 break;
Jean-François Moine21867802010-11-12 06:12:09 -03004309 case 3: /* Auto hz - ov7670 only */
4310 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004311 OV7670_COM8_BFILT);
Jean-François Moine21867802010-11-12 06:12:09 -03004312 i2c_w_mask(sd, OV7670_R3B_COM11, OV7670_COM11_HZAUTO,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004313 0x18);
4314 break;
4315 }
4316 } else {
Jean-François Moine62833ac2010-10-02 04:27:02 -03004317 switch (sd->ctrls[FREQ].val) {
Hans de Goede02ab18b2009-06-14 04:32:04 -03004318 case 0: /* Banding filter disabled */
4319 i2c_w_mask(sd, 0x2d, 0x00, 0x04);
4320 i2c_w_mask(sd, 0x2a, 0x00, 0x80);
4321 break;
4322 case 1: /* 50 hz (filter on and framerate adj) */
4323 i2c_w_mask(sd, 0x2d, 0x04, 0x04);
4324 i2c_w_mask(sd, 0x2a, 0x80, 0x80);
4325 /* 20 fps -> 16.667 fps */
4326 if (sd->sensor == SEN_OV6620 ||
Hans de Goede7d971372009-06-14 05:28:17 -03004327 sd->sensor == SEN_OV6630 ||
4328 sd->sensor == SEN_OV66308AF)
Hans de Goede02ab18b2009-06-14 04:32:04 -03004329 i2c_w(sd, 0x2b, 0x5e);
4330 else
4331 i2c_w(sd, 0x2b, 0xac);
4332 break;
4333 case 2: /* 60 hz (filter on, ...) */
4334 i2c_w_mask(sd, 0x2d, 0x04, 0x04);
4335 if (sd->sensor == SEN_OV6620 ||
Hans de Goede7d971372009-06-14 05:28:17 -03004336 sd->sensor == SEN_OV6630 ||
4337 sd->sensor == SEN_OV66308AF) {
Hans de Goede02ab18b2009-06-14 04:32:04 -03004338 /* 20 fps -> 15 fps */
4339 i2c_w_mask(sd, 0x2a, 0x80, 0x80);
4340 i2c_w(sd, 0x2b, 0xa8);
4341 } else {
4342 /* no framerate adj. */
4343 i2c_w_mask(sd, 0x2a, 0x00, 0x80);
4344 }
4345 break;
4346 }
4347 }
4348}
Jean-François Moine62833ac2010-10-02 04:27:02 -03004349static void setfreq(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004350{
4351 struct sd *sd = (struct sd *) gspca_dev;
4352
Jean-François Moine62833ac2010-10-02 04:27:02 -03004353 setfreq_i(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004354
Jean-François Moine62833ac2010-10-02 04:27:02 -03004355 /* Ugly but necessary */
4356 if (sd->bridge == BRIDGE_W9968CF)
4357 w9968cf_set_crop_window(sd);
Hans de Goede02ab18b2009-06-14 04:32:04 -03004358}
4359
4360static int sd_querymenu(struct gspca_dev *gspca_dev,
4361 struct v4l2_querymenu *menu)
4362{
4363 struct sd *sd = (struct sd *) gspca_dev;
4364
4365 switch (menu->id) {
4366 case V4L2_CID_POWER_LINE_FREQUENCY:
4367 switch (menu->index) {
4368 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
4369 strcpy((char *) menu->name, "NoFliker");
4370 return 0;
4371 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
4372 strcpy((char *) menu->name, "50 Hz");
4373 return 0;
4374 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
4375 strcpy((char *) menu->name, "60 Hz");
4376 return 0;
4377 case 3:
4378 if (sd->sensor != SEN_OV7670)
4379 return -EINVAL;
4380
4381 strcpy((char *) menu->name, "Automatic");
4382 return 0;
4383 }
4384 break;
4385 }
4386 return -EINVAL;
4387}
4388
Hans de Goede79b35902009-10-19 06:08:01 -03004389static int sd_get_jcomp(struct gspca_dev *gspca_dev,
4390 struct v4l2_jpegcompression *jcomp)
4391{
4392 struct sd *sd = (struct sd *) gspca_dev;
4393
4394 if (sd->bridge != BRIDGE_W9968CF)
4395 return -EINVAL;
4396
4397 memset(jcomp, 0, sizeof *jcomp);
4398 jcomp->quality = sd->quality;
4399 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT |
4400 V4L2_JPEG_MARKER_DRI;
4401 return 0;
4402}
4403
4404static int sd_set_jcomp(struct gspca_dev *gspca_dev,
4405 struct v4l2_jpegcompression *jcomp)
4406{
4407 struct sd *sd = (struct sd *) gspca_dev;
4408
4409 if (sd->bridge != BRIDGE_W9968CF)
4410 return -EINVAL;
4411
4412 if (gspca_dev->streaming)
4413 return -EBUSY;
4414
4415 if (jcomp->quality < QUALITY_MIN)
4416 sd->quality = QUALITY_MIN;
4417 else if (jcomp->quality > QUALITY_MAX)
4418 sd->quality = QUALITY_MAX;
4419 else
4420 sd->quality = jcomp->quality;
4421
4422 /* Return resulting jcomp params to app */
4423 sd_get_jcomp(gspca_dev, jcomp);
4424
4425 return 0;
4426}
4427
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004428/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03004429static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004430 .name = MODULE_NAME,
4431 .ctrls = sd_ctrls,
4432 .nctrls = ARRAY_SIZE(sd_ctrls),
4433 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03004434 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004435 .start = sd_start,
4436 .stopN = sd_stopN,
Hans de Goede79b35902009-10-19 06:08:01 -03004437 .stop0 = sd_stop0,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004438 .pkt_scan = sd_pkt_scan,
Hans de Goede417a4d22010-02-19 07:37:08 -03004439 .dq_callback = sd_reset_snapshot,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004440 .querymenu = sd_querymenu,
Hans de Goede79b35902009-10-19 06:08:01 -03004441 .get_jcomp = sd_get_jcomp,
4442 .set_jcomp = sd_set_jcomp,
Jean-François Moine28566432010-10-01 07:33:26 -03004443#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
Hans de Goede417a4d22010-02-19 07:37:08 -03004444 .other_input = 1,
4445#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004446};
4447
4448/* -- module initialisation -- */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03004449static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goedea511ba92009-10-16 07:13:07 -03004450 {USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF },
Hans de Goede49809d62009-06-07 12:10:39 -03004451 {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 },
4452 {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
4453 {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
4454 {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
Hans de Goede9e4d8252009-06-14 06:25:06 -03004455 {USB_DEVICE(0x041e, 0x4064),
Jean-François Moine87bae742010-11-12 05:31:34 -03004456 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
Rafal Milecki518c8df2009-10-02 03:54:44 -03004457 {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 },
Hans de Goede9e4d8252009-06-14 06:25:06 -03004458 {USB_DEVICE(0x041e, 0x4068),
Jean-François Moine87bae742010-11-12 05:31:34 -03004459 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
Hans de Goede49809d62009-06-07 12:10:39 -03004460 {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
4461 {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
Hans de Goede98184f72010-01-07 12:06:00 -03004462 {USB_DEVICE(0x054c, 0x0155),
Jean-François Moine87bae742010-11-12 05:31:34 -03004463 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
Hans de Goede1876bb92009-06-14 06:45:50 -03004464 {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 },
Hans de Goede49809d62009-06-07 12:10:39 -03004465 {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
4466 {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
4467 {USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 },
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004468 {USB_DEVICE(0x05a9, 0x2800), .driver_info = BRIDGE_OVFX2 },
Hans de Goede49809d62009-06-07 12:10:39 -03004469 {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 },
4470 {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 },
Hans de Goede1876bb92009-06-14 06:45:50 -03004471 {USB_DEVICE(0x05a9, 0xa511), .driver_info = BRIDGE_OV511PLUS },
Hans de Goede49809d62009-06-07 12:10:39 -03004472 {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS },
Hans de Goede1876bb92009-06-14 06:45:50 -03004473 {USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS },
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004474 {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 },
4475 {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 },
Hans de Goedea511ba92009-10-16 07:13:07 -03004476 {USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF },
Jean-François Moine87bae742010-11-12 05:31:34 -03004477 {USB_DEVICE(0x8020, 0xef04), .driver_info = BRIDGE_OVFX2 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004478 {}
4479};
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004480
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004481MODULE_DEVICE_TABLE(usb, device_table);
4482
4483/* -- device connect -- */
4484static int sd_probe(struct usb_interface *intf,
4485 const struct usb_device_id *id)
4486{
4487 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
4488 THIS_MODULE);
4489}
4490
4491static struct usb_driver sd_driver = {
4492 .name = MODULE_NAME,
4493 .id_table = device_table,
4494 .probe = sd_probe,
4495 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03004496#ifdef CONFIG_PM
4497 .suspend = gspca_suspend,
4498 .resume = gspca_resume,
4499#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004500};
4501
4502/* -- module insert / remove -- */
4503static int __init sd_mod_init(void)
4504{
Jean-François Moine54826432010-09-13 04:53:03 -03004505 return usb_register(&sd_driver);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004506}
4507static void __exit sd_mod_exit(void)
4508{
4509 usb_deregister(&sd_driver);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004510}
4511
4512module_init(sd_mod_init);
4513module_exit(sd_mod_exit);
4514
4515module_param(frame_rate, int, 0644);
4516MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)");