blob: aa3de2f5a272b7ff49cf395b6db64e95264a6785 [file] [log] [blame]
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001/**
2 * OV519 driver
3 *
4 * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr)
Hans de Goedeb46aaa02009-10-12 10:07:57 -03005 * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03006 *
Romain Beauxis2961e872008-12-05 06:25:26 -03007 * This module is adapted from the ov51x-jpeg package, which itself
8 * was adapted from the ov511 driver.
9 *
10 * Original copyright for the ov511 driver is:
11 *
Hans de Goedeb46aaa02009-10-12 10:07:57 -030012 * Copyright (c) 1999-2006 Mark W. McClelland
Romain Beauxis2961e872008-12-05 06:25:26 -030013 * Support for OV519, OV8610 Copyright (c) 2003 Joerg Heckenbach
Hans de Goedeb46aaa02009-10-12 10:07:57 -030014 * Many improvements by Bret Wallach <bwallac1@san.rr.com>
15 * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
16 * OV7620 fixes by Charl P. Botha <cpbotha@ieee.org>
17 * Changes by Claudio Matsuoka <claudio@conectiva.com>
Romain Beauxis2961e872008-12-05 06:25:26 -030018 *
19 * ov51x-jpeg original copyright is:
20 *
21 * Copyright (c) 2004-2007 Romain Beauxis <toots@rastageeks.org>
22 * Support for OV7670 sensors was contributed by Sam Skipsey <aoanla@yahoo.com>
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030023 *
24 * This program is free software; you can redistribute it and/or modify
25 * it under the terms of the GNU General Public License as published by
26 * the Free Software Foundation; either version 2 of the License, or
27 * any later version.
28 *
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
33 *
34 * You should have received a copy of the GNU General Public License
35 * along with this program; if not, write to the Free Software
36 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37 *
38 */
39#define MODULE_NAME "ov519"
40
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-Francois Moine6a7eba22008-06-30 15:50:11 -030044MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
45MODULE_DESCRIPTION("OV519 USB Camera Driver");
46MODULE_LICENSE("GPL");
47
48/* global parameters */
49static int frame_rate;
50
51/* Number of times to retry a failed I2C transaction. Increase this if you
52 * are getting "Failed to read sensor ID..." */
53static int i2c_detect_tries = 10;
54
55/* ov519 device descriptor */
56struct sd {
57 struct gspca_dev gspca_dev; /* !! must be the first item */
58
Hans de Goede92918a52009-06-14 06:21:35 -030059 __u8 packet_nr;
60
Hans de Goede49809d62009-06-07 12:10:39 -030061 char bridge;
62#define BRIDGE_OV511 0
63#define BRIDGE_OV511PLUS 1
64#define BRIDGE_OV518 2
65#define BRIDGE_OV518PLUS 3
66#define BRIDGE_OV519 4
Hans de Goede635118d2009-10-11 09:49:03 -030067#define BRIDGE_OVFX2 5
Hans de Goedea511ba92009-10-16 07:13:07 -030068#define BRIDGE_W9968CF 6
Hans de Goede9e4d8252009-06-14 06:25:06 -030069#define BRIDGE_MASK 7
70
71 char invert_led;
72#define BRIDGE_INVERT_LED 8
Hans de Goede49809d62009-06-07 12:10:39 -030073
Hans de Goede417a4d22010-02-19 07:37:08 -030074 char snapshot_pressed;
75 char snapshot_needs_reset;
76
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030077 /* Determined by sensor type */
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -030078 __u8 sif;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030079
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -030080 __u8 brightness;
81 __u8 contrast;
82 __u8 colors;
Jean-Francois Moine0cd67592008-07-29 05:25:28 -030083 __u8 hflip;
84 __u8 vflip;
Hans de Goede02ab18b2009-06-14 04:32:04 -030085 __u8 autobrightness;
86 __u8 freq;
Hans de Goede79b35902009-10-19 06:08:01 -030087 __u8 quality;
88#define QUALITY_MIN 50
89#define QUALITY_MAX 70
90#define QUALITY_DEF 50
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030091
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -030092 __u8 stopped; /* Streaming is temporarily paused */
Hans de Goeded6b6d7a2010-05-08 08:55:42 -030093 __u8 first_frame;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030094
Hans de Goede1876bb92009-06-14 06:45:50 -030095 __u8 frame_rate; /* current Framerate */
96 __u8 clockdiv; /* clockdiv override */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030097
98 char sensor; /* Type of image sensor chip (SEN_*) */
99#define SEN_UNKNOWN 0
Hans de Goede635118d2009-10-11 09:49:03 -0300100#define SEN_OV2610 1
101#define SEN_OV3610 2
102#define SEN_OV6620 3
103#define SEN_OV6630 4
104#define SEN_OV66308AF 5
105#define SEN_OV7610 6
106#define SEN_OV7620 7
Hans de Goede859cc472010-01-07 15:42:35 -0300107#define SEN_OV7620AE 8
108#define SEN_OV7640 9
Hans de Goede035d3a32010-01-09 08:14:43 -0300109#define SEN_OV7648 10
110#define SEN_OV7670 11
111#define SEN_OV76BE 12
112#define SEN_OV8610 13
Hans de Goedea511ba92009-10-16 07:13:07 -0300113
114 u8 sensor_addr;
115 int sensor_width;
116 int sensor_height;
Hans de Goedefb1f9022009-10-16 07:42:53 -0300117 int sensor_reg_cache[256];
Hans de Goede79b35902009-10-19 06:08:01 -0300118
119 u8 *jpeg_hdr;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300120};
121
Hans de Goedea511ba92009-10-16 07:13:07 -0300122/* Note this is a bit of a hack, but the w9968cf driver needs the code for all
123 the ov sensors which is already present here. When we have the time we
124 really should move the sensor drivers to v4l2 sub drivers. */
125#include "w996Xcf.c"
126
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300127/* V4L2 controls supported by the driver */
128static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
129static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
130static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
131static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
132static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
133static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300134static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
135static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
136static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
137static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
Hans de Goede02ab18b2009-06-14 04:32:04 -0300138static int sd_setautobrightness(struct gspca_dev *gspca_dev, __s32 val);
139static int sd_getautobrightness(struct gspca_dev *gspca_dev, __s32 *val);
140static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
141static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
Hans de Goede49809d62009-06-07 12:10:39 -0300142static void setbrightness(struct gspca_dev *gspca_dev);
143static void setcontrast(struct gspca_dev *gspca_dev);
144static void setcolors(struct gspca_dev *gspca_dev);
Hans de Goede02ab18b2009-06-14 04:32:04 -0300145static void setautobrightness(struct sd *sd);
146static void setfreq(struct sd *sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300147
Hans de Goede02ab18b2009-06-14 04:32:04 -0300148static const struct ctrl sd_ctrls[] = {
Hans de Goeded02134d2010-01-09 19:22:34 -0300149#define BRIGHTNESS_IDX 0
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300150 {
151 {
152 .id = V4L2_CID_BRIGHTNESS,
153 .type = V4L2_CTRL_TYPE_INTEGER,
154 .name = "Brightness",
155 .minimum = 0,
156 .maximum = 255,
157 .step = 1,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300158#define BRIGHTNESS_DEF 127
159 .default_value = BRIGHTNESS_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300160 },
161 .set = sd_setbrightness,
162 .get = sd_getbrightness,
163 },
Hans de Goeded02134d2010-01-09 19:22:34 -0300164#define CONTRAST_IDX 1
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300165 {
166 {
167 .id = V4L2_CID_CONTRAST,
168 .type = V4L2_CTRL_TYPE_INTEGER,
169 .name = "Contrast",
170 .minimum = 0,
171 .maximum = 255,
172 .step = 1,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300173#define CONTRAST_DEF 127
174 .default_value = CONTRAST_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300175 },
176 .set = sd_setcontrast,
177 .get = sd_getcontrast,
178 },
Hans de Goeded02134d2010-01-09 19:22:34 -0300179#define COLOR_IDX 2
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300180 {
181 {
182 .id = V4L2_CID_SATURATION,
183 .type = V4L2_CTRL_TYPE_INTEGER,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300184 .name = "Color",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300185 .minimum = 0,
186 .maximum = 255,
187 .step = 1,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300188#define COLOR_DEF 127
189 .default_value = COLOR_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300190 },
191 .set = sd_setcolors,
192 .get = sd_getcolors,
193 },
Hans de Goede02ab18b2009-06-14 04:32:04 -0300194/* The flip controls work with ov7670 only */
Jean-Francois Moinede004482008-09-03 17:12:16 -0300195#define HFLIP_IDX 3
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300196 {
197 {
198 .id = V4L2_CID_HFLIP,
199 .type = V4L2_CTRL_TYPE_BOOLEAN,
200 .name = "Mirror",
201 .minimum = 0,
202 .maximum = 1,
203 .step = 1,
204#define HFLIP_DEF 0
205 .default_value = HFLIP_DEF,
206 },
207 .set = sd_sethflip,
208 .get = sd_gethflip,
209 },
Jean-Francois Moinede004482008-09-03 17:12:16 -0300210#define VFLIP_IDX 4
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300211 {
212 {
213 .id = V4L2_CID_VFLIP,
214 .type = V4L2_CTRL_TYPE_BOOLEAN,
215 .name = "Vflip",
216 .minimum = 0,
217 .maximum = 1,
218 .step = 1,
219#define VFLIP_DEF 0
220 .default_value = VFLIP_DEF,
221 },
222 .set = sd_setvflip,
223 .get = sd_getvflip,
224 },
Hans de Goede02ab18b2009-06-14 04:32:04 -0300225#define AUTOBRIGHT_IDX 5
226 {
227 {
228 .id = V4L2_CID_AUTOBRIGHTNESS,
229 .type = V4L2_CTRL_TYPE_BOOLEAN,
230 .name = "Auto Brightness",
231 .minimum = 0,
232 .maximum = 1,
233 .step = 1,
234#define AUTOBRIGHT_DEF 1
235 .default_value = AUTOBRIGHT_DEF,
236 },
237 .set = sd_setautobrightness,
238 .get = sd_getautobrightness,
239 },
240#define FREQ_IDX 6
241 {
242 {
243 .id = V4L2_CID_POWER_LINE_FREQUENCY,
244 .type = V4L2_CTRL_TYPE_MENU,
245 .name = "Light frequency filter",
246 .minimum = 0,
247 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
248 .step = 1,
249#define FREQ_DEF 0
250 .default_value = FREQ_DEF,
251 },
252 .set = sd_setfreq,
253 .get = sd_getfreq,
254 },
255#define OV7670_FREQ_IDX 7
256 {
257 {
258 .id = V4L2_CID_POWER_LINE_FREQUENCY,
259 .type = V4L2_CTRL_TYPE_MENU,
260 .name = "Light frequency filter",
261 .minimum = 0,
262 .maximum = 3, /* 0: 0, 1: 50Hz, 2:60Hz 3: Auto Hz */
263 .step = 1,
264#define OV7670_FREQ_DEF 3
265 .default_value = OV7670_FREQ_DEF,
266 },
267 .set = sd_setfreq,
268 .get = sd_getfreq,
269 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300270};
271
Hans de Goede49809d62009-06-07 12:10:39 -0300272static const struct v4l2_pix_format ov519_vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300273 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
274 .bytesperline = 320,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300275 .sizeimage = 320 * 240 * 3 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300276 .colorspace = V4L2_COLORSPACE_JPEG,
277 .priv = 1},
278 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
279 .bytesperline = 640,
280 .sizeimage = 640 * 480 * 3 / 8 + 590,
281 .colorspace = V4L2_COLORSPACE_JPEG,
282 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300283};
Hans de Goede49809d62009-06-07 12:10:39 -0300284static const struct v4l2_pix_format ov519_sif_mode[] = {
Hans de Goede124cc9c2009-06-14 05:48:00 -0300285 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
286 .bytesperline = 160,
287 .sizeimage = 160 * 120 * 3 / 8 + 590,
288 .colorspace = V4L2_COLORSPACE_JPEG,
289 .priv = 3},
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300290 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
291 .bytesperline = 176,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300292 .sizeimage = 176 * 144 * 3 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300293 .colorspace = V4L2_COLORSPACE_JPEG,
294 .priv = 1},
Hans de Goede124cc9c2009-06-14 05:48:00 -0300295 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
296 .bytesperline = 320,
297 .sizeimage = 320 * 240 * 3 / 8 + 590,
298 .colorspace = V4L2_COLORSPACE_JPEG,
299 .priv = 2},
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300300 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
301 .bytesperline = 352,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300302 .sizeimage = 352 * 288 * 3 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300303 .colorspace = V4L2_COLORSPACE_JPEG,
304 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300305};
306
Hans de Goedeb282d872009-06-14 19:10:40 -0300307/* Note some of the sizeimage values for the ov511 / ov518 may seem
308 larger then necessary, however they need to be this big as the ov511 /
309 ov518 always fills the entire isoc frame, using 0 padding bytes when
310 it doesn't have any data. So with low framerates the amount of data
311 transfered can become quite large (libv4l will remove all the 0 padding
312 in userspace). */
Hans de Goede49809d62009-06-07 12:10:39 -0300313static const struct v4l2_pix_format ov518_vga_mode[] = {
314 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
315 .bytesperline = 320,
Hans de Goedeb282d872009-06-14 19:10:40 -0300316 .sizeimage = 320 * 240 * 3,
Hans de Goede49809d62009-06-07 12:10:39 -0300317 .colorspace = V4L2_COLORSPACE_JPEG,
318 .priv = 1},
319 {640, 480, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
320 .bytesperline = 640,
Hans de Goedeb282d872009-06-14 19:10:40 -0300321 .sizeimage = 640 * 480 * 2,
Hans de Goede49809d62009-06-07 12:10:39 -0300322 .colorspace = V4L2_COLORSPACE_JPEG,
323 .priv = 0},
324};
325static const struct v4l2_pix_format ov518_sif_mode[] = {
Hans de Goede124cc9c2009-06-14 05:48:00 -0300326 {160, 120, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
327 .bytesperline = 160,
Hans de Goedeb282d872009-06-14 19:10:40 -0300328 .sizeimage = 70000,
Hans de Goede124cc9c2009-06-14 05:48:00 -0300329 .colorspace = V4L2_COLORSPACE_JPEG,
330 .priv = 3},
Hans de Goede49809d62009-06-07 12:10:39 -0300331 {176, 144, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
332 .bytesperline = 176,
Hans de Goedeb282d872009-06-14 19:10:40 -0300333 .sizeimage = 70000,
Hans de Goede49809d62009-06-07 12:10:39 -0300334 .colorspace = V4L2_COLORSPACE_JPEG,
335 .priv = 1},
Hans de Goede124cc9c2009-06-14 05:48:00 -0300336 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
337 .bytesperline = 320,
Hans de Goedeb282d872009-06-14 19:10:40 -0300338 .sizeimage = 320 * 240 * 3,
Hans de Goede124cc9c2009-06-14 05:48:00 -0300339 .colorspace = V4L2_COLORSPACE_JPEG,
340 .priv = 2},
Hans de Goede49809d62009-06-07 12:10:39 -0300341 {352, 288, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
342 .bytesperline = 352,
Hans de Goedeb282d872009-06-14 19:10:40 -0300343 .sizeimage = 352 * 288 * 3,
Hans de Goede49809d62009-06-07 12:10:39 -0300344 .colorspace = V4L2_COLORSPACE_JPEG,
345 .priv = 0},
346};
347
Hans de Goede1876bb92009-06-14 06:45:50 -0300348static const struct v4l2_pix_format ov511_vga_mode[] = {
349 {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
350 .bytesperline = 320,
351 .sizeimage = 320 * 240 * 3,
352 .colorspace = V4L2_COLORSPACE_JPEG,
353 .priv = 1},
354 {640, 480, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
355 .bytesperline = 640,
356 .sizeimage = 640 * 480 * 2,
357 .colorspace = V4L2_COLORSPACE_JPEG,
358 .priv = 0},
359};
360static const struct v4l2_pix_format ov511_sif_mode[] = {
361 {160, 120, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
362 .bytesperline = 160,
Hans de Goedeb282d872009-06-14 19:10:40 -0300363 .sizeimage = 70000,
Hans de Goede1876bb92009-06-14 06:45:50 -0300364 .colorspace = V4L2_COLORSPACE_JPEG,
365 .priv = 3},
366 {176, 144, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
367 .bytesperline = 176,
Hans de Goedeb282d872009-06-14 19:10:40 -0300368 .sizeimage = 70000,
Hans de Goede1876bb92009-06-14 06:45:50 -0300369 .colorspace = V4L2_COLORSPACE_JPEG,
370 .priv = 1},
371 {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
372 .bytesperline = 320,
373 .sizeimage = 320 * 240 * 3,
374 .colorspace = V4L2_COLORSPACE_JPEG,
375 .priv = 2},
376 {352, 288, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
377 .bytesperline = 352,
378 .sizeimage = 352 * 288 * 3,
379 .colorspace = V4L2_COLORSPACE_JPEG,
380 .priv = 0},
381};
Hans de Goede49809d62009-06-07 12:10:39 -0300382
Hans de Goede635118d2009-10-11 09:49:03 -0300383static const struct v4l2_pix_format ovfx2_vga_mode[] = {
384 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
385 .bytesperline = 320,
386 .sizeimage = 320 * 240,
387 .colorspace = V4L2_COLORSPACE_SRGB,
388 .priv = 1},
389 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
390 .bytesperline = 640,
391 .sizeimage = 640 * 480,
392 .colorspace = V4L2_COLORSPACE_SRGB,
393 .priv = 0},
394};
395static const struct v4l2_pix_format ovfx2_cif_mode[] = {
396 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
397 .bytesperline = 160,
398 .sizeimage = 160 * 120,
399 .colorspace = V4L2_COLORSPACE_SRGB,
400 .priv = 3},
401 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
402 .bytesperline = 176,
403 .sizeimage = 176 * 144,
404 .colorspace = V4L2_COLORSPACE_SRGB,
405 .priv = 1},
406 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
407 .bytesperline = 320,
408 .sizeimage = 320 * 240,
409 .colorspace = V4L2_COLORSPACE_SRGB,
410 .priv = 2},
411 {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
412 .bytesperline = 352,
413 .sizeimage = 352 * 288,
414 .colorspace = V4L2_COLORSPACE_SRGB,
415 .priv = 0},
416};
417static const struct v4l2_pix_format ovfx2_ov2610_mode[] = {
418 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
419 .bytesperline = 1600,
420 .sizeimage = 1600 * 1200,
421 .colorspace = V4L2_COLORSPACE_SRGB},
422};
423static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
Hans de Goede635118d2009-10-11 09:49:03 -0300424 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
425 .bytesperline = 640,
426 .sizeimage = 640 * 480,
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300427 .colorspace = V4L2_COLORSPACE_SRGB,
428 .priv = 1},
429 {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
430 .bytesperline = 800,
431 .sizeimage = 800 * 600,
432 .colorspace = V4L2_COLORSPACE_SRGB,
433 .priv = 1},
434 {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
435 .bytesperline = 1024,
436 .sizeimage = 1024 * 768,
437 .colorspace = V4L2_COLORSPACE_SRGB,
438 .priv = 1},
439 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
440 .bytesperline = 1600,
441 .sizeimage = 1600 * 1200,
442 .colorspace = V4L2_COLORSPACE_SRGB,
443 .priv = 0},
444 {2048, 1536, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
445 .bytesperline = 2048,
446 .sizeimage = 2048 * 1536,
447 .colorspace = V4L2_COLORSPACE_SRGB,
448 .priv = 0},
Hans de Goede635118d2009-10-11 09:49:03 -0300449};
450
451
Hans de Goede49809d62009-06-07 12:10:39 -0300452/* Registers common to OV511 / OV518 */
Hans de Goede1876bb92009-06-14 06:45:50 -0300453#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */
Hans de Goede49809d62009-06-07 12:10:39 -0300454#define R51x_SYS_RESET 0x50
Hans de Goede1876bb92009-06-14 06:45:50 -0300455 /* Reset type flags */
456 #define OV511_RESET_OMNICE 0x08
Hans de Goede49809d62009-06-07 12:10:39 -0300457#define R51x_SYS_INIT 0x53
458#define R51x_SYS_SNAP 0x52
459#define R51x_SYS_CUST_ID 0x5F
460#define R51x_COMP_LUT_BEGIN 0x80
461
462/* OV511 Camera interface register numbers */
Hans de Goede1876bb92009-06-14 06:45:50 -0300463#define R511_CAM_DELAY 0x10
464#define R511_CAM_EDGE 0x11
465#define R511_CAM_PXCNT 0x12
466#define R511_CAM_LNCNT 0x13
467#define R511_CAM_PXDIV 0x14
468#define R511_CAM_LNDIV 0x15
469#define R511_CAM_UV_EN 0x16
470#define R511_CAM_LINE_MODE 0x17
471#define R511_CAM_OPTS 0x18
472
473#define R511_SNAP_FRAME 0x19
474#define R511_SNAP_PXCNT 0x1A
475#define R511_SNAP_LNCNT 0x1B
476#define R511_SNAP_PXDIV 0x1C
477#define R511_SNAP_LNDIV 0x1D
478#define R511_SNAP_UV_EN 0x1E
479#define R511_SNAP_UV_EN 0x1E
480#define R511_SNAP_OPTS 0x1F
481
482#define R511_DRAM_FLOW_CTL 0x20
483#define R511_FIFO_OPTS 0x31
484#define R511_I2C_CTL 0x40
Hans de Goede49809d62009-06-07 12:10:39 -0300485#define R511_SYS_LED_CTL 0x55 /* OV511+ only */
Hans de Goede1876bb92009-06-14 06:45:50 -0300486#define R511_COMP_EN 0x78
487#define R511_COMP_LUT_EN 0x79
Hans de Goede49809d62009-06-07 12:10:39 -0300488
489/* OV518 Camera interface register numbers */
490#define R518_GPIO_OUT 0x56 /* OV518(+) only */
491#define R518_GPIO_CTL 0x57 /* OV518(+) only */
492
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300493/* OV519 Camera interface register numbers */
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -0300494#define OV519_R10_H_SIZE 0x10
495#define OV519_R11_V_SIZE 0x11
496#define OV519_R12_X_OFFSETL 0x12
497#define OV519_R13_X_OFFSETH 0x13
498#define OV519_R14_Y_OFFSETL 0x14
499#define OV519_R15_Y_OFFSETH 0x15
500#define OV519_R16_DIVIDER 0x16
501#define OV519_R20_DFR 0x20
502#define OV519_R25_FORMAT 0x25
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300503
504/* OV519 System Controller register numbers */
505#define OV519_SYS_RESET1 0x51
506#define OV519_SYS_EN_CLK1 0x54
507
508#define OV519_GPIO_DATA_OUT0 0x71
509#define OV519_GPIO_IO_CTRL0 0x72
510
511#define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */
512
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300513/*
514 * The FX2 chip does not give us a zero length read at end of frame.
515 * It does, however, give a short read at the end of a frame, if
Daniel Mack3ad2f3f2010-02-03 08:01:28 +0800516 * necessary, rather than run two frames together.
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300517 *
518 * By choosing the right bulk transfer size, we are guaranteed to always
519 * get a short read for the last read of each frame. Frame sizes are
520 * always a composite number (width * height, or a multiple) so if we
521 * choose a prime number, we are guaranteed that the last read of a
522 * frame will be short.
523 *
524 * But it isn't that easy: the 2.6 kernel requires a multiple of 4KB,
525 * otherwise EOVERFLOW "babbling" errors occur. I have not been able
526 * to figure out why. [PMiller]
527 *
528 * The constant (13 * 4096) is the largest "prime enough" number less than 64KB.
529 *
530 * It isn't enough to know the number of bytes per frame, in case we
531 * have data dropouts or buffer overruns (even though the FX2 double
532 * buffers, there are some pretty strict real time constraints for
533 * isochronous transfer for larger frame sizes).
534 */
535#define OVFX2_BULK_SIZE (13 * 4096)
536
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300537/* I2C registers */
538#define R51x_I2C_W_SID 0x41
539#define R51x_I2C_SADDR_3 0x42
540#define R51x_I2C_SADDR_2 0x43
541#define R51x_I2C_R_SID 0x44
542#define R51x_I2C_DATA 0x45
543#define R518_I2C_CTL 0x47 /* OV518(+) only */
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300544#define OVFX2_I2C_ADDR 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300545
546/* I2C ADDRESSES */
547#define OV7xx0_SID 0x42
Hans de Goede229bb7d2009-10-11 07:41:46 -0300548#define OV_HIRES_SID 0x60 /* OV9xxx / OV2xxx / OV3xxx */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300549#define OV8xx0_SID 0xa0
550#define OV6xx0_SID 0xc0
551
552/* OV7610 registers */
553#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */
Hans de Goede49809d62009-06-07 12:10:39 -0300554#define OV7610_REG_BLUE 0x01 /* blue channel balance */
555#define OV7610_REG_RED 0x02 /* red channel balance */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300556#define OV7610_REG_SAT 0x03 /* saturation */
557#define OV8610_REG_HUE 0x04 /* 04 reserved */
558#define OV7610_REG_CNT 0x05 /* Y contrast */
559#define OV7610_REG_BRT 0x06 /* Y brightness */
560#define OV7610_REG_COM_C 0x14 /* misc common regs */
561#define OV7610_REG_ID_HIGH 0x1c /* manufacturer ID MSB */
562#define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */
563#define OV7610_REG_COM_I 0x29 /* misc settings */
564
565/* OV7670 registers */
566#define OV7670_REG_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */
567#define OV7670_REG_BLUE 0x01 /* blue gain */
568#define OV7670_REG_RED 0x02 /* red gain */
569#define OV7670_REG_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */
570#define OV7670_REG_COM1 0x04 /* Control 1 */
571#define OV7670_REG_AECHH 0x07 /* AEC MS 5 bits */
572#define OV7670_REG_COM3 0x0c /* Control 3 */
573#define OV7670_REG_COM4 0x0d /* Control 4 */
574#define OV7670_REG_COM5 0x0e /* All "reserved" */
575#define OV7670_REG_COM6 0x0f /* Control 6 */
576#define OV7670_REG_AECH 0x10 /* More bits of AEC value */
577#define OV7670_REG_CLKRC 0x11 /* Clock control */
578#define OV7670_REG_COM7 0x12 /* Control 7 */
579#define OV7670_COM7_FMT_VGA 0x00
580#define OV7670_COM7_YUV 0x00 /* YUV */
581#define OV7670_COM7_FMT_QVGA 0x10 /* QVGA format */
582#define OV7670_COM7_FMT_MASK 0x38
583#define OV7670_COM7_RESET 0x80 /* Register reset */
584#define OV7670_REG_COM8 0x13 /* Control 8 */
585#define OV7670_COM8_AEC 0x01 /* Auto exposure enable */
586#define OV7670_COM8_AWB 0x02 /* White balance enable */
587#define OV7670_COM8_AGC 0x04 /* Auto gain enable */
588#define OV7670_COM8_BFILT 0x20 /* Band filter enable */
589#define OV7670_COM8_AECSTEP 0x40 /* Unlimited AEC step size */
590#define OV7670_COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */
591#define OV7670_REG_COM9 0x14 /* Control 9 - gain ceiling */
592#define OV7670_REG_COM10 0x15 /* Control 10 */
593#define OV7670_REG_HSTART 0x17 /* Horiz start high bits */
594#define OV7670_REG_HSTOP 0x18 /* Horiz stop high bits */
595#define OV7670_REG_VSTART 0x19 /* Vert start high bits */
596#define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */
597#define OV7670_REG_MVFP 0x1e /* Mirror / vflip */
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300598#define OV7670_MVFP_VFLIP 0x10 /* vertical flip */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300599#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */
600#define OV7670_REG_AEW 0x24 /* AGC upper limit */
601#define OV7670_REG_AEB 0x25 /* AGC lower limit */
602#define OV7670_REG_VPT 0x26 /* AGC/AEC fast mode op region */
603#define OV7670_REG_HREF 0x32 /* HREF pieces */
604#define OV7670_REG_TSLB 0x3a /* lots of stuff */
605#define OV7670_REG_COM11 0x3b /* Control 11 */
606#define OV7670_COM11_EXP 0x02
607#define OV7670_COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */
608#define OV7670_REG_COM12 0x3c /* Control 12 */
609#define OV7670_REG_COM13 0x3d /* Control 13 */
610#define OV7670_COM13_GAMMA 0x80 /* Gamma enable */
611#define OV7670_COM13_UVSAT 0x40 /* UV saturation auto adjustment */
612#define OV7670_REG_COM14 0x3e /* Control 14 */
613#define OV7670_REG_EDGE 0x3f /* Edge enhancement factor */
614#define OV7670_REG_COM15 0x40 /* Control 15 */
615#define OV7670_COM15_R00FF 0xc0 /* 00 to FF */
616#define OV7670_REG_COM16 0x41 /* Control 16 */
617#define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */
618#define OV7670_REG_BRIGHT 0x55 /* Brightness */
619#define OV7670_REG_CONTRAS 0x56 /* Contrast control */
620#define OV7670_REG_GFIX 0x69 /* Fix gain control */
621#define OV7670_REG_RGB444 0x8c /* RGB 444 control */
622#define OV7670_REG_HAECC1 0x9f /* Hist AEC/AGC control 1 */
623#define OV7670_REG_HAECC2 0xa0 /* Hist AEC/AGC control 2 */
624#define OV7670_REG_BD50MAX 0xa5 /* 50hz banding step limit */
625#define OV7670_REG_HAECC3 0xa6 /* Hist AEC/AGC control 3 */
626#define OV7670_REG_HAECC4 0xa7 /* Hist AEC/AGC control 4 */
627#define OV7670_REG_HAECC5 0xa8 /* Hist AEC/AGC control 5 */
628#define OV7670_REG_HAECC6 0xa9 /* Hist AEC/AGC control 6 */
629#define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */
630#define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */
631
Jean-Francois Moine4202f712008-09-03 17:12:15 -0300632struct ov_regvals {
633 __u8 reg;
634 __u8 val;
635};
636struct ov_i2c_regvals {
637 __u8 reg;
638 __u8 val;
639};
640
Hans de Goede635118d2009-10-11 09:49:03 -0300641/* Settings for OV2610 camera chip */
642static const struct ov_i2c_regvals norm_2610[] =
643{
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300644 { 0x12, 0x80 }, /* reset */
Hans de Goede635118d2009-10-11 09:49:03 -0300645};
646
647static const struct ov_i2c_regvals norm_3620b[] =
648{
649 /*
650 * From the datasheet: "Note that after writing to register COMH
651 * (0x12) to change the sensor mode, registers related to the
652 * sensor’s cropping window will be reset back to their default
653 * values."
654 *
655 * "wait 4096 external clock ... to make sure the sensor is
656 * stable and ready to access registers" i.e. 160us at 24MHz
657 */
658
659 { 0x12, 0x80 }, /* COMH reset */
660 { 0x12, 0x00 }, /* QXGA, master */
661
662 /*
663 * 11 CLKRC "Clock Rate Control"
664 * [7] internal frequency doublers: on
665 * [6] video port mode: master
666 * [5:0] clock divider: 1
667 */
668 { 0x11, 0x80 },
669
670 /*
671 * 13 COMI "Common Control I"
672 * = 192 (0xC0) 11000000
673 * COMI[7] "AEC speed selection"
674 * = 1 (0x01) 1....... "Faster AEC correction"
675 * COMI[6] "AEC speed step selection"
676 * = 1 (0x01) .1...... "Big steps, fast"
677 * COMI[5] "Banding filter on off"
678 * = 0 (0x00) ..0..... "Off"
679 * COMI[4] "Banding filter option"
680 * = 0 (0x00) ...0.... "Main clock is 48 MHz and
681 * the PLL is ON"
682 * COMI[3] "Reserved"
683 * = 0 (0x00) ....0...
684 * COMI[2] "AGC auto manual control selection"
685 * = 0 (0x00) .....0.. "Manual"
686 * COMI[1] "AWB auto manual control selection"
687 * = 0 (0x00) ......0. "Manual"
688 * COMI[0] "Exposure control"
689 * = 0 (0x00) .......0 "Manual"
690 */
691 { 0x13, 0xC0 },
692
693 /*
694 * 09 COMC "Common Control C"
695 * = 8 (0x08) 00001000
696 * COMC[7:5] "Reserved"
697 * = 0 (0x00) 000.....
698 * COMC[4] "Sleep Mode Enable"
699 * = 0 (0x00) ...0.... "Normal mode"
700 * COMC[3:2] "Sensor sampling reset timing selection"
701 * = 2 (0x02) ....10.. "Longer reset time"
702 * COMC[1:0] "Output drive current select"
703 * = 0 (0x00) ......00 "Weakest"
704 */
705 { 0x09, 0x08 },
706
707 /*
708 * 0C COMD "Common Control D"
709 * = 8 (0x08) 00001000
710 * COMD[7] "Reserved"
711 * = 0 (0x00) 0.......
712 * COMD[6] "Swap MSB and LSB at the output port"
713 * = 0 (0x00) .0...... "False"
714 * COMD[5:3] "Reserved"
715 * = 1 (0x01) ..001...
716 * COMD[2] "Output Average On Off"
717 * = 0 (0x00) .....0.. "Output Normal"
718 * COMD[1] "Sensor precharge voltage selection"
719 * = 0 (0x00) ......0. "Selects internal
720 * reference precharge
721 * voltage"
722 * COMD[0] "Snapshot option"
723 * = 0 (0x00) .......0 "Enable live video output
724 * after snapshot sequence"
725 */
726 { 0x0c, 0x08 },
727
728 /*
729 * 0D COME "Common Control E"
730 * = 161 (0xA1) 10100001
731 * COME[7] "Output average option"
732 * = 1 (0x01) 1....... "Output average of 4 pixels"
733 * COME[6] "Anti-blooming control"
734 * = 0 (0x00) .0...... "Off"
735 * COME[5:3] "Reserved"
736 * = 4 (0x04) ..100...
737 * COME[2] "Clock output power down pin status"
738 * = 0 (0x00) .....0.. "Tri-state data output pin
739 * on power down"
740 * COME[1] "Data output pin status selection at power down"
741 * = 0 (0x00) ......0. "Tri-state VSYNC, PCLK,
742 * HREF, and CHSYNC pins on
743 * power down"
744 * COME[0] "Auto zero circuit select"
745 * = 1 (0x01) .......1 "On"
746 */
747 { 0x0d, 0xA1 },
748
749 /*
750 * 0E COMF "Common Control F"
751 * = 112 (0x70) 01110000
752 * COMF[7] "System clock selection"
753 * = 0 (0x00) 0....... "Use 24 MHz system clock"
754 * COMF[6:4] "Reserved"
755 * = 7 (0x07) .111....
756 * COMF[3] "Manual auto negative offset canceling selection"
757 * = 0 (0x00) ....0... "Auto detect negative
758 * offset and cancel it"
759 * COMF[2:0] "Reserved"
760 * = 0 (0x00) .....000
761 */
762 { 0x0e, 0x70 },
763
764 /*
765 * 0F COMG "Common Control G"
766 * = 66 (0x42) 01000010
767 * COMG[7] "Optical black output selection"
768 * = 0 (0x00) 0....... "Disable"
769 * COMG[6] "Black level calibrate selection"
770 * = 1 (0x01) .1...... "Use optical black pixels
771 * to calibrate"
772 * COMG[5:4] "Reserved"
773 * = 0 (0x00) ..00....
774 * COMG[3] "Channel offset adjustment"
775 * = 0 (0x00) ....0... "Disable offset adjustment"
776 * COMG[2] "ADC black level calibration option"
777 * = 0 (0x00) .....0.. "Use B/G line and G/R
778 * line to calibrate each
779 * channel's black level"
780 * COMG[1] "Reserved"
781 * = 1 (0x01) ......1.
782 * COMG[0] "ADC black level calibration enable"
783 * = 0 (0x00) .......0 "Disable"
784 */
785 { 0x0f, 0x42 },
786
787 /*
788 * 14 COMJ "Common Control J"
789 * = 198 (0xC6) 11000110
790 * COMJ[7:6] "AGC gain ceiling"
791 * = 3 (0x03) 11...... "8x"
792 * COMJ[5:4] "Reserved"
793 * = 0 (0x00) ..00....
794 * COMJ[3] "Auto banding filter"
795 * = 0 (0x00) ....0... "Banding filter is always
796 * on off depending on
797 * COMI[5] setting"
798 * COMJ[2] "VSYNC drop option"
799 * = 1 (0x01) .....1.. "SYNC is dropped if frame
800 * data is dropped"
801 * COMJ[1] "Frame data drop"
802 * = 1 (0x01) ......1. "Drop frame data if
803 * exposure is not within
804 * tolerance. In AEC mode,
805 * data is normally dropped
806 * when data is out of
807 * range."
808 * COMJ[0] "Reserved"
809 * = 0 (0x00) .......0
810 */
811 { 0x14, 0xC6 },
812
813 /*
814 * 15 COMK "Common Control K"
815 * = 2 (0x02) 00000010
816 * COMK[7] "CHSYNC pin output swap"
817 * = 0 (0x00) 0....... "CHSYNC"
818 * COMK[6] "HREF pin output swap"
819 * = 0 (0x00) .0...... "HREF"
820 * COMK[5] "PCLK output selection"
821 * = 0 (0x00) ..0..... "PCLK always output"
822 * COMK[4] "PCLK edge selection"
823 * = 0 (0x00) ...0.... "Data valid on falling edge"
824 * COMK[3] "HREF output polarity"
825 * = 0 (0x00) ....0... "positive"
826 * COMK[2] "Reserved"
827 * = 0 (0x00) .....0..
828 * COMK[1] "VSYNC polarity"
829 * = 1 (0x01) ......1. "negative"
830 * COMK[0] "HSYNC polarity"
831 * = 0 (0x00) .......0 "positive"
832 */
833 { 0x15, 0x02 },
834
835 /*
836 * 33 CHLF "Current Control"
837 * = 9 (0x09) 00001001
838 * CHLF[7:6] "Sensor current control"
839 * = 0 (0x00) 00......
840 * CHLF[5] "Sensor current range control"
841 * = 0 (0x00) ..0..... "normal range"
842 * CHLF[4] "Sensor current"
843 * = 0 (0x00) ...0.... "normal current"
844 * CHLF[3] "Sensor buffer current control"
845 * = 1 (0x01) ....1... "half current"
846 * CHLF[2] "Column buffer current control"
847 * = 0 (0x00) .....0.. "normal current"
848 * CHLF[1] "Analog DSP current control"
849 * = 0 (0x00) ......0. "normal current"
850 * CHLF[1] "ADC current control"
851 * = 0 (0x00) ......0. "normal current"
852 */
853 { 0x33, 0x09 },
854
855 /*
856 * 34 VBLM "Blooming Control"
857 * = 80 (0x50) 01010000
858 * VBLM[7] "Hard soft reset switch"
859 * = 0 (0x00) 0....... "Hard reset"
860 * VBLM[6:4] "Blooming voltage selection"
861 * = 5 (0x05) .101....
862 * VBLM[3:0] "Sensor current control"
863 * = 0 (0x00) ....0000
864 */
865 { 0x34, 0x50 },
866
867 /*
868 * 36 VCHG "Sensor Precharge Voltage Control"
869 * = 0 (0x00) 00000000
870 * VCHG[7] "Reserved"
871 * = 0 (0x00) 0.......
872 * VCHG[6:4] "Sensor precharge voltage control"
873 * = 0 (0x00) .000....
874 * VCHG[3:0] "Sensor array common reference"
875 * = 0 (0x00) ....0000
876 */
877 { 0x36, 0x00 },
878
879 /*
880 * 37 ADC "ADC Reference Control"
881 * = 4 (0x04) 00000100
882 * ADC[7:4] "Reserved"
883 * = 0 (0x00) 0000....
884 * ADC[3] "ADC input signal range"
885 * = 0 (0x00) ....0... "Input signal 1.0x"
886 * ADC[2:0] "ADC range control"
887 * = 4 (0x04) .....100
888 */
889 { 0x37, 0x04 },
890
891 /*
892 * 38 ACOM "Analog Common Ground"
893 * = 82 (0x52) 01010010
894 * ACOM[7] "Analog gain control"
895 * = 0 (0x00) 0....... "Gain 1x"
896 * ACOM[6] "Analog black level calibration"
897 * = 1 (0x01) .1...... "On"
898 * ACOM[5:0] "Reserved"
899 * = 18 (0x12) ..010010
900 */
901 { 0x38, 0x52 },
902
903 /*
904 * 3A FREFA "Internal Reference Adjustment"
905 * = 0 (0x00) 00000000
906 * FREFA[7:0] "Range"
907 * = 0 (0x00) 00000000
908 */
909 { 0x3a, 0x00 },
910
911 /*
912 * 3C FVOPT "Internal Reference Adjustment"
913 * = 31 (0x1F) 00011111
914 * FVOPT[7:0] "Range"
915 * = 31 (0x1F) 00011111
916 */
917 { 0x3c, 0x1F },
918
919 /*
920 * 44 Undocumented = 0 (0x00) 00000000
921 * 44[7:0] "It's a secret"
922 * = 0 (0x00) 00000000
923 */
924 { 0x44, 0x00 },
925
926 /*
927 * 40 Undocumented = 0 (0x00) 00000000
928 * 40[7:0] "It's a secret"
929 * = 0 (0x00) 00000000
930 */
931 { 0x40, 0x00 },
932
933 /*
934 * 41 Undocumented = 0 (0x00) 00000000
935 * 41[7:0] "It's a secret"
936 * = 0 (0x00) 00000000
937 */
938 { 0x41, 0x00 },
939
940 /*
941 * 42 Undocumented = 0 (0x00) 00000000
942 * 42[7:0] "It's a secret"
943 * = 0 (0x00) 00000000
944 */
945 { 0x42, 0x00 },
946
947 /*
948 * 43 Undocumented = 0 (0x00) 00000000
949 * 43[7:0] "It's a secret"
950 * = 0 (0x00) 00000000
951 */
952 { 0x43, 0x00 },
953
954 /*
955 * 45 Undocumented = 128 (0x80) 10000000
956 * 45[7:0] "It's a secret"
957 * = 128 (0x80) 10000000
958 */
959 { 0x45, 0x80 },
960
961 /*
962 * 48 Undocumented = 192 (0xC0) 11000000
963 * 48[7:0] "It's a secret"
964 * = 192 (0xC0) 11000000
965 */
966 { 0x48, 0xC0 },
967
968 /*
969 * 49 Undocumented = 25 (0x19) 00011001
970 * 49[7:0] "It's a secret"
971 * = 25 (0x19) 00011001
972 */
973 { 0x49, 0x19 },
974
975 /*
976 * 4B Undocumented = 128 (0x80) 10000000
977 * 4B[7:0] "It's a secret"
978 * = 128 (0x80) 10000000
979 */
980 { 0x4B, 0x80 },
981
982 /*
983 * 4D Undocumented = 196 (0xC4) 11000100
984 * 4D[7:0] "It's a secret"
985 * = 196 (0xC4) 11000100
986 */
987 { 0x4D, 0xC4 },
988
989 /*
990 * 35 VREF "Reference Voltage Control"
991 * = 76 (0x4C) 01001100
992 * VREF[7:5] "Column high reference control"
993 * = 2 (0x02) 010..... "higher voltage"
994 * VREF[4:2] "Column low reference control"
995 * = 3 (0x03) ...011.. "Highest voltage"
996 * VREF[1:0] "Reserved"
997 * = 0 (0x00) ......00
998 */
999 { 0x35, 0x4C },
1000
1001 /*
1002 * 3D Undocumented = 0 (0x00) 00000000
1003 * 3D[7:0] "It's a secret"
1004 * = 0 (0x00) 00000000
1005 */
1006 { 0x3D, 0x00 },
1007
1008 /*
1009 * 3E Undocumented = 0 (0x00) 00000000
1010 * 3E[7:0] "It's a secret"
1011 * = 0 (0x00) 00000000
1012 */
1013 { 0x3E, 0x00 },
1014
1015 /*
1016 * 3B FREFB "Internal Reference Adjustment"
1017 * = 24 (0x18) 00011000
1018 * FREFB[7:0] "Range"
1019 * = 24 (0x18) 00011000
1020 */
1021 { 0x3b, 0x18 },
1022
1023 /*
1024 * 33 CHLF "Current Control"
1025 * = 25 (0x19) 00011001
1026 * CHLF[7:6] "Sensor current control"
1027 * = 0 (0x00) 00......
1028 * CHLF[5] "Sensor current range control"
1029 * = 0 (0x00) ..0..... "normal range"
1030 * CHLF[4] "Sensor current"
1031 * = 1 (0x01) ...1.... "double current"
1032 * CHLF[3] "Sensor buffer current control"
1033 * = 1 (0x01) ....1... "half current"
1034 * CHLF[2] "Column buffer current control"
1035 * = 0 (0x00) .....0.. "normal current"
1036 * CHLF[1] "Analog DSP current control"
1037 * = 0 (0x00) ......0. "normal current"
1038 * CHLF[1] "ADC current control"
1039 * = 0 (0x00) ......0. "normal current"
1040 */
1041 { 0x33, 0x19 },
1042
1043 /*
1044 * 34 VBLM "Blooming Control"
1045 * = 90 (0x5A) 01011010
1046 * VBLM[7] "Hard soft reset switch"
1047 * = 0 (0x00) 0....... "Hard reset"
1048 * VBLM[6:4] "Blooming voltage selection"
1049 * = 5 (0x05) .101....
1050 * VBLM[3:0] "Sensor current control"
1051 * = 10 (0x0A) ....1010
1052 */
1053 { 0x34, 0x5A },
1054
1055 /*
1056 * 3B FREFB "Internal Reference Adjustment"
1057 * = 0 (0x00) 00000000
1058 * FREFB[7:0] "Range"
1059 * = 0 (0x00) 00000000
1060 */
1061 { 0x3b, 0x00 },
1062
1063 /*
1064 * 33 CHLF "Current Control"
1065 * = 9 (0x09) 00001001
1066 * CHLF[7:6] "Sensor current control"
1067 * = 0 (0x00) 00......
1068 * CHLF[5] "Sensor current range control"
1069 * = 0 (0x00) ..0..... "normal range"
1070 * CHLF[4] "Sensor current"
1071 * = 0 (0x00) ...0.... "normal current"
1072 * CHLF[3] "Sensor buffer current control"
1073 * = 1 (0x01) ....1... "half current"
1074 * CHLF[2] "Column buffer current control"
1075 * = 0 (0x00) .....0.. "normal current"
1076 * CHLF[1] "Analog DSP current control"
1077 * = 0 (0x00) ......0. "normal current"
1078 * CHLF[1] "ADC current control"
1079 * = 0 (0x00) ......0. "normal current"
1080 */
1081 { 0x33, 0x09 },
1082
1083 /*
1084 * 34 VBLM "Blooming Control"
1085 * = 80 (0x50) 01010000
1086 * VBLM[7] "Hard soft reset switch"
1087 * = 0 (0x00) 0....... "Hard reset"
1088 * VBLM[6:4] "Blooming voltage selection"
1089 * = 5 (0x05) .101....
1090 * VBLM[3:0] "Sensor current control"
1091 * = 0 (0x00) ....0000
1092 */
1093 { 0x34, 0x50 },
1094
1095 /*
1096 * 12 COMH "Common Control H"
1097 * = 64 (0x40) 01000000
1098 * COMH[7] "SRST"
1099 * = 0 (0x00) 0....... "No-op"
1100 * COMH[6:4] "Resolution selection"
1101 * = 4 (0x04) .100.... "XGA"
1102 * COMH[3] "Master slave selection"
1103 * = 0 (0x00) ....0... "Master mode"
1104 * COMH[2] "Internal B/R channel option"
1105 * = 0 (0x00) .....0.. "B/R use same channel"
1106 * COMH[1] "Color bar test pattern"
1107 * = 0 (0x00) ......0. "Off"
1108 * COMH[0] "Reserved"
1109 * = 0 (0x00) .......0
1110 */
1111 { 0x12, 0x40 },
1112
1113 /*
1114 * 17 HREFST "Horizontal window start"
1115 * = 31 (0x1F) 00011111
1116 * HREFST[7:0] "Horizontal window start, 8 MSBs"
1117 * = 31 (0x1F) 00011111
1118 */
1119 { 0x17, 0x1F },
1120
1121 /*
1122 * 18 HREFEND "Horizontal window end"
1123 * = 95 (0x5F) 01011111
1124 * HREFEND[7:0] "Horizontal Window End, 8 MSBs"
1125 * = 95 (0x5F) 01011111
1126 */
1127 { 0x18, 0x5F },
1128
1129 /*
1130 * 19 VSTRT "Vertical window start"
1131 * = 0 (0x00) 00000000
1132 * VSTRT[7:0] "Vertical Window Start, 8 MSBs"
1133 * = 0 (0x00) 00000000
1134 */
1135 { 0x19, 0x00 },
1136
1137 /*
1138 * 1A VEND "Vertical window end"
1139 * = 96 (0x60) 01100000
1140 * VEND[7:0] "Vertical Window End, 8 MSBs"
1141 * = 96 (0x60) 01100000
1142 */
1143 { 0x1a, 0x60 },
1144
1145 /*
1146 * 32 COMM "Common Control M"
1147 * = 18 (0x12) 00010010
1148 * COMM[7:6] "Pixel clock divide option"
1149 * = 0 (0x00) 00...... "/1"
1150 * COMM[5:3] "Horizontal window end position, 3 LSBs"
1151 * = 2 (0x02) ..010...
1152 * COMM[2:0] "Horizontal window start position, 3 LSBs"
1153 * = 2 (0x02) .....010
1154 */
1155 { 0x32, 0x12 },
1156
1157 /*
1158 * 03 COMA "Common Control A"
1159 * = 74 (0x4A) 01001010
1160 * COMA[7:4] "AWB Update Threshold"
1161 * = 4 (0x04) 0100....
1162 * COMA[3:2] "Vertical window end line control 2 LSBs"
1163 * = 2 (0x02) ....10..
1164 * COMA[1:0] "Vertical window start line control 2 LSBs"
1165 * = 2 (0x02) ......10
1166 */
1167 { 0x03, 0x4A },
1168
1169 /*
1170 * 11 CLKRC "Clock Rate Control"
1171 * = 128 (0x80) 10000000
1172 * CLKRC[7] "Internal frequency doublers on off seclection"
1173 * = 1 (0x01) 1....... "On"
1174 * CLKRC[6] "Digital video master slave selection"
1175 * = 0 (0x00) .0...... "Master mode, sensor
1176 * provides PCLK"
1177 * CLKRC[5:0] "Clock divider { CLK = PCLK/(1+CLKRC[5:0]) }"
1178 * = 0 (0x00) ..000000
1179 */
1180 { 0x11, 0x80 },
1181
1182 /*
1183 * 12 COMH "Common Control H"
1184 * = 0 (0x00) 00000000
1185 * COMH[7] "SRST"
1186 * = 0 (0x00) 0....... "No-op"
1187 * COMH[6:4] "Resolution selection"
1188 * = 0 (0x00) .000.... "QXGA"
1189 * COMH[3] "Master slave selection"
1190 * = 0 (0x00) ....0... "Master mode"
1191 * COMH[2] "Internal B/R channel option"
1192 * = 0 (0x00) .....0.. "B/R use same channel"
1193 * COMH[1] "Color bar test pattern"
1194 * = 0 (0x00) ......0. "Off"
1195 * COMH[0] "Reserved"
1196 * = 0 (0x00) .......0
1197 */
1198 { 0x12, 0x00 },
1199
1200 /*
1201 * 12 COMH "Common Control H"
1202 * = 64 (0x40) 01000000
1203 * COMH[7] "SRST"
1204 * = 0 (0x00) 0....... "No-op"
1205 * COMH[6:4] "Resolution selection"
1206 * = 4 (0x04) .100.... "XGA"
1207 * COMH[3] "Master slave selection"
1208 * = 0 (0x00) ....0... "Master mode"
1209 * COMH[2] "Internal B/R channel option"
1210 * = 0 (0x00) .....0.. "B/R use same channel"
1211 * COMH[1] "Color bar test pattern"
1212 * = 0 (0x00) ......0. "Off"
1213 * COMH[0] "Reserved"
1214 * = 0 (0x00) .......0
1215 */
1216 { 0x12, 0x40 },
1217
1218 /*
1219 * 17 HREFST "Horizontal window start"
1220 * = 31 (0x1F) 00011111
1221 * HREFST[7:0] "Horizontal window start, 8 MSBs"
1222 * = 31 (0x1F) 00011111
1223 */
1224 { 0x17, 0x1F },
1225
1226 /*
1227 * 18 HREFEND "Horizontal window end"
1228 * = 95 (0x5F) 01011111
1229 * HREFEND[7:0] "Horizontal Window End, 8 MSBs"
1230 * = 95 (0x5F) 01011111
1231 */
1232 { 0x18, 0x5F },
1233
1234 /*
1235 * 19 VSTRT "Vertical window start"
1236 * = 0 (0x00) 00000000
1237 * VSTRT[7:0] "Vertical Window Start, 8 MSBs"
1238 * = 0 (0x00) 00000000
1239 */
1240 { 0x19, 0x00 },
1241
1242 /*
1243 * 1A VEND "Vertical window end"
1244 * = 96 (0x60) 01100000
1245 * VEND[7:0] "Vertical Window End, 8 MSBs"
1246 * = 96 (0x60) 01100000
1247 */
1248 { 0x1a, 0x60 },
1249
1250 /*
1251 * 32 COMM "Common Control M"
1252 * = 18 (0x12) 00010010
1253 * COMM[7:6] "Pixel clock divide option"
1254 * = 0 (0x00) 00...... "/1"
1255 * COMM[5:3] "Horizontal window end position, 3 LSBs"
1256 * = 2 (0x02) ..010...
1257 * COMM[2:0] "Horizontal window start position, 3 LSBs"
1258 * = 2 (0x02) .....010
1259 */
1260 { 0x32, 0x12 },
1261
1262 /*
1263 * 03 COMA "Common Control A"
1264 * = 74 (0x4A) 01001010
1265 * COMA[7:4] "AWB Update Threshold"
1266 * = 4 (0x04) 0100....
1267 * COMA[3:2] "Vertical window end line control 2 LSBs"
1268 * = 2 (0x02) ....10..
1269 * COMA[1:0] "Vertical window start line control 2 LSBs"
1270 * = 2 (0x02) ......10
1271 */
1272 { 0x03, 0x4A },
1273
1274 /*
1275 * 02 RED "Red Gain Control"
1276 * = 175 (0xAF) 10101111
1277 * RED[7] "Action"
1278 * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
1279 * RED[6:0] "Value"
1280 * = 47 (0x2F) .0101111
1281 */
1282 { 0x02, 0xAF },
1283
1284 /*
1285 * 2D ADDVSL "VSYNC Pulse Width"
1286 * = 210 (0xD2) 11010010
1287 * ADDVSL[7:0] "VSYNC pulse width, LSB"
1288 * = 210 (0xD2) 11010010
1289 */
1290 { 0x2d, 0xD2 },
1291
1292 /*
1293 * 00 GAIN = 24 (0x18) 00011000
1294 * GAIN[7:6] "Reserved"
1295 * = 0 (0x00) 00......
1296 * GAIN[5] "Double"
1297 * = 0 (0x00) ..0..... "False"
1298 * GAIN[4] "Double"
1299 * = 1 (0x01) ...1.... "True"
1300 * GAIN[3:0] "Range"
1301 * = 8 (0x08) ....1000
1302 */
1303 { 0x00, 0x18 },
1304
1305 /*
1306 * 01 BLUE "Blue Gain Control"
1307 * = 240 (0xF0) 11110000
1308 * BLUE[7] "Action"
1309 * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
1310 * BLUE[6:0] "Value"
1311 * = 112 (0x70) .1110000
1312 */
1313 { 0x01, 0xF0 },
1314
1315 /*
1316 * 10 AEC "Automatic Exposure Control"
1317 * = 10 (0x0A) 00001010
1318 * AEC[7:0] "Automatic Exposure Control, 8 MSBs"
1319 * = 10 (0x0A) 00001010
1320 */
1321 { 0x10, 0x0A },
1322
1323 { 0xE1, 0x67 },
1324 { 0xE3, 0x03 },
1325 { 0xE4, 0x26 },
1326 { 0xE5, 0x3E },
1327 { 0xF8, 0x01 },
1328 { 0xFF, 0x01 },
1329};
1330
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001331static const struct ov_i2c_regvals norm_6x20[] = {
1332 { 0x12, 0x80 }, /* reset */
1333 { 0x11, 0x01 },
1334 { 0x03, 0x60 },
1335 { 0x05, 0x7f }, /* For when autoadjust is off */
1336 { 0x07, 0xa8 },
1337 /* The ratio of 0x0c and 0x0d controls the white point */
1338 { 0x0c, 0x24 },
1339 { 0x0d, 0x24 },
1340 { 0x0f, 0x15 }, /* COMS */
1341 { 0x10, 0x75 }, /* AEC Exposure time */
1342 { 0x12, 0x24 }, /* Enable AGC */
1343 { 0x14, 0x04 },
1344 /* 0x16: 0x06 helps frame stability with moving objects */
1345 { 0x16, 0x06 },
1346/* { 0x20, 0x30 }, * Aperture correction enable */
1347 { 0x26, 0xb2 }, /* BLC enable */
1348 /* 0x28: 0x05 Selects RGB format if RGB on */
1349 { 0x28, 0x05 },
1350 { 0x2a, 0x04 }, /* Disable framerate adjust */
1351/* { 0x2b, 0xac }, * Framerate; Set 2a[7] first */
Hans de Goedeae49c402009-06-14 19:15:07 -03001352 { 0x2d, 0x85 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001353 { 0x33, 0xa0 }, /* Color Processing Parameter */
1354 { 0x34, 0xd2 }, /* Max A/D range */
1355 { 0x38, 0x8b },
1356 { 0x39, 0x40 },
1357
1358 { 0x3c, 0x39 }, /* Enable AEC mode changing */
1359 { 0x3c, 0x3c }, /* Change AEC mode */
1360 { 0x3c, 0x24 }, /* Disable AEC mode changing */
1361
1362 { 0x3d, 0x80 },
1363 /* These next two registers (0x4a, 0x4b) are undocumented.
1364 * They control the color balance */
1365 { 0x4a, 0x80 },
1366 { 0x4b, 0x80 },
1367 { 0x4d, 0xd2 }, /* This reduces noise a bit */
1368 { 0x4e, 0xc1 },
1369 { 0x4f, 0x04 },
1370/* Do 50-53 have any effect? */
1371/* Toggle 0x12[2] off and on here? */
1372};
1373
1374static const struct ov_i2c_regvals norm_6x30[] = {
1375 { 0x12, 0x80 }, /* Reset */
1376 { 0x00, 0x1f }, /* Gain */
1377 { 0x01, 0x99 }, /* Blue gain */
1378 { 0x02, 0x7c }, /* Red gain */
1379 { 0x03, 0xc0 }, /* Saturation */
1380 { 0x05, 0x0a }, /* Contrast */
1381 { 0x06, 0x95 }, /* Brightness */
1382 { 0x07, 0x2d }, /* Sharpness */
1383 { 0x0c, 0x20 },
1384 { 0x0d, 0x20 },
Hans de Goede02ab18b2009-06-14 04:32:04 -03001385 { 0x0e, 0xa0 }, /* Was 0x20, bit7 enables a 2x gain which we need */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001386 { 0x0f, 0x05 },
1387 { 0x10, 0x9a },
1388 { 0x11, 0x00 }, /* Pixel clock = fastest */
1389 { 0x12, 0x24 }, /* Enable AGC and AWB */
1390 { 0x13, 0x21 },
1391 { 0x14, 0x80 },
1392 { 0x15, 0x01 },
1393 { 0x16, 0x03 },
1394 { 0x17, 0x38 },
1395 { 0x18, 0xea },
1396 { 0x19, 0x04 },
1397 { 0x1a, 0x93 },
1398 { 0x1b, 0x00 },
1399 { 0x1e, 0xc4 },
1400 { 0x1f, 0x04 },
1401 { 0x20, 0x20 },
1402 { 0x21, 0x10 },
1403 { 0x22, 0x88 },
1404 { 0x23, 0xc0 }, /* Crystal circuit power level */
1405 { 0x25, 0x9a }, /* Increase AEC black ratio */
1406 { 0x26, 0xb2 }, /* BLC enable */
1407 { 0x27, 0xa2 },
1408 { 0x28, 0x00 },
1409 { 0x29, 0x00 },
1410 { 0x2a, 0x84 }, /* 60 Hz power */
1411 { 0x2b, 0xa8 }, /* 60 Hz power */
1412 { 0x2c, 0xa0 },
1413 { 0x2d, 0x95 }, /* Enable auto-brightness */
1414 { 0x2e, 0x88 },
1415 { 0x33, 0x26 },
1416 { 0x34, 0x03 },
1417 { 0x36, 0x8f },
1418 { 0x37, 0x80 },
1419 { 0x38, 0x83 },
1420 { 0x39, 0x80 },
1421 { 0x3a, 0x0f },
1422 { 0x3b, 0x3c },
1423 { 0x3c, 0x1a },
1424 { 0x3d, 0x80 },
1425 { 0x3e, 0x80 },
1426 { 0x3f, 0x0e },
1427 { 0x40, 0x00 }, /* White bal */
1428 { 0x41, 0x00 }, /* White bal */
1429 { 0x42, 0x80 },
1430 { 0x43, 0x3f }, /* White bal */
1431 { 0x44, 0x80 },
1432 { 0x45, 0x20 },
1433 { 0x46, 0x20 },
1434 { 0x47, 0x80 },
1435 { 0x48, 0x7f },
1436 { 0x49, 0x00 },
1437 { 0x4a, 0x00 },
1438 { 0x4b, 0x80 },
1439 { 0x4c, 0xd0 },
1440 { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
1441 { 0x4e, 0x40 },
1442 { 0x4f, 0x07 }, /* UV avg., col. killer: max */
1443 { 0x50, 0xff },
1444 { 0x54, 0x23 }, /* Max AGC gain: 18dB */
1445 { 0x55, 0xff },
1446 { 0x56, 0x12 },
1447 { 0x57, 0x81 },
1448 { 0x58, 0x75 },
1449 { 0x59, 0x01 }, /* AGC dark current comp.: +1 */
1450 { 0x5a, 0x2c },
1451 { 0x5b, 0x0f }, /* AWB chrominance levels */
1452 { 0x5c, 0x10 },
1453 { 0x3d, 0x80 },
1454 { 0x27, 0xa6 },
1455 { 0x12, 0x20 }, /* Toggle AWB */
1456 { 0x12, 0x24 },
1457};
1458
1459/* Lawrence Glaister <lg@jfm.bc.ca> reports:
1460 *
1461 * Register 0x0f in the 7610 has the following effects:
1462 *
1463 * 0x85 (AEC method 1): Best overall, good contrast range
1464 * 0x45 (AEC method 2): Very overexposed
1465 * 0xa5 (spec sheet default): Ok, but the black level is
1466 * shifted resulting in loss of contrast
1467 * 0x05 (old driver setting): very overexposed, too much
1468 * contrast
1469 */
1470static const struct ov_i2c_regvals norm_7610[] = {
1471 { 0x10, 0xff },
1472 { 0x16, 0x06 },
1473 { 0x28, 0x24 },
1474 { 0x2b, 0xac },
1475 { 0x12, 0x00 },
1476 { 0x38, 0x81 },
1477 { 0x28, 0x24 }, /* 0c */
1478 { 0x0f, 0x85 }, /* lg's setting */
1479 { 0x15, 0x01 },
1480 { 0x20, 0x1c },
1481 { 0x23, 0x2a },
1482 { 0x24, 0x10 },
1483 { 0x25, 0x8a },
1484 { 0x26, 0xa2 },
1485 { 0x27, 0xc2 },
1486 { 0x2a, 0x04 },
1487 { 0x2c, 0xfe },
1488 { 0x2d, 0x93 },
1489 { 0x30, 0x71 },
1490 { 0x31, 0x60 },
1491 { 0x32, 0x26 },
1492 { 0x33, 0x20 },
1493 { 0x34, 0x48 },
1494 { 0x12, 0x24 },
1495 { 0x11, 0x01 },
1496 { 0x0c, 0x24 },
1497 { 0x0d, 0x24 },
1498};
1499
1500static const struct ov_i2c_regvals norm_7620[] = {
Hans de Goedea511ba92009-10-16 07:13:07 -03001501 { 0x12, 0x80 }, /* reset */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001502 { 0x00, 0x00 }, /* gain */
1503 { 0x01, 0x80 }, /* blue gain */
1504 { 0x02, 0x80 }, /* red gain */
1505 { 0x03, 0xc0 }, /* OV7670_REG_VREF */
1506 { 0x06, 0x60 },
1507 { 0x07, 0x00 },
1508 { 0x0c, 0x24 },
1509 { 0x0c, 0x24 },
1510 { 0x0d, 0x24 },
1511 { 0x11, 0x01 },
1512 { 0x12, 0x24 },
1513 { 0x13, 0x01 },
1514 { 0x14, 0x84 },
1515 { 0x15, 0x01 },
1516 { 0x16, 0x03 },
1517 { 0x17, 0x2f },
1518 { 0x18, 0xcf },
1519 { 0x19, 0x06 },
1520 { 0x1a, 0xf5 },
1521 { 0x1b, 0x00 },
1522 { 0x20, 0x18 },
1523 { 0x21, 0x80 },
1524 { 0x22, 0x80 },
1525 { 0x23, 0x00 },
1526 { 0x26, 0xa2 },
1527 { 0x27, 0xea },
Hans de Goedeb282d872009-06-14 19:10:40 -03001528 { 0x28, 0x22 }, /* Was 0x20, bit1 enables a 2x gain which we need */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001529 { 0x29, 0x00 },
1530 { 0x2a, 0x10 },
1531 { 0x2b, 0x00 },
1532 { 0x2c, 0x88 },
1533 { 0x2d, 0x91 },
1534 { 0x2e, 0x80 },
1535 { 0x2f, 0x44 },
1536 { 0x60, 0x27 },
1537 { 0x61, 0x02 },
1538 { 0x62, 0x5f },
1539 { 0x63, 0xd5 },
1540 { 0x64, 0x57 },
1541 { 0x65, 0x83 },
1542 { 0x66, 0x55 },
1543 { 0x67, 0x92 },
1544 { 0x68, 0xcf },
1545 { 0x69, 0x76 },
1546 { 0x6a, 0x22 },
1547 { 0x6b, 0x00 },
1548 { 0x6c, 0x02 },
1549 { 0x6d, 0x44 },
1550 { 0x6e, 0x80 },
1551 { 0x6f, 0x1d },
1552 { 0x70, 0x8b },
1553 { 0x71, 0x00 },
1554 { 0x72, 0x14 },
1555 { 0x73, 0x54 },
1556 { 0x74, 0x00 },
1557 { 0x75, 0x8e },
1558 { 0x76, 0x00 },
1559 { 0x77, 0xff },
1560 { 0x78, 0x80 },
1561 { 0x79, 0x80 },
1562 { 0x7a, 0x80 },
1563 { 0x7b, 0xe2 },
1564 { 0x7c, 0x00 },
1565};
1566
1567/* 7640 and 7648. The defaults should be OK for most registers. */
1568static const struct ov_i2c_regvals norm_7640[] = {
1569 { 0x12, 0x80 },
1570 { 0x12, 0x14 },
1571};
1572
1573/* 7670. Defaults taken from OmniVision provided data,
1574* as provided by Jonathan Corbet of OLPC */
1575static const struct ov_i2c_regvals norm_7670[] = {
1576 { OV7670_REG_COM7, OV7670_COM7_RESET },
1577 { OV7670_REG_TSLB, 0x04 }, /* OV */
1578 { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
1579 { OV7670_REG_CLKRC, 0x01 },
1580/*
1581 * Set the hardware window. These values from OV don't entirely
1582 * make sense - hstop is less than hstart. But they work...
1583 */
1584 { OV7670_REG_HSTART, 0x13 },
1585 { OV7670_REG_HSTOP, 0x01 },
1586 { OV7670_REG_HREF, 0xb6 },
1587 { OV7670_REG_VSTART, 0x02 },
1588 { OV7670_REG_VSTOP, 0x7a },
1589 { OV7670_REG_VREF, 0x0a },
1590
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001591 { OV7670_REG_COM3, 0x00 },
1592 { OV7670_REG_COM14, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001593/* Mystery scaling numbers */
1594 { 0x70, 0x3a },
1595 { 0x71, 0x35 },
1596 { 0x72, 0x11 },
1597 { 0x73, 0xf0 },
1598 { 0xa2, 0x02 },
1599/* { OV7670_REG_COM10, 0x0 }, */
1600
1601/* Gamma curve values */
1602 { 0x7a, 0x20 },
1603 { 0x7b, 0x10 },
1604 { 0x7c, 0x1e },
1605 { 0x7d, 0x35 },
1606 { 0x7e, 0x5a },
1607 { 0x7f, 0x69 },
1608 { 0x80, 0x76 },
1609 { 0x81, 0x80 },
1610 { 0x82, 0x88 },
1611 { 0x83, 0x8f },
1612 { 0x84, 0x96 },
1613 { 0x85, 0xa3 },
1614 { 0x86, 0xaf },
1615 { 0x87, 0xc4 },
1616 { 0x88, 0xd7 },
1617 { 0x89, 0xe8 },
1618
1619/* AGC and AEC parameters. Note we start by disabling those features,
1620 then turn them only after tweaking the values. */
1621 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
1622 | OV7670_COM8_AECSTEP
1623 | OV7670_COM8_BFILT },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001624 { OV7670_REG_GAIN, 0x00 },
1625 { OV7670_REG_AECH, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001626 { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */
1627 { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
1628 { OV7670_REG_BD50MAX, 0x05 },
1629 { OV7670_REG_BD60MAX, 0x07 },
1630 { OV7670_REG_AEW, 0x95 },
1631 { OV7670_REG_AEB, 0x33 },
1632 { OV7670_REG_VPT, 0xe3 },
1633 { OV7670_REG_HAECC1, 0x78 },
1634 { OV7670_REG_HAECC2, 0x68 },
1635 { 0xa1, 0x03 }, /* magic */
1636 { OV7670_REG_HAECC3, 0xd8 },
1637 { OV7670_REG_HAECC4, 0xd8 },
1638 { OV7670_REG_HAECC5, 0xf0 },
1639 { OV7670_REG_HAECC6, 0x90 },
1640 { OV7670_REG_HAECC7, 0x94 },
1641 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
1642 | OV7670_COM8_AECSTEP
1643 | OV7670_COM8_BFILT
1644 | OV7670_COM8_AGC
1645 | OV7670_COM8_AEC },
1646
1647/* Almost all of these are magic "reserved" values. */
1648 { OV7670_REG_COM5, 0x61 },
1649 { OV7670_REG_COM6, 0x4b },
1650 { 0x16, 0x02 },
1651 { OV7670_REG_MVFP, 0x07 },
1652 { 0x21, 0x02 },
1653 { 0x22, 0x91 },
1654 { 0x29, 0x07 },
1655 { 0x33, 0x0b },
1656 { 0x35, 0x0b },
1657 { 0x37, 0x1d },
1658 { 0x38, 0x71 },
1659 { 0x39, 0x2a },
1660 { OV7670_REG_COM12, 0x78 },
1661 { 0x4d, 0x40 },
1662 { 0x4e, 0x20 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001663 { OV7670_REG_GFIX, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001664 { 0x6b, 0x4a },
1665 { 0x74, 0x10 },
1666 { 0x8d, 0x4f },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001667 { 0x8e, 0x00 },
1668 { 0x8f, 0x00 },
1669 { 0x90, 0x00 },
1670 { 0x91, 0x00 },
1671 { 0x96, 0x00 },
1672 { 0x9a, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001673 { 0xb0, 0x84 },
1674 { 0xb1, 0x0c },
1675 { 0xb2, 0x0e },
1676 { 0xb3, 0x82 },
1677 { 0xb8, 0x0a },
1678
1679/* More reserved magic, some of which tweaks white balance */
1680 { 0x43, 0x0a },
1681 { 0x44, 0xf0 },
1682 { 0x45, 0x34 },
1683 { 0x46, 0x58 },
1684 { 0x47, 0x28 },
1685 { 0x48, 0x3a },
1686 { 0x59, 0x88 },
1687 { 0x5a, 0x88 },
1688 { 0x5b, 0x44 },
1689 { 0x5c, 0x67 },
1690 { 0x5d, 0x49 },
1691 { 0x5e, 0x0e },
1692 { 0x6c, 0x0a },
1693 { 0x6d, 0x55 },
1694 { 0x6e, 0x11 },
1695 { 0x6f, 0x9f },
1696 /* "9e for advance AWB" */
1697 { 0x6a, 0x40 },
1698 { OV7670_REG_BLUE, 0x40 },
1699 { OV7670_REG_RED, 0x60 },
1700 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
1701 | OV7670_COM8_AECSTEP
1702 | OV7670_COM8_BFILT
1703 | OV7670_COM8_AGC
1704 | OV7670_COM8_AEC
1705 | OV7670_COM8_AWB },
1706
1707/* Matrix coefficients */
1708 { 0x4f, 0x80 },
1709 { 0x50, 0x80 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001710 { 0x51, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001711 { 0x52, 0x22 },
1712 { 0x53, 0x5e },
1713 { 0x54, 0x80 },
1714 { 0x58, 0x9e },
1715
1716 { OV7670_REG_COM16, OV7670_COM16_AWBGAIN },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001717 { OV7670_REG_EDGE, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001718 { 0x75, 0x05 },
1719 { 0x76, 0xe1 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001720 { 0x4c, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001721 { 0x77, 0x01 },
1722 { OV7670_REG_COM13, OV7670_COM13_GAMMA
1723 | OV7670_COM13_UVSAT
1724 | 2}, /* was 3 */
1725 { 0x4b, 0x09 },
1726 { 0xc9, 0x60 },
1727 { OV7670_REG_COM16, 0x38 },
1728 { 0x56, 0x40 },
1729
1730 { 0x34, 0x11 },
1731 { OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
1732 { 0xa4, 0x88 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001733 { 0x96, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001734 { 0x97, 0x30 },
1735 { 0x98, 0x20 },
1736 { 0x99, 0x30 },
1737 { 0x9a, 0x84 },
1738 { 0x9b, 0x29 },
1739 { 0x9c, 0x03 },
1740 { 0x9d, 0x4c },
1741 { 0x9e, 0x3f },
1742 { 0x78, 0x04 },
1743
1744/* Extra-weird stuff. Some sort of multiplexor register */
1745 { 0x79, 0x01 },
1746 { 0xc8, 0xf0 },
1747 { 0x79, 0x0f },
1748 { 0xc8, 0x00 },
1749 { 0x79, 0x10 },
1750 { 0xc8, 0x7e },
1751 { 0x79, 0x0a },
1752 { 0xc8, 0x80 },
1753 { 0x79, 0x0b },
1754 { 0xc8, 0x01 },
1755 { 0x79, 0x0c },
1756 { 0xc8, 0x0f },
1757 { 0x79, 0x0d },
1758 { 0xc8, 0x20 },
1759 { 0x79, 0x09 },
1760 { 0xc8, 0x80 },
1761 { 0x79, 0x02 },
1762 { 0xc8, 0xc0 },
1763 { 0x79, 0x03 },
1764 { 0xc8, 0x40 },
1765 { 0x79, 0x05 },
1766 { 0xc8, 0x30 },
1767 { 0x79, 0x26 },
1768};
1769
1770static const struct ov_i2c_regvals norm_8610[] = {
1771 { 0x12, 0x80 },
1772 { 0x00, 0x00 },
1773 { 0x01, 0x80 },
1774 { 0x02, 0x80 },
1775 { 0x03, 0xc0 },
1776 { 0x04, 0x30 },
1777 { 0x05, 0x30 }, /* was 0x10, new from windrv 090403 */
1778 { 0x06, 0x70 }, /* was 0x80, new from windrv 090403 */
1779 { 0x0a, 0x86 },
1780 { 0x0b, 0xb0 },
1781 { 0x0c, 0x20 },
1782 { 0x0d, 0x20 },
1783 { 0x11, 0x01 },
1784 { 0x12, 0x25 },
1785 { 0x13, 0x01 },
1786 { 0x14, 0x04 },
1787 { 0x15, 0x01 }, /* Lin and Win think different about UV order */
1788 { 0x16, 0x03 },
1789 { 0x17, 0x38 }, /* was 0x2f, new from windrv 090403 */
1790 { 0x18, 0xea }, /* was 0xcf, new from windrv 090403 */
1791 { 0x19, 0x02 }, /* was 0x06, new from windrv 090403 */
1792 { 0x1a, 0xf5 },
1793 { 0x1b, 0x00 },
1794 { 0x20, 0xd0 }, /* was 0x90, new from windrv 090403 */
1795 { 0x23, 0xc0 }, /* was 0x00, new from windrv 090403 */
1796 { 0x24, 0x30 }, /* was 0x1d, new from windrv 090403 */
1797 { 0x25, 0x50 }, /* was 0x57, new from windrv 090403 */
1798 { 0x26, 0xa2 },
1799 { 0x27, 0xea },
1800 { 0x28, 0x00 },
1801 { 0x29, 0x00 },
1802 { 0x2a, 0x80 },
1803 { 0x2b, 0xc8 }, /* was 0xcc, new from windrv 090403 */
1804 { 0x2c, 0xac },
1805 { 0x2d, 0x45 }, /* was 0xd5, new from windrv 090403 */
1806 { 0x2e, 0x80 },
1807 { 0x2f, 0x14 }, /* was 0x01, new from windrv 090403 */
1808 { 0x4c, 0x00 },
1809 { 0x4d, 0x30 }, /* was 0x10, new from windrv 090403 */
1810 { 0x60, 0x02 }, /* was 0x01, new from windrv 090403 */
1811 { 0x61, 0x00 }, /* was 0x09, new from windrv 090403 */
1812 { 0x62, 0x5f }, /* was 0xd7, new from windrv 090403 */
1813 { 0x63, 0xff },
1814 { 0x64, 0x53 }, /* new windrv 090403 says 0x57,
1815 * maybe thats wrong */
1816 { 0x65, 0x00 },
1817 { 0x66, 0x55 },
1818 { 0x67, 0xb0 },
1819 { 0x68, 0xc0 }, /* was 0xaf, new from windrv 090403 */
1820 { 0x69, 0x02 },
1821 { 0x6a, 0x22 },
1822 { 0x6b, 0x00 },
1823 { 0x6c, 0x99 }, /* was 0x80, old windrv says 0x00, but
1824 * deleting bit7 colors the first images red */
1825 { 0x6d, 0x11 }, /* was 0x00, new from windrv 090403 */
1826 { 0x6e, 0x11 }, /* was 0x00, new from windrv 090403 */
1827 { 0x6f, 0x01 },
1828 { 0x70, 0x8b },
1829 { 0x71, 0x00 },
1830 { 0x72, 0x14 },
1831 { 0x73, 0x54 },
1832 { 0x74, 0x00 },/* 0x60? - was 0x00, new from windrv 090403 */
1833 { 0x75, 0x0e },
1834 { 0x76, 0x02 }, /* was 0x02, new from windrv 090403 */
1835 { 0x77, 0xff },
1836 { 0x78, 0x80 },
1837 { 0x79, 0x80 },
1838 { 0x7a, 0x80 },
1839 { 0x7b, 0x10 }, /* was 0x13, new from windrv 090403 */
1840 { 0x7c, 0x00 },
1841 { 0x7d, 0x08 }, /* was 0x09, new from windrv 090403 */
1842 { 0x7e, 0x08 }, /* was 0xc0, new from windrv 090403 */
1843 { 0x7f, 0xfb },
1844 { 0x80, 0x28 },
1845 { 0x81, 0x00 },
1846 { 0x82, 0x23 },
1847 { 0x83, 0x0b },
1848 { 0x84, 0x00 },
1849 { 0x85, 0x62 }, /* was 0x61, new from windrv 090403 */
1850 { 0x86, 0xc9 },
1851 { 0x87, 0x00 },
1852 { 0x88, 0x00 },
1853 { 0x89, 0x01 },
1854 { 0x12, 0x20 },
1855 { 0x12, 0x25 }, /* was 0x24, new from windrv 090403 */
1856};
1857
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001858static unsigned char ov7670_abs_to_sm(unsigned char v)
1859{
1860 if (v > 127)
1861 return v & 0x7f;
1862 return (128 - v) | 0x80;
1863}
1864
1865/* Write a OV519 register */
Hans de Goedea511ba92009-10-16 07:13:07 -03001866static int reg_w(struct sd *sd, __u16 index, __u16 value)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001867{
Hans de Goedea511ba92009-10-16 07:13:07 -03001868 int ret, req = 0;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001869
1870 switch (sd->bridge) {
1871 case BRIDGE_OV511:
1872 case BRIDGE_OV511PLUS:
1873 req = 2;
1874 break;
1875 case BRIDGE_OVFX2:
Hans de Goedea511ba92009-10-16 07:13:07 -03001876 req = 0x0a;
1877 /* fall through */
1878 case BRIDGE_W9968CF:
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001879 ret = usb_control_msg(sd->gspca_dev.dev,
1880 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
Hans de Goedea511ba92009-10-16 07:13:07 -03001881 req,
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001882 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Hans de Goedea511ba92009-10-16 07:13:07 -03001883 value, index, NULL, 0, 500);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001884 goto leave;
1885 default:
1886 req = 1;
1887 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001888
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001889 sd->gspca_dev.usb_buf[0] = value;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001890 ret = usb_control_msg(sd->gspca_dev.dev,
1891 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
Hans de Goede49809d62009-06-07 12:10:39 -03001892 req,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001893 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1894 0, index,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001895 sd->gspca_dev.usb_buf, 1, 500);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001896leave:
Hans de Goedea511ba92009-10-16 07:13:07 -03001897 if (ret < 0) {
1898 PDEBUG(D_ERR, "Write reg 0x%04x -> [0x%02x] failed",
1899 value, index);
1900 return ret;
1901 }
1902
1903 PDEBUG(D_USBO, "Write reg 0x%04x -> [0x%02x]", value, index);
1904 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001905}
1906
Hans de Goedea511ba92009-10-16 07:13:07 -03001907/* Read from a OV519 register, note not valid for the w9968cf!! */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001908/* returns: negative is error, pos or zero is data */
1909static int reg_r(struct sd *sd, __u16 index)
1910{
1911 int ret;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001912 int req;
1913
1914 switch (sd->bridge) {
1915 case BRIDGE_OV511:
1916 case BRIDGE_OV511PLUS:
1917 req = 3;
1918 break;
1919 case BRIDGE_OVFX2:
1920 req = 0x0b;
1921 break;
1922 default:
1923 req = 1;
1924 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001925
1926 ret = usb_control_msg(sd->gspca_dev.dev,
1927 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
Hans de Goede49809d62009-06-07 12:10:39 -03001928 req,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001929 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001930 0, index, sd->gspca_dev.usb_buf, 1, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001931
Hans de Goedea511ba92009-10-16 07:13:07 -03001932 if (ret >= 0) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001933 ret = sd->gspca_dev.usb_buf[0];
Hans de Goedea511ba92009-10-16 07:13:07 -03001934 PDEBUG(D_USBI, "Read reg [0x%02X] -> 0x%04X", index, ret);
1935 } else
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001936 PDEBUG(D_ERR, "Read reg [0x%02x] failed", index);
Hans de Goedea511ba92009-10-16 07:13:07 -03001937
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001938 return ret;
1939}
1940
1941/* Read 8 values from a OV519 register */
1942static int reg_r8(struct sd *sd,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001943 __u16 index)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001944{
1945 int ret;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001946
1947 ret = usb_control_msg(sd->gspca_dev.dev,
1948 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
1949 1, /* REQ_IO */
1950 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001951 0, index, sd->gspca_dev.usb_buf, 8, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001952
1953 if (ret >= 0)
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001954 ret = sd->gspca_dev.usb_buf[0];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001955 else
1956 PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index);
Hans de Goedea511ba92009-10-16 07:13:07 -03001957
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001958 return ret;
1959}
1960
1961/*
1962 * Writes bits at positions specified by mask to an OV51x reg. Bits that are in
1963 * the same position as 1's in "mask" are cleared and set to "value". Bits
1964 * that are in the same position as 0's in "mask" are preserved, regardless
1965 * of their respective state in "value".
1966 */
1967static int reg_w_mask(struct sd *sd,
1968 __u16 index,
1969 __u8 value,
1970 __u8 mask)
1971{
1972 int ret;
1973 __u8 oldval;
1974
1975 if (mask != 0xff) {
1976 value &= mask; /* Enforce mask on value */
1977 ret = reg_r(sd, index);
1978 if (ret < 0)
1979 return ret;
1980
1981 oldval = ret & ~mask; /* Clear the masked bits */
1982 value |= oldval; /* Set the desired bits */
1983 }
1984 return reg_w(sd, index, value);
1985}
1986
1987/*
Hans de Goede49809d62009-06-07 12:10:39 -03001988 * Writes multiple (n) byte value to a single register. Only valid with certain
1989 * registers (0x30 and 0xc4 - 0xce).
1990 */
1991static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n)
1992{
1993 int ret;
1994
Jean-Francois Moine83955552009-12-12 06:58:01 -03001995 *((__le32 *) sd->gspca_dev.usb_buf) = __cpu_to_le32(value);
Hans de Goede49809d62009-06-07 12:10:39 -03001996
1997 ret = usb_control_msg(sd->gspca_dev.dev,
1998 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
1999 1 /* REG_IO */,
2000 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2001 0, index,
2002 sd->gspca_dev.usb_buf, n, 500);
Hans de Goedea511ba92009-10-16 07:13:07 -03002003 if (ret < 0) {
Hans de Goede49809d62009-06-07 12:10:39 -03002004 PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value);
Hans de Goedea511ba92009-10-16 07:13:07 -03002005 return ret;
2006 }
2007
2008 return 0;
Hans de Goede49809d62009-06-07 12:10:39 -03002009}
2010
Hans de Goede1876bb92009-06-14 06:45:50 -03002011static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value)
2012{
2013 int rc, retries;
2014
2015 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
2016
2017 /* Three byte write cycle */
2018 for (retries = 6; ; ) {
2019 /* Select camera register */
2020 rc = reg_w(sd, R51x_I2C_SADDR_3, reg);
2021 if (rc < 0)
2022 return rc;
2023
2024 /* Write "value" to I2C data port of OV511 */
2025 rc = reg_w(sd, R51x_I2C_DATA, value);
2026 if (rc < 0)
2027 return rc;
2028
2029 /* Initiate 3-byte write cycle */
2030 rc = reg_w(sd, R511_I2C_CTL, 0x01);
2031 if (rc < 0)
2032 return rc;
2033
Jean-Francois Moine83955552009-12-12 06:58:01 -03002034 do {
Hans de Goede1876bb92009-06-14 06:45:50 -03002035 rc = reg_r(sd, R511_I2C_CTL);
Jean-Francois Moine83955552009-12-12 06:58:01 -03002036 } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
Hans de Goede1876bb92009-06-14 06:45:50 -03002037
2038 if (rc < 0)
2039 return rc;
2040
2041 if ((rc & 2) == 0) /* Ack? */
2042 break;
2043 if (--retries < 0) {
2044 PDEBUG(D_USBO, "i2c write retries exhausted");
2045 return -1;
2046 }
2047 }
2048
2049 return 0;
2050}
2051
2052static int ov511_i2c_r(struct sd *sd, __u8 reg)
2053{
2054 int rc, value, retries;
2055
2056 /* Two byte write cycle */
2057 for (retries = 6; ; ) {
2058 /* Select camera register */
2059 rc = reg_w(sd, R51x_I2C_SADDR_2, reg);
2060 if (rc < 0)
2061 return rc;
2062
2063 /* Initiate 2-byte write cycle */
2064 rc = reg_w(sd, R511_I2C_CTL, 0x03);
2065 if (rc < 0)
2066 return rc;
2067
Jean-Francois Moine83955552009-12-12 06:58:01 -03002068 do {
Hans de Goede1876bb92009-06-14 06:45:50 -03002069 rc = reg_r(sd, R511_I2C_CTL);
Jean-Francois Moine83955552009-12-12 06:58:01 -03002070 } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
Hans de Goede1876bb92009-06-14 06:45:50 -03002071
2072 if (rc < 0)
2073 return rc;
2074
2075 if ((rc & 2) == 0) /* Ack? */
2076 break;
2077
2078 /* I2C abort */
2079 reg_w(sd, R511_I2C_CTL, 0x10);
2080
2081 if (--retries < 0) {
2082 PDEBUG(D_USBI, "i2c write retries exhausted");
2083 return -1;
2084 }
2085 }
2086
2087 /* Two byte read cycle */
2088 for (retries = 6; ; ) {
2089 /* Initiate 2-byte read cycle */
2090 rc = reg_w(sd, R511_I2C_CTL, 0x05);
2091 if (rc < 0)
2092 return rc;
2093
Jean-Francois Moine83955552009-12-12 06:58:01 -03002094 do {
Hans de Goede1876bb92009-06-14 06:45:50 -03002095 rc = reg_r(sd, R511_I2C_CTL);
Jean-Francois Moine83955552009-12-12 06:58:01 -03002096 } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
Hans de Goede1876bb92009-06-14 06:45:50 -03002097
2098 if (rc < 0)
2099 return rc;
2100
2101 if ((rc & 2) == 0) /* Ack? */
2102 break;
2103
2104 /* I2C abort */
2105 rc = reg_w(sd, R511_I2C_CTL, 0x10);
2106 if (rc < 0)
2107 return rc;
2108
2109 if (--retries < 0) {
2110 PDEBUG(D_USBI, "i2c read retries exhausted");
2111 return -1;
2112 }
2113 }
2114
2115 value = reg_r(sd, R51x_I2C_DATA);
2116
2117 PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
2118
2119 /* This is needed to make i2c_w() work */
2120 rc = reg_w(sd, R511_I2C_CTL, 0x05);
2121 if (rc < 0)
2122 return rc;
2123
2124 return value;
2125}
Hans de Goede49809d62009-06-07 12:10:39 -03002126
2127/*
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002128 * The OV518 I2C I/O procedure is different, hence, this function.
2129 * This is normally only called from i2c_w(). Note that this function
2130 * always succeeds regardless of whether the sensor is present and working.
2131 */
Hans de Goede1876bb92009-06-14 06:45:50 -03002132static int ov518_i2c_w(struct sd *sd,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002133 __u8 reg,
2134 __u8 value)
2135{
2136 int rc;
2137
2138 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
2139
2140 /* Select camera register */
2141 rc = reg_w(sd, R51x_I2C_SADDR_3, reg);
2142 if (rc < 0)
2143 return rc;
2144
2145 /* Write "value" to I2C data port of OV511 */
2146 rc = reg_w(sd, R51x_I2C_DATA, value);
2147 if (rc < 0)
2148 return rc;
2149
2150 /* Initiate 3-byte write cycle */
2151 rc = reg_w(sd, R518_I2C_CTL, 0x01);
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002152 if (rc < 0)
2153 return rc;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002154
2155 /* wait for write complete */
2156 msleep(4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002157 return reg_r8(sd, R518_I2C_CTL);
2158}
2159
2160/*
2161 * returns: negative is error, pos or zero is data
2162 *
2163 * The OV518 I2C I/O procedure is different, hence, this function.
2164 * This is normally only called from i2c_r(). Note that this function
2165 * always succeeds regardless of whether the sensor is present and working.
2166 */
Hans de Goede1876bb92009-06-14 06:45:50 -03002167static int ov518_i2c_r(struct sd *sd, __u8 reg)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002168{
2169 int rc, value;
2170
2171 /* Select camera register */
2172 rc = reg_w(sd, R51x_I2C_SADDR_2, reg);
2173 if (rc < 0)
2174 return rc;
2175
2176 /* Initiate 2-byte write cycle */
2177 rc = reg_w(sd, R518_I2C_CTL, 0x03);
2178 if (rc < 0)
2179 return rc;
2180
2181 /* Initiate 2-byte read cycle */
2182 rc = reg_w(sd, R518_I2C_CTL, 0x05);
2183 if (rc < 0)
2184 return rc;
2185 value = reg_r(sd, R51x_I2C_DATA);
2186 PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
2187 return value;
2188}
2189
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002190static int ovfx2_i2c_w(struct sd *sd, __u8 reg, __u8 value)
2191{
2192 int ret;
2193
2194 ret = usb_control_msg(sd->gspca_dev.dev,
2195 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
2196 0x02,
2197 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2198 (__u16)value, (__u16)reg, NULL, 0, 500);
2199
Hans de Goedea511ba92009-10-16 07:13:07 -03002200 if (ret < 0) {
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002201 PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg);
Hans de Goedea511ba92009-10-16 07:13:07 -03002202 return ret;
2203 }
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002204
Hans de Goedea511ba92009-10-16 07:13:07 -03002205 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
2206 return 0;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002207}
2208
2209static int ovfx2_i2c_r(struct sd *sd, __u8 reg)
2210{
2211 int ret;
2212
2213 ret = usb_control_msg(sd->gspca_dev.dev,
2214 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
2215 0x03,
2216 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2217 0, (__u16)reg, sd->gspca_dev.usb_buf, 1, 500);
2218
2219 if (ret >= 0) {
2220 ret = sd->gspca_dev.usb_buf[0];
2221 PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, ret);
2222 } else
2223 PDEBUG(D_ERR, "i2c read [0x%02x] failed", reg);
2224
2225 return ret;
2226}
2227
Hans de Goede1876bb92009-06-14 06:45:50 -03002228static int i2c_w(struct sd *sd, __u8 reg, __u8 value)
2229{
Hans de Goedefb1f9022009-10-16 07:42:53 -03002230 int ret = -1;
2231
2232 if (sd->sensor_reg_cache[reg] == value)
2233 return 0;
2234
Hans de Goede1876bb92009-06-14 06:45:50 -03002235 switch (sd->bridge) {
2236 case BRIDGE_OV511:
2237 case BRIDGE_OV511PLUS:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002238 ret = ov511_i2c_w(sd, reg, value);
2239 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002240 case BRIDGE_OV518:
2241 case BRIDGE_OV518PLUS:
2242 case BRIDGE_OV519:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002243 ret = ov518_i2c_w(sd, reg, value);
2244 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002245 case BRIDGE_OVFX2:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002246 ret = ovfx2_i2c_w(sd, reg, value);
2247 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03002248 case BRIDGE_W9968CF:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002249 ret = w9968cf_i2c_w(sd, reg, value);
2250 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002251 }
Hans de Goedefb1f9022009-10-16 07:42:53 -03002252
2253 if (ret >= 0) {
2254 /* Up on sensor reset empty the register cache */
2255 if (reg == 0x12 && (value & 0x80))
2256 memset(sd->sensor_reg_cache, -1,
2257 sizeof(sd->sensor_reg_cache));
2258 else
2259 sd->sensor_reg_cache[reg] = value;
2260 }
2261
2262 return ret;
Hans de Goede1876bb92009-06-14 06:45:50 -03002263}
2264
2265static int i2c_r(struct sd *sd, __u8 reg)
2266{
Hans de Goede8394bcf2009-10-16 11:26:22 -03002267 int ret = -1;
Hans de Goedefb1f9022009-10-16 07:42:53 -03002268
2269 if (sd->sensor_reg_cache[reg] != -1)
2270 return sd->sensor_reg_cache[reg];
2271
Hans de Goede1876bb92009-06-14 06:45:50 -03002272 switch (sd->bridge) {
2273 case BRIDGE_OV511:
2274 case BRIDGE_OV511PLUS:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002275 ret = ov511_i2c_r(sd, reg);
2276 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002277 case BRIDGE_OV518:
2278 case BRIDGE_OV518PLUS:
2279 case BRIDGE_OV519:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002280 ret = ov518_i2c_r(sd, reg);
2281 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002282 case BRIDGE_OVFX2:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002283 ret = ovfx2_i2c_r(sd, reg);
2284 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03002285 case BRIDGE_W9968CF:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002286 ret = w9968cf_i2c_r(sd, reg);
2287 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002288 }
Hans de Goedefb1f9022009-10-16 07:42:53 -03002289
2290 if (ret >= 0)
2291 sd->sensor_reg_cache[reg] = ret;
2292
2293 return ret;
Hans de Goede1876bb92009-06-14 06:45:50 -03002294}
2295
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002296/* Writes bits at positions specified by mask to an I2C reg. Bits that are in
2297 * the same position as 1's in "mask" are cleared and set to "value". Bits
2298 * that are in the same position as 0's in "mask" are preserved, regardless
2299 * of their respective state in "value".
2300 */
2301static int i2c_w_mask(struct sd *sd,
2302 __u8 reg,
2303 __u8 value,
2304 __u8 mask)
2305{
2306 int rc;
2307 __u8 oldval;
2308
2309 value &= mask; /* Enforce mask on value */
2310 rc = i2c_r(sd, reg);
2311 if (rc < 0)
2312 return rc;
2313 oldval = rc & ~mask; /* Clear the masked bits */
2314 value |= oldval; /* Set the desired bits */
2315 return i2c_w(sd, reg, value);
2316}
2317
2318/* Temporarily stops OV511 from functioning. Must do this before changing
2319 * registers while the camera is streaming */
2320static inline int ov51x_stop(struct sd *sd)
2321{
2322 PDEBUG(D_STREAM, "stopping");
2323 sd->stopped = 1;
Hans de Goede49809d62009-06-07 12:10:39 -03002324 switch (sd->bridge) {
2325 case BRIDGE_OV511:
2326 case BRIDGE_OV511PLUS:
2327 return reg_w(sd, R51x_SYS_RESET, 0x3d);
2328 case BRIDGE_OV518:
2329 case BRIDGE_OV518PLUS:
2330 return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
2331 case BRIDGE_OV519:
2332 return reg_w(sd, OV519_SYS_RESET1, 0x0f);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002333 case BRIDGE_OVFX2:
2334 return reg_w_mask(sd, 0x0f, 0x00, 0x02);
Hans de Goedea511ba92009-10-16 07:13:07 -03002335 case BRIDGE_W9968CF:
Hans de Goede79b35902009-10-19 06:08:01 -03002336 return reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */
Hans de Goede49809d62009-06-07 12:10:39 -03002337 }
2338
2339 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002340}
2341
2342/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
2343 * actually stopped (for performance). */
2344static inline int ov51x_restart(struct sd *sd)
2345{
Hans de Goede49809d62009-06-07 12:10:39 -03002346 int rc;
2347
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002348 PDEBUG(D_STREAM, "restarting");
2349 if (!sd->stopped)
2350 return 0;
2351 sd->stopped = 0;
2352
2353 /* Reinitialize the stream */
Hans de Goede49809d62009-06-07 12:10:39 -03002354 switch (sd->bridge) {
2355 case BRIDGE_OV511:
2356 case BRIDGE_OV511PLUS:
2357 return reg_w(sd, R51x_SYS_RESET, 0x00);
2358 case BRIDGE_OV518:
2359 case BRIDGE_OV518PLUS:
2360 rc = reg_w(sd, 0x2f, 0x80);
2361 if (rc < 0)
2362 return rc;
2363 return reg_w(sd, R51x_SYS_RESET, 0x00);
2364 case BRIDGE_OV519:
2365 return reg_w(sd, OV519_SYS_RESET1, 0x00);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002366 case BRIDGE_OVFX2:
2367 return reg_w_mask(sd, 0x0f, 0x02, 0x02);
Hans de Goedea511ba92009-10-16 07:13:07 -03002368 case BRIDGE_W9968CF:
2369 return reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */
Hans de Goede49809d62009-06-07 12:10:39 -03002370 }
2371
2372 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002373}
2374
Hans de Goede229bb7d2009-10-11 07:41:46 -03002375static int ov51x_set_slave_ids(struct sd *sd, __u8 slave);
2376
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002377/* This does an initial reset of an OmniVision sensor and ensures that I2C
2378 * is synchronized. Returns <0 on failure.
2379 */
Hans de Goede229bb7d2009-10-11 07:41:46 -03002380static int init_ov_sensor(struct sd *sd, __u8 slave)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002381{
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002382 int i;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002383
Hans de Goede229bb7d2009-10-11 07:41:46 -03002384 if (ov51x_set_slave_ids(sd, slave) < 0)
2385 return -EIO;
2386
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002387 /* Reset the sensor */
2388 if (i2c_w(sd, 0x12, 0x80) < 0)
2389 return -EIO;
2390
2391 /* Wait for it to initialize */
2392 msleep(150);
2393
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002394 for (i = 0; i < i2c_detect_tries; i++) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002395 if (i2c_r(sd, OV7610_REG_ID_HIGH) == 0x7f &&
2396 i2c_r(sd, OV7610_REG_ID_LOW) == 0xa2) {
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002397 PDEBUG(D_PROBE, "I2C synced in %d attempt(s)", i);
2398 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002399 }
2400
2401 /* Reset the sensor */
2402 if (i2c_w(sd, 0x12, 0x80) < 0)
2403 return -EIO;
2404 /* Wait for it to initialize */
2405 msleep(150);
2406 /* Dummy read to sync I2C */
2407 if (i2c_r(sd, 0x00) < 0)
2408 return -EIO;
2409 }
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002410 return -EIO;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002411}
2412
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002413/* Set the read and write slave IDs. The "slave" argument is the write slave,
2414 * and the read slave will be set to (slave + 1).
2415 * This should not be called from outside the i2c I/O functions.
2416 * Sets I2C read and write slave IDs. Returns <0 for error
2417 */
2418static int ov51x_set_slave_ids(struct sd *sd,
2419 __u8 slave)
2420{
2421 int rc;
2422
Hans de Goedea511ba92009-10-16 07:13:07 -03002423 switch (sd->bridge) {
2424 case BRIDGE_OVFX2:
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002425 return reg_w(sd, OVFX2_I2C_ADDR, slave);
Hans de Goedea511ba92009-10-16 07:13:07 -03002426 case BRIDGE_W9968CF:
2427 sd->sensor_addr = slave;
2428 return 0;
2429 }
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002430
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002431 rc = reg_w(sd, R51x_I2C_W_SID, slave);
2432 if (rc < 0)
2433 return rc;
2434 return reg_w(sd, R51x_I2C_R_SID, slave + 1);
2435}
2436
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002437static int write_regvals(struct sd *sd,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002438 const struct ov_regvals *regvals,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002439 int n)
2440{
2441 int rc;
2442
2443 while (--n >= 0) {
2444 rc = reg_w(sd, regvals->reg, regvals->val);
2445 if (rc < 0)
2446 return rc;
2447 regvals++;
2448 }
2449 return 0;
2450}
2451
2452static int write_i2c_regvals(struct sd *sd,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002453 const struct ov_i2c_regvals *regvals,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002454 int n)
2455{
2456 int rc;
2457
2458 while (--n >= 0) {
2459 rc = i2c_w(sd, regvals->reg, regvals->val);
2460 if (rc < 0)
2461 return rc;
2462 regvals++;
2463 }
2464 return 0;
2465}
2466
2467/****************************************************************************
2468 *
2469 * OV511 and sensor configuration
2470 *
2471 ***************************************************************************/
2472
Hans de Goede635118d2009-10-11 09:49:03 -03002473/* This initializes the OV2x10 / OV3610 / OV3620 */
2474static int ov_hires_configure(struct sd *sd)
2475{
2476 int high, low;
2477
2478 if (sd->bridge != BRIDGE_OVFX2) {
2479 PDEBUG(D_ERR, "error hires sensors only supported with ovfx2");
2480 return -1;
2481 }
2482
2483 PDEBUG(D_PROBE, "starting ov hires configuration");
2484
2485 /* Detect sensor (sub)type */
2486 high = i2c_r(sd, 0x0a);
2487 low = i2c_r(sd, 0x0b);
2488 /* info("%x, %x", high, low); */
2489 if (high == 0x96 && low == 0x40) {
2490 PDEBUG(D_PROBE, "Sensor is an OV2610");
2491 sd->sensor = SEN_OV2610;
2492 } else if (high == 0x36 && (low & 0x0f) == 0x00) {
2493 PDEBUG(D_PROBE, "Sensor is an OV3610");
2494 sd->sensor = SEN_OV3610;
2495 } else {
2496 PDEBUG(D_ERR, "Error unknown sensor type: 0x%02x%02x",
2497 high, low);
2498 return -1;
2499 }
2500
2501 /* Set sensor-specific vars */
2502 return 0;
2503}
2504
2505
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002506/* This initializes the OV8110, OV8610 sensor. The OV8110 uses
2507 * the same register settings as the OV8610, since they are very similar.
2508 */
2509static int ov8xx0_configure(struct sd *sd)
2510{
2511 int rc;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002512
2513 PDEBUG(D_PROBE, "starting ov8xx0 configuration");
2514
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002515 /* Detect sensor (sub)type */
2516 rc = i2c_r(sd, OV7610_REG_COM_I);
2517 if (rc < 0) {
2518 PDEBUG(D_ERR, "Error detecting sensor type");
2519 return -1;
2520 }
2521 if ((rc & 3) == 1) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002522 sd->sensor = SEN_OV8610;
2523 } else {
2524 PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3);
2525 return -1;
2526 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002527
2528 /* Set sensor-specific vars */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002529 return 0;
2530}
2531
2532/* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses
2533 * the same register settings as the OV7610, since they are very similar.
2534 */
2535static int ov7xx0_configure(struct sd *sd)
2536{
2537 int rc, high, low;
2538
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002539
2540 PDEBUG(D_PROBE, "starting OV7xx0 configuration");
2541
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002542 /* Detect sensor (sub)type */
2543 rc = i2c_r(sd, OV7610_REG_COM_I);
2544
2545 /* add OV7670 here
2546 * it appears to be wrongly detected as a 7610 by default */
2547 if (rc < 0) {
2548 PDEBUG(D_ERR, "Error detecting sensor type");
2549 return -1;
2550 }
2551 if ((rc & 3) == 3) {
2552 /* quick hack to make OV7670s work */
2553 high = i2c_r(sd, 0x0a);
2554 low = i2c_r(sd, 0x0b);
2555 /* info("%x, %x", high, low); */
2556 if (high == 0x76 && low == 0x73) {
2557 PDEBUG(D_PROBE, "Sensor is an OV7670");
2558 sd->sensor = SEN_OV7670;
2559 } else {
2560 PDEBUG(D_PROBE, "Sensor is an OV7610");
2561 sd->sensor = SEN_OV7610;
2562 }
2563 } else if ((rc & 3) == 1) {
2564 /* I don't know what's different about the 76BE yet. */
Hans de Goedeb282d872009-06-14 19:10:40 -03002565 if (i2c_r(sd, 0x15) & 1) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002566 PDEBUG(D_PROBE, "Sensor is an OV7620AE");
Hans de Goede859cc472010-01-07 15:42:35 -03002567 sd->sensor = SEN_OV7620AE;
Hans de Goedeb282d872009-06-14 19:10:40 -03002568 } else {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002569 PDEBUG(D_PROBE, "Sensor is an OV76BE");
Hans de Goedeb282d872009-06-14 19:10:40 -03002570 sd->sensor = SEN_OV76BE;
2571 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002572 } else if ((rc & 3) == 0) {
2573 /* try to read product id registers */
2574 high = i2c_r(sd, 0x0a);
2575 if (high < 0) {
2576 PDEBUG(D_ERR, "Error detecting camera chip PID");
2577 return high;
2578 }
2579 low = i2c_r(sd, 0x0b);
2580 if (low < 0) {
2581 PDEBUG(D_ERR, "Error detecting camera chip VER");
2582 return low;
2583 }
2584 if (high == 0x76) {
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002585 switch (low) {
2586 case 0x30:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002587 PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635");
Jean-Francois Moine4202f712008-09-03 17:12:15 -03002588 PDEBUG(D_ERR,
2589 "7630 is not supported by this driver");
2590 return -1;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002591 case 0x40:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002592 PDEBUG(D_PROBE, "Sensor is an OV7645");
2593 sd->sensor = SEN_OV7640; /* FIXME */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002594 break;
2595 case 0x45:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002596 PDEBUG(D_PROBE, "Sensor is an OV7645B");
2597 sd->sensor = SEN_OV7640; /* FIXME */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002598 break;
2599 case 0x48:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002600 PDEBUG(D_PROBE, "Sensor is an OV7648");
Hans de Goede035d3a32010-01-09 08:14:43 -03002601 sd->sensor = SEN_OV7648;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002602 break;
2603 default:
2604 PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002605 return -1;
2606 }
2607 } else {
2608 PDEBUG(D_PROBE, "Sensor is an OV7620");
2609 sd->sensor = SEN_OV7620;
2610 }
2611 } else {
2612 PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3);
2613 return -1;
2614 }
2615
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002616 /* Set sensor-specific vars */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002617 return 0;
2618}
2619
2620/* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */
2621static int ov6xx0_configure(struct sd *sd)
2622{
2623 int rc;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03002624 PDEBUG(D_PROBE, "starting OV6xx0 configuration");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002625
2626 /* Detect sensor (sub)type */
2627 rc = i2c_r(sd, OV7610_REG_COM_I);
2628 if (rc < 0) {
2629 PDEBUG(D_ERR, "Error detecting sensor type");
2630 return -1;
2631 }
2632
2633 /* Ugh. The first two bits are the version bits, but
2634 * the entire register value must be used. I guess OVT
2635 * underestimated how many variants they would make. */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002636 switch (rc) {
2637 case 0x00:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002638 sd->sensor = SEN_OV6630;
2639 PDEBUG(D_ERR,
2640 "WARNING: Sensor is an OV66308. Your camera may have");
2641 PDEBUG(D_ERR, "been misdetected in previous driver versions.");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002642 break;
2643 case 0x01:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002644 sd->sensor = SEN_OV6620;
Hans de Goede7d971372009-06-14 05:28:17 -03002645 PDEBUG(D_PROBE, "Sensor is an OV6620");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002646 break;
2647 case 0x02:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002648 sd->sensor = SEN_OV6630;
2649 PDEBUG(D_PROBE, "Sensor is an OV66308AE");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002650 break;
2651 case 0x03:
Hans de Goede7d971372009-06-14 05:28:17 -03002652 sd->sensor = SEN_OV66308AF;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002653 PDEBUG(D_PROBE, "Sensor is an OV66308AF");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002654 break;
2655 case 0x90:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002656 sd->sensor = SEN_OV6630;
2657 PDEBUG(D_ERR,
2658 "WARNING: Sensor is an OV66307. Your camera may have");
2659 PDEBUG(D_ERR, "been misdetected in previous driver versions.");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002660 break;
2661 default:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002662 PDEBUG(D_ERR, "FATAL: Unknown sensor version: 0x%02x", rc);
2663 return -1;
2664 }
2665
2666 /* Set sensor-specific vars */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002667 sd->sif = 1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002668
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002669 return 0;
2670}
2671
2672/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
2673static void ov51x_led_control(struct sd *sd, int on)
2674{
Hans de Goede9e4d8252009-06-14 06:25:06 -03002675 if (sd->invert_led)
2676 on = !on;
2677
Hans de Goede49809d62009-06-07 12:10:39 -03002678 switch (sd->bridge) {
2679 /* OV511 has no LED control */
2680 case BRIDGE_OV511PLUS:
2681 reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0);
2682 break;
2683 case BRIDGE_OV518:
2684 case BRIDGE_OV518PLUS:
2685 reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02);
2686 break;
2687 case BRIDGE_OV519:
2688 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */
2689 break;
2690 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002691}
2692
Hans de Goede417a4d22010-02-19 07:37:08 -03002693static void sd_reset_snapshot(struct gspca_dev *gspca_dev)
2694{
2695 struct sd *sd = (struct sd *) gspca_dev;
2696
2697 if (!sd->snapshot_needs_reset)
2698 return;
2699
2700 /* Note it is important that we clear sd->snapshot_needs_reset,
2701 before actually clearing the snapshot state in the bridge
2702 otherwise we might race with the pkt_scan interrupt handler */
2703 sd->snapshot_needs_reset = 0;
2704
2705 switch (sd->bridge) {
Hans de Goede88e8d202010-02-20 04:45:49 -03002706 case BRIDGE_OV511:
2707 case BRIDGE_OV511PLUS:
2708 reg_w(sd, R51x_SYS_SNAP, 0x02);
2709 reg_w(sd, R51x_SYS_SNAP, 0x00);
2710 break;
Hans de Goede92e232a2010-02-20 04:30:45 -03002711 case BRIDGE_OV518:
2712 case BRIDGE_OV518PLUS:
2713 reg_w(sd, R51x_SYS_SNAP, 0x02); /* Reset */
2714 reg_w(sd, R51x_SYS_SNAP, 0x01); /* Enable */
2715 break;
Hans de Goede417a4d22010-02-19 07:37:08 -03002716 case BRIDGE_OV519:
2717 reg_w(sd, R51x_SYS_RESET, 0x40);
2718 reg_w(sd, R51x_SYS_RESET, 0x00);
2719 break;
2720 }
2721}
2722
Hans de Goede1876bb92009-06-14 06:45:50 -03002723static int ov51x_upload_quan_tables(struct sd *sd)
Hans de Goede49809d62009-06-07 12:10:39 -03002724{
Hans de Goede1876bb92009-06-14 06:45:50 -03002725 const unsigned char yQuanTable511[] = {
2726 0, 1, 1, 2, 2, 3, 3, 4,
2727 1, 1, 1, 2, 2, 3, 4, 4,
2728 1, 1, 2, 2, 3, 4, 4, 4,
2729 2, 2, 2, 3, 4, 4, 4, 4,
2730 2, 2, 3, 4, 4, 5, 5, 5,
2731 3, 3, 4, 4, 5, 5, 5, 5,
2732 3, 4, 4, 4, 5, 5, 5, 5,
2733 4, 4, 4, 4, 5, 5, 5, 5
2734 };
2735
2736 const unsigned char uvQuanTable511[] = {
2737 0, 2, 2, 3, 4, 4, 4, 4,
2738 2, 2, 2, 4, 4, 4, 4, 4,
2739 2, 2, 3, 4, 4, 4, 4, 4,
2740 3, 4, 4, 4, 4, 4, 4, 4,
2741 4, 4, 4, 4, 4, 4, 4, 4,
2742 4, 4, 4, 4, 4, 4, 4, 4,
2743 4, 4, 4, 4, 4, 4, 4, 4,
2744 4, 4, 4, 4, 4, 4, 4, 4
2745 };
2746
2747 /* OV518 quantization tables are 8x4 (instead of 8x8) */
Hans de Goede49809d62009-06-07 12:10:39 -03002748 const unsigned char yQuanTable518[] = {
2749 5, 4, 5, 6, 6, 7, 7, 7,
2750 5, 5, 5, 5, 6, 7, 7, 7,
2751 6, 6, 6, 6, 7, 7, 7, 8,
2752 7, 7, 6, 7, 7, 7, 8, 8
2753 };
2754
2755 const unsigned char uvQuanTable518[] = {
2756 6, 6, 6, 7, 7, 7, 7, 7,
2757 6, 6, 6, 7, 7, 7, 7, 7,
2758 6, 6, 6, 7, 7, 7, 7, 8,
2759 7, 7, 7, 7, 7, 7, 8, 8
2760 };
2761
Hans de Goede1876bb92009-06-14 06:45:50 -03002762 const unsigned char *pYTable, *pUVTable;
Hans de Goede49809d62009-06-07 12:10:39 -03002763 unsigned char val0, val1;
Hans de Goede1876bb92009-06-14 06:45:50 -03002764 int i, size, rc, reg = R51x_COMP_LUT_BEGIN;
Hans de Goede49809d62009-06-07 12:10:39 -03002765
2766 PDEBUG(D_PROBE, "Uploading quantization tables");
2767
Hans de Goede1876bb92009-06-14 06:45:50 -03002768 if (sd->bridge == BRIDGE_OV511 || sd->bridge == BRIDGE_OV511PLUS) {
2769 pYTable = yQuanTable511;
2770 pUVTable = uvQuanTable511;
2771 size = 32;
2772 } else {
2773 pYTable = yQuanTable518;
2774 pUVTable = uvQuanTable518;
2775 size = 16;
2776 }
2777
2778 for (i = 0; i < size; i++) {
Hans de Goede49809d62009-06-07 12:10:39 -03002779 val0 = *pYTable++;
2780 val1 = *pYTable++;
2781 val0 &= 0x0f;
2782 val1 &= 0x0f;
2783 val0 |= val1 << 4;
2784 rc = reg_w(sd, reg, val0);
2785 if (rc < 0)
2786 return rc;
2787
2788 val0 = *pUVTable++;
2789 val1 = *pUVTable++;
2790 val0 &= 0x0f;
2791 val1 &= 0x0f;
2792 val0 |= val1 << 4;
Hans de Goede1876bb92009-06-14 06:45:50 -03002793 rc = reg_w(sd, reg + size, val0);
Hans de Goede49809d62009-06-07 12:10:39 -03002794 if (rc < 0)
2795 return rc;
2796
2797 reg++;
2798 }
2799
2800 return 0;
2801}
2802
Hans de Goede1876bb92009-06-14 06:45:50 -03002803/* This initializes the OV511/OV511+ and the sensor */
2804static int ov511_configure(struct gspca_dev *gspca_dev)
2805{
2806 struct sd *sd = (struct sd *) gspca_dev;
2807 int rc;
2808
2809 /* For 511 and 511+ */
2810 const struct ov_regvals init_511[] = {
2811 { R51x_SYS_RESET, 0x7f },
2812 { R51x_SYS_INIT, 0x01 },
2813 { R51x_SYS_RESET, 0x7f },
2814 { R51x_SYS_INIT, 0x01 },
2815 { R51x_SYS_RESET, 0x3f },
2816 { R51x_SYS_INIT, 0x01 },
2817 { R51x_SYS_RESET, 0x3d },
2818 };
2819
2820 const struct ov_regvals norm_511[] = {
2821 { R511_DRAM_FLOW_CTL, 0x01 },
2822 { R51x_SYS_SNAP, 0x00 },
2823 { R51x_SYS_SNAP, 0x02 },
2824 { R51x_SYS_SNAP, 0x00 },
2825 { R511_FIFO_OPTS, 0x1f },
2826 { R511_COMP_EN, 0x00 },
2827 { R511_COMP_LUT_EN, 0x03 },
2828 };
2829
2830 const struct ov_regvals norm_511_p[] = {
2831 { R511_DRAM_FLOW_CTL, 0xff },
2832 { R51x_SYS_SNAP, 0x00 },
2833 { R51x_SYS_SNAP, 0x02 },
2834 { R51x_SYS_SNAP, 0x00 },
2835 { R511_FIFO_OPTS, 0xff },
2836 { R511_COMP_EN, 0x00 },
2837 { R511_COMP_LUT_EN, 0x03 },
2838 };
2839
2840 const struct ov_regvals compress_511[] = {
2841 { 0x70, 0x1f },
2842 { 0x71, 0x05 },
2843 { 0x72, 0x06 },
2844 { 0x73, 0x06 },
2845 { 0x74, 0x14 },
2846 { 0x75, 0x03 },
2847 { 0x76, 0x04 },
2848 { 0x77, 0x04 },
2849 };
2850
2851 PDEBUG(D_PROBE, "Device custom id %x", reg_r(sd, R51x_SYS_CUST_ID));
2852
2853 rc = write_regvals(sd, init_511, ARRAY_SIZE(init_511));
2854 if (rc < 0)
2855 return rc;
2856
2857 switch (sd->bridge) {
2858 case BRIDGE_OV511:
2859 rc = write_regvals(sd, norm_511, ARRAY_SIZE(norm_511));
2860 if (rc < 0)
2861 return rc;
2862 break;
2863 case BRIDGE_OV511PLUS:
2864 rc = write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p));
2865 if (rc < 0)
2866 return rc;
2867 break;
2868 }
2869
2870 /* Init compression */
2871 rc = write_regvals(sd, compress_511, ARRAY_SIZE(compress_511));
2872 if (rc < 0)
2873 return rc;
2874
2875 rc = ov51x_upload_quan_tables(sd);
2876 if (rc < 0) {
2877 PDEBUG(D_ERR, "Error uploading quantization tables");
2878 return rc;
2879 }
2880
2881 return 0;
2882}
2883
Hans de Goede49809d62009-06-07 12:10:39 -03002884/* This initializes the OV518/OV518+ and the sensor */
2885static int ov518_configure(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002886{
2887 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goede49809d62009-06-07 12:10:39 -03002888 int rc;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002889
Hans de Goede49809d62009-06-07 12:10:39 -03002890 /* For 518 and 518+ */
Hans de Goedee080fcd2009-06-18 05:03:16 -03002891 const struct ov_regvals init_518[] = {
Hans de Goede49809d62009-06-07 12:10:39 -03002892 { R51x_SYS_RESET, 0x40 },
2893 { R51x_SYS_INIT, 0xe1 },
2894 { R51x_SYS_RESET, 0x3e },
2895 { R51x_SYS_INIT, 0xe1 },
2896 { R51x_SYS_RESET, 0x00 },
2897 { R51x_SYS_INIT, 0xe1 },
2898 { 0x46, 0x00 },
2899 { 0x5d, 0x03 },
2900 };
2901
Hans de Goedee080fcd2009-06-18 05:03:16 -03002902 const struct ov_regvals norm_518[] = {
Hans de Goede49809d62009-06-07 12:10:39 -03002903 { R51x_SYS_SNAP, 0x02 }, /* Reset */
2904 { R51x_SYS_SNAP, 0x01 }, /* Enable */
2905 { 0x31, 0x0f },
2906 { 0x5d, 0x03 },
2907 { 0x24, 0x9f },
2908 { 0x25, 0x90 },
2909 { 0x20, 0x00 },
2910 { 0x51, 0x04 },
2911 { 0x71, 0x19 },
2912 { 0x2f, 0x80 },
2913 };
2914
Hans de Goedee080fcd2009-06-18 05:03:16 -03002915 const struct ov_regvals norm_518_p[] = {
Hans de Goede49809d62009-06-07 12:10:39 -03002916 { R51x_SYS_SNAP, 0x02 }, /* Reset */
2917 { R51x_SYS_SNAP, 0x01 }, /* Enable */
2918 { 0x31, 0x0f },
2919 { 0x5d, 0x03 },
2920 { 0x24, 0x9f },
2921 { 0x25, 0x90 },
2922 { 0x20, 0x60 },
2923 { 0x51, 0x02 },
2924 { 0x71, 0x19 },
2925 { 0x40, 0xff },
2926 { 0x41, 0x42 },
2927 { 0x46, 0x00 },
2928 { 0x33, 0x04 },
2929 { 0x21, 0x19 },
2930 { 0x3f, 0x10 },
2931 { 0x2f, 0x80 },
2932 };
2933
2934 /* First 5 bits of custom ID reg are a revision ID on OV518 */
2935 PDEBUG(D_PROBE, "Device revision %d",
2936 0x1F & reg_r(sd, R51x_SYS_CUST_ID));
2937
2938 rc = write_regvals(sd, init_518, ARRAY_SIZE(init_518));
2939 if (rc < 0)
2940 return rc;
2941
2942 /* Set LED GPIO pin to output mode */
2943 rc = reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02);
2944 if (rc < 0)
2945 return rc;
2946
2947 switch (sd->bridge) {
2948 case BRIDGE_OV518:
2949 rc = write_regvals(sd, norm_518, ARRAY_SIZE(norm_518));
2950 if (rc < 0)
2951 return rc;
2952 break;
2953 case BRIDGE_OV518PLUS:
2954 rc = write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p));
2955 if (rc < 0)
2956 return rc;
2957 break;
2958 }
2959
Hans de Goede1876bb92009-06-14 06:45:50 -03002960 rc = ov51x_upload_quan_tables(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03002961 if (rc < 0) {
2962 PDEBUG(D_ERR, "Error uploading quantization tables");
2963 return rc;
2964 }
2965
2966 rc = reg_w(sd, 0x2f, 0x80);
2967 if (rc < 0)
2968 return rc;
2969
2970 return 0;
2971}
2972
2973static int ov519_configure(struct sd *sd)
2974{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002975 static const struct ov_regvals init_519[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002976 { 0x5a, 0x6d }, /* EnableSystem */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002977 { 0x53, 0x9b },
2978 { 0x54, 0xff }, /* set bit2 to enable jpeg */
2979 { 0x5d, 0x03 },
2980 { 0x49, 0x01 },
2981 { 0x48, 0x00 },
2982 /* Set LED pin to output mode. Bit 4 must be cleared or sensor
2983 * detection will fail. This deserves further investigation. */
2984 { OV519_GPIO_IO_CTRL0, 0xee },
2985 { 0x51, 0x0f }, /* SetUsbInit */
2986 { 0x51, 0x00 },
2987 { 0x22, 0x00 },
2988 /* windows reads 0x55 at this point*/
2989 };
2990
Hans de Goede49809d62009-06-07 12:10:39 -03002991 return write_regvals(sd, init_519, ARRAY_SIZE(init_519));
2992}
2993
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002994static int ovfx2_configure(struct sd *sd)
2995{
2996 static const struct ov_regvals init_fx2[] = {
2997 { 0x00, 0x60 },
2998 { 0x02, 0x01 },
2999 { 0x0f, 0x1d },
3000 { 0xe9, 0x82 },
3001 { 0xea, 0xc7 },
3002 { 0xeb, 0x10 },
3003 { 0xec, 0xf6 },
3004 };
3005
3006 sd->stopped = 1;
3007
3008 return write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
3009}
3010
Hans de Goede49809d62009-06-07 12:10:39 -03003011/* this function is called at probe time */
3012static int sd_config(struct gspca_dev *gspca_dev,
3013 const struct usb_device_id *id)
3014{
3015 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003016 struct cam *cam = &gspca_dev->cam;
Hans de Goede49809d62009-06-07 12:10:39 -03003017 int ret = 0;
3018
Hans de Goede9e4d8252009-06-14 06:25:06 -03003019 sd->bridge = id->driver_info & BRIDGE_MASK;
3020 sd->invert_led = id->driver_info & BRIDGE_INVERT_LED;
Hans de Goede49809d62009-06-07 12:10:39 -03003021
3022 switch (sd->bridge) {
Hans de Goede1876bb92009-06-14 06:45:50 -03003023 case BRIDGE_OV511:
3024 case BRIDGE_OV511PLUS:
3025 ret = ov511_configure(gspca_dev);
3026 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003027 case BRIDGE_OV518:
3028 case BRIDGE_OV518PLUS:
3029 ret = ov518_configure(gspca_dev);
3030 break;
3031 case BRIDGE_OV519:
3032 ret = ov519_configure(sd);
3033 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003034 case BRIDGE_OVFX2:
3035 ret = ovfx2_configure(sd);
3036 cam->bulk_size = OVFX2_BULK_SIZE;
3037 cam->bulk_nurbs = MAX_NURBS;
3038 cam->bulk = 1;
3039 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03003040 case BRIDGE_W9968CF:
3041 ret = w9968cf_configure(sd);
3042 cam->reverse_alts = 1;
3043 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003044 }
3045
3046 if (ret)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003047 goto error;
Hans de Goede49809d62009-06-07 12:10:39 -03003048
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003049 ov51x_led_control(sd, 0); /* turn LED off */
3050
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003051 /* The OV519 must be more aggressive about sensor detection since
3052 * I2C write will never fail if the sensor is not present. We have
3053 * to try to initialize the sensor to detect its presence */
Hans de Goede229bb7d2009-10-11 07:41:46 -03003054
3055 /* Test for 76xx */
3056 if (init_ov_sensor(sd, OV7xx0_SID) >= 0) {
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003057 if (ov7xx0_configure(sd) < 0) {
3058 PDEBUG(D_ERR, "Failed to configure OV7xx0");
3059 goto error;
3060 }
Hans de Goede229bb7d2009-10-11 07:41:46 -03003061 /* Test for 6xx0 */
3062 } else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) {
3063 if (ov6xx0_configure(sd) < 0) {
3064 PDEBUG(D_ERR, "Failed to configure OV6xx0");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003065 goto error;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003066 }
Hans de Goede229bb7d2009-10-11 07:41:46 -03003067 /* Test for 8xx0 */
3068 } else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) {
3069 if (ov8xx0_configure(sd) < 0) {
3070 PDEBUG(D_ERR, "Failed to configure OV8xx0");
3071 goto error;
3072 }
Hans de Goede635118d2009-10-11 09:49:03 -03003073 /* Test for 3xxx / 2xxx */
3074 } else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) {
3075 if (ov_hires_configure(sd) < 0) {
3076 PDEBUG(D_ERR, "Failed to configure high res OV");
3077 goto error;
3078 }
Hans de Goede229bb7d2009-10-11 07:41:46 -03003079 } else {
3080 PDEBUG(D_ERR, "Can't determine sensor slave IDs");
3081 goto error;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003082 }
3083
Hans de Goede49809d62009-06-07 12:10:39 -03003084 switch (sd->bridge) {
Hans de Goede1876bb92009-06-14 06:45:50 -03003085 case BRIDGE_OV511:
3086 case BRIDGE_OV511PLUS:
3087 if (!sd->sif) {
3088 cam->cam_mode = ov511_vga_mode;
3089 cam->nmodes = ARRAY_SIZE(ov511_vga_mode);
3090 } else {
3091 cam->cam_mode = ov511_sif_mode;
3092 cam->nmodes = ARRAY_SIZE(ov511_sif_mode);
3093 }
3094 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003095 case BRIDGE_OV518:
3096 case BRIDGE_OV518PLUS:
3097 if (!sd->sif) {
3098 cam->cam_mode = ov518_vga_mode;
3099 cam->nmodes = ARRAY_SIZE(ov518_vga_mode);
3100 } else {
3101 cam->cam_mode = ov518_sif_mode;
3102 cam->nmodes = ARRAY_SIZE(ov518_sif_mode);
3103 }
3104 break;
3105 case BRIDGE_OV519:
3106 if (!sd->sif) {
3107 cam->cam_mode = ov519_vga_mode;
3108 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
3109 } else {
3110 cam->cam_mode = ov519_sif_mode;
3111 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3112 }
3113 break;
Hans de Goede635118d2009-10-11 09:49:03 -03003114 case BRIDGE_OVFX2:
3115 if (sd->sensor == SEN_OV2610) {
3116 cam->cam_mode = ovfx2_ov2610_mode;
3117 cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode);
3118 } else if (sd->sensor == SEN_OV3610) {
3119 cam->cam_mode = ovfx2_ov3610_mode;
3120 cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode);
3121 } else if (!sd->sif) {
3122 cam->cam_mode = ov519_vga_mode;
3123 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
3124 } else {
3125 cam->cam_mode = ov519_sif_mode;
3126 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3127 }
3128 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03003129 case BRIDGE_W9968CF:
3130 cam->cam_mode = w9968cf_vga_mode;
3131 cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
Hans de Goede79b35902009-10-19 06:08:01 -03003132 if (sd->sif)
3133 cam->nmodes--;
Hans de Goedea511ba92009-10-16 07:13:07 -03003134
3135 /* w9968cf needs initialisation once the sensor is known */
3136 if (w9968cf_init(sd) < 0)
3137 goto error;
3138 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003139 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003140 sd->brightness = BRIGHTNESS_DEF;
Hans de Goedef5cee952009-06-14 06:32:52 -03003141 if (sd->sensor == SEN_OV6630 || sd->sensor == SEN_OV66308AF)
3142 sd->contrast = 200; /* The default is too low for the ov6630 */
3143 else
3144 sd->contrast = CONTRAST_DEF;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003145 sd->colors = COLOR_DEF;
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003146 sd->hflip = HFLIP_DEF;
3147 sd->vflip = VFLIP_DEF;
Hans de Goede02ab18b2009-06-14 04:32:04 -03003148 sd->autobrightness = AUTOBRIGHT_DEF;
3149 if (sd->sensor == SEN_OV7670) {
3150 sd->freq = OV7670_FREQ_DEF;
3151 gspca_dev->ctrl_dis = 1 << FREQ_IDX;
3152 } else {
3153 sd->freq = FREQ_DEF;
3154 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) |
3155 (1 << OV7670_FREQ_IDX);
3156 }
Hans de Goede79b35902009-10-19 06:08:01 -03003157 sd->quality = QUALITY_DEF;
Hans de Goede035d3a32010-01-09 08:14:43 -03003158 if (sd->sensor == SEN_OV7640 ||
Hans de Goeded02134d2010-01-09 19:22:34 -03003159 sd->sensor == SEN_OV7648)
3160 gspca_dev->ctrl_dis |= (1 << AUTOBRIGHT_IDX) |
3161 (1 << CONTRAST_IDX);
3162 if (sd->sensor == SEN_OV7670)
Hans de Goede02ab18b2009-06-14 04:32:04 -03003163 gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX;
3164 /* OV8610 Frequency filter control should work but needs testing */
3165 if (sd->sensor == SEN_OV8610)
3166 gspca_dev->ctrl_dis |= 1 << FREQ_IDX;
Hans de Goede635118d2009-10-11 09:49:03 -03003167 /* No controls for the OV2610/OV3610 */
3168 if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
3169 gspca_dev->ctrl_dis |= 0xFF;
Hans de Goede02ab18b2009-06-14 04:32:04 -03003170
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003171 return 0;
3172error:
3173 PDEBUG(D_ERR, "OV519 Config failed");
3174 return -EBUSY;
3175}
3176
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03003177/* this function is called at probe and resume time */
3178static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003179{
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003180 struct sd *sd = (struct sd *) gspca_dev;
3181
3182 /* initialize the sensor */
3183 switch (sd->sensor) {
Hans de Goede635118d2009-10-11 09:49:03 -03003184 case SEN_OV2610:
3185 if (write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610)))
3186 return -EIO;
3187 /* Enable autogain, autoexpo, awb, bandfilter */
3188 if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
3189 return -EIO;
3190 break;
3191 case SEN_OV3610:
3192 if (write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b)))
3193 return -EIO;
3194 /* Enable autogain, autoexpo, awb, bandfilter */
3195 if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
3196 return -EIO;
3197 break;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003198 case SEN_OV6620:
3199 if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)))
3200 return -EIO;
3201 break;
3202 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03003203 case SEN_OV66308AF:
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003204 if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)))
3205 return -EIO;
3206 break;
3207 default:
3208/* case SEN_OV7610: */
3209/* case SEN_OV76BE: */
3210 if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610)))
3211 return -EIO;
Hans de Goedeae49c402009-06-14 19:15:07 -03003212 if (i2c_w_mask(sd, 0x0e, 0x00, 0x40))
3213 return -EIO;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003214 break;
3215 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03003216 case SEN_OV7620AE:
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003217 if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)))
3218 return -EIO;
3219 break;
3220 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003221 case SEN_OV7648:
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003222 if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)))
3223 return -EIO;
3224 break;
3225 case SEN_OV7670:
3226 if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)))
3227 return -EIO;
3228 break;
3229 case SEN_OV8610:
3230 if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610)))
3231 return -EIO;
3232 break;
3233 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003234 return 0;
3235}
3236
Hans de Goede1876bb92009-06-14 06:45:50 -03003237/* Set up the OV511/OV511+ with the given image parameters.
3238 *
3239 * Do not put any sensor-specific code in here (including I2C I/O functions)
3240 */
3241static int ov511_mode_init_regs(struct sd *sd)
3242{
3243 int hsegs, vsegs, packet_size, fps, needed;
3244 int interlaced = 0;
3245 struct usb_host_interface *alt;
3246 struct usb_interface *intf;
3247
3248 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
3249 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
3250 if (!alt) {
3251 PDEBUG(D_ERR, "Couldn't get altsetting");
3252 return -EIO;
3253 }
3254
3255 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
3256 reg_w(sd, R51x_FIFO_PSIZE, packet_size >> 5);
3257
3258 reg_w(sd, R511_CAM_UV_EN, 0x01);
3259 reg_w(sd, R511_SNAP_UV_EN, 0x01);
3260 reg_w(sd, R511_SNAP_OPTS, 0x03);
3261
3262 /* Here I'm assuming that snapshot size == image size.
3263 * I hope that's always true. --claudio
3264 */
3265 hsegs = (sd->gspca_dev.width >> 3) - 1;
3266 vsegs = (sd->gspca_dev.height >> 3) - 1;
3267
3268 reg_w(sd, R511_CAM_PXCNT, hsegs);
3269 reg_w(sd, R511_CAM_LNCNT, vsegs);
3270 reg_w(sd, R511_CAM_PXDIV, 0x00);
3271 reg_w(sd, R511_CAM_LNDIV, 0x00);
3272
3273 /* YUV420, low pass filter on */
3274 reg_w(sd, R511_CAM_OPTS, 0x03);
3275
3276 /* Snapshot additions */
3277 reg_w(sd, R511_SNAP_PXCNT, hsegs);
3278 reg_w(sd, R511_SNAP_LNCNT, vsegs);
3279 reg_w(sd, R511_SNAP_PXDIV, 0x00);
3280 reg_w(sd, R511_SNAP_LNDIV, 0x00);
3281
3282 /******** Set the framerate ********/
3283 if (frame_rate > 0)
3284 sd->frame_rate = frame_rate;
3285
3286 switch (sd->sensor) {
3287 case SEN_OV6620:
3288 /* No framerate control, doesn't like higher rates yet */
3289 sd->clockdiv = 3;
3290 break;
3291
3292 /* Note once the FIXME's in mode_init_ov_sensor_regs() are fixed
3293 for more sensors we need to do this for them too */
3294 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03003295 case SEN_OV7620AE:
Hans de Goede1876bb92009-06-14 06:45:50 -03003296 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003297 case SEN_OV7648:
Hans de Goedeb282d872009-06-14 19:10:40 -03003298 case SEN_OV76BE:
Hans de Goede1876bb92009-06-14 06:45:50 -03003299 if (sd->gspca_dev.width == 320)
3300 interlaced = 1;
3301 /* Fall through */
3302 case SEN_OV6630:
Hans de Goede1876bb92009-06-14 06:45:50 -03003303 case SEN_OV7610:
3304 case SEN_OV7670:
3305 switch (sd->frame_rate) {
3306 case 30:
3307 case 25:
3308 /* Not enough bandwidth to do 640x480 @ 30 fps */
3309 if (sd->gspca_dev.width != 640) {
3310 sd->clockdiv = 0;
3311 break;
3312 }
3313 /* Fall through for 640x480 case */
3314 default:
3315/* case 20: */
3316/* case 15: */
3317 sd->clockdiv = 1;
3318 break;
3319 case 10:
3320 sd->clockdiv = 2;
3321 break;
3322 case 5:
3323 sd->clockdiv = 5;
3324 break;
3325 }
3326 if (interlaced) {
3327 sd->clockdiv = (sd->clockdiv + 1) * 2 - 1;
3328 /* Higher then 10 does not work */
3329 if (sd->clockdiv > 10)
3330 sd->clockdiv = 10;
3331 }
3332 break;
3333
3334 case SEN_OV8610:
3335 /* No framerate control ?? */
3336 sd->clockdiv = 0;
3337 break;
3338 }
3339
3340 /* Check if we have enough bandwidth to disable compression */
3341 fps = (interlaced ? 60 : 30) / (sd->clockdiv + 1) + 1;
3342 needed = fps * sd->gspca_dev.width * sd->gspca_dev.height * 3 / 2;
3343 /* 1400 is a conservative estimate of the max nr of isoc packets/sec */
3344 if (needed > 1400 * packet_size) {
3345 /* Enable Y and UV quantization and compression */
3346 reg_w(sd, R511_COMP_EN, 0x07);
3347 reg_w(sd, R511_COMP_LUT_EN, 0x03);
3348 } else {
3349 reg_w(sd, R511_COMP_EN, 0x06);
3350 reg_w(sd, R511_COMP_LUT_EN, 0x00);
3351 }
3352
3353 reg_w(sd, R51x_SYS_RESET, OV511_RESET_OMNICE);
3354 reg_w(sd, R51x_SYS_RESET, 0);
3355
3356 return 0;
3357}
3358
Hans de Goede49809d62009-06-07 12:10:39 -03003359/* Sets up the OV518/OV518+ with the given image parameters
3360 *
3361 * OV518 needs a completely different approach, until we can figure out what
3362 * the individual registers do. Also, only 15 FPS is supported now.
3363 *
3364 * Do not put any sensor-specific code in here (including I2C I/O functions)
3365 */
3366static int ov518_mode_init_regs(struct sd *sd)
3367{
Hans de Goedeb282d872009-06-14 19:10:40 -03003368 int hsegs, vsegs, packet_size;
3369 struct usb_host_interface *alt;
3370 struct usb_interface *intf;
3371
3372 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
3373 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
3374 if (!alt) {
3375 PDEBUG(D_ERR, "Couldn't get altsetting");
3376 return -EIO;
3377 }
3378
3379 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
3380 ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2);
Hans de Goede49809d62009-06-07 12:10:39 -03003381
3382 /******** Set the mode ********/
3383
3384 reg_w(sd, 0x2b, 0);
3385 reg_w(sd, 0x2c, 0);
3386 reg_w(sd, 0x2d, 0);
3387 reg_w(sd, 0x2e, 0);
3388 reg_w(sd, 0x3b, 0);
3389 reg_w(sd, 0x3c, 0);
3390 reg_w(sd, 0x3d, 0);
3391 reg_w(sd, 0x3e, 0);
3392
3393 if (sd->bridge == BRIDGE_OV518) {
3394 /* Set 8-bit (YVYU) input format */
3395 reg_w_mask(sd, 0x20, 0x08, 0x08);
3396
3397 /* Set 12-bit (4:2:0) output format */
3398 reg_w_mask(sd, 0x28, 0x80, 0xf0);
3399 reg_w_mask(sd, 0x38, 0x80, 0xf0);
3400 } else {
3401 reg_w(sd, 0x28, 0x80);
3402 reg_w(sd, 0x38, 0x80);
3403 }
3404
3405 hsegs = sd->gspca_dev.width / 16;
3406 vsegs = sd->gspca_dev.height / 4;
3407
3408 reg_w(sd, 0x29, hsegs);
3409 reg_w(sd, 0x2a, vsegs);
3410
3411 reg_w(sd, 0x39, hsegs);
3412 reg_w(sd, 0x3a, vsegs);
3413
3414 /* Windows driver does this here; who knows why */
3415 reg_w(sd, 0x2f, 0x80);
3416
Hans de Goedeb282d872009-06-14 19:10:40 -03003417 /******** Set the framerate ********/
3418 sd->clockdiv = 1;
Hans de Goede49809d62009-06-07 12:10:39 -03003419
3420 /* Mode independent, but framerate dependent, regs */
Hans de Goedeb282d872009-06-14 19:10:40 -03003421 /* 0x51: Clock divider; Only works on some cams which use 2 crystals */
3422 reg_w(sd, 0x51, 0x04);
Hans de Goede49809d62009-06-07 12:10:39 -03003423 reg_w(sd, 0x22, 0x18);
3424 reg_w(sd, 0x23, 0xff);
3425
Hans de Goedeb282d872009-06-14 19:10:40 -03003426 if (sd->bridge == BRIDGE_OV518PLUS) {
3427 switch (sd->sensor) {
Hans de Goede859cc472010-01-07 15:42:35 -03003428 case SEN_OV7620AE:
Hans de Goedeb282d872009-06-14 19:10:40 -03003429 if (sd->gspca_dev.width == 320) {
3430 reg_w(sd, 0x20, 0x00);
3431 reg_w(sd, 0x21, 0x19);
3432 } else {
3433 reg_w(sd, 0x20, 0x60);
3434 reg_w(sd, 0x21, 0x1f);
3435 }
3436 break;
Hans de Goede859cc472010-01-07 15:42:35 -03003437 case SEN_OV7620:
3438 reg_w(sd, 0x20, 0x00);
3439 reg_w(sd, 0x21, 0x19);
3440 break;
Hans de Goedeb282d872009-06-14 19:10:40 -03003441 default:
3442 reg_w(sd, 0x21, 0x19);
3443 }
3444 } else
Hans de Goede49809d62009-06-07 12:10:39 -03003445 reg_w(sd, 0x71, 0x17); /* Compression-related? */
3446
3447 /* FIXME: Sensor-specific */
3448 /* Bit 5 is what matters here. Of course, it is "reserved" */
3449 i2c_w(sd, 0x54, 0x23);
3450
3451 reg_w(sd, 0x2f, 0x80);
3452
3453 if (sd->bridge == BRIDGE_OV518PLUS) {
3454 reg_w(sd, 0x24, 0x94);
3455 reg_w(sd, 0x25, 0x90);
3456 ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */
3457 ov518_reg_w32(sd, 0xc6, 540, 2); /* 21ch */
3458 ov518_reg_w32(sd, 0xc7, 540, 2); /* 21ch */
3459 ov518_reg_w32(sd, 0xc8, 108, 2); /* 6ch */
3460 ov518_reg_w32(sd, 0xca, 131098, 3); /* 2001ah */
3461 ov518_reg_w32(sd, 0xcb, 532, 2); /* 214h */
3462 ov518_reg_w32(sd, 0xcc, 2400, 2); /* 960h */
3463 ov518_reg_w32(sd, 0xcd, 32, 2); /* 20h */
3464 ov518_reg_w32(sd, 0xce, 608, 2); /* 260h */
3465 } else {
3466 reg_w(sd, 0x24, 0x9f);
3467 reg_w(sd, 0x25, 0x90);
3468 ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */
3469 ov518_reg_w32(sd, 0xc6, 381, 2); /* 17dh */
3470 ov518_reg_w32(sd, 0xc7, 381, 2); /* 17dh */
3471 ov518_reg_w32(sd, 0xc8, 128, 2); /* 80h */
3472 ov518_reg_w32(sd, 0xca, 183331, 3); /* 2cc23h */
3473 ov518_reg_w32(sd, 0xcb, 746, 2); /* 2eah */
3474 ov518_reg_w32(sd, 0xcc, 1750, 2); /* 6d6h */
3475 ov518_reg_w32(sd, 0xcd, 45, 2); /* 2dh */
3476 ov518_reg_w32(sd, 0xce, 851, 2); /* 353h */
3477 }
3478
3479 reg_w(sd, 0x2f, 0x80);
3480
3481 return 0;
3482}
3483
3484
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003485/* Sets up the OV519 with the given image parameters
3486 *
3487 * OV519 needs a completely different approach, until we can figure out what
3488 * the individual registers do.
3489 *
3490 * Do not put any sensor-specific code in here (including I2C I/O functions)
3491 */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003492static int ov519_mode_init_regs(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003493{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003494 static const struct ov_regvals mode_init_519_ov7670[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003495 { 0x5d, 0x03 }, /* Turn off suspend mode */
3496 { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
3497 { 0x54, 0x0f }, /* bit2 (jpeg enable) */
3498 { 0xa2, 0x20 }, /* a2-a5 are undocumented */
3499 { 0xa3, 0x18 },
3500 { 0xa4, 0x04 },
3501 { 0xa5, 0x28 },
3502 { 0x37, 0x00 }, /* SetUsbInit */
3503 { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
3504 /* Enable both fields, YUV Input, disable defect comp (why?) */
3505 { 0x20, 0x0c },
3506 { 0x21, 0x38 },
3507 { 0x22, 0x1d },
3508 { 0x17, 0x50 }, /* undocumented */
3509 { 0x37, 0x00 }, /* undocumented */
3510 { 0x40, 0xff }, /* I2C timeout counter */
3511 { 0x46, 0x00 }, /* I2C clock prescaler */
3512 { 0x59, 0x04 }, /* new from windrv 090403 */
3513 { 0xff, 0x00 }, /* undocumented */
3514 /* windows reads 0x55 at this point, why? */
3515 };
3516
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003517 static const struct ov_regvals mode_init_519[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003518 { 0x5d, 0x03 }, /* Turn off suspend mode */
3519 { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
3520 { 0x54, 0x0f }, /* bit2 (jpeg enable) */
3521 { 0xa2, 0x20 }, /* a2-a5 are undocumented */
3522 { 0xa3, 0x18 },
3523 { 0xa4, 0x04 },
3524 { 0xa5, 0x28 },
3525 { 0x37, 0x00 }, /* SetUsbInit */
3526 { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
3527 /* Enable both fields, YUV Input, disable defect comp (why?) */
3528 { 0x22, 0x1d },
3529 { 0x17, 0x50 }, /* undocumented */
3530 { 0x37, 0x00 }, /* undocumented */
3531 { 0x40, 0xff }, /* I2C timeout counter */
3532 { 0x46, 0x00 }, /* I2C clock prescaler */
3533 { 0x59, 0x04 }, /* new from windrv 090403 */
3534 { 0xff, 0x00 }, /* undocumented */
3535 /* windows reads 0x55 at this point, why? */
3536 };
3537
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003538 /******** Set the mode ********/
3539 if (sd->sensor != SEN_OV7670) {
3540 if (write_regvals(sd, mode_init_519,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003541 ARRAY_SIZE(mode_init_519)))
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003542 return -EIO;
Hans de Goede035d3a32010-01-09 08:14:43 -03003543 if (sd->sensor == SEN_OV7640 ||
3544 sd->sensor == SEN_OV7648) {
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003545 /* Select 8-bit input mode */
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003546 reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10);
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003547 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003548 } else {
3549 if (write_regvals(sd, mode_init_519_ov7670,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003550 ARRAY_SIZE(mode_init_519_ov7670)))
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003551 return -EIO;
3552 }
3553
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003554 reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4);
3555 reg_w(sd, OV519_R11_V_SIZE, sd->gspca_dev.height >> 3);
Hans de Goede80142ef2009-06-14 06:26:49 -03003556 if (sd->sensor == SEN_OV7670 &&
3557 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
3558 reg_w(sd, OV519_R12_X_OFFSETL, 0x04);
Hans de Goede035d3a32010-01-09 08:14:43 -03003559 else if (sd->sensor == SEN_OV7648 &&
3560 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
3561 reg_w(sd, OV519_R12_X_OFFSETL, 0x01);
Hans de Goede80142ef2009-06-14 06:26:49 -03003562 else
3563 reg_w(sd, OV519_R12_X_OFFSETL, 0x00);
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003564 reg_w(sd, OV519_R13_X_OFFSETH, 0x00);
3565 reg_w(sd, OV519_R14_Y_OFFSETL, 0x00);
3566 reg_w(sd, OV519_R15_Y_OFFSETH, 0x00);
3567 reg_w(sd, OV519_R16_DIVIDER, 0x00);
3568 reg_w(sd, OV519_R25_FORMAT, 0x03); /* YUV422 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003569 reg_w(sd, 0x26, 0x00); /* Undocumented */
3570
3571 /******** Set the framerate ********/
3572 if (frame_rate > 0)
3573 sd->frame_rate = frame_rate;
3574
3575/* FIXME: These are only valid at the max resolution. */
3576 sd->clockdiv = 0;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003577 switch (sd->sensor) {
3578 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003579 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003580 switch (sd->frame_rate) {
Jean-Francois Moine53e74512008-11-08 06:10:19 -03003581 default:
3582/* case 30: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003583 reg_w(sd, 0xa4, 0x0c);
3584 reg_w(sd, 0x23, 0xff);
3585 break;
3586 case 25:
3587 reg_w(sd, 0xa4, 0x0c);
3588 reg_w(sd, 0x23, 0x1f);
3589 break;
3590 case 20:
3591 reg_w(sd, 0xa4, 0x0c);
3592 reg_w(sd, 0x23, 0x1b);
3593 break;
Jean-Francois Moine53e74512008-11-08 06:10:19 -03003594 case 15:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003595 reg_w(sd, 0xa4, 0x04);
3596 reg_w(sd, 0x23, 0xff);
3597 sd->clockdiv = 1;
3598 break;
3599 case 10:
3600 reg_w(sd, 0xa4, 0x04);
3601 reg_w(sd, 0x23, 0x1f);
3602 sd->clockdiv = 1;
3603 break;
3604 case 5:
3605 reg_w(sd, 0xa4, 0x04);
3606 reg_w(sd, 0x23, 0x1b);
3607 sd->clockdiv = 1;
3608 break;
3609 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003610 break;
3611 case SEN_OV8610:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003612 switch (sd->frame_rate) {
3613 default: /* 15 fps */
3614/* case 15: */
3615 reg_w(sd, 0xa4, 0x06);
3616 reg_w(sd, 0x23, 0xff);
3617 break;
3618 case 10:
3619 reg_w(sd, 0xa4, 0x06);
3620 reg_w(sd, 0x23, 0x1f);
3621 break;
3622 case 5:
3623 reg_w(sd, 0xa4, 0x06);
3624 reg_w(sd, 0x23, 0x1b);
3625 break;
3626 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003627 break;
3628 case SEN_OV7670: /* guesses, based on 7640 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003629 PDEBUG(D_STREAM, "Setting framerate to %d fps",
3630 (sd->frame_rate == 0) ? 15 : sd->frame_rate);
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003631 reg_w(sd, 0xa4, 0x10);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003632 switch (sd->frame_rate) {
3633 case 30:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003634 reg_w(sd, 0x23, 0xff);
3635 break;
3636 case 20:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003637 reg_w(sd, 0x23, 0x1b);
3638 break;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003639 default:
3640/* case 15: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003641 reg_w(sd, 0x23, 0xff);
3642 sd->clockdiv = 1;
3643 break;
3644 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003645 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003646 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003647 return 0;
3648}
3649
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003650static int mode_init_ov_sensor_regs(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003651{
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003652 struct gspca_dev *gspca_dev;
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003653 int qvga, xstart, xend, ystart, yend;
3654 __u8 v;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003655
3656 gspca_dev = &sd->gspca_dev;
Hans de Goede124cc9c2009-06-14 05:48:00 -03003657 qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003658
3659 /******** Mode (VGA/QVGA) and sensor specific regs ********/
3660 switch (sd->sensor) {
Hans de Goede635118d2009-10-11 09:49:03 -03003661 case SEN_OV2610:
3662 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3663 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
3664 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
3665 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
3666 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
3667 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
3668 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
3669 return 0;
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003670 case SEN_OV3610:
Hans de Goede635118d2009-10-11 09:49:03 -03003671 if (qvga) {
3672 xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003673 ystart = (776 - gspca_dev->height) / 2;
Hans de Goede635118d2009-10-11 09:49:03 -03003674 } else {
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003675 xstart = (2076 - gspca_dev->width) / 2 + (0x10 << 4);
Hans de Goede635118d2009-10-11 09:49:03 -03003676 ystart = (1544 - gspca_dev->height) / 2;
3677 }
3678 xend = xstart + gspca_dev->width;
3679 yend = ystart + gspca_dev->height;
3680 /* Writing to the COMH register resets the other windowing regs
3681 to their default values, so we must do this first. */
3682 i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0xf0);
3683 i2c_w_mask(sd, 0x32,
3684 (((xend >> 1) & 7) << 3) | ((xstart >> 1) & 7),
3685 0x3f);
3686 i2c_w_mask(sd, 0x03,
3687 (((yend >> 1) & 3) << 2) | ((ystart >> 1) & 3),
3688 0x0f);
3689 i2c_w(sd, 0x17, xstart >> 4);
3690 i2c_w(sd, 0x18, xend >> 4);
3691 i2c_w(sd, 0x19, ystart >> 3);
3692 i2c_w(sd, 0x1a, yend >> 3);
3693 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003694 case SEN_OV8610:
3695 /* For OV8610 qvga means qsvga */
3696 i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003697 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3698 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3699 i2c_w_mask(sd, 0x2d, 0x00, 0x40); /* from windrv 090403 */
3700 i2c_w_mask(sd, 0x28, 0x20, 0x20); /* progressive mode on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003701 break;
3702 case SEN_OV7610:
3703 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003704 i2c_w(sd, 0x35, qvga?0x1e:0x9e);
3705 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3706 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003707 break;
3708 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03003709 case SEN_OV7620AE:
Hans de Goedeb282d872009-06-14 19:10:40 -03003710 case SEN_OV76BE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003711 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3712 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
3713 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
3714 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
3715 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
Hans de Goedeb282d872009-06-14 19:10:40 -03003716 i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003717 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003718 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3719 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3720 if (sd->sensor == SEN_OV76BE)
3721 i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003722 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003723 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003724 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003725 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3726 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
Hans de Goede8d0082f2010-01-09 19:45:44 -03003727 /* Setting this undocumented bit in qvga mode removes a very
3728 annoying vertical shaking of the image */
Hans de Goede035d3a32010-01-09 08:14:43 -03003729 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
Hans de Goede8d0082f2010-01-09 19:45:44 -03003730 /* Unknown */
Hans de Goede035d3a32010-01-09 08:14:43 -03003731 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
Hans de Goede8d0082f2010-01-09 19:45:44 -03003732 /* Allow higher automatic gain (to allow higher framerates) */
Hans de Goede035d3a32010-01-09 08:14:43 -03003733 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003734 i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003735 break;
3736 case SEN_OV7670:
3737 /* set COM7_FMT_VGA or COM7_FMT_QVGA
3738 * do we need to set anything else?
3739 * HSTART etc are set in set_ov_sensor_window itself */
3740 i2c_w_mask(sd, OV7670_REG_COM7,
3741 qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA,
3742 OV7670_COM7_FMT_MASK);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003743 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3744 i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB,
3745 OV7670_COM8_AWB);
3746 if (qvga) { /* QVGA from ov7670.c by
3747 * Jonathan Corbet */
3748 xstart = 164;
3749 xend = 28;
3750 ystart = 14;
3751 yend = 494;
3752 } else { /* VGA */
3753 xstart = 158;
3754 xend = 14;
3755 ystart = 10;
3756 yend = 490;
3757 }
3758 /* OV7670 hardware window registers are split across
3759 * multiple locations */
3760 i2c_w(sd, OV7670_REG_HSTART, xstart >> 3);
3761 i2c_w(sd, OV7670_REG_HSTOP, xend >> 3);
3762 v = i2c_r(sd, OV7670_REG_HREF);
3763 v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07);
3764 msleep(10); /* need to sleep between read and write to
3765 * same reg! */
3766 i2c_w(sd, OV7670_REG_HREF, v);
3767
3768 i2c_w(sd, OV7670_REG_VSTART, ystart >> 2);
3769 i2c_w(sd, OV7670_REG_VSTOP, yend >> 2);
3770 v = i2c_r(sd, OV7670_REG_VREF);
3771 v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03);
3772 msleep(10); /* need to sleep between read and write to
3773 * same reg! */
3774 i2c_w(sd, OV7670_REG_VREF, v);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003775 break;
3776 case SEN_OV6620:
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003777 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3778 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3779 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3780 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003781 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03003782 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003783 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003784 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003785 break;
3786 default:
3787 return -EINVAL;
3788 }
3789
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003790 /******** Clock programming ********/
Hans de Goedeae49c402009-06-14 19:15:07 -03003791 i2c_w(sd, 0x11, sd->clockdiv);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003792
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003793 return 0;
3794}
3795
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003796static void sethvflip(struct sd *sd)
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003797{
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003798 if (sd->sensor != SEN_OV7670)
3799 return;
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003800 if (sd->gspca_dev.streaming)
3801 ov51x_stop(sd);
3802 i2c_w_mask(sd, OV7670_REG_MVFP,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003803 OV7670_MVFP_MIRROR * sd->hflip
3804 | OV7670_MVFP_VFLIP * sd->vflip,
3805 OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP);
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003806 if (sd->gspca_dev.streaming)
3807 ov51x_restart(sd);
3808}
3809
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003810static int set_ov_sensor_window(struct sd *sd)
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003811{
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003812 struct gspca_dev *gspca_dev;
Hans de Goede124cc9c2009-06-14 05:48:00 -03003813 int qvga, crop;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003814 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003815 int ret;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003816
Hans de Goede635118d2009-10-11 09:49:03 -03003817 /* mode setup is fully handled in mode_init_ov_sensor_regs for these */
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003818 if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610 ||
3819 sd->sensor == SEN_OV7670)
Hans de Goede635118d2009-10-11 09:49:03 -03003820 return mode_init_ov_sensor_regs(sd);
3821
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003822 gspca_dev = &sd->gspca_dev;
Hans de Goede124cc9c2009-06-14 05:48:00 -03003823 qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
3824 crop = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 2;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003825
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003826 /* The different sensor ICs handle setting up of window differently.
3827 * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */
3828 switch (sd->sensor) {
3829 case SEN_OV8610:
3830 hwsbase = 0x1e;
3831 hwebase = 0x1e;
3832 vwsbase = 0x02;
3833 vwebase = 0x02;
3834 break;
3835 case SEN_OV7610:
3836 case SEN_OV76BE:
3837 hwsbase = 0x38;
3838 hwebase = 0x3a;
3839 vwsbase = vwebase = 0x05;
3840 break;
3841 case SEN_OV6620:
3842 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03003843 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003844 hwsbase = 0x38;
3845 hwebase = 0x3a;
3846 vwsbase = 0x05;
3847 vwebase = 0x06;
Hans de Goede7d971372009-06-14 05:28:17 -03003848 if (sd->sensor == SEN_OV66308AF && qvga)
Hans de Goede49809d62009-06-07 12:10:39 -03003849 /* HDG: this fixes U and V getting swapped */
Hans de Goede7d971372009-06-14 05:28:17 -03003850 hwsbase++;
Hans de Goede124cc9c2009-06-14 05:48:00 -03003851 if (crop) {
3852 hwsbase += 8;
3853 hwebase += 8;
3854 vwsbase += 11;
3855 vwebase += 11;
3856 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003857 break;
3858 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03003859 case SEN_OV7620AE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003860 hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */
3861 hwebase = 0x2f;
3862 vwsbase = vwebase = 0x05;
3863 break;
3864 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003865 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003866 hwsbase = 0x1a;
3867 hwebase = 0x1a;
3868 vwsbase = vwebase = 0x03;
3869 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003870 default:
3871 return -EINVAL;
3872 }
3873
3874 switch (sd->sensor) {
3875 case SEN_OV6620:
3876 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03003877 case SEN_OV66308AF:
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003878 if (qvga) { /* QCIF */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003879 hwscale = 0;
3880 vwscale = 0;
3881 } else { /* CIF */
3882 hwscale = 1;
3883 vwscale = 1; /* The datasheet says 0;
3884 * it's wrong */
3885 }
3886 break;
3887 case SEN_OV8610:
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003888 if (qvga) { /* QSVGA */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003889 hwscale = 1;
3890 vwscale = 1;
3891 } else { /* SVGA */
3892 hwscale = 2;
3893 vwscale = 2;
3894 }
3895 break;
3896 default: /* SEN_OV7xx0 */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003897 if (qvga) { /* QVGA */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003898 hwscale = 1;
3899 vwscale = 0;
3900 } else { /* VGA */
3901 hwscale = 2;
3902 vwscale = 1;
3903 }
3904 }
3905
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003906 ret = mode_init_ov_sensor_regs(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003907 if (ret < 0)
3908 return ret;
3909
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003910 i2c_w(sd, 0x17, hwsbase);
Hans de Goedea511ba92009-10-16 07:13:07 -03003911 i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale));
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003912 i2c_w(sd, 0x19, vwsbase);
Hans de Goedea511ba92009-10-16 07:13:07 -03003913 i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale));
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003914
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003915 return 0;
3916}
3917
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003918/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03003919static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003920{
3921 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goede49809d62009-06-07 12:10:39 -03003922 int ret = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003923
Hans de Goedea511ba92009-10-16 07:13:07 -03003924 /* Default for most bridges, allow bridge_mode_init_regs to override */
3925 sd->sensor_width = sd->gspca_dev.width;
3926 sd->sensor_height = sd->gspca_dev.height;
3927
Hans de Goede49809d62009-06-07 12:10:39 -03003928 switch (sd->bridge) {
Hans de Goede1876bb92009-06-14 06:45:50 -03003929 case BRIDGE_OV511:
3930 case BRIDGE_OV511PLUS:
3931 ret = ov511_mode_init_regs(sd);
3932 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003933 case BRIDGE_OV518:
3934 case BRIDGE_OV518PLUS:
3935 ret = ov518_mode_init_regs(sd);
3936 break;
3937 case BRIDGE_OV519:
3938 ret = ov519_mode_init_regs(sd);
3939 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003940 /* case BRIDGE_OVFX2: nothing to do */
Hans de Goedea511ba92009-10-16 07:13:07 -03003941 case BRIDGE_W9968CF:
3942 ret = w9968cf_mode_init_regs(sd);
3943 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003944 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003945 if (ret < 0)
3946 goto out;
Hans de Goede49809d62009-06-07 12:10:39 -03003947
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003948 ret = set_ov_sensor_window(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003949 if (ret < 0)
3950 goto out;
3951
Hans de Goede49809d62009-06-07 12:10:39 -03003952 setcontrast(gspca_dev);
3953 setbrightness(gspca_dev);
3954 setcolors(gspca_dev);
Hans de Goede02ab18b2009-06-14 04:32:04 -03003955 sethvflip(sd);
3956 setautobrightness(sd);
3957 setfreq(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03003958
Hans de Goede417a4d22010-02-19 07:37:08 -03003959 /* Force clear snapshot state in case the snapshot button was
3960 pressed while we weren't streaming */
3961 sd->snapshot_needs_reset = 1;
3962 sd_reset_snapshot(gspca_dev);
3963 sd->snapshot_pressed = 0;
3964
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03003965 sd->first_frame = 3;
3966
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003967 ret = ov51x_restart(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003968 if (ret < 0)
3969 goto out;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003970 ov51x_led_control(sd, 1);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03003971 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003972out:
3973 PDEBUG(D_ERR, "camera start error:%d", ret);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03003974 return ret;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003975}
3976
3977static void sd_stopN(struct gspca_dev *gspca_dev)
3978{
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003979 struct sd *sd = (struct sd *) gspca_dev;
3980
3981 ov51x_stop(sd);
3982 ov51x_led_control(sd, 0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003983}
3984
Hans de Goede79b35902009-10-19 06:08:01 -03003985static void sd_stop0(struct gspca_dev *gspca_dev)
3986{
3987 struct sd *sd = (struct sd *) gspca_dev;
3988
3989 if (sd->bridge == BRIDGE_W9968CF)
3990 w9968cf_stop0(sd);
3991}
3992
Hans de Goede92e232a2010-02-20 04:30:45 -03003993static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state)
3994{
3995 struct sd *sd = (struct sd *) gspca_dev;
3996
3997 if (sd->snapshot_pressed != state) {
3998#ifdef CONFIG_INPUT
3999 input_report_key(gspca_dev->input_dev, KEY_CAMERA, state);
4000 input_sync(gspca_dev->input_dev);
4001#endif
4002 if (state)
4003 sd->snapshot_needs_reset = 1;
4004
4005 sd->snapshot_pressed = state;
4006 } else {
Hans de Goede88e8d202010-02-20 04:45:49 -03004007 /* On the ov511 / ov519 we need to reset the button state
4008 multiple times, as resetting does not work as long as the
4009 button stays pressed */
4010 switch (sd->bridge) {
4011 case BRIDGE_OV511:
4012 case BRIDGE_OV511PLUS:
4013 case BRIDGE_OV519:
4014 if (state)
4015 sd->snapshot_needs_reset = 1;
4016 break;
4017 }
Hans de Goede92e232a2010-02-20 04:30:45 -03004018 }
4019}
4020
Hans de Goede1876bb92009-06-14 06:45:50 -03004021static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004022 u8 *in, /* isoc packet */
4023 int len) /* iso packet length */
Hans de Goede1876bb92009-06-14 06:45:50 -03004024{
4025 struct sd *sd = (struct sd *) gspca_dev;
4026
4027 /* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th
4028 * byte non-zero. The EOF packet has image width/height in the
4029 * 10th and 11th bytes. The 9th byte is given as follows:
4030 *
4031 * bit 7: EOF
4032 * 6: compression enabled
4033 * 5: 422/420/400 modes
4034 * 4: 422/420/400 modes
4035 * 3: 1
4036 * 2: snapshot button on
4037 * 1: snapshot frame
4038 * 0: even/odd field
4039 */
4040 if (!(in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) &&
4041 (in[8] & 0x08)) {
Hans de Goede88e8d202010-02-20 04:45:49 -03004042 ov51x_handle_button(gspca_dev, (in[8] >> 2) & 1);
Hans de Goede1876bb92009-06-14 06:45:50 -03004043 if (in[8] & 0x80) {
4044 /* Frame end */
4045 if ((in[9] + 1) * 8 != gspca_dev->width ||
4046 (in[10] + 1) * 8 != gspca_dev->height) {
4047 PDEBUG(D_ERR, "Invalid frame size, got: %dx%d,"
4048 " requested: %dx%d\n",
4049 (in[9] + 1) * 8, (in[10] + 1) * 8,
4050 gspca_dev->width, gspca_dev->height);
4051 gspca_dev->last_packet_type = DISCARD_PACKET;
4052 return;
4053 }
4054 /* Add 11 byte footer to frame, might be usefull */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004055 gspca_frame_add(gspca_dev, LAST_PACKET, in, 11);
Hans de Goede1876bb92009-06-14 06:45:50 -03004056 return;
4057 } else {
4058 /* Frame start */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004059 gspca_frame_add(gspca_dev, FIRST_PACKET, in, 0);
Hans de Goede1876bb92009-06-14 06:45:50 -03004060 sd->packet_nr = 0;
4061 }
4062 }
4063
4064 /* Ignore the packet number */
4065 len--;
4066
4067 /* intermediate packet */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004068 gspca_frame_add(gspca_dev, INTER_PACKET, in, len);
Hans de Goede1876bb92009-06-14 06:45:50 -03004069}
4070
Hans de Goede49809d62009-06-07 12:10:39 -03004071static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004072 u8 *data, /* isoc packet */
Hans de Goede49809d62009-06-07 12:10:39 -03004073 int len) /* iso packet length */
4074{
Hans de Goede92918a52009-06-14 06:21:35 -03004075 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goede49809d62009-06-07 12:10:39 -03004076
4077 /* A false positive here is likely, until OVT gives me
4078 * the definitive SOF/EOF format */
4079 if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
Hans de Goede92e232a2010-02-20 04:30:45 -03004080 ov51x_handle_button(gspca_dev, (data[6] >> 1) & 1);
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004081 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
4082 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
Hans de Goede92918a52009-06-14 06:21:35 -03004083 sd->packet_nr = 0;
4084 }
4085
4086 if (gspca_dev->last_packet_type == DISCARD_PACKET)
4087 return;
4088
4089 /* Does this device use packet numbers ? */
4090 if (len & 7) {
4091 len--;
4092 if (sd->packet_nr == data[len])
4093 sd->packet_nr++;
4094 /* The last few packets of the frame (which are all 0's
4095 except that they may contain part of the footer), are
4096 numbered 0 */
4097 else if (sd->packet_nr == 0 || data[len]) {
4098 PDEBUG(D_ERR, "Invalid packet nr: %d (expect: %d)",
4099 (int)data[len], (int)sd->packet_nr);
4100 gspca_dev->last_packet_type = DISCARD_PACKET;
4101 return;
4102 }
Hans de Goede49809d62009-06-07 12:10:39 -03004103 }
4104
4105 /* intermediate packet */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004106 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004107}
4108
4109static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004110 u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004111 int len) /* iso packet length */
4112{
4113 /* Header of ov519 is 16 bytes:
4114 * Byte Value Description
4115 * 0 0xff magic
4116 * 1 0xff magic
4117 * 2 0xff magic
4118 * 3 0xXX 0x50 = SOF, 0x51 = EOF
4119 * 9 0xXX 0x01 initial frame without data,
4120 * 0x00 standard frame with image
4121 * 14 Lo in EOF: length of image data / 8
4122 * 15 Hi
4123 */
4124
4125 if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) {
4126 switch (data[3]) {
4127 case 0x50: /* start of frame */
Hans de Goede417a4d22010-02-19 07:37:08 -03004128 /* Don't check the button state here, as the state
4129 usually (always ?) changes at EOF and checking it
4130 here leads to unnecessary snapshot state resets. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004131#define HDRSZ 16
4132 data += HDRSZ;
4133 len -= HDRSZ;
4134#undef HDRSZ
4135 if (data[0] == 0xff || data[1] == 0xd8)
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004136 gspca_frame_add(gspca_dev, FIRST_PACKET,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004137 data, len);
4138 else
4139 gspca_dev->last_packet_type = DISCARD_PACKET;
4140 return;
4141 case 0x51: /* end of frame */
Hans de Goede92e232a2010-02-20 04:30:45 -03004142 ov51x_handle_button(gspca_dev, data[11] & 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004143 if (data[9] != 0)
4144 gspca_dev->last_packet_type = DISCARD_PACKET;
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004145 gspca_frame_add(gspca_dev, LAST_PACKET,
4146 NULL, 0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004147 return;
4148 }
4149 }
4150
4151 /* intermediate packet */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004152 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004153}
4154
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004155static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004156 u8 *data, /* isoc packet */
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004157 int len) /* iso packet length */
4158{
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03004159 struct sd *sd = (struct sd *) gspca_dev;
4160 struct gspca_frame *frame;
4161
4162 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
4163
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004164 /* A short read signals EOF */
4165 if (len < OVFX2_BULK_SIZE) {
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03004166 /* If the frame is short, and it is one of the first ones
4167 the sensor and bridge are still syncing, so drop it. */
4168 if (sd->first_frame) {
4169 sd->first_frame--;
4170 frame = gspca_get_i_frame(gspca_dev);
4171 if (!frame || (frame->data_end - frame->data) <
4172 (sd->gspca_dev.width * sd->gspca_dev.height))
4173 gspca_dev->last_packet_type = DISCARD_PACKET;
4174 }
4175 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004176 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004177 }
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004178}
4179
Hans de Goede49809d62009-06-07 12:10:39 -03004180static void sd_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004181 u8 *data, /* isoc packet */
Hans de Goede49809d62009-06-07 12:10:39 -03004182 int len) /* iso packet length */
4183{
4184 struct sd *sd = (struct sd *) gspca_dev;
4185
4186 switch (sd->bridge) {
4187 case BRIDGE_OV511:
4188 case BRIDGE_OV511PLUS:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004189 ov511_pkt_scan(gspca_dev, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004190 break;
4191 case BRIDGE_OV518:
4192 case BRIDGE_OV518PLUS:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004193 ov518_pkt_scan(gspca_dev, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004194 break;
4195 case BRIDGE_OV519:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004196 ov519_pkt_scan(gspca_dev, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004197 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004198 case BRIDGE_OVFX2:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004199 ovfx2_pkt_scan(gspca_dev, data, len);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004200 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03004201 case BRIDGE_W9968CF:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004202 w9968cf_pkt_scan(gspca_dev, data, len);
Hans de Goedea511ba92009-10-16 07:13:07 -03004203 break;
Hans de Goede49809d62009-06-07 12:10:39 -03004204 }
4205}
4206
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004207/* -- management routines -- */
4208
4209static void setbrightness(struct gspca_dev *gspca_dev)
4210{
4211 struct sd *sd = (struct sd *) gspca_dev;
4212 int val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004213
4214 val = sd->brightness;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004215 switch (sd->sensor) {
4216 case SEN_OV8610:
4217 case SEN_OV7610:
4218 case SEN_OV76BE:
4219 case SEN_OV6620:
4220 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004221 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004222 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03004223 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004224 i2c_w(sd, OV7610_REG_BRT, val);
4225 break;
4226 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03004227 case SEN_OV7620AE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004228 /* 7620 doesn't like manual changes when in auto mode */
Hans de Goede02ab18b2009-06-14 04:32:04 -03004229 if (!sd->autobrightness)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004230 i2c_w(sd, OV7610_REG_BRT, val);
4231 break;
4232 case SEN_OV7670:
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004233/*win trace
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004234 * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */
4235 i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val));
4236 break;
4237 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004238}
4239
4240static void setcontrast(struct gspca_dev *gspca_dev)
4241{
4242 struct sd *sd = (struct sd *) gspca_dev;
4243 int val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004244
4245 val = sd->contrast;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004246 switch (sd->sensor) {
4247 case SEN_OV7610:
4248 case SEN_OV6620:
4249 i2c_w(sd, OV7610_REG_CNT, val);
4250 break;
4251 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004252 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004253 i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f);
Hans de Goede49809d62009-06-07 12:10:39 -03004254 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004255 case SEN_OV8610: {
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03004256 static const __u8 ctab[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004257 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f
4258 };
4259
4260 /* Use Y gamma control instead. Bit 0 enables it. */
4261 i2c_w(sd, 0x64, ctab[val >> 5]);
4262 break;
4263 }
Hans de Goede859cc472010-01-07 15:42:35 -03004264 case SEN_OV7620:
4265 case SEN_OV7620AE: {
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03004266 static const __u8 ctab[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004267 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
4268 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
4269 };
4270
4271 /* Use Y gamma control instead. Bit 0 enables it. */
4272 i2c_w(sd, 0x64, ctab[val >> 4]);
4273 break;
4274 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004275 case SEN_OV7670:
4276 /* check that this isn't just the same as ov7610 */
4277 i2c_w(sd, OV7670_REG_CONTRAS, val >> 1);
4278 break;
4279 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004280}
4281
4282static void setcolors(struct gspca_dev *gspca_dev)
4283{
4284 struct sd *sd = (struct sd *) gspca_dev;
4285 int val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004286
4287 val = sd->colors;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004288 switch (sd->sensor) {
4289 case SEN_OV8610:
4290 case SEN_OV7610:
4291 case SEN_OV76BE:
4292 case SEN_OV6620:
4293 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004294 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004295 i2c_w(sd, OV7610_REG_SAT, val);
4296 break;
4297 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03004298 case SEN_OV7620AE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004299 /* Use UV gamma control instead. Bits 0 & 7 are reserved. */
4300/* rc = ov_i2c_write(sd->dev, 0x62, (val >> 9) & 0x7e);
4301 if (rc < 0)
4302 goto out; */
4303 i2c_w(sd, OV7610_REG_SAT, val);
4304 break;
4305 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03004306 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004307 i2c_w(sd, OV7610_REG_SAT, val & 0xf0);
4308 break;
4309 case SEN_OV7670:
4310 /* supported later once I work out how to do it
4311 * transparently fail now! */
4312 /* set REG_COM13 values for UV sat auto mode */
4313 break;
4314 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004315}
4316
Hans de Goede02ab18b2009-06-14 04:32:04 -03004317static void setautobrightness(struct sd *sd)
4318{
Hans de Goede035d3a32010-01-09 08:14:43 -03004319 if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7648 ||
4320 sd->sensor == SEN_OV7670 ||
Hans de Goede635118d2009-10-11 09:49:03 -03004321 sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
Hans de Goede02ab18b2009-06-14 04:32:04 -03004322 return;
4323
4324 i2c_w_mask(sd, 0x2d, sd->autobrightness ? 0x10 : 0x00, 0x10);
4325}
4326
4327static void setfreq(struct sd *sd)
4328{
Hans de Goede635118d2009-10-11 09:49:03 -03004329 if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
4330 return;
4331
Hans de Goede02ab18b2009-06-14 04:32:04 -03004332 if (sd->sensor == SEN_OV7670) {
4333 switch (sd->freq) {
4334 case 0: /* Banding filter disabled */
4335 i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_BFILT);
4336 break;
4337 case 1: /* 50 hz */
4338 i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT,
4339 OV7670_COM8_BFILT);
4340 i2c_w_mask(sd, OV7670_REG_COM11, 0x08, 0x18);
4341 break;
4342 case 2: /* 60 hz */
4343 i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT,
4344 OV7670_COM8_BFILT);
4345 i2c_w_mask(sd, OV7670_REG_COM11, 0x00, 0x18);
4346 break;
4347 case 3: /* Auto hz */
4348 i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT,
4349 OV7670_COM8_BFILT);
4350 i2c_w_mask(sd, OV7670_REG_COM11, OV7670_COM11_HZAUTO,
4351 0x18);
4352 break;
4353 }
4354 } else {
4355 switch (sd->freq) {
4356 case 0: /* Banding filter disabled */
4357 i2c_w_mask(sd, 0x2d, 0x00, 0x04);
4358 i2c_w_mask(sd, 0x2a, 0x00, 0x80);
4359 break;
4360 case 1: /* 50 hz (filter on and framerate adj) */
4361 i2c_w_mask(sd, 0x2d, 0x04, 0x04);
4362 i2c_w_mask(sd, 0x2a, 0x80, 0x80);
4363 /* 20 fps -> 16.667 fps */
4364 if (sd->sensor == SEN_OV6620 ||
Hans de Goede7d971372009-06-14 05:28:17 -03004365 sd->sensor == SEN_OV6630 ||
4366 sd->sensor == SEN_OV66308AF)
Hans de Goede02ab18b2009-06-14 04:32:04 -03004367 i2c_w(sd, 0x2b, 0x5e);
4368 else
4369 i2c_w(sd, 0x2b, 0xac);
4370 break;
4371 case 2: /* 60 hz (filter on, ...) */
4372 i2c_w_mask(sd, 0x2d, 0x04, 0x04);
4373 if (sd->sensor == SEN_OV6620 ||
Hans de Goede7d971372009-06-14 05:28:17 -03004374 sd->sensor == SEN_OV6630 ||
4375 sd->sensor == SEN_OV66308AF) {
Hans de Goede02ab18b2009-06-14 04:32:04 -03004376 /* 20 fps -> 15 fps */
4377 i2c_w_mask(sd, 0x2a, 0x80, 0x80);
4378 i2c_w(sd, 0x2b, 0xa8);
4379 } else {
4380 /* no framerate adj. */
4381 i2c_w_mask(sd, 0x2a, 0x00, 0x80);
4382 }
4383 break;
4384 }
4385 }
4386}
4387
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004388static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
4389{
4390 struct sd *sd = (struct sd *) gspca_dev;
4391
4392 sd->brightness = val;
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004393 if (gspca_dev->streaming)
4394 setbrightness(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004395 return 0;
4396}
4397
4398static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
4399{
4400 struct sd *sd = (struct sd *) gspca_dev;
4401
4402 *val = sd->brightness;
4403 return 0;
4404}
4405
4406static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
4407{
4408 struct sd *sd = (struct sd *) gspca_dev;
4409
4410 sd->contrast = val;
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004411 if (gspca_dev->streaming)
4412 setcontrast(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004413 return 0;
4414}
4415
4416static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
4417{
4418 struct sd *sd = (struct sd *) gspca_dev;
4419
4420 *val = sd->contrast;
4421 return 0;
4422}
4423
4424static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
4425{
4426 struct sd *sd = (struct sd *) gspca_dev;
4427
4428 sd->colors = val;
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004429 if (gspca_dev->streaming)
4430 setcolors(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004431 return 0;
4432}
4433
4434static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
4435{
4436 struct sd *sd = (struct sd *) gspca_dev;
4437
4438 *val = sd->colors;
4439 return 0;
4440}
4441
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03004442static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
4443{
4444 struct sd *sd = (struct sd *) gspca_dev;
4445
4446 sd->hflip = val;
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004447 if (gspca_dev->streaming)
4448 sethvflip(sd);
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03004449 return 0;
4450}
4451
4452static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
4453{
4454 struct sd *sd = (struct sd *) gspca_dev;
4455
4456 *val = sd->hflip;
4457 return 0;
4458}
4459
4460static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
4461{
4462 struct sd *sd = (struct sd *) gspca_dev;
4463
4464 sd->vflip = val;
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004465 if (gspca_dev->streaming)
4466 sethvflip(sd);
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03004467 return 0;
4468}
4469
4470static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
4471{
4472 struct sd *sd = (struct sd *) gspca_dev;
4473
4474 *val = sd->vflip;
4475 return 0;
4476}
4477
Hans de Goede02ab18b2009-06-14 04:32:04 -03004478static int sd_setautobrightness(struct gspca_dev *gspca_dev, __s32 val)
4479{
4480 struct sd *sd = (struct sd *) gspca_dev;
4481
4482 sd->autobrightness = val;
4483 if (gspca_dev->streaming)
4484 setautobrightness(sd);
4485 return 0;
4486}
4487
4488static int sd_getautobrightness(struct gspca_dev *gspca_dev, __s32 *val)
4489{
4490 struct sd *sd = (struct sd *) gspca_dev;
4491
4492 *val = sd->autobrightness;
4493 return 0;
4494}
4495
4496static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
4497{
4498 struct sd *sd = (struct sd *) gspca_dev;
4499
4500 sd->freq = val;
Hans de Goedea511ba92009-10-16 07:13:07 -03004501 if (gspca_dev->streaming) {
Hans de Goede02ab18b2009-06-14 04:32:04 -03004502 setfreq(sd);
Hans de Goedea511ba92009-10-16 07:13:07 -03004503 /* Ugly but necessary */
4504 if (sd->bridge == BRIDGE_W9968CF)
4505 w9968cf_set_crop_window(sd);
4506 }
Hans de Goede02ab18b2009-06-14 04:32:04 -03004507 return 0;
4508}
4509
4510static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
4511{
4512 struct sd *sd = (struct sd *) gspca_dev;
4513
4514 *val = sd->freq;
4515 return 0;
4516}
4517
4518static int sd_querymenu(struct gspca_dev *gspca_dev,
4519 struct v4l2_querymenu *menu)
4520{
4521 struct sd *sd = (struct sd *) gspca_dev;
4522
4523 switch (menu->id) {
4524 case V4L2_CID_POWER_LINE_FREQUENCY:
4525 switch (menu->index) {
4526 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
4527 strcpy((char *) menu->name, "NoFliker");
4528 return 0;
4529 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
4530 strcpy((char *) menu->name, "50 Hz");
4531 return 0;
4532 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
4533 strcpy((char *) menu->name, "60 Hz");
4534 return 0;
4535 case 3:
4536 if (sd->sensor != SEN_OV7670)
4537 return -EINVAL;
4538
4539 strcpy((char *) menu->name, "Automatic");
4540 return 0;
4541 }
4542 break;
4543 }
4544 return -EINVAL;
4545}
4546
Hans de Goede79b35902009-10-19 06:08:01 -03004547static int sd_get_jcomp(struct gspca_dev *gspca_dev,
4548 struct v4l2_jpegcompression *jcomp)
4549{
4550 struct sd *sd = (struct sd *) gspca_dev;
4551
4552 if (sd->bridge != BRIDGE_W9968CF)
4553 return -EINVAL;
4554
4555 memset(jcomp, 0, sizeof *jcomp);
4556 jcomp->quality = sd->quality;
4557 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT |
4558 V4L2_JPEG_MARKER_DRI;
4559 return 0;
4560}
4561
4562static int sd_set_jcomp(struct gspca_dev *gspca_dev,
4563 struct v4l2_jpegcompression *jcomp)
4564{
4565 struct sd *sd = (struct sd *) gspca_dev;
4566
4567 if (sd->bridge != BRIDGE_W9968CF)
4568 return -EINVAL;
4569
4570 if (gspca_dev->streaming)
4571 return -EBUSY;
4572
4573 if (jcomp->quality < QUALITY_MIN)
4574 sd->quality = QUALITY_MIN;
4575 else if (jcomp->quality > QUALITY_MAX)
4576 sd->quality = QUALITY_MAX;
4577 else
4578 sd->quality = jcomp->quality;
4579
4580 /* Return resulting jcomp params to app */
4581 sd_get_jcomp(gspca_dev, jcomp);
4582
4583 return 0;
4584}
4585
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004586/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03004587static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004588 .name = MODULE_NAME,
4589 .ctrls = sd_ctrls,
4590 .nctrls = ARRAY_SIZE(sd_ctrls),
4591 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03004592 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004593 .start = sd_start,
4594 .stopN = sd_stopN,
Hans de Goede79b35902009-10-19 06:08:01 -03004595 .stop0 = sd_stop0,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004596 .pkt_scan = sd_pkt_scan,
Hans de Goede417a4d22010-02-19 07:37:08 -03004597 .dq_callback = sd_reset_snapshot,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004598 .querymenu = sd_querymenu,
Hans de Goede79b35902009-10-19 06:08:01 -03004599 .get_jcomp = sd_get_jcomp,
4600 .set_jcomp = sd_set_jcomp,
Hans de Goede417a4d22010-02-19 07:37:08 -03004601#ifdef CONFIG_INPUT
4602 .other_input = 1,
4603#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004604};
4605
4606/* -- module initialisation -- */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03004607static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goedea511ba92009-10-16 07:13:07 -03004608 {USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF },
Hans de Goede49809d62009-06-07 12:10:39 -03004609 {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 },
4610 {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
4611 {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
4612 {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
Hans de Goede9e4d8252009-06-14 06:25:06 -03004613 {USB_DEVICE(0x041e, 0x4064),
4614 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
Rafal Milecki518c8df2009-10-02 03:54:44 -03004615 {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 },
Hans de Goede9e4d8252009-06-14 06:25:06 -03004616 {USB_DEVICE(0x041e, 0x4068),
4617 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
Hans de Goede49809d62009-06-07 12:10:39 -03004618 {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
4619 {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
Hans de Goede98184f72010-01-07 12:06:00 -03004620 {USB_DEVICE(0x054c, 0x0155),
4621 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
Hans de Goede1876bb92009-06-14 06:45:50 -03004622 {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 },
Hans de Goede49809d62009-06-07 12:10:39 -03004623 {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
4624 {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
4625 {USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 },
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004626 {USB_DEVICE(0x05a9, 0x2800), .driver_info = BRIDGE_OVFX2 },
Hans de Goede49809d62009-06-07 12:10:39 -03004627 {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 },
4628 {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 },
Hans de Goede1876bb92009-06-14 06:45:50 -03004629 {USB_DEVICE(0x05a9, 0xa511), .driver_info = BRIDGE_OV511PLUS },
Hans de Goede49809d62009-06-07 12:10:39 -03004630 {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS },
Hans de Goede1876bb92009-06-14 06:45:50 -03004631 {USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS },
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004632 {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 },
4633 {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 },
Hans de Goedea511ba92009-10-16 07:13:07 -03004634 {USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF },
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004635 {USB_DEVICE(0x8020, 0xEF04), .driver_info = BRIDGE_OVFX2 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004636 {}
4637};
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004638
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004639MODULE_DEVICE_TABLE(usb, device_table);
4640
4641/* -- device connect -- */
4642static int sd_probe(struct usb_interface *intf,
4643 const struct usb_device_id *id)
4644{
4645 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
4646 THIS_MODULE);
4647}
4648
4649static struct usb_driver sd_driver = {
4650 .name = MODULE_NAME,
4651 .id_table = device_table,
4652 .probe = sd_probe,
4653 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03004654#ifdef CONFIG_PM
4655 .suspend = gspca_suspend,
4656 .resume = gspca_resume,
4657#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004658};
4659
4660/* -- module insert / remove -- */
4661static int __init sd_mod_init(void)
4662{
Alexey Klimovf69e9522009-01-01 13:02:07 -03004663 int ret;
4664 ret = usb_register(&sd_driver);
4665 if (ret < 0)
Alexey Klimove6b14842009-01-01 13:04:58 -03004666 return ret;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03004667 PDEBUG(D_PROBE, "registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004668 return 0;
4669}
4670static void __exit sd_mod_exit(void)
4671{
4672 usb_deregister(&sd_driver);
4673 PDEBUG(D_PROBE, "deregistered");
4674}
4675
4676module_init(sd_mod_init);
4677module_exit(sd_mod_exit);
4678
4679module_param(frame_rate, int, 0644);
4680MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)");