blob: f94f41eb222e1873db8ab5f2fedd478b73438db3 [file] [log] [blame]
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001/**
2 * OV519 driver
3 *
4 * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr)
Hans de Goedeb46aaa02009-10-12 10:07:57 -03005 * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03006 *
Romain Beauxis2961e8752008-12-05 06:25:26 -03007 * This module is adapted from the ov51x-jpeg package, which itself
8 * was adapted from the ov511 driver.
9 *
10 * Original copyright for the ov511 driver is:
11 *
Hans de Goedeb46aaa02009-10-12 10:07:57 -030012 * Copyright (c) 1999-2006 Mark W. McClelland
Romain Beauxis2961e8752008-12-05 06:25:26 -030013 * Support for OV519, OV8610 Copyright (c) 2003 Joerg Heckenbach
Hans de Goedeb46aaa02009-10-12 10:07:57 -030014 * Many improvements by Bret Wallach <bwallac1@san.rr.com>
15 * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
16 * OV7620 fixes by Charl P. Botha <cpbotha@ieee.org>
17 * Changes by Claudio Matsuoka <claudio@conectiva.com>
Romain Beauxis2961e8752008-12-05 06:25:26 -030018 *
19 * ov51x-jpeg original copyright is:
20 *
21 * Copyright (c) 2004-2007 Romain Beauxis <toots@rastageeks.org>
22 * Support for OV7670 sensors was contributed by Sam Skipsey <aoanla@yahoo.com>
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030023 *
24 * This program is free software; you can redistribute it and/or modify
25 * it under the terms of the GNU General Public License as published by
26 * the Free Software Foundation; either version 2 of the License, or
27 * any later version.
28 *
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
33 *
34 * You should have received a copy of the GNU General Public License
35 * along with this program; if not, write to the Free Software
36 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37 *
38 */
39#define MODULE_NAME "ov519"
40
41#include "gspca.h"
42
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030043MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
44MODULE_DESCRIPTION("OV519 USB Camera Driver");
45MODULE_LICENSE("GPL");
46
47/* global parameters */
48static int frame_rate;
49
50/* Number of times to retry a failed I2C transaction. Increase this if you
51 * are getting "Failed to read sensor ID..." */
52static int i2c_detect_tries = 10;
53
54/* ov519 device descriptor */
55struct sd {
56 struct gspca_dev gspca_dev; /* !! must be the first item */
57
Hans de Goede92918a52009-06-14 06:21:35 -030058 __u8 packet_nr;
59
Hans de Goede49809d62009-06-07 12:10:39 -030060 char bridge;
61#define BRIDGE_OV511 0
62#define BRIDGE_OV511PLUS 1
63#define BRIDGE_OV518 2
64#define BRIDGE_OV518PLUS 3
65#define BRIDGE_OV519 4
Hans de Goede635118d2009-10-11 09:49:03 -030066#define BRIDGE_OVFX2 5
Hans de Goedea511ba92009-10-16 07:13:07 -030067#define BRIDGE_W9968CF 6
Hans de Goede9e4d8252009-06-14 06:25:06 -030068#define BRIDGE_MASK 7
69
70 char invert_led;
71#define BRIDGE_INVERT_LED 8
Hans de Goede49809d62009-06-07 12:10:39 -030072
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030073 /* Determined by sensor type */
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -030074 __u8 sif;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030075
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -030076 __u8 brightness;
77 __u8 contrast;
78 __u8 colors;
Jean-Francois Moine0cd67592008-07-29 05:25:28 -030079 __u8 hflip;
80 __u8 vflip;
Hans de Goede02ab18b2009-06-14 04:32:04 -030081 __u8 autobrightness;
82 __u8 freq;
Hans de Goede79b35902009-10-19 06:08:01 -030083 __u8 quality;
84#define QUALITY_MIN 50
85#define QUALITY_MAX 70
86#define QUALITY_DEF 50
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030087
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -030088 __u8 stopped; /* Streaming is temporarily paused */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030089
Hans de Goede1876bb92009-06-14 06:45:50 -030090 __u8 frame_rate; /* current Framerate */
91 __u8 clockdiv; /* clockdiv override */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030092
93 char sensor; /* Type of image sensor chip (SEN_*) */
94#define SEN_UNKNOWN 0
Hans de Goede635118d2009-10-11 09:49:03 -030095#define SEN_OV2610 1
96#define SEN_OV3610 2
97#define SEN_OV6620 3
98#define SEN_OV6630 4
99#define SEN_OV66308AF 5
100#define SEN_OV7610 6
101#define SEN_OV7620 7
Hans de Goede859cc472010-01-07 15:42:35 -0300102#define SEN_OV7620AE 8
103#define SEN_OV7640 9
Hans de Goede035d3a32010-01-09 08:14:43 -0300104#define SEN_OV7648 10
105#define SEN_OV7670 11
106#define SEN_OV76BE 12
107#define SEN_OV8610 13
Hans de Goedea511ba92009-10-16 07:13:07 -0300108
109 u8 sensor_addr;
110 int sensor_width;
111 int sensor_height;
Hans de Goedefb1f9022009-10-16 07:42:53 -0300112 int sensor_reg_cache[256];
Hans de Goede79b35902009-10-19 06:08:01 -0300113
114 u8 *jpeg_hdr;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300115};
116
Hans de Goedea511ba92009-10-16 07:13:07 -0300117/* Note this is a bit of a hack, but the w9968cf driver needs the code for all
118 the ov sensors which is already present here. When we have the time we
119 really should move the sensor drivers to v4l2 sub drivers. */
120#include "w996Xcf.c"
121
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300122/* V4L2 controls supported by the driver */
123static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
124static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
125static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
126static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
127static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
128static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300129static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
130static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
131static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
132static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
Hans de Goede02ab18b2009-06-14 04:32:04 -0300133static int sd_setautobrightness(struct gspca_dev *gspca_dev, __s32 val);
134static int sd_getautobrightness(struct gspca_dev *gspca_dev, __s32 *val);
135static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
136static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
Hans de Goede49809d62009-06-07 12:10:39 -0300137static void setbrightness(struct gspca_dev *gspca_dev);
138static void setcontrast(struct gspca_dev *gspca_dev);
139static void setcolors(struct gspca_dev *gspca_dev);
Hans de Goede02ab18b2009-06-14 04:32:04 -0300140static void setautobrightness(struct sd *sd);
141static void setfreq(struct sd *sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300142
Hans de Goede02ab18b2009-06-14 04:32:04 -0300143static const struct ctrl sd_ctrls[] = {
Hans de Goeded02134d2010-01-09 19:22:34 -0300144#define BRIGHTNESS_IDX 0
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300145 {
146 {
147 .id = V4L2_CID_BRIGHTNESS,
148 .type = V4L2_CTRL_TYPE_INTEGER,
149 .name = "Brightness",
150 .minimum = 0,
151 .maximum = 255,
152 .step = 1,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300153#define BRIGHTNESS_DEF 127
154 .default_value = BRIGHTNESS_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300155 },
156 .set = sd_setbrightness,
157 .get = sd_getbrightness,
158 },
Hans de Goeded02134d2010-01-09 19:22:34 -0300159#define CONTRAST_IDX 1
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300160 {
161 {
162 .id = V4L2_CID_CONTRAST,
163 .type = V4L2_CTRL_TYPE_INTEGER,
164 .name = "Contrast",
165 .minimum = 0,
166 .maximum = 255,
167 .step = 1,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300168#define CONTRAST_DEF 127
169 .default_value = CONTRAST_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300170 },
171 .set = sd_setcontrast,
172 .get = sd_getcontrast,
173 },
Hans de Goeded02134d2010-01-09 19:22:34 -0300174#define COLOR_IDX 2
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300175 {
176 {
177 .id = V4L2_CID_SATURATION,
178 .type = V4L2_CTRL_TYPE_INTEGER,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300179 .name = "Color",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300180 .minimum = 0,
181 .maximum = 255,
182 .step = 1,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300183#define COLOR_DEF 127
184 .default_value = COLOR_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300185 },
186 .set = sd_setcolors,
187 .get = sd_getcolors,
188 },
Hans de Goede02ab18b2009-06-14 04:32:04 -0300189/* The flip controls work with ov7670 only */
Jean-Francois Moinede004482008-09-03 17:12:16 -0300190#define HFLIP_IDX 3
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300191 {
192 {
193 .id = V4L2_CID_HFLIP,
194 .type = V4L2_CTRL_TYPE_BOOLEAN,
195 .name = "Mirror",
196 .minimum = 0,
197 .maximum = 1,
198 .step = 1,
199#define HFLIP_DEF 0
200 .default_value = HFLIP_DEF,
201 },
202 .set = sd_sethflip,
203 .get = sd_gethflip,
204 },
Jean-Francois Moinede004482008-09-03 17:12:16 -0300205#define VFLIP_IDX 4
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300206 {
207 {
208 .id = V4L2_CID_VFLIP,
209 .type = V4L2_CTRL_TYPE_BOOLEAN,
210 .name = "Vflip",
211 .minimum = 0,
212 .maximum = 1,
213 .step = 1,
214#define VFLIP_DEF 0
215 .default_value = VFLIP_DEF,
216 },
217 .set = sd_setvflip,
218 .get = sd_getvflip,
219 },
Hans de Goede02ab18b2009-06-14 04:32:04 -0300220#define AUTOBRIGHT_IDX 5
221 {
222 {
223 .id = V4L2_CID_AUTOBRIGHTNESS,
224 .type = V4L2_CTRL_TYPE_BOOLEAN,
225 .name = "Auto Brightness",
226 .minimum = 0,
227 .maximum = 1,
228 .step = 1,
229#define AUTOBRIGHT_DEF 1
230 .default_value = AUTOBRIGHT_DEF,
231 },
232 .set = sd_setautobrightness,
233 .get = sd_getautobrightness,
234 },
235#define FREQ_IDX 6
236 {
237 {
238 .id = V4L2_CID_POWER_LINE_FREQUENCY,
239 .type = V4L2_CTRL_TYPE_MENU,
240 .name = "Light frequency filter",
241 .minimum = 0,
242 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
243 .step = 1,
244#define FREQ_DEF 0
245 .default_value = FREQ_DEF,
246 },
247 .set = sd_setfreq,
248 .get = sd_getfreq,
249 },
250#define OV7670_FREQ_IDX 7
251 {
252 {
253 .id = V4L2_CID_POWER_LINE_FREQUENCY,
254 .type = V4L2_CTRL_TYPE_MENU,
255 .name = "Light frequency filter",
256 .minimum = 0,
257 .maximum = 3, /* 0: 0, 1: 50Hz, 2:60Hz 3: Auto Hz */
258 .step = 1,
259#define OV7670_FREQ_DEF 3
260 .default_value = OV7670_FREQ_DEF,
261 },
262 .set = sd_setfreq,
263 .get = sd_getfreq,
264 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300265};
266
Hans de Goede49809d62009-06-07 12:10:39 -0300267static const struct v4l2_pix_format ov519_vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300268 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
269 .bytesperline = 320,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300270 .sizeimage = 320 * 240 * 3 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300271 .colorspace = V4L2_COLORSPACE_JPEG,
272 .priv = 1},
273 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
274 .bytesperline = 640,
275 .sizeimage = 640 * 480 * 3 / 8 + 590,
276 .colorspace = V4L2_COLORSPACE_JPEG,
277 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300278};
Hans de Goede49809d62009-06-07 12:10:39 -0300279static const struct v4l2_pix_format ov519_sif_mode[] = {
Hans de Goede124cc9c2009-06-14 05:48:00 -0300280 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
281 .bytesperline = 160,
282 .sizeimage = 160 * 120 * 3 / 8 + 590,
283 .colorspace = V4L2_COLORSPACE_JPEG,
284 .priv = 3},
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300285 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
286 .bytesperline = 176,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300287 .sizeimage = 176 * 144 * 3 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300288 .colorspace = V4L2_COLORSPACE_JPEG,
289 .priv = 1},
Hans de Goede124cc9c2009-06-14 05:48:00 -0300290 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
291 .bytesperline = 320,
292 .sizeimage = 320 * 240 * 3 / 8 + 590,
293 .colorspace = V4L2_COLORSPACE_JPEG,
294 .priv = 2},
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300295 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
296 .bytesperline = 352,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300297 .sizeimage = 352 * 288 * 3 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300298 .colorspace = V4L2_COLORSPACE_JPEG,
299 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300300};
301
Hans de Goedeb282d872009-06-14 19:10:40 -0300302/* Note some of the sizeimage values for the ov511 / ov518 may seem
303 larger then necessary, however they need to be this big as the ov511 /
304 ov518 always fills the entire isoc frame, using 0 padding bytes when
305 it doesn't have any data. So with low framerates the amount of data
306 transfered can become quite large (libv4l will remove all the 0 padding
307 in userspace). */
Hans de Goede49809d62009-06-07 12:10:39 -0300308static const struct v4l2_pix_format ov518_vga_mode[] = {
309 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
310 .bytesperline = 320,
Hans de Goedeb282d872009-06-14 19:10:40 -0300311 .sizeimage = 320 * 240 * 3,
Hans de Goede49809d62009-06-07 12:10:39 -0300312 .colorspace = V4L2_COLORSPACE_JPEG,
313 .priv = 1},
314 {640, 480, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
315 .bytesperline = 640,
Hans de Goedeb282d872009-06-14 19:10:40 -0300316 .sizeimage = 640 * 480 * 2,
Hans de Goede49809d62009-06-07 12:10:39 -0300317 .colorspace = V4L2_COLORSPACE_JPEG,
318 .priv = 0},
319};
320static const struct v4l2_pix_format ov518_sif_mode[] = {
Hans de Goede124cc9c2009-06-14 05:48:00 -0300321 {160, 120, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
322 .bytesperline = 160,
Hans de Goedeb282d872009-06-14 19:10:40 -0300323 .sizeimage = 70000,
Hans de Goede124cc9c2009-06-14 05:48:00 -0300324 .colorspace = V4L2_COLORSPACE_JPEG,
325 .priv = 3},
Hans de Goede49809d62009-06-07 12:10:39 -0300326 {176, 144, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
327 .bytesperline = 176,
Hans de Goedeb282d872009-06-14 19:10:40 -0300328 .sizeimage = 70000,
Hans de Goede49809d62009-06-07 12:10:39 -0300329 .colorspace = V4L2_COLORSPACE_JPEG,
330 .priv = 1},
Hans de Goede124cc9c2009-06-14 05:48:00 -0300331 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
332 .bytesperline = 320,
Hans de Goedeb282d872009-06-14 19:10:40 -0300333 .sizeimage = 320 * 240 * 3,
Hans de Goede124cc9c2009-06-14 05:48:00 -0300334 .colorspace = V4L2_COLORSPACE_JPEG,
335 .priv = 2},
Hans de Goede49809d62009-06-07 12:10:39 -0300336 {352, 288, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
337 .bytesperline = 352,
Hans de Goedeb282d872009-06-14 19:10:40 -0300338 .sizeimage = 352 * 288 * 3,
Hans de Goede49809d62009-06-07 12:10:39 -0300339 .colorspace = V4L2_COLORSPACE_JPEG,
340 .priv = 0},
341};
342
Hans de Goede1876bb92009-06-14 06:45:50 -0300343static const struct v4l2_pix_format ov511_vga_mode[] = {
344 {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
345 .bytesperline = 320,
346 .sizeimage = 320 * 240 * 3,
347 .colorspace = V4L2_COLORSPACE_JPEG,
348 .priv = 1},
349 {640, 480, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
350 .bytesperline = 640,
351 .sizeimage = 640 * 480 * 2,
352 .colorspace = V4L2_COLORSPACE_JPEG,
353 .priv = 0},
354};
355static const struct v4l2_pix_format ov511_sif_mode[] = {
356 {160, 120, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
357 .bytesperline = 160,
Hans de Goedeb282d872009-06-14 19:10:40 -0300358 .sizeimage = 70000,
Hans de Goede1876bb92009-06-14 06:45:50 -0300359 .colorspace = V4L2_COLORSPACE_JPEG,
360 .priv = 3},
361 {176, 144, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
362 .bytesperline = 176,
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 = 1},
366 {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
367 .bytesperline = 320,
368 .sizeimage = 320 * 240 * 3,
369 .colorspace = V4L2_COLORSPACE_JPEG,
370 .priv = 2},
371 {352, 288, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
372 .bytesperline = 352,
373 .sizeimage = 352 * 288 * 3,
374 .colorspace = V4L2_COLORSPACE_JPEG,
375 .priv = 0},
376};
Hans de Goede49809d62009-06-07 12:10:39 -0300377
Hans de Goede635118d2009-10-11 09:49:03 -0300378static const struct v4l2_pix_format ovfx2_vga_mode[] = {
379 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
380 .bytesperline = 320,
381 .sizeimage = 320 * 240,
382 .colorspace = V4L2_COLORSPACE_SRGB,
383 .priv = 1},
384 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
385 .bytesperline = 640,
386 .sizeimage = 640 * 480,
387 .colorspace = V4L2_COLORSPACE_SRGB,
388 .priv = 0},
389};
390static const struct v4l2_pix_format ovfx2_cif_mode[] = {
391 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
392 .bytesperline = 160,
393 .sizeimage = 160 * 120,
394 .colorspace = V4L2_COLORSPACE_SRGB,
395 .priv = 3},
396 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
397 .bytesperline = 176,
398 .sizeimage = 176 * 144,
399 .colorspace = V4L2_COLORSPACE_SRGB,
400 .priv = 1},
401 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
402 .bytesperline = 320,
403 .sizeimage = 320 * 240,
404 .colorspace = V4L2_COLORSPACE_SRGB,
405 .priv = 2},
406 {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
407 .bytesperline = 352,
408 .sizeimage = 352 * 288,
409 .colorspace = V4L2_COLORSPACE_SRGB,
410 .priv = 0},
411};
412static const struct v4l2_pix_format ovfx2_ov2610_mode[] = {
413 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
414 .bytesperline = 1600,
415 .sizeimage = 1600 * 1200,
416 .colorspace = V4L2_COLORSPACE_SRGB},
417};
418static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
Hans de Goede635118d2009-10-11 09:49:03 -0300419 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
420 .bytesperline = 640,
421 .sizeimage = 640 * 480,
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300422 .colorspace = V4L2_COLORSPACE_SRGB,
423 .priv = 1},
424 {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
425 .bytesperline = 800,
426 .sizeimage = 800 * 600,
427 .colorspace = V4L2_COLORSPACE_SRGB,
428 .priv = 1},
429 {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
430 .bytesperline = 1024,
431 .sizeimage = 1024 * 768,
432 .colorspace = V4L2_COLORSPACE_SRGB,
433 .priv = 1},
434 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
435 .bytesperline = 1600,
436 .sizeimage = 1600 * 1200,
437 .colorspace = V4L2_COLORSPACE_SRGB,
438 .priv = 0},
439 {2048, 1536, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
440 .bytesperline = 2048,
441 .sizeimage = 2048 * 1536,
442 .colorspace = V4L2_COLORSPACE_SRGB,
443 .priv = 0},
Hans de Goede635118d2009-10-11 09:49:03 -0300444};
445
446
Hans de Goede49809d62009-06-07 12:10:39 -0300447/* Registers common to OV511 / OV518 */
Hans de Goede1876bb92009-06-14 06:45:50 -0300448#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */
Hans de Goede49809d62009-06-07 12:10:39 -0300449#define R51x_SYS_RESET 0x50
Hans de Goede1876bb92009-06-14 06:45:50 -0300450 /* Reset type flags */
451 #define OV511_RESET_OMNICE 0x08
Hans de Goede49809d62009-06-07 12:10:39 -0300452#define R51x_SYS_INIT 0x53
453#define R51x_SYS_SNAP 0x52
454#define R51x_SYS_CUST_ID 0x5F
455#define R51x_COMP_LUT_BEGIN 0x80
456
457/* OV511 Camera interface register numbers */
Hans de Goede1876bb92009-06-14 06:45:50 -0300458#define R511_CAM_DELAY 0x10
459#define R511_CAM_EDGE 0x11
460#define R511_CAM_PXCNT 0x12
461#define R511_CAM_LNCNT 0x13
462#define R511_CAM_PXDIV 0x14
463#define R511_CAM_LNDIV 0x15
464#define R511_CAM_UV_EN 0x16
465#define R511_CAM_LINE_MODE 0x17
466#define R511_CAM_OPTS 0x18
467
468#define R511_SNAP_FRAME 0x19
469#define R511_SNAP_PXCNT 0x1A
470#define R511_SNAP_LNCNT 0x1B
471#define R511_SNAP_PXDIV 0x1C
472#define R511_SNAP_LNDIV 0x1D
473#define R511_SNAP_UV_EN 0x1E
474#define R511_SNAP_UV_EN 0x1E
475#define R511_SNAP_OPTS 0x1F
476
477#define R511_DRAM_FLOW_CTL 0x20
478#define R511_FIFO_OPTS 0x31
479#define R511_I2C_CTL 0x40
Hans de Goede49809d62009-06-07 12:10:39 -0300480#define R511_SYS_LED_CTL 0x55 /* OV511+ only */
Hans de Goede1876bb92009-06-14 06:45:50 -0300481#define R511_COMP_EN 0x78
482#define R511_COMP_LUT_EN 0x79
Hans de Goede49809d62009-06-07 12:10:39 -0300483
484/* OV518 Camera interface register numbers */
485#define R518_GPIO_OUT 0x56 /* OV518(+) only */
486#define R518_GPIO_CTL 0x57 /* OV518(+) only */
487
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300488/* OV519 Camera interface register numbers */
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -0300489#define OV519_R10_H_SIZE 0x10
490#define OV519_R11_V_SIZE 0x11
491#define OV519_R12_X_OFFSETL 0x12
492#define OV519_R13_X_OFFSETH 0x13
493#define OV519_R14_Y_OFFSETL 0x14
494#define OV519_R15_Y_OFFSETH 0x15
495#define OV519_R16_DIVIDER 0x16
496#define OV519_R20_DFR 0x20
497#define OV519_R25_FORMAT 0x25
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300498
499/* OV519 System Controller register numbers */
500#define OV519_SYS_RESET1 0x51
501#define OV519_SYS_EN_CLK1 0x54
502
503#define OV519_GPIO_DATA_OUT0 0x71
504#define OV519_GPIO_IO_CTRL0 0x72
505
506#define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */
507
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300508/*
509 * The FX2 chip does not give us a zero length read at end of frame.
510 * It does, however, give a short read at the end of a frame, if
511 * neccessary, rather than run two frames together.
512 *
513 * By choosing the right bulk transfer size, we are guaranteed to always
514 * get a short read for the last read of each frame. Frame sizes are
515 * always a composite number (width * height, or a multiple) so if we
516 * choose a prime number, we are guaranteed that the last read of a
517 * frame will be short.
518 *
519 * But it isn't that easy: the 2.6 kernel requires a multiple of 4KB,
520 * otherwise EOVERFLOW "babbling" errors occur. I have not been able
521 * to figure out why. [PMiller]
522 *
523 * The constant (13 * 4096) is the largest "prime enough" number less than 64KB.
524 *
525 * It isn't enough to know the number of bytes per frame, in case we
526 * have data dropouts or buffer overruns (even though the FX2 double
527 * buffers, there are some pretty strict real time constraints for
528 * isochronous transfer for larger frame sizes).
529 */
530#define OVFX2_BULK_SIZE (13 * 4096)
531
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300532/* I2C registers */
533#define R51x_I2C_W_SID 0x41
534#define R51x_I2C_SADDR_3 0x42
535#define R51x_I2C_SADDR_2 0x43
536#define R51x_I2C_R_SID 0x44
537#define R51x_I2C_DATA 0x45
538#define R518_I2C_CTL 0x47 /* OV518(+) only */
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300539#define OVFX2_I2C_ADDR 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300540
541/* I2C ADDRESSES */
542#define OV7xx0_SID 0x42
Hans de Goede229bb7d2009-10-11 07:41:46 -0300543#define OV_HIRES_SID 0x60 /* OV9xxx / OV2xxx / OV3xxx */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300544#define OV8xx0_SID 0xa0
545#define OV6xx0_SID 0xc0
546
547/* OV7610 registers */
548#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */
Hans de Goede49809d62009-06-07 12:10:39 -0300549#define OV7610_REG_BLUE 0x01 /* blue channel balance */
550#define OV7610_REG_RED 0x02 /* red channel balance */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300551#define OV7610_REG_SAT 0x03 /* saturation */
552#define OV8610_REG_HUE 0x04 /* 04 reserved */
553#define OV7610_REG_CNT 0x05 /* Y contrast */
554#define OV7610_REG_BRT 0x06 /* Y brightness */
555#define OV7610_REG_COM_C 0x14 /* misc common regs */
556#define OV7610_REG_ID_HIGH 0x1c /* manufacturer ID MSB */
557#define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */
558#define OV7610_REG_COM_I 0x29 /* misc settings */
559
560/* OV7670 registers */
561#define OV7670_REG_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */
562#define OV7670_REG_BLUE 0x01 /* blue gain */
563#define OV7670_REG_RED 0x02 /* red gain */
564#define OV7670_REG_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */
565#define OV7670_REG_COM1 0x04 /* Control 1 */
566#define OV7670_REG_AECHH 0x07 /* AEC MS 5 bits */
567#define OV7670_REG_COM3 0x0c /* Control 3 */
568#define OV7670_REG_COM4 0x0d /* Control 4 */
569#define OV7670_REG_COM5 0x0e /* All "reserved" */
570#define OV7670_REG_COM6 0x0f /* Control 6 */
571#define OV7670_REG_AECH 0x10 /* More bits of AEC value */
572#define OV7670_REG_CLKRC 0x11 /* Clock control */
573#define OV7670_REG_COM7 0x12 /* Control 7 */
574#define OV7670_COM7_FMT_VGA 0x00
575#define OV7670_COM7_YUV 0x00 /* YUV */
576#define OV7670_COM7_FMT_QVGA 0x10 /* QVGA format */
577#define OV7670_COM7_FMT_MASK 0x38
578#define OV7670_COM7_RESET 0x80 /* Register reset */
579#define OV7670_REG_COM8 0x13 /* Control 8 */
580#define OV7670_COM8_AEC 0x01 /* Auto exposure enable */
581#define OV7670_COM8_AWB 0x02 /* White balance enable */
582#define OV7670_COM8_AGC 0x04 /* Auto gain enable */
583#define OV7670_COM8_BFILT 0x20 /* Band filter enable */
584#define OV7670_COM8_AECSTEP 0x40 /* Unlimited AEC step size */
585#define OV7670_COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */
586#define OV7670_REG_COM9 0x14 /* Control 9 - gain ceiling */
587#define OV7670_REG_COM10 0x15 /* Control 10 */
588#define OV7670_REG_HSTART 0x17 /* Horiz start high bits */
589#define OV7670_REG_HSTOP 0x18 /* Horiz stop high bits */
590#define OV7670_REG_VSTART 0x19 /* Vert start high bits */
591#define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */
592#define OV7670_REG_MVFP 0x1e /* Mirror / vflip */
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300593#define OV7670_MVFP_VFLIP 0x10 /* vertical flip */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300594#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */
595#define OV7670_REG_AEW 0x24 /* AGC upper limit */
596#define OV7670_REG_AEB 0x25 /* AGC lower limit */
597#define OV7670_REG_VPT 0x26 /* AGC/AEC fast mode op region */
598#define OV7670_REG_HREF 0x32 /* HREF pieces */
599#define OV7670_REG_TSLB 0x3a /* lots of stuff */
600#define OV7670_REG_COM11 0x3b /* Control 11 */
601#define OV7670_COM11_EXP 0x02
602#define OV7670_COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */
603#define OV7670_REG_COM12 0x3c /* Control 12 */
604#define OV7670_REG_COM13 0x3d /* Control 13 */
605#define OV7670_COM13_GAMMA 0x80 /* Gamma enable */
606#define OV7670_COM13_UVSAT 0x40 /* UV saturation auto adjustment */
607#define OV7670_REG_COM14 0x3e /* Control 14 */
608#define OV7670_REG_EDGE 0x3f /* Edge enhancement factor */
609#define OV7670_REG_COM15 0x40 /* Control 15 */
610#define OV7670_COM15_R00FF 0xc0 /* 00 to FF */
611#define OV7670_REG_COM16 0x41 /* Control 16 */
612#define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */
613#define OV7670_REG_BRIGHT 0x55 /* Brightness */
614#define OV7670_REG_CONTRAS 0x56 /* Contrast control */
615#define OV7670_REG_GFIX 0x69 /* Fix gain control */
616#define OV7670_REG_RGB444 0x8c /* RGB 444 control */
617#define OV7670_REG_HAECC1 0x9f /* Hist AEC/AGC control 1 */
618#define OV7670_REG_HAECC2 0xa0 /* Hist AEC/AGC control 2 */
619#define OV7670_REG_BD50MAX 0xa5 /* 50hz banding step limit */
620#define OV7670_REG_HAECC3 0xa6 /* Hist AEC/AGC control 3 */
621#define OV7670_REG_HAECC4 0xa7 /* Hist AEC/AGC control 4 */
622#define OV7670_REG_HAECC5 0xa8 /* Hist AEC/AGC control 5 */
623#define OV7670_REG_HAECC6 0xa9 /* Hist AEC/AGC control 6 */
624#define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */
625#define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */
626
Jean-Francois Moine4202f712008-09-03 17:12:15 -0300627struct ov_regvals {
628 __u8 reg;
629 __u8 val;
630};
631struct ov_i2c_regvals {
632 __u8 reg;
633 __u8 val;
634};
635
Hans de Goede635118d2009-10-11 09:49:03 -0300636/* Settings for OV2610 camera chip */
637static const struct ov_i2c_regvals norm_2610[] =
638{
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300639 { 0x12, 0x80 }, /* reset */
Hans de Goede635118d2009-10-11 09:49:03 -0300640};
641
642static const struct ov_i2c_regvals norm_3620b[] =
643{
644 /*
645 * From the datasheet: "Note that after writing to register COMH
646 * (0x12) to change the sensor mode, registers related to the
647 * sensor’s cropping window will be reset back to their default
648 * values."
649 *
650 * "wait 4096 external clock ... to make sure the sensor is
651 * stable and ready to access registers" i.e. 160us at 24MHz
652 */
653
654 { 0x12, 0x80 }, /* COMH reset */
655 { 0x12, 0x00 }, /* QXGA, master */
656
657 /*
658 * 11 CLKRC "Clock Rate Control"
659 * [7] internal frequency doublers: on
660 * [6] video port mode: master
661 * [5:0] clock divider: 1
662 */
663 { 0x11, 0x80 },
664
665 /*
666 * 13 COMI "Common Control I"
667 * = 192 (0xC0) 11000000
668 * COMI[7] "AEC speed selection"
669 * = 1 (0x01) 1....... "Faster AEC correction"
670 * COMI[6] "AEC speed step selection"
671 * = 1 (0x01) .1...... "Big steps, fast"
672 * COMI[5] "Banding filter on off"
673 * = 0 (0x00) ..0..... "Off"
674 * COMI[4] "Banding filter option"
675 * = 0 (0x00) ...0.... "Main clock is 48 MHz and
676 * the PLL is ON"
677 * COMI[3] "Reserved"
678 * = 0 (0x00) ....0...
679 * COMI[2] "AGC auto manual control selection"
680 * = 0 (0x00) .....0.. "Manual"
681 * COMI[1] "AWB auto manual control selection"
682 * = 0 (0x00) ......0. "Manual"
683 * COMI[0] "Exposure control"
684 * = 0 (0x00) .......0 "Manual"
685 */
686 { 0x13, 0xC0 },
687
688 /*
689 * 09 COMC "Common Control C"
690 * = 8 (0x08) 00001000
691 * COMC[7:5] "Reserved"
692 * = 0 (0x00) 000.....
693 * COMC[4] "Sleep Mode Enable"
694 * = 0 (0x00) ...0.... "Normal mode"
695 * COMC[3:2] "Sensor sampling reset timing selection"
696 * = 2 (0x02) ....10.. "Longer reset time"
697 * COMC[1:0] "Output drive current select"
698 * = 0 (0x00) ......00 "Weakest"
699 */
700 { 0x09, 0x08 },
701
702 /*
703 * 0C COMD "Common Control D"
704 * = 8 (0x08) 00001000
705 * COMD[7] "Reserved"
706 * = 0 (0x00) 0.......
707 * COMD[6] "Swap MSB and LSB at the output port"
708 * = 0 (0x00) .0...... "False"
709 * COMD[5:3] "Reserved"
710 * = 1 (0x01) ..001...
711 * COMD[2] "Output Average On Off"
712 * = 0 (0x00) .....0.. "Output Normal"
713 * COMD[1] "Sensor precharge voltage selection"
714 * = 0 (0x00) ......0. "Selects internal
715 * reference precharge
716 * voltage"
717 * COMD[0] "Snapshot option"
718 * = 0 (0x00) .......0 "Enable live video output
719 * after snapshot sequence"
720 */
721 { 0x0c, 0x08 },
722
723 /*
724 * 0D COME "Common Control E"
725 * = 161 (0xA1) 10100001
726 * COME[7] "Output average option"
727 * = 1 (0x01) 1....... "Output average of 4 pixels"
728 * COME[6] "Anti-blooming control"
729 * = 0 (0x00) .0...... "Off"
730 * COME[5:3] "Reserved"
731 * = 4 (0x04) ..100...
732 * COME[2] "Clock output power down pin status"
733 * = 0 (0x00) .....0.. "Tri-state data output pin
734 * on power down"
735 * COME[1] "Data output pin status selection at power down"
736 * = 0 (0x00) ......0. "Tri-state VSYNC, PCLK,
737 * HREF, and CHSYNC pins on
738 * power down"
739 * COME[0] "Auto zero circuit select"
740 * = 1 (0x01) .......1 "On"
741 */
742 { 0x0d, 0xA1 },
743
744 /*
745 * 0E COMF "Common Control F"
746 * = 112 (0x70) 01110000
747 * COMF[7] "System clock selection"
748 * = 0 (0x00) 0....... "Use 24 MHz system clock"
749 * COMF[6:4] "Reserved"
750 * = 7 (0x07) .111....
751 * COMF[3] "Manual auto negative offset canceling selection"
752 * = 0 (0x00) ....0... "Auto detect negative
753 * offset and cancel it"
754 * COMF[2:0] "Reserved"
755 * = 0 (0x00) .....000
756 */
757 { 0x0e, 0x70 },
758
759 /*
760 * 0F COMG "Common Control G"
761 * = 66 (0x42) 01000010
762 * COMG[7] "Optical black output selection"
763 * = 0 (0x00) 0....... "Disable"
764 * COMG[6] "Black level calibrate selection"
765 * = 1 (0x01) .1...... "Use optical black pixels
766 * to calibrate"
767 * COMG[5:4] "Reserved"
768 * = 0 (0x00) ..00....
769 * COMG[3] "Channel offset adjustment"
770 * = 0 (0x00) ....0... "Disable offset adjustment"
771 * COMG[2] "ADC black level calibration option"
772 * = 0 (0x00) .....0.. "Use B/G line and G/R
773 * line to calibrate each
774 * channel's black level"
775 * COMG[1] "Reserved"
776 * = 1 (0x01) ......1.
777 * COMG[0] "ADC black level calibration enable"
778 * = 0 (0x00) .......0 "Disable"
779 */
780 { 0x0f, 0x42 },
781
782 /*
783 * 14 COMJ "Common Control J"
784 * = 198 (0xC6) 11000110
785 * COMJ[7:6] "AGC gain ceiling"
786 * = 3 (0x03) 11...... "8x"
787 * COMJ[5:4] "Reserved"
788 * = 0 (0x00) ..00....
789 * COMJ[3] "Auto banding filter"
790 * = 0 (0x00) ....0... "Banding filter is always
791 * on off depending on
792 * COMI[5] setting"
793 * COMJ[2] "VSYNC drop option"
794 * = 1 (0x01) .....1.. "SYNC is dropped if frame
795 * data is dropped"
796 * COMJ[1] "Frame data drop"
797 * = 1 (0x01) ......1. "Drop frame data if
798 * exposure is not within
799 * tolerance. In AEC mode,
800 * data is normally dropped
801 * when data is out of
802 * range."
803 * COMJ[0] "Reserved"
804 * = 0 (0x00) .......0
805 */
806 { 0x14, 0xC6 },
807
808 /*
809 * 15 COMK "Common Control K"
810 * = 2 (0x02) 00000010
811 * COMK[7] "CHSYNC pin output swap"
812 * = 0 (0x00) 0....... "CHSYNC"
813 * COMK[6] "HREF pin output swap"
814 * = 0 (0x00) .0...... "HREF"
815 * COMK[5] "PCLK output selection"
816 * = 0 (0x00) ..0..... "PCLK always output"
817 * COMK[4] "PCLK edge selection"
818 * = 0 (0x00) ...0.... "Data valid on falling edge"
819 * COMK[3] "HREF output polarity"
820 * = 0 (0x00) ....0... "positive"
821 * COMK[2] "Reserved"
822 * = 0 (0x00) .....0..
823 * COMK[1] "VSYNC polarity"
824 * = 1 (0x01) ......1. "negative"
825 * COMK[0] "HSYNC polarity"
826 * = 0 (0x00) .......0 "positive"
827 */
828 { 0x15, 0x02 },
829
830 /*
831 * 33 CHLF "Current Control"
832 * = 9 (0x09) 00001001
833 * CHLF[7:6] "Sensor current control"
834 * = 0 (0x00) 00......
835 * CHLF[5] "Sensor current range control"
836 * = 0 (0x00) ..0..... "normal range"
837 * CHLF[4] "Sensor current"
838 * = 0 (0x00) ...0.... "normal current"
839 * CHLF[3] "Sensor buffer current control"
840 * = 1 (0x01) ....1... "half current"
841 * CHLF[2] "Column buffer current control"
842 * = 0 (0x00) .....0.. "normal current"
843 * CHLF[1] "Analog DSP current control"
844 * = 0 (0x00) ......0. "normal current"
845 * CHLF[1] "ADC current control"
846 * = 0 (0x00) ......0. "normal current"
847 */
848 { 0x33, 0x09 },
849
850 /*
851 * 34 VBLM "Blooming Control"
852 * = 80 (0x50) 01010000
853 * VBLM[7] "Hard soft reset switch"
854 * = 0 (0x00) 0....... "Hard reset"
855 * VBLM[6:4] "Blooming voltage selection"
856 * = 5 (0x05) .101....
857 * VBLM[3:0] "Sensor current control"
858 * = 0 (0x00) ....0000
859 */
860 { 0x34, 0x50 },
861
862 /*
863 * 36 VCHG "Sensor Precharge Voltage Control"
864 * = 0 (0x00) 00000000
865 * VCHG[7] "Reserved"
866 * = 0 (0x00) 0.......
867 * VCHG[6:4] "Sensor precharge voltage control"
868 * = 0 (0x00) .000....
869 * VCHG[3:0] "Sensor array common reference"
870 * = 0 (0x00) ....0000
871 */
872 { 0x36, 0x00 },
873
874 /*
875 * 37 ADC "ADC Reference Control"
876 * = 4 (0x04) 00000100
877 * ADC[7:4] "Reserved"
878 * = 0 (0x00) 0000....
879 * ADC[3] "ADC input signal range"
880 * = 0 (0x00) ....0... "Input signal 1.0x"
881 * ADC[2:0] "ADC range control"
882 * = 4 (0x04) .....100
883 */
884 { 0x37, 0x04 },
885
886 /*
887 * 38 ACOM "Analog Common Ground"
888 * = 82 (0x52) 01010010
889 * ACOM[7] "Analog gain control"
890 * = 0 (0x00) 0....... "Gain 1x"
891 * ACOM[6] "Analog black level calibration"
892 * = 1 (0x01) .1...... "On"
893 * ACOM[5:0] "Reserved"
894 * = 18 (0x12) ..010010
895 */
896 { 0x38, 0x52 },
897
898 /*
899 * 3A FREFA "Internal Reference Adjustment"
900 * = 0 (0x00) 00000000
901 * FREFA[7:0] "Range"
902 * = 0 (0x00) 00000000
903 */
904 { 0x3a, 0x00 },
905
906 /*
907 * 3C FVOPT "Internal Reference Adjustment"
908 * = 31 (0x1F) 00011111
909 * FVOPT[7:0] "Range"
910 * = 31 (0x1F) 00011111
911 */
912 { 0x3c, 0x1F },
913
914 /*
915 * 44 Undocumented = 0 (0x00) 00000000
916 * 44[7:0] "It's a secret"
917 * = 0 (0x00) 00000000
918 */
919 { 0x44, 0x00 },
920
921 /*
922 * 40 Undocumented = 0 (0x00) 00000000
923 * 40[7:0] "It's a secret"
924 * = 0 (0x00) 00000000
925 */
926 { 0x40, 0x00 },
927
928 /*
929 * 41 Undocumented = 0 (0x00) 00000000
930 * 41[7:0] "It's a secret"
931 * = 0 (0x00) 00000000
932 */
933 { 0x41, 0x00 },
934
935 /*
936 * 42 Undocumented = 0 (0x00) 00000000
937 * 42[7:0] "It's a secret"
938 * = 0 (0x00) 00000000
939 */
940 { 0x42, 0x00 },
941
942 /*
943 * 43 Undocumented = 0 (0x00) 00000000
944 * 43[7:0] "It's a secret"
945 * = 0 (0x00) 00000000
946 */
947 { 0x43, 0x00 },
948
949 /*
950 * 45 Undocumented = 128 (0x80) 10000000
951 * 45[7:0] "It's a secret"
952 * = 128 (0x80) 10000000
953 */
954 { 0x45, 0x80 },
955
956 /*
957 * 48 Undocumented = 192 (0xC0) 11000000
958 * 48[7:0] "It's a secret"
959 * = 192 (0xC0) 11000000
960 */
961 { 0x48, 0xC0 },
962
963 /*
964 * 49 Undocumented = 25 (0x19) 00011001
965 * 49[7:0] "It's a secret"
966 * = 25 (0x19) 00011001
967 */
968 { 0x49, 0x19 },
969
970 /*
971 * 4B Undocumented = 128 (0x80) 10000000
972 * 4B[7:0] "It's a secret"
973 * = 128 (0x80) 10000000
974 */
975 { 0x4B, 0x80 },
976
977 /*
978 * 4D Undocumented = 196 (0xC4) 11000100
979 * 4D[7:0] "It's a secret"
980 * = 196 (0xC4) 11000100
981 */
982 { 0x4D, 0xC4 },
983
984 /*
985 * 35 VREF "Reference Voltage Control"
986 * = 76 (0x4C) 01001100
987 * VREF[7:5] "Column high reference control"
988 * = 2 (0x02) 010..... "higher voltage"
989 * VREF[4:2] "Column low reference control"
990 * = 3 (0x03) ...011.. "Highest voltage"
991 * VREF[1:0] "Reserved"
992 * = 0 (0x00) ......00
993 */
994 { 0x35, 0x4C },
995
996 /*
997 * 3D Undocumented = 0 (0x00) 00000000
998 * 3D[7:0] "It's a secret"
999 * = 0 (0x00) 00000000
1000 */
1001 { 0x3D, 0x00 },
1002
1003 /*
1004 * 3E Undocumented = 0 (0x00) 00000000
1005 * 3E[7:0] "It's a secret"
1006 * = 0 (0x00) 00000000
1007 */
1008 { 0x3E, 0x00 },
1009
1010 /*
1011 * 3B FREFB "Internal Reference Adjustment"
1012 * = 24 (0x18) 00011000
1013 * FREFB[7:0] "Range"
1014 * = 24 (0x18) 00011000
1015 */
1016 { 0x3b, 0x18 },
1017
1018 /*
1019 * 33 CHLF "Current Control"
1020 * = 25 (0x19) 00011001
1021 * CHLF[7:6] "Sensor current control"
1022 * = 0 (0x00) 00......
1023 * CHLF[5] "Sensor current range control"
1024 * = 0 (0x00) ..0..... "normal range"
1025 * CHLF[4] "Sensor current"
1026 * = 1 (0x01) ...1.... "double current"
1027 * CHLF[3] "Sensor buffer current control"
1028 * = 1 (0x01) ....1... "half current"
1029 * CHLF[2] "Column buffer current control"
1030 * = 0 (0x00) .....0.. "normal current"
1031 * CHLF[1] "Analog DSP current control"
1032 * = 0 (0x00) ......0. "normal current"
1033 * CHLF[1] "ADC current control"
1034 * = 0 (0x00) ......0. "normal current"
1035 */
1036 { 0x33, 0x19 },
1037
1038 /*
1039 * 34 VBLM "Blooming Control"
1040 * = 90 (0x5A) 01011010
1041 * VBLM[7] "Hard soft reset switch"
1042 * = 0 (0x00) 0....... "Hard reset"
1043 * VBLM[6:4] "Blooming voltage selection"
1044 * = 5 (0x05) .101....
1045 * VBLM[3:0] "Sensor current control"
1046 * = 10 (0x0A) ....1010
1047 */
1048 { 0x34, 0x5A },
1049
1050 /*
1051 * 3B FREFB "Internal Reference Adjustment"
1052 * = 0 (0x00) 00000000
1053 * FREFB[7:0] "Range"
1054 * = 0 (0x00) 00000000
1055 */
1056 { 0x3b, 0x00 },
1057
1058 /*
1059 * 33 CHLF "Current Control"
1060 * = 9 (0x09) 00001001
1061 * CHLF[7:6] "Sensor current control"
1062 * = 0 (0x00) 00......
1063 * CHLF[5] "Sensor current range control"
1064 * = 0 (0x00) ..0..... "normal range"
1065 * CHLF[4] "Sensor current"
1066 * = 0 (0x00) ...0.... "normal current"
1067 * CHLF[3] "Sensor buffer current control"
1068 * = 1 (0x01) ....1... "half current"
1069 * CHLF[2] "Column buffer current control"
1070 * = 0 (0x00) .....0.. "normal current"
1071 * CHLF[1] "Analog DSP current control"
1072 * = 0 (0x00) ......0. "normal current"
1073 * CHLF[1] "ADC current control"
1074 * = 0 (0x00) ......0. "normal current"
1075 */
1076 { 0x33, 0x09 },
1077
1078 /*
1079 * 34 VBLM "Blooming Control"
1080 * = 80 (0x50) 01010000
1081 * VBLM[7] "Hard soft reset switch"
1082 * = 0 (0x00) 0....... "Hard reset"
1083 * VBLM[6:4] "Blooming voltage selection"
1084 * = 5 (0x05) .101....
1085 * VBLM[3:0] "Sensor current control"
1086 * = 0 (0x00) ....0000
1087 */
1088 { 0x34, 0x50 },
1089
1090 /*
1091 * 12 COMH "Common Control H"
1092 * = 64 (0x40) 01000000
1093 * COMH[7] "SRST"
1094 * = 0 (0x00) 0....... "No-op"
1095 * COMH[6:4] "Resolution selection"
1096 * = 4 (0x04) .100.... "XGA"
1097 * COMH[3] "Master slave selection"
1098 * = 0 (0x00) ....0... "Master mode"
1099 * COMH[2] "Internal B/R channel option"
1100 * = 0 (0x00) .....0.. "B/R use same channel"
1101 * COMH[1] "Color bar test pattern"
1102 * = 0 (0x00) ......0. "Off"
1103 * COMH[0] "Reserved"
1104 * = 0 (0x00) .......0
1105 */
1106 { 0x12, 0x40 },
1107
1108 /*
1109 * 17 HREFST "Horizontal window start"
1110 * = 31 (0x1F) 00011111
1111 * HREFST[7:0] "Horizontal window start, 8 MSBs"
1112 * = 31 (0x1F) 00011111
1113 */
1114 { 0x17, 0x1F },
1115
1116 /*
1117 * 18 HREFEND "Horizontal window end"
1118 * = 95 (0x5F) 01011111
1119 * HREFEND[7:0] "Horizontal Window End, 8 MSBs"
1120 * = 95 (0x5F) 01011111
1121 */
1122 { 0x18, 0x5F },
1123
1124 /*
1125 * 19 VSTRT "Vertical window start"
1126 * = 0 (0x00) 00000000
1127 * VSTRT[7:0] "Vertical Window Start, 8 MSBs"
1128 * = 0 (0x00) 00000000
1129 */
1130 { 0x19, 0x00 },
1131
1132 /*
1133 * 1A VEND "Vertical window end"
1134 * = 96 (0x60) 01100000
1135 * VEND[7:0] "Vertical Window End, 8 MSBs"
1136 * = 96 (0x60) 01100000
1137 */
1138 { 0x1a, 0x60 },
1139
1140 /*
1141 * 32 COMM "Common Control M"
1142 * = 18 (0x12) 00010010
1143 * COMM[7:6] "Pixel clock divide option"
1144 * = 0 (0x00) 00...... "/1"
1145 * COMM[5:3] "Horizontal window end position, 3 LSBs"
1146 * = 2 (0x02) ..010...
1147 * COMM[2:0] "Horizontal window start position, 3 LSBs"
1148 * = 2 (0x02) .....010
1149 */
1150 { 0x32, 0x12 },
1151
1152 /*
1153 * 03 COMA "Common Control A"
1154 * = 74 (0x4A) 01001010
1155 * COMA[7:4] "AWB Update Threshold"
1156 * = 4 (0x04) 0100....
1157 * COMA[3:2] "Vertical window end line control 2 LSBs"
1158 * = 2 (0x02) ....10..
1159 * COMA[1:0] "Vertical window start line control 2 LSBs"
1160 * = 2 (0x02) ......10
1161 */
1162 { 0x03, 0x4A },
1163
1164 /*
1165 * 11 CLKRC "Clock Rate Control"
1166 * = 128 (0x80) 10000000
1167 * CLKRC[7] "Internal frequency doublers on off seclection"
1168 * = 1 (0x01) 1....... "On"
1169 * CLKRC[6] "Digital video master slave selection"
1170 * = 0 (0x00) .0...... "Master mode, sensor
1171 * provides PCLK"
1172 * CLKRC[5:0] "Clock divider { CLK = PCLK/(1+CLKRC[5:0]) }"
1173 * = 0 (0x00) ..000000
1174 */
1175 { 0x11, 0x80 },
1176
1177 /*
1178 * 12 COMH "Common Control H"
1179 * = 0 (0x00) 00000000
1180 * COMH[7] "SRST"
1181 * = 0 (0x00) 0....... "No-op"
1182 * COMH[6:4] "Resolution selection"
1183 * = 0 (0x00) .000.... "QXGA"
1184 * COMH[3] "Master slave selection"
1185 * = 0 (0x00) ....0... "Master mode"
1186 * COMH[2] "Internal B/R channel option"
1187 * = 0 (0x00) .....0.. "B/R use same channel"
1188 * COMH[1] "Color bar test pattern"
1189 * = 0 (0x00) ......0. "Off"
1190 * COMH[0] "Reserved"
1191 * = 0 (0x00) .......0
1192 */
1193 { 0x12, 0x00 },
1194
1195 /*
1196 * 12 COMH "Common Control H"
1197 * = 64 (0x40) 01000000
1198 * COMH[7] "SRST"
1199 * = 0 (0x00) 0....... "No-op"
1200 * COMH[6:4] "Resolution selection"
1201 * = 4 (0x04) .100.... "XGA"
1202 * COMH[3] "Master slave selection"
1203 * = 0 (0x00) ....0... "Master mode"
1204 * COMH[2] "Internal B/R channel option"
1205 * = 0 (0x00) .....0.. "B/R use same channel"
1206 * COMH[1] "Color bar test pattern"
1207 * = 0 (0x00) ......0. "Off"
1208 * COMH[0] "Reserved"
1209 * = 0 (0x00) .......0
1210 */
1211 { 0x12, 0x40 },
1212
1213 /*
1214 * 17 HREFST "Horizontal window start"
1215 * = 31 (0x1F) 00011111
1216 * HREFST[7:0] "Horizontal window start, 8 MSBs"
1217 * = 31 (0x1F) 00011111
1218 */
1219 { 0x17, 0x1F },
1220
1221 /*
1222 * 18 HREFEND "Horizontal window end"
1223 * = 95 (0x5F) 01011111
1224 * HREFEND[7:0] "Horizontal Window End, 8 MSBs"
1225 * = 95 (0x5F) 01011111
1226 */
1227 { 0x18, 0x5F },
1228
1229 /*
1230 * 19 VSTRT "Vertical window start"
1231 * = 0 (0x00) 00000000
1232 * VSTRT[7:0] "Vertical Window Start, 8 MSBs"
1233 * = 0 (0x00) 00000000
1234 */
1235 { 0x19, 0x00 },
1236
1237 /*
1238 * 1A VEND "Vertical window end"
1239 * = 96 (0x60) 01100000
1240 * VEND[7:0] "Vertical Window End, 8 MSBs"
1241 * = 96 (0x60) 01100000
1242 */
1243 { 0x1a, 0x60 },
1244
1245 /*
1246 * 32 COMM "Common Control M"
1247 * = 18 (0x12) 00010010
1248 * COMM[7:6] "Pixel clock divide option"
1249 * = 0 (0x00) 00...... "/1"
1250 * COMM[5:3] "Horizontal window end position, 3 LSBs"
1251 * = 2 (0x02) ..010...
1252 * COMM[2:0] "Horizontal window start position, 3 LSBs"
1253 * = 2 (0x02) .....010
1254 */
1255 { 0x32, 0x12 },
1256
1257 /*
1258 * 03 COMA "Common Control A"
1259 * = 74 (0x4A) 01001010
1260 * COMA[7:4] "AWB Update Threshold"
1261 * = 4 (0x04) 0100....
1262 * COMA[3:2] "Vertical window end line control 2 LSBs"
1263 * = 2 (0x02) ....10..
1264 * COMA[1:0] "Vertical window start line control 2 LSBs"
1265 * = 2 (0x02) ......10
1266 */
1267 { 0x03, 0x4A },
1268
1269 /*
1270 * 02 RED "Red Gain Control"
1271 * = 175 (0xAF) 10101111
1272 * RED[7] "Action"
1273 * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
1274 * RED[6:0] "Value"
1275 * = 47 (0x2F) .0101111
1276 */
1277 { 0x02, 0xAF },
1278
1279 /*
1280 * 2D ADDVSL "VSYNC Pulse Width"
1281 * = 210 (0xD2) 11010010
1282 * ADDVSL[7:0] "VSYNC pulse width, LSB"
1283 * = 210 (0xD2) 11010010
1284 */
1285 { 0x2d, 0xD2 },
1286
1287 /*
1288 * 00 GAIN = 24 (0x18) 00011000
1289 * GAIN[7:6] "Reserved"
1290 * = 0 (0x00) 00......
1291 * GAIN[5] "Double"
1292 * = 0 (0x00) ..0..... "False"
1293 * GAIN[4] "Double"
1294 * = 1 (0x01) ...1.... "True"
1295 * GAIN[3:0] "Range"
1296 * = 8 (0x08) ....1000
1297 */
1298 { 0x00, 0x18 },
1299
1300 /*
1301 * 01 BLUE "Blue Gain Control"
1302 * = 240 (0xF0) 11110000
1303 * BLUE[7] "Action"
1304 * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
1305 * BLUE[6:0] "Value"
1306 * = 112 (0x70) .1110000
1307 */
1308 { 0x01, 0xF0 },
1309
1310 /*
1311 * 10 AEC "Automatic Exposure Control"
1312 * = 10 (0x0A) 00001010
1313 * AEC[7:0] "Automatic Exposure Control, 8 MSBs"
1314 * = 10 (0x0A) 00001010
1315 */
1316 { 0x10, 0x0A },
1317
1318 { 0xE1, 0x67 },
1319 { 0xE3, 0x03 },
1320 { 0xE4, 0x26 },
1321 { 0xE5, 0x3E },
1322 { 0xF8, 0x01 },
1323 { 0xFF, 0x01 },
1324};
1325
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001326static const struct ov_i2c_regvals norm_6x20[] = {
1327 { 0x12, 0x80 }, /* reset */
1328 { 0x11, 0x01 },
1329 { 0x03, 0x60 },
1330 { 0x05, 0x7f }, /* For when autoadjust is off */
1331 { 0x07, 0xa8 },
1332 /* The ratio of 0x0c and 0x0d controls the white point */
1333 { 0x0c, 0x24 },
1334 { 0x0d, 0x24 },
1335 { 0x0f, 0x15 }, /* COMS */
1336 { 0x10, 0x75 }, /* AEC Exposure time */
1337 { 0x12, 0x24 }, /* Enable AGC */
1338 { 0x14, 0x04 },
1339 /* 0x16: 0x06 helps frame stability with moving objects */
1340 { 0x16, 0x06 },
1341/* { 0x20, 0x30 }, * Aperture correction enable */
1342 { 0x26, 0xb2 }, /* BLC enable */
1343 /* 0x28: 0x05 Selects RGB format if RGB on */
1344 { 0x28, 0x05 },
1345 { 0x2a, 0x04 }, /* Disable framerate adjust */
1346/* { 0x2b, 0xac }, * Framerate; Set 2a[7] first */
Hans de Goedeae49c402009-06-14 19:15:07 -03001347 { 0x2d, 0x85 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001348 { 0x33, 0xa0 }, /* Color Processing Parameter */
1349 { 0x34, 0xd2 }, /* Max A/D range */
1350 { 0x38, 0x8b },
1351 { 0x39, 0x40 },
1352
1353 { 0x3c, 0x39 }, /* Enable AEC mode changing */
1354 { 0x3c, 0x3c }, /* Change AEC mode */
1355 { 0x3c, 0x24 }, /* Disable AEC mode changing */
1356
1357 { 0x3d, 0x80 },
1358 /* These next two registers (0x4a, 0x4b) are undocumented.
1359 * They control the color balance */
1360 { 0x4a, 0x80 },
1361 { 0x4b, 0x80 },
1362 { 0x4d, 0xd2 }, /* This reduces noise a bit */
1363 { 0x4e, 0xc1 },
1364 { 0x4f, 0x04 },
1365/* Do 50-53 have any effect? */
1366/* Toggle 0x12[2] off and on here? */
1367};
1368
1369static const struct ov_i2c_regvals norm_6x30[] = {
1370 { 0x12, 0x80 }, /* Reset */
1371 { 0x00, 0x1f }, /* Gain */
1372 { 0x01, 0x99 }, /* Blue gain */
1373 { 0x02, 0x7c }, /* Red gain */
1374 { 0x03, 0xc0 }, /* Saturation */
1375 { 0x05, 0x0a }, /* Contrast */
1376 { 0x06, 0x95 }, /* Brightness */
1377 { 0x07, 0x2d }, /* Sharpness */
1378 { 0x0c, 0x20 },
1379 { 0x0d, 0x20 },
Hans de Goede02ab18b2009-06-14 04:32:04 -03001380 { 0x0e, 0xa0 }, /* Was 0x20, bit7 enables a 2x gain which we need */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001381 { 0x0f, 0x05 },
1382 { 0x10, 0x9a },
1383 { 0x11, 0x00 }, /* Pixel clock = fastest */
1384 { 0x12, 0x24 }, /* Enable AGC and AWB */
1385 { 0x13, 0x21 },
1386 { 0x14, 0x80 },
1387 { 0x15, 0x01 },
1388 { 0x16, 0x03 },
1389 { 0x17, 0x38 },
1390 { 0x18, 0xea },
1391 { 0x19, 0x04 },
1392 { 0x1a, 0x93 },
1393 { 0x1b, 0x00 },
1394 { 0x1e, 0xc4 },
1395 { 0x1f, 0x04 },
1396 { 0x20, 0x20 },
1397 { 0x21, 0x10 },
1398 { 0x22, 0x88 },
1399 { 0x23, 0xc0 }, /* Crystal circuit power level */
1400 { 0x25, 0x9a }, /* Increase AEC black ratio */
1401 { 0x26, 0xb2 }, /* BLC enable */
1402 { 0x27, 0xa2 },
1403 { 0x28, 0x00 },
1404 { 0x29, 0x00 },
1405 { 0x2a, 0x84 }, /* 60 Hz power */
1406 { 0x2b, 0xa8 }, /* 60 Hz power */
1407 { 0x2c, 0xa0 },
1408 { 0x2d, 0x95 }, /* Enable auto-brightness */
1409 { 0x2e, 0x88 },
1410 { 0x33, 0x26 },
1411 { 0x34, 0x03 },
1412 { 0x36, 0x8f },
1413 { 0x37, 0x80 },
1414 { 0x38, 0x83 },
1415 { 0x39, 0x80 },
1416 { 0x3a, 0x0f },
1417 { 0x3b, 0x3c },
1418 { 0x3c, 0x1a },
1419 { 0x3d, 0x80 },
1420 { 0x3e, 0x80 },
1421 { 0x3f, 0x0e },
1422 { 0x40, 0x00 }, /* White bal */
1423 { 0x41, 0x00 }, /* White bal */
1424 { 0x42, 0x80 },
1425 { 0x43, 0x3f }, /* White bal */
1426 { 0x44, 0x80 },
1427 { 0x45, 0x20 },
1428 { 0x46, 0x20 },
1429 { 0x47, 0x80 },
1430 { 0x48, 0x7f },
1431 { 0x49, 0x00 },
1432 { 0x4a, 0x00 },
1433 { 0x4b, 0x80 },
1434 { 0x4c, 0xd0 },
1435 { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
1436 { 0x4e, 0x40 },
1437 { 0x4f, 0x07 }, /* UV avg., col. killer: max */
1438 { 0x50, 0xff },
1439 { 0x54, 0x23 }, /* Max AGC gain: 18dB */
1440 { 0x55, 0xff },
1441 { 0x56, 0x12 },
1442 { 0x57, 0x81 },
1443 { 0x58, 0x75 },
1444 { 0x59, 0x01 }, /* AGC dark current comp.: +1 */
1445 { 0x5a, 0x2c },
1446 { 0x5b, 0x0f }, /* AWB chrominance levels */
1447 { 0x5c, 0x10 },
1448 { 0x3d, 0x80 },
1449 { 0x27, 0xa6 },
1450 { 0x12, 0x20 }, /* Toggle AWB */
1451 { 0x12, 0x24 },
1452};
1453
1454/* Lawrence Glaister <lg@jfm.bc.ca> reports:
1455 *
1456 * Register 0x0f in the 7610 has the following effects:
1457 *
1458 * 0x85 (AEC method 1): Best overall, good contrast range
1459 * 0x45 (AEC method 2): Very overexposed
1460 * 0xa5 (spec sheet default): Ok, but the black level is
1461 * shifted resulting in loss of contrast
1462 * 0x05 (old driver setting): very overexposed, too much
1463 * contrast
1464 */
1465static const struct ov_i2c_regvals norm_7610[] = {
1466 { 0x10, 0xff },
1467 { 0x16, 0x06 },
1468 { 0x28, 0x24 },
1469 { 0x2b, 0xac },
1470 { 0x12, 0x00 },
1471 { 0x38, 0x81 },
1472 { 0x28, 0x24 }, /* 0c */
1473 { 0x0f, 0x85 }, /* lg's setting */
1474 { 0x15, 0x01 },
1475 { 0x20, 0x1c },
1476 { 0x23, 0x2a },
1477 { 0x24, 0x10 },
1478 { 0x25, 0x8a },
1479 { 0x26, 0xa2 },
1480 { 0x27, 0xc2 },
1481 { 0x2a, 0x04 },
1482 { 0x2c, 0xfe },
1483 { 0x2d, 0x93 },
1484 { 0x30, 0x71 },
1485 { 0x31, 0x60 },
1486 { 0x32, 0x26 },
1487 { 0x33, 0x20 },
1488 { 0x34, 0x48 },
1489 { 0x12, 0x24 },
1490 { 0x11, 0x01 },
1491 { 0x0c, 0x24 },
1492 { 0x0d, 0x24 },
1493};
1494
1495static const struct ov_i2c_regvals norm_7620[] = {
Hans de Goedea511ba92009-10-16 07:13:07 -03001496 { 0x12, 0x80 }, /* reset */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001497 { 0x00, 0x00 }, /* gain */
1498 { 0x01, 0x80 }, /* blue gain */
1499 { 0x02, 0x80 }, /* red gain */
1500 { 0x03, 0xc0 }, /* OV7670_REG_VREF */
1501 { 0x06, 0x60 },
1502 { 0x07, 0x00 },
1503 { 0x0c, 0x24 },
1504 { 0x0c, 0x24 },
1505 { 0x0d, 0x24 },
1506 { 0x11, 0x01 },
1507 { 0x12, 0x24 },
1508 { 0x13, 0x01 },
1509 { 0x14, 0x84 },
1510 { 0x15, 0x01 },
1511 { 0x16, 0x03 },
1512 { 0x17, 0x2f },
1513 { 0x18, 0xcf },
1514 { 0x19, 0x06 },
1515 { 0x1a, 0xf5 },
1516 { 0x1b, 0x00 },
1517 { 0x20, 0x18 },
1518 { 0x21, 0x80 },
1519 { 0x22, 0x80 },
1520 { 0x23, 0x00 },
1521 { 0x26, 0xa2 },
1522 { 0x27, 0xea },
Hans de Goedeb282d872009-06-14 19:10:40 -03001523 { 0x28, 0x22 }, /* Was 0x20, bit1 enables a 2x gain which we need */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001524 { 0x29, 0x00 },
1525 { 0x2a, 0x10 },
1526 { 0x2b, 0x00 },
1527 { 0x2c, 0x88 },
1528 { 0x2d, 0x91 },
1529 { 0x2e, 0x80 },
1530 { 0x2f, 0x44 },
1531 { 0x60, 0x27 },
1532 { 0x61, 0x02 },
1533 { 0x62, 0x5f },
1534 { 0x63, 0xd5 },
1535 { 0x64, 0x57 },
1536 { 0x65, 0x83 },
1537 { 0x66, 0x55 },
1538 { 0x67, 0x92 },
1539 { 0x68, 0xcf },
1540 { 0x69, 0x76 },
1541 { 0x6a, 0x22 },
1542 { 0x6b, 0x00 },
1543 { 0x6c, 0x02 },
1544 { 0x6d, 0x44 },
1545 { 0x6e, 0x80 },
1546 { 0x6f, 0x1d },
1547 { 0x70, 0x8b },
1548 { 0x71, 0x00 },
1549 { 0x72, 0x14 },
1550 { 0x73, 0x54 },
1551 { 0x74, 0x00 },
1552 { 0x75, 0x8e },
1553 { 0x76, 0x00 },
1554 { 0x77, 0xff },
1555 { 0x78, 0x80 },
1556 { 0x79, 0x80 },
1557 { 0x7a, 0x80 },
1558 { 0x7b, 0xe2 },
1559 { 0x7c, 0x00 },
1560};
1561
1562/* 7640 and 7648. The defaults should be OK for most registers. */
1563static const struct ov_i2c_regvals norm_7640[] = {
1564 { 0x12, 0x80 },
1565 { 0x12, 0x14 },
1566};
1567
1568/* 7670. Defaults taken from OmniVision provided data,
1569* as provided by Jonathan Corbet of OLPC */
1570static const struct ov_i2c_regvals norm_7670[] = {
1571 { OV7670_REG_COM7, OV7670_COM7_RESET },
1572 { OV7670_REG_TSLB, 0x04 }, /* OV */
1573 { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
1574 { OV7670_REG_CLKRC, 0x01 },
1575/*
1576 * Set the hardware window. These values from OV don't entirely
1577 * make sense - hstop is less than hstart. But they work...
1578 */
1579 { OV7670_REG_HSTART, 0x13 },
1580 { OV7670_REG_HSTOP, 0x01 },
1581 { OV7670_REG_HREF, 0xb6 },
1582 { OV7670_REG_VSTART, 0x02 },
1583 { OV7670_REG_VSTOP, 0x7a },
1584 { OV7670_REG_VREF, 0x0a },
1585
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001586 { OV7670_REG_COM3, 0x00 },
1587 { OV7670_REG_COM14, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001588/* Mystery scaling numbers */
1589 { 0x70, 0x3a },
1590 { 0x71, 0x35 },
1591 { 0x72, 0x11 },
1592 { 0x73, 0xf0 },
1593 { 0xa2, 0x02 },
1594/* { OV7670_REG_COM10, 0x0 }, */
1595
1596/* Gamma curve values */
1597 { 0x7a, 0x20 },
1598 { 0x7b, 0x10 },
1599 { 0x7c, 0x1e },
1600 { 0x7d, 0x35 },
1601 { 0x7e, 0x5a },
1602 { 0x7f, 0x69 },
1603 { 0x80, 0x76 },
1604 { 0x81, 0x80 },
1605 { 0x82, 0x88 },
1606 { 0x83, 0x8f },
1607 { 0x84, 0x96 },
1608 { 0x85, 0xa3 },
1609 { 0x86, 0xaf },
1610 { 0x87, 0xc4 },
1611 { 0x88, 0xd7 },
1612 { 0x89, 0xe8 },
1613
1614/* AGC and AEC parameters. Note we start by disabling those features,
1615 then turn them only after tweaking the values. */
1616 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
1617 | OV7670_COM8_AECSTEP
1618 | OV7670_COM8_BFILT },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001619 { OV7670_REG_GAIN, 0x00 },
1620 { OV7670_REG_AECH, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001621 { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */
1622 { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
1623 { OV7670_REG_BD50MAX, 0x05 },
1624 { OV7670_REG_BD60MAX, 0x07 },
1625 { OV7670_REG_AEW, 0x95 },
1626 { OV7670_REG_AEB, 0x33 },
1627 { OV7670_REG_VPT, 0xe3 },
1628 { OV7670_REG_HAECC1, 0x78 },
1629 { OV7670_REG_HAECC2, 0x68 },
1630 { 0xa1, 0x03 }, /* magic */
1631 { OV7670_REG_HAECC3, 0xd8 },
1632 { OV7670_REG_HAECC4, 0xd8 },
1633 { OV7670_REG_HAECC5, 0xf0 },
1634 { OV7670_REG_HAECC6, 0x90 },
1635 { OV7670_REG_HAECC7, 0x94 },
1636 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
1637 | OV7670_COM8_AECSTEP
1638 | OV7670_COM8_BFILT
1639 | OV7670_COM8_AGC
1640 | OV7670_COM8_AEC },
1641
1642/* Almost all of these are magic "reserved" values. */
1643 { OV7670_REG_COM5, 0x61 },
1644 { OV7670_REG_COM6, 0x4b },
1645 { 0x16, 0x02 },
1646 { OV7670_REG_MVFP, 0x07 },
1647 { 0x21, 0x02 },
1648 { 0x22, 0x91 },
1649 { 0x29, 0x07 },
1650 { 0x33, 0x0b },
1651 { 0x35, 0x0b },
1652 { 0x37, 0x1d },
1653 { 0x38, 0x71 },
1654 { 0x39, 0x2a },
1655 { OV7670_REG_COM12, 0x78 },
1656 { 0x4d, 0x40 },
1657 { 0x4e, 0x20 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001658 { OV7670_REG_GFIX, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001659 { 0x6b, 0x4a },
1660 { 0x74, 0x10 },
1661 { 0x8d, 0x4f },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001662 { 0x8e, 0x00 },
1663 { 0x8f, 0x00 },
1664 { 0x90, 0x00 },
1665 { 0x91, 0x00 },
1666 { 0x96, 0x00 },
1667 { 0x9a, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001668 { 0xb0, 0x84 },
1669 { 0xb1, 0x0c },
1670 { 0xb2, 0x0e },
1671 { 0xb3, 0x82 },
1672 { 0xb8, 0x0a },
1673
1674/* More reserved magic, some of which tweaks white balance */
1675 { 0x43, 0x0a },
1676 { 0x44, 0xf0 },
1677 { 0x45, 0x34 },
1678 { 0x46, 0x58 },
1679 { 0x47, 0x28 },
1680 { 0x48, 0x3a },
1681 { 0x59, 0x88 },
1682 { 0x5a, 0x88 },
1683 { 0x5b, 0x44 },
1684 { 0x5c, 0x67 },
1685 { 0x5d, 0x49 },
1686 { 0x5e, 0x0e },
1687 { 0x6c, 0x0a },
1688 { 0x6d, 0x55 },
1689 { 0x6e, 0x11 },
1690 { 0x6f, 0x9f },
1691 /* "9e for advance AWB" */
1692 { 0x6a, 0x40 },
1693 { OV7670_REG_BLUE, 0x40 },
1694 { OV7670_REG_RED, 0x60 },
1695 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
1696 | OV7670_COM8_AECSTEP
1697 | OV7670_COM8_BFILT
1698 | OV7670_COM8_AGC
1699 | OV7670_COM8_AEC
1700 | OV7670_COM8_AWB },
1701
1702/* Matrix coefficients */
1703 { 0x4f, 0x80 },
1704 { 0x50, 0x80 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001705 { 0x51, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001706 { 0x52, 0x22 },
1707 { 0x53, 0x5e },
1708 { 0x54, 0x80 },
1709 { 0x58, 0x9e },
1710
1711 { OV7670_REG_COM16, OV7670_COM16_AWBGAIN },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001712 { OV7670_REG_EDGE, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001713 { 0x75, 0x05 },
1714 { 0x76, 0xe1 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001715 { 0x4c, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001716 { 0x77, 0x01 },
1717 { OV7670_REG_COM13, OV7670_COM13_GAMMA
1718 | OV7670_COM13_UVSAT
1719 | 2}, /* was 3 */
1720 { 0x4b, 0x09 },
1721 { 0xc9, 0x60 },
1722 { OV7670_REG_COM16, 0x38 },
1723 { 0x56, 0x40 },
1724
1725 { 0x34, 0x11 },
1726 { OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
1727 { 0xa4, 0x88 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001728 { 0x96, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001729 { 0x97, 0x30 },
1730 { 0x98, 0x20 },
1731 { 0x99, 0x30 },
1732 { 0x9a, 0x84 },
1733 { 0x9b, 0x29 },
1734 { 0x9c, 0x03 },
1735 { 0x9d, 0x4c },
1736 { 0x9e, 0x3f },
1737 { 0x78, 0x04 },
1738
1739/* Extra-weird stuff. Some sort of multiplexor register */
1740 { 0x79, 0x01 },
1741 { 0xc8, 0xf0 },
1742 { 0x79, 0x0f },
1743 { 0xc8, 0x00 },
1744 { 0x79, 0x10 },
1745 { 0xc8, 0x7e },
1746 { 0x79, 0x0a },
1747 { 0xc8, 0x80 },
1748 { 0x79, 0x0b },
1749 { 0xc8, 0x01 },
1750 { 0x79, 0x0c },
1751 { 0xc8, 0x0f },
1752 { 0x79, 0x0d },
1753 { 0xc8, 0x20 },
1754 { 0x79, 0x09 },
1755 { 0xc8, 0x80 },
1756 { 0x79, 0x02 },
1757 { 0xc8, 0xc0 },
1758 { 0x79, 0x03 },
1759 { 0xc8, 0x40 },
1760 { 0x79, 0x05 },
1761 { 0xc8, 0x30 },
1762 { 0x79, 0x26 },
1763};
1764
1765static const struct ov_i2c_regvals norm_8610[] = {
1766 { 0x12, 0x80 },
1767 { 0x00, 0x00 },
1768 { 0x01, 0x80 },
1769 { 0x02, 0x80 },
1770 { 0x03, 0xc0 },
1771 { 0x04, 0x30 },
1772 { 0x05, 0x30 }, /* was 0x10, new from windrv 090403 */
1773 { 0x06, 0x70 }, /* was 0x80, new from windrv 090403 */
1774 { 0x0a, 0x86 },
1775 { 0x0b, 0xb0 },
1776 { 0x0c, 0x20 },
1777 { 0x0d, 0x20 },
1778 { 0x11, 0x01 },
1779 { 0x12, 0x25 },
1780 { 0x13, 0x01 },
1781 { 0x14, 0x04 },
1782 { 0x15, 0x01 }, /* Lin and Win think different about UV order */
1783 { 0x16, 0x03 },
1784 { 0x17, 0x38 }, /* was 0x2f, new from windrv 090403 */
1785 { 0x18, 0xea }, /* was 0xcf, new from windrv 090403 */
1786 { 0x19, 0x02 }, /* was 0x06, new from windrv 090403 */
1787 { 0x1a, 0xf5 },
1788 { 0x1b, 0x00 },
1789 { 0x20, 0xd0 }, /* was 0x90, new from windrv 090403 */
1790 { 0x23, 0xc0 }, /* was 0x00, new from windrv 090403 */
1791 { 0x24, 0x30 }, /* was 0x1d, new from windrv 090403 */
1792 { 0x25, 0x50 }, /* was 0x57, new from windrv 090403 */
1793 { 0x26, 0xa2 },
1794 { 0x27, 0xea },
1795 { 0x28, 0x00 },
1796 { 0x29, 0x00 },
1797 { 0x2a, 0x80 },
1798 { 0x2b, 0xc8 }, /* was 0xcc, new from windrv 090403 */
1799 { 0x2c, 0xac },
1800 { 0x2d, 0x45 }, /* was 0xd5, new from windrv 090403 */
1801 { 0x2e, 0x80 },
1802 { 0x2f, 0x14 }, /* was 0x01, new from windrv 090403 */
1803 { 0x4c, 0x00 },
1804 { 0x4d, 0x30 }, /* was 0x10, new from windrv 090403 */
1805 { 0x60, 0x02 }, /* was 0x01, new from windrv 090403 */
1806 { 0x61, 0x00 }, /* was 0x09, new from windrv 090403 */
1807 { 0x62, 0x5f }, /* was 0xd7, new from windrv 090403 */
1808 { 0x63, 0xff },
1809 { 0x64, 0x53 }, /* new windrv 090403 says 0x57,
1810 * maybe thats wrong */
1811 { 0x65, 0x00 },
1812 { 0x66, 0x55 },
1813 { 0x67, 0xb0 },
1814 { 0x68, 0xc0 }, /* was 0xaf, new from windrv 090403 */
1815 { 0x69, 0x02 },
1816 { 0x6a, 0x22 },
1817 { 0x6b, 0x00 },
1818 { 0x6c, 0x99 }, /* was 0x80, old windrv says 0x00, but
1819 * deleting bit7 colors the first images red */
1820 { 0x6d, 0x11 }, /* was 0x00, new from windrv 090403 */
1821 { 0x6e, 0x11 }, /* was 0x00, new from windrv 090403 */
1822 { 0x6f, 0x01 },
1823 { 0x70, 0x8b },
1824 { 0x71, 0x00 },
1825 { 0x72, 0x14 },
1826 { 0x73, 0x54 },
1827 { 0x74, 0x00 },/* 0x60? - was 0x00, new from windrv 090403 */
1828 { 0x75, 0x0e },
1829 { 0x76, 0x02 }, /* was 0x02, new from windrv 090403 */
1830 { 0x77, 0xff },
1831 { 0x78, 0x80 },
1832 { 0x79, 0x80 },
1833 { 0x7a, 0x80 },
1834 { 0x7b, 0x10 }, /* was 0x13, new from windrv 090403 */
1835 { 0x7c, 0x00 },
1836 { 0x7d, 0x08 }, /* was 0x09, new from windrv 090403 */
1837 { 0x7e, 0x08 }, /* was 0xc0, new from windrv 090403 */
1838 { 0x7f, 0xfb },
1839 { 0x80, 0x28 },
1840 { 0x81, 0x00 },
1841 { 0x82, 0x23 },
1842 { 0x83, 0x0b },
1843 { 0x84, 0x00 },
1844 { 0x85, 0x62 }, /* was 0x61, new from windrv 090403 */
1845 { 0x86, 0xc9 },
1846 { 0x87, 0x00 },
1847 { 0x88, 0x00 },
1848 { 0x89, 0x01 },
1849 { 0x12, 0x20 },
1850 { 0x12, 0x25 }, /* was 0x24, new from windrv 090403 */
1851};
1852
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001853static unsigned char ov7670_abs_to_sm(unsigned char v)
1854{
1855 if (v > 127)
1856 return v & 0x7f;
1857 return (128 - v) | 0x80;
1858}
1859
1860/* Write a OV519 register */
Hans de Goedea511ba92009-10-16 07:13:07 -03001861static int reg_w(struct sd *sd, __u16 index, __u16 value)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001862{
Hans de Goedea511ba92009-10-16 07:13:07 -03001863 int ret, req = 0;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001864
1865 switch (sd->bridge) {
1866 case BRIDGE_OV511:
1867 case BRIDGE_OV511PLUS:
1868 req = 2;
1869 break;
1870 case BRIDGE_OVFX2:
Hans de Goedea511ba92009-10-16 07:13:07 -03001871 req = 0x0a;
1872 /* fall through */
1873 case BRIDGE_W9968CF:
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001874 ret = usb_control_msg(sd->gspca_dev.dev,
1875 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
Hans de Goedea511ba92009-10-16 07:13:07 -03001876 req,
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001877 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Hans de Goedea511ba92009-10-16 07:13:07 -03001878 value, index, NULL, 0, 500);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001879 goto leave;
1880 default:
1881 req = 1;
1882 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001883
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001884 sd->gspca_dev.usb_buf[0] = value;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001885 ret = usb_control_msg(sd->gspca_dev.dev,
1886 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
Hans de Goede49809d62009-06-07 12:10:39 -03001887 req,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001888 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1889 0, index,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001890 sd->gspca_dev.usb_buf, 1, 500);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001891leave:
Hans de Goedea511ba92009-10-16 07:13:07 -03001892 if (ret < 0) {
1893 PDEBUG(D_ERR, "Write reg 0x%04x -> [0x%02x] failed",
1894 value, index);
1895 return ret;
1896 }
1897
1898 PDEBUG(D_USBO, "Write reg 0x%04x -> [0x%02x]", value, index);
1899 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001900}
1901
Hans de Goedea511ba92009-10-16 07:13:07 -03001902/* Read from a OV519 register, note not valid for the w9968cf!! */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001903/* returns: negative is error, pos or zero is data */
1904static int reg_r(struct sd *sd, __u16 index)
1905{
1906 int ret;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001907 int req;
1908
1909 switch (sd->bridge) {
1910 case BRIDGE_OV511:
1911 case BRIDGE_OV511PLUS:
1912 req = 3;
1913 break;
1914 case BRIDGE_OVFX2:
1915 req = 0x0b;
1916 break;
1917 default:
1918 req = 1;
1919 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001920
1921 ret = usb_control_msg(sd->gspca_dev.dev,
1922 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
Hans de Goede49809d62009-06-07 12:10:39 -03001923 req,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001924 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001925 0, index, sd->gspca_dev.usb_buf, 1, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001926
Hans de Goedea511ba92009-10-16 07:13:07 -03001927 if (ret >= 0) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001928 ret = sd->gspca_dev.usb_buf[0];
Hans de Goedea511ba92009-10-16 07:13:07 -03001929 PDEBUG(D_USBI, "Read reg [0x%02X] -> 0x%04X", index, ret);
1930 } else
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001931 PDEBUG(D_ERR, "Read reg [0x%02x] failed", index);
Hans de Goedea511ba92009-10-16 07:13:07 -03001932
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001933 return ret;
1934}
1935
1936/* Read 8 values from a OV519 register */
1937static int reg_r8(struct sd *sd,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001938 __u16 index)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001939{
1940 int ret;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001941
1942 ret = usb_control_msg(sd->gspca_dev.dev,
1943 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
1944 1, /* REQ_IO */
1945 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001946 0, index, sd->gspca_dev.usb_buf, 8, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001947
1948 if (ret >= 0)
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001949 ret = sd->gspca_dev.usb_buf[0];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001950 else
1951 PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index);
Hans de Goedea511ba92009-10-16 07:13:07 -03001952
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001953 return ret;
1954}
1955
1956/*
1957 * Writes bits at positions specified by mask to an OV51x reg. Bits that are in
1958 * the same position as 1's in "mask" are cleared and set to "value". Bits
1959 * that are in the same position as 0's in "mask" are preserved, regardless
1960 * of their respective state in "value".
1961 */
1962static int reg_w_mask(struct sd *sd,
1963 __u16 index,
1964 __u8 value,
1965 __u8 mask)
1966{
1967 int ret;
1968 __u8 oldval;
1969
1970 if (mask != 0xff) {
1971 value &= mask; /* Enforce mask on value */
1972 ret = reg_r(sd, index);
1973 if (ret < 0)
1974 return ret;
1975
1976 oldval = ret & ~mask; /* Clear the masked bits */
1977 value |= oldval; /* Set the desired bits */
1978 }
1979 return reg_w(sd, index, value);
1980}
1981
1982/*
Hans de Goede49809d62009-06-07 12:10:39 -03001983 * Writes multiple (n) byte value to a single register. Only valid with certain
1984 * registers (0x30 and 0xc4 - 0xce).
1985 */
1986static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n)
1987{
1988 int ret;
1989
Jean-Francois Moine83955552009-12-12 06:58:01 -03001990 *((__le32 *) sd->gspca_dev.usb_buf) = __cpu_to_le32(value);
Hans de Goede49809d62009-06-07 12:10:39 -03001991
1992 ret = usb_control_msg(sd->gspca_dev.dev,
1993 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
1994 1 /* REG_IO */,
1995 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1996 0, index,
1997 sd->gspca_dev.usb_buf, n, 500);
Hans de Goedea511ba92009-10-16 07:13:07 -03001998 if (ret < 0) {
Hans de Goede49809d62009-06-07 12:10:39 -03001999 PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value);
Hans de Goedea511ba92009-10-16 07:13:07 -03002000 return ret;
2001 }
2002
2003 return 0;
Hans de Goede49809d62009-06-07 12:10:39 -03002004}
2005
Hans de Goede1876bb92009-06-14 06:45:50 -03002006static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value)
2007{
2008 int rc, retries;
2009
2010 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
2011
2012 /* Three byte write cycle */
2013 for (retries = 6; ; ) {
2014 /* Select camera register */
2015 rc = reg_w(sd, R51x_I2C_SADDR_3, reg);
2016 if (rc < 0)
2017 return rc;
2018
2019 /* Write "value" to I2C data port of OV511 */
2020 rc = reg_w(sd, R51x_I2C_DATA, value);
2021 if (rc < 0)
2022 return rc;
2023
2024 /* Initiate 3-byte write cycle */
2025 rc = reg_w(sd, R511_I2C_CTL, 0x01);
2026 if (rc < 0)
2027 return rc;
2028
Jean-Francois Moine83955552009-12-12 06:58:01 -03002029 do {
Hans de Goede1876bb92009-06-14 06:45:50 -03002030 rc = reg_r(sd, R511_I2C_CTL);
Jean-Francois Moine83955552009-12-12 06:58:01 -03002031 } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
Hans de Goede1876bb92009-06-14 06:45:50 -03002032
2033 if (rc < 0)
2034 return rc;
2035
2036 if ((rc & 2) == 0) /* Ack? */
2037 break;
2038 if (--retries < 0) {
2039 PDEBUG(D_USBO, "i2c write retries exhausted");
2040 return -1;
2041 }
2042 }
2043
2044 return 0;
2045}
2046
2047static int ov511_i2c_r(struct sd *sd, __u8 reg)
2048{
2049 int rc, value, retries;
2050
2051 /* Two byte write cycle */
2052 for (retries = 6; ; ) {
2053 /* Select camera register */
2054 rc = reg_w(sd, R51x_I2C_SADDR_2, reg);
2055 if (rc < 0)
2056 return rc;
2057
2058 /* Initiate 2-byte write cycle */
2059 rc = reg_w(sd, R511_I2C_CTL, 0x03);
2060 if (rc < 0)
2061 return rc;
2062
Jean-Francois Moine83955552009-12-12 06:58:01 -03002063 do {
Hans de Goede1876bb92009-06-14 06:45:50 -03002064 rc = reg_r(sd, R511_I2C_CTL);
Jean-Francois Moine83955552009-12-12 06:58:01 -03002065 } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
Hans de Goede1876bb92009-06-14 06:45:50 -03002066
2067 if (rc < 0)
2068 return rc;
2069
2070 if ((rc & 2) == 0) /* Ack? */
2071 break;
2072
2073 /* I2C abort */
2074 reg_w(sd, R511_I2C_CTL, 0x10);
2075
2076 if (--retries < 0) {
2077 PDEBUG(D_USBI, "i2c write retries exhausted");
2078 return -1;
2079 }
2080 }
2081
2082 /* Two byte read cycle */
2083 for (retries = 6; ; ) {
2084 /* Initiate 2-byte read cycle */
2085 rc = reg_w(sd, R511_I2C_CTL, 0x05);
2086 if (rc < 0)
2087 return rc;
2088
Jean-Francois Moine83955552009-12-12 06:58:01 -03002089 do {
Hans de Goede1876bb92009-06-14 06:45:50 -03002090 rc = reg_r(sd, R511_I2C_CTL);
Jean-Francois Moine83955552009-12-12 06:58:01 -03002091 } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
Hans de Goede1876bb92009-06-14 06:45:50 -03002092
2093 if (rc < 0)
2094 return rc;
2095
2096 if ((rc & 2) == 0) /* Ack? */
2097 break;
2098
2099 /* I2C abort */
2100 rc = reg_w(sd, R511_I2C_CTL, 0x10);
2101 if (rc < 0)
2102 return rc;
2103
2104 if (--retries < 0) {
2105 PDEBUG(D_USBI, "i2c read retries exhausted");
2106 return -1;
2107 }
2108 }
2109
2110 value = reg_r(sd, R51x_I2C_DATA);
2111
2112 PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
2113
2114 /* This is needed to make i2c_w() work */
2115 rc = reg_w(sd, R511_I2C_CTL, 0x05);
2116 if (rc < 0)
2117 return rc;
2118
2119 return value;
2120}
Hans de Goede49809d62009-06-07 12:10:39 -03002121
2122/*
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002123 * The OV518 I2C I/O procedure is different, hence, this function.
2124 * This is normally only called from i2c_w(). Note that this function
2125 * always succeeds regardless of whether the sensor is present and working.
2126 */
Hans de Goede1876bb92009-06-14 06:45:50 -03002127static int ov518_i2c_w(struct sd *sd,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002128 __u8 reg,
2129 __u8 value)
2130{
2131 int rc;
2132
2133 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
2134
2135 /* Select camera register */
2136 rc = reg_w(sd, R51x_I2C_SADDR_3, reg);
2137 if (rc < 0)
2138 return rc;
2139
2140 /* Write "value" to I2C data port of OV511 */
2141 rc = reg_w(sd, R51x_I2C_DATA, value);
2142 if (rc < 0)
2143 return rc;
2144
2145 /* Initiate 3-byte write cycle */
2146 rc = reg_w(sd, R518_I2C_CTL, 0x01);
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002147 if (rc < 0)
2148 return rc;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002149
2150 /* wait for write complete */
2151 msleep(4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002152 return reg_r8(sd, R518_I2C_CTL);
2153}
2154
2155/*
2156 * returns: negative is error, pos or zero is data
2157 *
2158 * The OV518 I2C I/O procedure is different, hence, this function.
2159 * This is normally only called from i2c_r(). Note that this function
2160 * always succeeds regardless of whether the sensor is present and working.
2161 */
Hans de Goede1876bb92009-06-14 06:45:50 -03002162static int ov518_i2c_r(struct sd *sd, __u8 reg)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002163{
2164 int rc, value;
2165
2166 /* Select camera register */
2167 rc = reg_w(sd, R51x_I2C_SADDR_2, reg);
2168 if (rc < 0)
2169 return rc;
2170
2171 /* Initiate 2-byte write cycle */
2172 rc = reg_w(sd, R518_I2C_CTL, 0x03);
2173 if (rc < 0)
2174 return rc;
2175
2176 /* Initiate 2-byte read cycle */
2177 rc = reg_w(sd, R518_I2C_CTL, 0x05);
2178 if (rc < 0)
2179 return rc;
2180 value = reg_r(sd, R51x_I2C_DATA);
2181 PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
2182 return value;
2183}
2184
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002185static int ovfx2_i2c_w(struct sd *sd, __u8 reg, __u8 value)
2186{
2187 int ret;
2188
2189 ret = usb_control_msg(sd->gspca_dev.dev,
2190 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
2191 0x02,
2192 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2193 (__u16)value, (__u16)reg, NULL, 0, 500);
2194
Hans de Goedea511ba92009-10-16 07:13:07 -03002195 if (ret < 0) {
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002196 PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg);
Hans de Goedea511ba92009-10-16 07:13:07 -03002197 return ret;
2198 }
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002199
Hans de Goedea511ba92009-10-16 07:13:07 -03002200 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
2201 return 0;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002202}
2203
2204static int ovfx2_i2c_r(struct sd *sd, __u8 reg)
2205{
2206 int ret;
2207
2208 ret = usb_control_msg(sd->gspca_dev.dev,
2209 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
2210 0x03,
2211 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2212 0, (__u16)reg, sd->gspca_dev.usb_buf, 1, 500);
2213
2214 if (ret >= 0) {
2215 ret = sd->gspca_dev.usb_buf[0];
2216 PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, ret);
2217 } else
2218 PDEBUG(D_ERR, "i2c read [0x%02x] failed", reg);
2219
2220 return ret;
2221}
2222
Hans de Goede1876bb92009-06-14 06:45:50 -03002223static int i2c_w(struct sd *sd, __u8 reg, __u8 value)
2224{
Hans de Goedefb1f9022009-10-16 07:42:53 -03002225 int ret = -1;
2226
2227 if (sd->sensor_reg_cache[reg] == value)
2228 return 0;
2229
Hans de Goede1876bb92009-06-14 06:45:50 -03002230 switch (sd->bridge) {
2231 case BRIDGE_OV511:
2232 case BRIDGE_OV511PLUS:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002233 ret = ov511_i2c_w(sd, reg, value);
2234 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002235 case BRIDGE_OV518:
2236 case BRIDGE_OV518PLUS:
2237 case BRIDGE_OV519:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002238 ret = ov518_i2c_w(sd, reg, value);
2239 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002240 case BRIDGE_OVFX2:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002241 ret = ovfx2_i2c_w(sd, reg, value);
2242 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03002243 case BRIDGE_W9968CF:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002244 ret = w9968cf_i2c_w(sd, reg, value);
2245 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002246 }
Hans de Goedefb1f9022009-10-16 07:42:53 -03002247
2248 if (ret >= 0) {
2249 /* Up on sensor reset empty the register cache */
2250 if (reg == 0x12 && (value & 0x80))
2251 memset(sd->sensor_reg_cache, -1,
2252 sizeof(sd->sensor_reg_cache));
2253 else
2254 sd->sensor_reg_cache[reg] = value;
2255 }
2256
2257 return ret;
Hans de Goede1876bb92009-06-14 06:45:50 -03002258}
2259
2260static int i2c_r(struct sd *sd, __u8 reg)
2261{
Hans de Goede8394bcf2009-10-16 11:26:22 -03002262 int ret = -1;
Hans de Goedefb1f9022009-10-16 07:42:53 -03002263
2264 if (sd->sensor_reg_cache[reg] != -1)
2265 return sd->sensor_reg_cache[reg];
2266
Hans de Goede1876bb92009-06-14 06:45:50 -03002267 switch (sd->bridge) {
2268 case BRIDGE_OV511:
2269 case BRIDGE_OV511PLUS:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002270 ret = ov511_i2c_r(sd, reg);
2271 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002272 case BRIDGE_OV518:
2273 case BRIDGE_OV518PLUS:
2274 case BRIDGE_OV519:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002275 ret = ov518_i2c_r(sd, reg);
2276 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002277 case BRIDGE_OVFX2:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002278 ret = ovfx2_i2c_r(sd, reg);
2279 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03002280 case BRIDGE_W9968CF:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002281 ret = w9968cf_i2c_r(sd, reg);
2282 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002283 }
Hans de Goedefb1f9022009-10-16 07:42:53 -03002284
2285 if (ret >= 0)
2286 sd->sensor_reg_cache[reg] = ret;
2287
2288 return ret;
Hans de Goede1876bb92009-06-14 06:45:50 -03002289}
2290
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002291/* Writes bits at positions specified by mask to an I2C reg. Bits that are in
2292 * the same position as 1's in "mask" are cleared and set to "value". Bits
2293 * that are in the same position as 0's in "mask" are preserved, regardless
2294 * of their respective state in "value".
2295 */
2296static int i2c_w_mask(struct sd *sd,
2297 __u8 reg,
2298 __u8 value,
2299 __u8 mask)
2300{
2301 int rc;
2302 __u8 oldval;
2303
2304 value &= mask; /* Enforce mask on value */
2305 rc = i2c_r(sd, reg);
2306 if (rc < 0)
2307 return rc;
2308 oldval = rc & ~mask; /* Clear the masked bits */
2309 value |= oldval; /* Set the desired bits */
2310 return i2c_w(sd, reg, value);
2311}
2312
2313/* Temporarily stops OV511 from functioning. Must do this before changing
2314 * registers while the camera is streaming */
2315static inline int ov51x_stop(struct sd *sd)
2316{
2317 PDEBUG(D_STREAM, "stopping");
2318 sd->stopped = 1;
Hans de Goede49809d62009-06-07 12:10:39 -03002319 switch (sd->bridge) {
2320 case BRIDGE_OV511:
2321 case BRIDGE_OV511PLUS:
2322 return reg_w(sd, R51x_SYS_RESET, 0x3d);
2323 case BRIDGE_OV518:
2324 case BRIDGE_OV518PLUS:
2325 return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
2326 case BRIDGE_OV519:
2327 return reg_w(sd, OV519_SYS_RESET1, 0x0f);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002328 case BRIDGE_OVFX2:
2329 return reg_w_mask(sd, 0x0f, 0x00, 0x02);
Hans de Goedea511ba92009-10-16 07:13:07 -03002330 case BRIDGE_W9968CF:
Hans de Goede79b35902009-10-19 06:08:01 -03002331 return reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */
Hans de Goede49809d62009-06-07 12:10:39 -03002332 }
2333
2334 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002335}
2336
2337/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
2338 * actually stopped (for performance). */
2339static inline int ov51x_restart(struct sd *sd)
2340{
Hans de Goede49809d62009-06-07 12:10:39 -03002341 int rc;
2342
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002343 PDEBUG(D_STREAM, "restarting");
2344 if (!sd->stopped)
2345 return 0;
2346 sd->stopped = 0;
2347
2348 /* Reinitialize the stream */
Hans de Goede49809d62009-06-07 12:10:39 -03002349 switch (sd->bridge) {
2350 case BRIDGE_OV511:
2351 case BRIDGE_OV511PLUS:
2352 return reg_w(sd, R51x_SYS_RESET, 0x00);
2353 case BRIDGE_OV518:
2354 case BRIDGE_OV518PLUS:
2355 rc = reg_w(sd, 0x2f, 0x80);
2356 if (rc < 0)
2357 return rc;
2358 return reg_w(sd, R51x_SYS_RESET, 0x00);
2359 case BRIDGE_OV519:
2360 return reg_w(sd, OV519_SYS_RESET1, 0x00);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002361 case BRIDGE_OVFX2:
2362 return reg_w_mask(sd, 0x0f, 0x02, 0x02);
Hans de Goedea511ba92009-10-16 07:13:07 -03002363 case BRIDGE_W9968CF:
2364 return reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */
Hans de Goede49809d62009-06-07 12:10:39 -03002365 }
2366
2367 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002368}
2369
Hans de Goede229bb7d2009-10-11 07:41:46 -03002370static int ov51x_set_slave_ids(struct sd *sd, __u8 slave);
2371
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002372/* This does an initial reset of an OmniVision sensor and ensures that I2C
2373 * is synchronized. Returns <0 on failure.
2374 */
Hans de Goede229bb7d2009-10-11 07:41:46 -03002375static int init_ov_sensor(struct sd *sd, __u8 slave)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002376{
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002377 int i;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002378
Hans de Goede229bb7d2009-10-11 07:41:46 -03002379 if (ov51x_set_slave_ids(sd, slave) < 0)
2380 return -EIO;
2381
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002382 /* Reset the sensor */
2383 if (i2c_w(sd, 0x12, 0x80) < 0)
2384 return -EIO;
2385
2386 /* Wait for it to initialize */
2387 msleep(150);
2388
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002389 for (i = 0; i < i2c_detect_tries; i++) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002390 if (i2c_r(sd, OV7610_REG_ID_HIGH) == 0x7f &&
2391 i2c_r(sd, OV7610_REG_ID_LOW) == 0xa2) {
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002392 PDEBUG(D_PROBE, "I2C synced in %d attempt(s)", i);
2393 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002394 }
2395
2396 /* Reset the sensor */
2397 if (i2c_w(sd, 0x12, 0x80) < 0)
2398 return -EIO;
2399 /* Wait for it to initialize */
2400 msleep(150);
2401 /* Dummy read to sync I2C */
2402 if (i2c_r(sd, 0x00) < 0)
2403 return -EIO;
2404 }
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002405 return -EIO;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002406}
2407
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002408/* Set the read and write slave IDs. The "slave" argument is the write slave,
2409 * and the read slave will be set to (slave + 1).
2410 * This should not be called from outside the i2c I/O functions.
2411 * Sets I2C read and write slave IDs. Returns <0 for error
2412 */
2413static int ov51x_set_slave_ids(struct sd *sd,
2414 __u8 slave)
2415{
2416 int rc;
2417
Hans de Goedea511ba92009-10-16 07:13:07 -03002418 switch (sd->bridge) {
2419 case BRIDGE_OVFX2:
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002420 return reg_w(sd, OVFX2_I2C_ADDR, slave);
Hans de Goedea511ba92009-10-16 07:13:07 -03002421 case BRIDGE_W9968CF:
2422 sd->sensor_addr = slave;
2423 return 0;
2424 }
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002425
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002426 rc = reg_w(sd, R51x_I2C_W_SID, slave);
2427 if (rc < 0)
2428 return rc;
2429 return reg_w(sd, R51x_I2C_R_SID, slave + 1);
2430}
2431
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002432static int write_regvals(struct sd *sd,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002433 const struct ov_regvals *regvals,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002434 int n)
2435{
2436 int rc;
2437
2438 while (--n >= 0) {
2439 rc = reg_w(sd, regvals->reg, regvals->val);
2440 if (rc < 0)
2441 return rc;
2442 regvals++;
2443 }
2444 return 0;
2445}
2446
2447static int write_i2c_regvals(struct sd *sd,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002448 const struct ov_i2c_regvals *regvals,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002449 int n)
2450{
2451 int rc;
2452
2453 while (--n >= 0) {
2454 rc = i2c_w(sd, regvals->reg, regvals->val);
2455 if (rc < 0)
2456 return rc;
2457 regvals++;
2458 }
2459 return 0;
2460}
2461
2462/****************************************************************************
2463 *
2464 * OV511 and sensor configuration
2465 *
2466 ***************************************************************************/
2467
Hans de Goede635118d2009-10-11 09:49:03 -03002468/* This initializes the OV2x10 / OV3610 / OV3620 */
2469static int ov_hires_configure(struct sd *sd)
2470{
2471 int high, low;
2472
2473 if (sd->bridge != BRIDGE_OVFX2) {
2474 PDEBUG(D_ERR, "error hires sensors only supported with ovfx2");
2475 return -1;
2476 }
2477
2478 PDEBUG(D_PROBE, "starting ov hires configuration");
2479
2480 /* Detect sensor (sub)type */
2481 high = i2c_r(sd, 0x0a);
2482 low = i2c_r(sd, 0x0b);
2483 /* info("%x, %x", high, low); */
2484 if (high == 0x96 && low == 0x40) {
2485 PDEBUG(D_PROBE, "Sensor is an OV2610");
2486 sd->sensor = SEN_OV2610;
2487 } else if (high == 0x36 && (low & 0x0f) == 0x00) {
2488 PDEBUG(D_PROBE, "Sensor is an OV3610");
2489 sd->sensor = SEN_OV3610;
2490 } else {
2491 PDEBUG(D_ERR, "Error unknown sensor type: 0x%02x%02x",
2492 high, low);
2493 return -1;
2494 }
2495
2496 /* Set sensor-specific vars */
2497 return 0;
2498}
2499
2500
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002501/* This initializes the OV8110, OV8610 sensor. The OV8110 uses
2502 * the same register settings as the OV8610, since they are very similar.
2503 */
2504static int ov8xx0_configure(struct sd *sd)
2505{
2506 int rc;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002507
2508 PDEBUG(D_PROBE, "starting ov8xx0 configuration");
2509
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002510 /* Detect sensor (sub)type */
2511 rc = i2c_r(sd, OV7610_REG_COM_I);
2512 if (rc < 0) {
2513 PDEBUG(D_ERR, "Error detecting sensor type");
2514 return -1;
2515 }
2516 if ((rc & 3) == 1) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002517 sd->sensor = SEN_OV8610;
2518 } else {
2519 PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3);
2520 return -1;
2521 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002522
2523 /* Set sensor-specific vars */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002524 return 0;
2525}
2526
2527/* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses
2528 * the same register settings as the OV7610, since they are very similar.
2529 */
2530static int ov7xx0_configure(struct sd *sd)
2531{
2532 int rc, high, low;
2533
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002534
2535 PDEBUG(D_PROBE, "starting OV7xx0 configuration");
2536
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002537 /* Detect sensor (sub)type */
2538 rc = i2c_r(sd, OV7610_REG_COM_I);
2539
2540 /* add OV7670 here
2541 * it appears to be wrongly detected as a 7610 by default */
2542 if (rc < 0) {
2543 PDEBUG(D_ERR, "Error detecting sensor type");
2544 return -1;
2545 }
2546 if ((rc & 3) == 3) {
2547 /* quick hack to make OV7670s work */
2548 high = i2c_r(sd, 0x0a);
2549 low = i2c_r(sd, 0x0b);
2550 /* info("%x, %x", high, low); */
2551 if (high == 0x76 && low == 0x73) {
2552 PDEBUG(D_PROBE, "Sensor is an OV7670");
2553 sd->sensor = SEN_OV7670;
2554 } else {
2555 PDEBUG(D_PROBE, "Sensor is an OV7610");
2556 sd->sensor = SEN_OV7610;
2557 }
2558 } else if ((rc & 3) == 1) {
2559 /* I don't know what's different about the 76BE yet. */
Hans de Goedeb282d872009-06-14 19:10:40 -03002560 if (i2c_r(sd, 0x15) & 1) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002561 PDEBUG(D_PROBE, "Sensor is an OV7620AE");
Hans de Goede859cc472010-01-07 15:42:35 -03002562 sd->sensor = SEN_OV7620AE;
Hans de Goedeb282d872009-06-14 19:10:40 -03002563 } else {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002564 PDEBUG(D_PROBE, "Sensor is an OV76BE");
Hans de Goedeb282d872009-06-14 19:10:40 -03002565 sd->sensor = SEN_OV76BE;
2566 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002567 } else if ((rc & 3) == 0) {
2568 /* try to read product id registers */
2569 high = i2c_r(sd, 0x0a);
2570 if (high < 0) {
2571 PDEBUG(D_ERR, "Error detecting camera chip PID");
2572 return high;
2573 }
2574 low = i2c_r(sd, 0x0b);
2575 if (low < 0) {
2576 PDEBUG(D_ERR, "Error detecting camera chip VER");
2577 return low;
2578 }
2579 if (high == 0x76) {
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002580 switch (low) {
2581 case 0x30:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002582 PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635");
Jean-Francois Moine4202f712008-09-03 17:12:15 -03002583 PDEBUG(D_ERR,
2584 "7630 is not supported by this driver");
2585 return -1;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002586 case 0x40:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002587 PDEBUG(D_PROBE, "Sensor is an OV7645");
2588 sd->sensor = SEN_OV7640; /* FIXME */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002589 break;
2590 case 0x45:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002591 PDEBUG(D_PROBE, "Sensor is an OV7645B");
2592 sd->sensor = SEN_OV7640; /* FIXME */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002593 break;
2594 case 0x48:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002595 PDEBUG(D_PROBE, "Sensor is an OV7648");
Hans de Goede035d3a32010-01-09 08:14:43 -03002596 sd->sensor = SEN_OV7648;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002597 break;
2598 default:
2599 PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002600 return -1;
2601 }
2602 } else {
2603 PDEBUG(D_PROBE, "Sensor is an OV7620");
2604 sd->sensor = SEN_OV7620;
2605 }
2606 } else {
2607 PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3);
2608 return -1;
2609 }
2610
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002611 /* Set sensor-specific vars */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002612 return 0;
2613}
2614
2615/* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */
2616static int ov6xx0_configure(struct sd *sd)
2617{
2618 int rc;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03002619 PDEBUG(D_PROBE, "starting OV6xx0 configuration");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002620
2621 /* Detect sensor (sub)type */
2622 rc = i2c_r(sd, OV7610_REG_COM_I);
2623 if (rc < 0) {
2624 PDEBUG(D_ERR, "Error detecting sensor type");
2625 return -1;
2626 }
2627
2628 /* Ugh. The first two bits are the version bits, but
2629 * the entire register value must be used. I guess OVT
2630 * underestimated how many variants they would make. */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002631 switch (rc) {
2632 case 0x00:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002633 sd->sensor = SEN_OV6630;
2634 PDEBUG(D_ERR,
2635 "WARNING: Sensor is an OV66308. Your camera may have");
2636 PDEBUG(D_ERR, "been misdetected in previous driver versions.");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002637 break;
2638 case 0x01:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002639 sd->sensor = SEN_OV6620;
Hans de Goede7d971372009-06-14 05:28:17 -03002640 PDEBUG(D_PROBE, "Sensor is an OV6620");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002641 break;
2642 case 0x02:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002643 sd->sensor = SEN_OV6630;
2644 PDEBUG(D_PROBE, "Sensor is an OV66308AE");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002645 break;
2646 case 0x03:
Hans de Goede7d971372009-06-14 05:28:17 -03002647 sd->sensor = SEN_OV66308AF;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002648 PDEBUG(D_PROBE, "Sensor is an OV66308AF");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002649 break;
2650 case 0x90:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002651 sd->sensor = SEN_OV6630;
2652 PDEBUG(D_ERR,
2653 "WARNING: Sensor is an OV66307. Your camera may have");
2654 PDEBUG(D_ERR, "been misdetected in previous driver versions.");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002655 break;
2656 default:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002657 PDEBUG(D_ERR, "FATAL: Unknown sensor version: 0x%02x", rc);
2658 return -1;
2659 }
2660
2661 /* Set sensor-specific vars */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002662 sd->sif = 1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002663
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002664 return 0;
2665}
2666
2667/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
2668static void ov51x_led_control(struct sd *sd, int on)
2669{
Hans de Goede9e4d8252009-06-14 06:25:06 -03002670 if (sd->invert_led)
2671 on = !on;
2672
Hans de Goede49809d62009-06-07 12:10:39 -03002673 switch (sd->bridge) {
2674 /* OV511 has no LED control */
2675 case BRIDGE_OV511PLUS:
2676 reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0);
2677 break;
2678 case BRIDGE_OV518:
2679 case BRIDGE_OV518PLUS:
2680 reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02);
2681 break;
2682 case BRIDGE_OV519:
2683 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */
2684 break;
2685 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002686}
2687
Hans de Goede1876bb92009-06-14 06:45:50 -03002688static int ov51x_upload_quan_tables(struct sd *sd)
Hans de Goede49809d62009-06-07 12:10:39 -03002689{
Hans de Goede1876bb92009-06-14 06:45:50 -03002690 const unsigned char yQuanTable511[] = {
2691 0, 1, 1, 2, 2, 3, 3, 4,
2692 1, 1, 1, 2, 2, 3, 4, 4,
2693 1, 1, 2, 2, 3, 4, 4, 4,
2694 2, 2, 2, 3, 4, 4, 4, 4,
2695 2, 2, 3, 4, 4, 5, 5, 5,
2696 3, 3, 4, 4, 5, 5, 5, 5,
2697 3, 4, 4, 4, 5, 5, 5, 5,
2698 4, 4, 4, 4, 5, 5, 5, 5
2699 };
2700
2701 const unsigned char uvQuanTable511[] = {
2702 0, 2, 2, 3, 4, 4, 4, 4,
2703 2, 2, 2, 4, 4, 4, 4, 4,
2704 2, 2, 3, 4, 4, 4, 4, 4,
2705 3, 4, 4, 4, 4, 4, 4, 4,
2706 4, 4, 4, 4, 4, 4, 4, 4,
2707 4, 4, 4, 4, 4, 4, 4, 4,
2708 4, 4, 4, 4, 4, 4, 4, 4,
2709 4, 4, 4, 4, 4, 4, 4, 4
2710 };
2711
2712 /* OV518 quantization tables are 8x4 (instead of 8x8) */
Hans de Goede49809d62009-06-07 12:10:39 -03002713 const unsigned char yQuanTable518[] = {
2714 5, 4, 5, 6, 6, 7, 7, 7,
2715 5, 5, 5, 5, 6, 7, 7, 7,
2716 6, 6, 6, 6, 7, 7, 7, 8,
2717 7, 7, 6, 7, 7, 7, 8, 8
2718 };
2719
2720 const unsigned char uvQuanTable518[] = {
2721 6, 6, 6, 7, 7, 7, 7, 7,
2722 6, 6, 6, 7, 7, 7, 7, 7,
2723 6, 6, 6, 7, 7, 7, 7, 8,
2724 7, 7, 7, 7, 7, 7, 8, 8
2725 };
2726
Hans de Goede1876bb92009-06-14 06:45:50 -03002727 const unsigned char *pYTable, *pUVTable;
Hans de Goede49809d62009-06-07 12:10:39 -03002728 unsigned char val0, val1;
Hans de Goede1876bb92009-06-14 06:45:50 -03002729 int i, size, rc, reg = R51x_COMP_LUT_BEGIN;
Hans de Goede49809d62009-06-07 12:10:39 -03002730
2731 PDEBUG(D_PROBE, "Uploading quantization tables");
2732
Hans de Goede1876bb92009-06-14 06:45:50 -03002733 if (sd->bridge == BRIDGE_OV511 || sd->bridge == BRIDGE_OV511PLUS) {
2734 pYTable = yQuanTable511;
2735 pUVTable = uvQuanTable511;
2736 size = 32;
2737 } else {
2738 pYTable = yQuanTable518;
2739 pUVTable = uvQuanTable518;
2740 size = 16;
2741 }
2742
2743 for (i = 0; i < size; i++) {
Hans de Goede49809d62009-06-07 12:10:39 -03002744 val0 = *pYTable++;
2745 val1 = *pYTable++;
2746 val0 &= 0x0f;
2747 val1 &= 0x0f;
2748 val0 |= val1 << 4;
2749 rc = reg_w(sd, reg, val0);
2750 if (rc < 0)
2751 return rc;
2752
2753 val0 = *pUVTable++;
2754 val1 = *pUVTable++;
2755 val0 &= 0x0f;
2756 val1 &= 0x0f;
2757 val0 |= val1 << 4;
Hans de Goede1876bb92009-06-14 06:45:50 -03002758 rc = reg_w(sd, reg + size, val0);
Hans de Goede49809d62009-06-07 12:10:39 -03002759 if (rc < 0)
2760 return rc;
2761
2762 reg++;
2763 }
2764
2765 return 0;
2766}
2767
Hans de Goede1876bb92009-06-14 06:45:50 -03002768/* This initializes the OV511/OV511+ and the sensor */
2769static int ov511_configure(struct gspca_dev *gspca_dev)
2770{
2771 struct sd *sd = (struct sd *) gspca_dev;
2772 int rc;
2773
2774 /* For 511 and 511+ */
2775 const struct ov_regvals init_511[] = {
2776 { R51x_SYS_RESET, 0x7f },
2777 { R51x_SYS_INIT, 0x01 },
2778 { R51x_SYS_RESET, 0x7f },
2779 { R51x_SYS_INIT, 0x01 },
2780 { R51x_SYS_RESET, 0x3f },
2781 { R51x_SYS_INIT, 0x01 },
2782 { R51x_SYS_RESET, 0x3d },
2783 };
2784
2785 const struct ov_regvals norm_511[] = {
2786 { R511_DRAM_FLOW_CTL, 0x01 },
2787 { R51x_SYS_SNAP, 0x00 },
2788 { R51x_SYS_SNAP, 0x02 },
2789 { R51x_SYS_SNAP, 0x00 },
2790 { R511_FIFO_OPTS, 0x1f },
2791 { R511_COMP_EN, 0x00 },
2792 { R511_COMP_LUT_EN, 0x03 },
2793 };
2794
2795 const struct ov_regvals norm_511_p[] = {
2796 { R511_DRAM_FLOW_CTL, 0xff },
2797 { R51x_SYS_SNAP, 0x00 },
2798 { R51x_SYS_SNAP, 0x02 },
2799 { R51x_SYS_SNAP, 0x00 },
2800 { R511_FIFO_OPTS, 0xff },
2801 { R511_COMP_EN, 0x00 },
2802 { R511_COMP_LUT_EN, 0x03 },
2803 };
2804
2805 const struct ov_regvals compress_511[] = {
2806 { 0x70, 0x1f },
2807 { 0x71, 0x05 },
2808 { 0x72, 0x06 },
2809 { 0x73, 0x06 },
2810 { 0x74, 0x14 },
2811 { 0x75, 0x03 },
2812 { 0x76, 0x04 },
2813 { 0x77, 0x04 },
2814 };
2815
2816 PDEBUG(D_PROBE, "Device custom id %x", reg_r(sd, R51x_SYS_CUST_ID));
2817
2818 rc = write_regvals(sd, init_511, ARRAY_SIZE(init_511));
2819 if (rc < 0)
2820 return rc;
2821
2822 switch (sd->bridge) {
2823 case BRIDGE_OV511:
2824 rc = write_regvals(sd, norm_511, ARRAY_SIZE(norm_511));
2825 if (rc < 0)
2826 return rc;
2827 break;
2828 case BRIDGE_OV511PLUS:
2829 rc = write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p));
2830 if (rc < 0)
2831 return rc;
2832 break;
2833 }
2834
2835 /* Init compression */
2836 rc = write_regvals(sd, compress_511, ARRAY_SIZE(compress_511));
2837 if (rc < 0)
2838 return rc;
2839
2840 rc = ov51x_upload_quan_tables(sd);
2841 if (rc < 0) {
2842 PDEBUG(D_ERR, "Error uploading quantization tables");
2843 return rc;
2844 }
2845
2846 return 0;
2847}
2848
Hans de Goede49809d62009-06-07 12:10:39 -03002849/* This initializes the OV518/OV518+ and the sensor */
2850static int ov518_configure(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002851{
2852 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goede49809d62009-06-07 12:10:39 -03002853 int rc;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002854
Hans de Goede49809d62009-06-07 12:10:39 -03002855 /* For 518 and 518+ */
Hans de Goedee080fcd2009-06-18 05:03:16 -03002856 const struct ov_regvals init_518[] = {
Hans de Goede49809d62009-06-07 12:10:39 -03002857 { R51x_SYS_RESET, 0x40 },
2858 { R51x_SYS_INIT, 0xe1 },
2859 { R51x_SYS_RESET, 0x3e },
2860 { R51x_SYS_INIT, 0xe1 },
2861 { R51x_SYS_RESET, 0x00 },
2862 { R51x_SYS_INIT, 0xe1 },
2863 { 0x46, 0x00 },
2864 { 0x5d, 0x03 },
2865 };
2866
Hans de Goedee080fcd2009-06-18 05:03:16 -03002867 const struct ov_regvals norm_518[] = {
Hans de Goede49809d62009-06-07 12:10:39 -03002868 { R51x_SYS_SNAP, 0x02 }, /* Reset */
2869 { R51x_SYS_SNAP, 0x01 }, /* Enable */
2870 { 0x31, 0x0f },
2871 { 0x5d, 0x03 },
2872 { 0x24, 0x9f },
2873 { 0x25, 0x90 },
2874 { 0x20, 0x00 },
2875 { 0x51, 0x04 },
2876 { 0x71, 0x19 },
2877 { 0x2f, 0x80 },
2878 };
2879
Hans de Goedee080fcd2009-06-18 05:03:16 -03002880 const struct ov_regvals norm_518_p[] = {
Hans de Goede49809d62009-06-07 12:10:39 -03002881 { R51x_SYS_SNAP, 0x02 }, /* Reset */
2882 { R51x_SYS_SNAP, 0x01 }, /* Enable */
2883 { 0x31, 0x0f },
2884 { 0x5d, 0x03 },
2885 { 0x24, 0x9f },
2886 { 0x25, 0x90 },
2887 { 0x20, 0x60 },
2888 { 0x51, 0x02 },
2889 { 0x71, 0x19 },
2890 { 0x40, 0xff },
2891 { 0x41, 0x42 },
2892 { 0x46, 0x00 },
2893 { 0x33, 0x04 },
2894 { 0x21, 0x19 },
2895 { 0x3f, 0x10 },
2896 { 0x2f, 0x80 },
2897 };
2898
2899 /* First 5 bits of custom ID reg are a revision ID on OV518 */
2900 PDEBUG(D_PROBE, "Device revision %d",
2901 0x1F & reg_r(sd, R51x_SYS_CUST_ID));
2902
2903 rc = write_regvals(sd, init_518, ARRAY_SIZE(init_518));
2904 if (rc < 0)
2905 return rc;
2906
2907 /* Set LED GPIO pin to output mode */
2908 rc = reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02);
2909 if (rc < 0)
2910 return rc;
2911
2912 switch (sd->bridge) {
2913 case BRIDGE_OV518:
2914 rc = write_regvals(sd, norm_518, ARRAY_SIZE(norm_518));
2915 if (rc < 0)
2916 return rc;
2917 break;
2918 case BRIDGE_OV518PLUS:
2919 rc = write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p));
2920 if (rc < 0)
2921 return rc;
2922 break;
2923 }
2924
Hans de Goede1876bb92009-06-14 06:45:50 -03002925 rc = ov51x_upload_quan_tables(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03002926 if (rc < 0) {
2927 PDEBUG(D_ERR, "Error uploading quantization tables");
2928 return rc;
2929 }
2930
2931 rc = reg_w(sd, 0x2f, 0x80);
2932 if (rc < 0)
2933 return rc;
2934
2935 return 0;
2936}
2937
2938static int ov519_configure(struct sd *sd)
2939{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002940 static const struct ov_regvals init_519[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002941 { 0x5a, 0x6d }, /* EnableSystem */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002942 { 0x53, 0x9b },
2943 { 0x54, 0xff }, /* set bit2 to enable jpeg */
2944 { 0x5d, 0x03 },
2945 { 0x49, 0x01 },
2946 { 0x48, 0x00 },
2947 /* Set LED pin to output mode. Bit 4 must be cleared or sensor
2948 * detection will fail. This deserves further investigation. */
2949 { OV519_GPIO_IO_CTRL0, 0xee },
2950 { 0x51, 0x0f }, /* SetUsbInit */
2951 { 0x51, 0x00 },
2952 { 0x22, 0x00 },
2953 /* windows reads 0x55 at this point*/
2954 };
2955
Hans de Goede49809d62009-06-07 12:10:39 -03002956 return write_regvals(sd, init_519, ARRAY_SIZE(init_519));
2957}
2958
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002959static int ovfx2_configure(struct sd *sd)
2960{
2961 static const struct ov_regvals init_fx2[] = {
2962 { 0x00, 0x60 },
2963 { 0x02, 0x01 },
2964 { 0x0f, 0x1d },
2965 { 0xe9, 0x82 },
2966 { 0xea, 0xc7 },
2967 { 0xeb, 0x10 },
2968 { 0xec, 0xf6 },
2969 };
2970
2971 sd->stopped = 1;
2972
2973 return write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
2974}
2975
Hans de Goede49809d62009-06-07 12:10:39 -03002976/* this function is called at probe time */
2977static int sd_config(struct gspca_dev *gspca_dev,
2978 const struct usb_device_id *id)
2979{
2980 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002981 struct cam *cam = &gspca_dev->cam;
Hans de Goede49809d62009-06-07 12:10:39 -03002982 int ret = 0;
2983
Hans de Goede9e4d8252009-06-14 06:25:06 -03002984 sd->bridge = id->driver_info & BRIDGE_MASK;
2985 sd->invert_led = id->driver_info & BRIDGE_INVERT_LED;
Hans de Goede49809d62009-06-07 12:10:39 -03002986
2987 switch (sd->bridge) {
Hans de Goede1876bb92009-06-14 06:45:50 -03002988 case BRIDGE_OV511:
2989 case BRIDGE_OV511PLUS:
2990 ret = ov511_configure(gspca_dev);
2991 break;
Hans de Goede49809d62009-06-07 12:10:39 -03002992 case BRIDGE_OV518:
2993 case BRIDGE_OV518PLUS:
2994 ret = ov518_configure(gspca_dev);
2995 break;
2996 case BRIDGE_OV519:
2997 ret = ov519_configure(sd);
2998 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002999 case BRIDGE_OVFX2:
3000 ret = ovfx2_configure(sd);
3001 cam->bulk_size = OVFX2_BULK_SIZE;
3002 cam->bulk_nurbs = MAX_NURBS;
3003 cam->bulk = 1;
3004 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03003005 case BRIDGE_W9968CF:
3006 ret = w9968cf_configure(sd);
3007 cam->reverse_alts = 1;
3008 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003009 }
3010
3011 if (ret)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003012 goto error;
Hans de Goede49809d62009-06-07 12:10:39 -03003013
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003014 ov51x_led_control(sd, 0); /* turn LED off */
3015
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003016 /* The OV519 must be more aggressive about sensor detection since
3017 * I2C write will never fail if the sensor is not present. We have
3018 * to try to initialize the sensor to detect its presence */
Hans de Goede229bb7d2009-10-11 07:41:46 -03003019
3020 /* Test for 76xx */
3021 if (init_ov_sensor(sd, OV7xx0_SID) >= 0) {
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003022 if (ov7xx0_configure(sd) < 0) {
3023 PDEBUG(D_ERR, "Failed to configure OV7xx0");
3024 goto error;
3025 }
Hans de Goede229bb7d2009-10-11 07:41:46 -03003026 /* Test for 6xx0 */
3027 } else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) {
3028 if (ov6xx0_configure(sd) < 0) {
3029 PDEBUG(D_ERR, "Failed to configure OV6xx0");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003030 goto error;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003031 }
Hans de Goede229bb7d2009-10-11 07:41:46 -03003032 /* Test for 8xx0 */
3033 } else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) {
3034 if (ov8xx0_configure(sd) < 0) {
3035 PDEBUG(D_ERR, "Failed to configure OV8xx0");
3036 goto error;
3037 }
Hans de Goede635118d2009-10-11 09:49:03 -03003038 /* Test for 3xxx / 2xxx */
3039 } else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) {
3040 if (ov_hires_configure(sd) < 0) {
3041 PDEBUG(D_ERR, "Failed to configure high res OV");
3042 goto error;
3043 }
Hans de Goede229bb7d2009-10-11 07:41:46 -03003044 } else {
3045 PDEBUG(D_ERR, "Can't determine sensor slave IDs");
3046 goto error;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003047 }
3048
Hans de Goede49809d62009-06-07 12:10:39 -03003049 switch (sd->bridge) {
Hans de Goede1876bb92009-06-14 06:45:50 -03003050 case BRIDGE_OV511:
3051 case BRIDGE_OV511PLUS:
3052 if (!sd->sif) {
3053 cam->cam_mode = ov511_vga_mode;
3054 cam->nmodes = ARRAY_SIZE(ov511_vga_mode);
3055 } else {
3056 cam->cam_mode = ov511_sif_mode;
3057 cam->nmodes = ARRAY_SIZE(ov511_sif_mode);
3058 }
3059 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003060 case BRIDGE_OV518:
3061 case BRIDGE_OV518PLUS:
3062 if (!sd->sif) {
3063 cam->cam_mode = ov518_vga_mode;
3064 cam->nmodes = ARRAY_SIZE(ov518_vga_mode);
3065 } else {
3066 cam->cam_mode = ov518_sif_mode;
3067 cam->nmodes = ARRAY_SIZE(ov518_sif_mode);
3068 }
3069 break;
3070 case BRIDGE_OV519:
3071 if (!sd->sif) {
3072 cam->cam_mode = ov519_vga_mode;
3073 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
3074 } else {
3075 cam->cam_mode = ov519_sif_mode;
3076 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3077 }
3078 break;
Hans de Goede635118d2009-10-11 09:49:03 -03003079 case BRIDGE_OVFX2:
3080 if (sd->sensor == SEN_OV2610) {
3081 cam->cam_mode = ovfx2_ov2610_mode;
3082 cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode);
3083 } else if (sd->sensor == SEN_OV3610) {
3084 cam->cam_mode = ovfx2_ov3610_mode;
3085 cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode);
3086 } else if (!sd->sif) {
3087 cam->cam_mode = ov519_vga_mode;
3088 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
3089 } else {
3090 cam->cam_mode = ov519_sif_mode;
3091 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3092 }
3093 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03003094 case BRIDGE_W9968CF:
3095 cam->cam_mode = w9968cf_vga_mode;
3096 cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
Hans de Goede79b35902009-10-19 06:08:01 -03003097 if (sd->sif)
3098 cam->nmodes--;
Hans de Goedea511ba92009-10-16 07:13:07 -03003099
3100 /* w9968cf needs initialisation once the sensor is known */
3101 if (w9968cf_init(sd) < 0)
3102 goto error;
3103 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003104 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003105 sd->brightness = BRIGHTNESS_DEF;
Hans de Goedef5cee952009-06-14 06:32:52 -03003106 if (sd->sensor == SEN_OV6630 || sd->sensor == SEN_OV66308AF)
3107 sd->contrast = 200; /* The default is too low for the ov6630 */
3108 else
3109 sd->contrast = CONTRAST_DEF;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003110 sd->colors = COLOR_DEF;
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003111 sd->hflip = HFLIP_DEF;
3112 sd->vflip = VFLIP_DEF;
Hans de Goede02ab18b2009-06-14 04:32:04 -03003113 sd->autobrightness = AUTOBRIGHT_DEF;
3114 if (sd->sensor == SEN_OV7670) {
3115 sd->freq = OV7670_FREQ_DEF;
3116 gspca_dev->ctrl_dis = 1 << FREQ_IDX;
3117 } else {
3118 sd->freq = FREQ_DEF;
3119 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) |
3120 (1 << OV7670_FREQ_IDX);
3121 }
Hans de Goede79b35902009-10-19 06:08:01 -03003122 sd->quality = QUALITY_DEF;
Hans de Goede035d3a32010-01-09 08:14:43 -03003123 if (sd->sensor == SEN_OV7640 ||
Hans de Goeded02134d2010-01-09 19:22:34 -03003124 sd->sensor == SEN_OV7648)
3125 gspca_dev->ctrl_dis |= (1 << AUTOBRIGHT_IDX) |
3126 (1 << CONTRAST_IDX);
3127 if (sd->sensor == SEN_OV7670)
Hans de Goede02ab18b2009-06-14 04:32:04 -03003128 gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX;
3129 /* OV8610 Frequency filter control should work but needs testing */
3130 if (sd->sensor == SEN_OV8610)
3131 gspca_dev->ctrl_dis |= 1 << FREQ_IDX;
Hans de Goede635118d2009-10-11 09:49:03 -03003132 /* No controls for the OV2610/OV3610 */
3133 if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
3134 gspca_dev->ctrl_dis |= 0xFF;
Hans de Goede02ab18b2009-06-14 04:32:04 -03003135
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003136 return 0;
3137error:
3138 PDEBUG(D_ERR, "OV519 Config failed");
3139 return -EBUSY;
3140}
3141
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03003142/* this function is called at probe and resume time */
3143static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003144{
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003145 struct sd *sd = (struct sd *) gspca_dev;
3146
3147 /* initialize the sensor */
3148 switch (sd->sensor) {
Hans de Goede635118d2009-10-11 09:49:03 -03003149 case SEN_OV2610:
3150 if (write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610)))
3151 return -EIO;
3152 /* Enable autogain, autoexpo, awb, bandfilter */
3153 if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
3154 return -EIO;
3155 break;
3156 case SEN_OV3610:
3157 if (write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b)))
3158 return -EIO;
3159 /* Enable autogain, autoexpo, awb, bandfilter */
3160 if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
3161 return -EIO;
3162 break;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003163 case SEN_OV6620:
3164 if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)))
3165 return -EIO;
3166 break;
3167 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03003168 case SEN_OV66308AF:
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003169 if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)))
3170 return -EIO;
3171 break;
3172 default:
3173/* case SEN_OV7610: */
3174/* case SEN_OV76BE: */
3175 if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610)))
3176 return -EIO;
Hans de Goedeae49c402009-06-14 19:15:07 -03003177 if (i2c_w_mask(sd, 0x0e, 0x00, 0x40))
3178 return -EIO;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003179 break;
3180 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03003181 case SEN_OV7620AE:
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003182 if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)))
3183 return -EIO;
3184 break;
3185 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003186 case SEN_OV7648:
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003187 if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)))
3188 return -EIO;
3189 break;
3190 case SEN_OV7670:
3191 if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)))
3192 return -EIO;
3193 break;
3194 case SEN_OV8610:
3195 if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610)))
3196 return -EIO;
3197 break;
3198 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003199 return 0;
3200}
3201
Hans de Goede1876bb92009-06-14 06:45:50 -03003202/* Set up the OV511/OV511+ with the given image parameters.
3203 *
3204 * Do not put any sensor-specific code in here (including I2C I/O functions)
3205 */
3206static int ov511_mode_init_regs(struct sd *sd)
3207{
3208 int hsegs, vsegs, packet_size, fps, needed;
3209 int interlaced = 0;
3210 struct usb_host_interface *alt;
3211 struct usb_interface *intf;
3212
3213 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
3214 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
3215 if (!alt) {
3216 PDEBUG(D_ERR, "Couldn't get altsetting");
3217 return -EIO;
3218 }
3219
3220 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
3221 reg_w(sd, R51x_FIFO_PSIZE, packet_size >> 5);
3222
3223 reg_w(sd, R511_CAM_UV_EN, 0x01);
3224 reg_w(sd, R511_SNAP_UV_EN, 0x01);
3225 reg_w(sd, R511_SNAP_OPTS, 0x03);
3226
3227 /* Here I'm assuming that snapshot size == image size.
3228 * I hope that's always true. --claudio
3229 */
3230 hsegs = (sd->gspca_dev.width >> 3) - 1;
3231 vsegs = (sd->gspca_dev.height >> 3) - 1;
3232
3233 reg_w(sd, R511_CAM_PXCNT, hsegs);
3234 reg_w(sd, R511_CAM_LNCNT, vsegs);
3235 reg_w(sd, R511_CAM_PXDIV, 0x00);
3236 reg_w(sd, R511_CAM_LNDIV, 0x00);
3237
3238 /* YUV420, low pass filter on */
3239 reg_w(sd, R511_CAM_OPTS, 0x03);
3240
3241 /* Snapshot additions */
3242 reg_w(sd, R511_SNAP_PXCNT, hsegs);
3243 reg_w(sd, R511_SNAP_LNCNT, vsegs);
3244 reg_w(sd, R511_SNAP_PXDIV, 0x00);
3245 reg_w(sd, R511_SNAP_LNDIV, 0x00);
3246
3247 /******** Set the framerate ********/
3248 if (frame_rate > 0)
3249 sd->frame_rate = frame_rate;
3250
3251 switch (sd->sensor) {
3252 case SEN_OV6620:
3253 /* No framerate control, doesn't like higher rates yet */
3254 sd->clockdiv = 3;
3255 break;
3256
3257 /* Note once the FIXME's in mode_init_ov_sensor_regs() are fixed
3258 for more sensors we need to do this for them too */
3259 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03003260 case SEN_OV7620AE:
Hans de Goede1876bb92009-06-14 06:45:50 -03003261 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003262 case SEN_OV7648:
Hans de Goedeb282d872009-06-14 19:10:40 -03003263 case SEN_OV76BE:
Hans de Goede1876bb92009-06-14 06:45:50 -03003264 if (sd->gspca_dev.width == 320)
3265 interlaced = 1;
3266 /* Fall through */
3267 case SEN_OV6630:
Hans de Goede1876bb92009-06-14 06:45:50 -03003268 case SEN_OV7610:
3269 case SEN_OV7670:
3270 switch (sd->frame_rate) {
3271 case 30:
3272 case 25:
3273 /* Not enough bandwidth to do 640x480 @ 30 fps */
3274 if (sd->gspca_dev.width != 640) {
3275 sd->clockdiv = 0;
3276 break;
3277 }
3278 /* Fall through for 640x480 case */
3279 default:
3280/* case 20: */
3281/* case 15: */
3282 sd->clockdiv = 1;
3283 break;
3284 case 10:
3285 sd->clockdiv = 2;
3286 break;
3287 case 5:
3288 sd->clockdiv = 5;
3289 break;
3290 }
3291 if (interlaced) {
3292 sd->clockdiv = (sd->clockdiv + 1) * 2 - 1;
3293 /* Higher then 10 does not work */
3294 if (sd->clockdiv > 10)
3295 sd->clockdiv = 10;
3296 }
3297 break;
3298
3299 case SEN_OV8610:
3300 /* No framerate control ?? */
3301 sd->clockdiv = 0;
3302 break;
3303 }
3304
3305 /* Check if we have enough bandwidth to disable compression */
3306 fps = (interlaced ? 60 : 30) / (sd->clockdiv + 1) + 1;
3307 needed = fps * sd->gspca_dev.width * sd->gspca_dev.height * 3 / 2;
3308 /* 1400 is a conservative estimate of the max nr of isoc packets/sec */
3309 if (needed > 1400 * packet_size) {
3310 /* Enable Y and UV quantization and compression */
3311 reg_w(sd, R511_COMP_EN, 0x07);
3312 reg_w(sd, R511_COMP_LUT_EN, 0x03);
3313 } else {
3314 reg_w(sd, R511_COMP_EN, 0x06);
3315 reg_w(sd, R511_COMP_LUT_EN, 0x00);
3316 }
3317
3318 reg_w(sd, R51x_SYS_RESET, OV511_RESET_OMNICE);
3319 reg_w(sd, R51x_SYS_RESET, 0);
3320
3321 return 0;
3322}
3323
Hans de Goede49809d62009-06-07 12:10:39 -03003324/* Sets up the OV518/OV518+ with the given image parameters
3325 *
3326 * OV518 needs a completely different approach, until we can figure out what
3327 * the individual registers do. Also, only 15 FPS is supported now.
3328 *
3329 * Do not put any sensor-specific code in here (including I2C I/O functions)
3330 */
3331static int ov518_mode_init_regs(struct sd *sd)
3332{
Hans de Goedeb282d872009-06-14 19:10:40 -03003333 int hsegs, vsegs, packet_size;
3334 struct usb_host_interface *alt;
3335 struct usb_interface *intf;
3336
3337 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
3338 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
3339 if (!alt) {
3340 PDEBUG(D_ERR, "Couldn't get altsetting");
3341 return -EIO;
3342 }
3343
3344 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
3345 ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2);
Hans de Goede49809d62009-06-07 12:10:39 -03003346
3347 /******** Set the mode ********/
3348
3349 reg_w(sd, 0x2b, 0);
3350 reg_w(sd, 0x2c, 0);
3351 reg_w(sd, 0x2d, 0);
3352 reg_w(sd, 0x2e, 0);
3353 reg_w(sd, 0x3b, 0);
3354 reg_w(sd, 0x3c, 0);
3355 reg_w(sd, 0x3d, 0);
3356 reg_w(sd, 0x3e, 0);
3357
3358 if (sd->bridge == BRIDGE_OV518) {
3359 /* Set 8-bit (YVYU) input format */
3360 reg_w_mask(sd, 0x20, 0x08, 0x08);
3361
3362 /* Set 12-bit (4:2:0) output format */
3363 reg_w_mask(sd, 0x28, 0x80, 0xf0);
3364 reg_w_mask(sd, 0x38, 0x80, 0xf0);
3365 } else {
3366 reg_w(sd, 0x28, 0x80);
3367 reg_w(sd, 0x38, 0x80);
3368 }
3369
3370 hsegs = sd->gspca_dev.width / 16;
3371 vsegs = sd->gspca_dev.height / 4;
3372
3373 reg_w(sd, 0x29, hsegs);
3374 reg_w(sd, 0x2a, vsegs);
3375
3376 reg_w(sd, 0x39, hsegs);
3377 reg_w(sd, 0x3a, vsegs);
3378
3379 /* Windows driver does this here; who knows why */
3380 reg_w(sd, 0x2f, 0x80);
3381
Hans de Goedeb282d872009-06-14 19:10:40 -03003382 /******** Set the framerate ********/
3383 sd->clockdiv = 1;
Hans de Goede49809d62009-06-07 12:10:39 -03003384
3385 /* Mode independent, but framerate dependent, regs */
Hans de Goedeb282d872009-06-14 19:10:40 -03003386 /* 0x51: Clock divider; Only works on some cams which use 2 crystals */
3387 reg_w(sd, 0x51, 0x04);
Hans de Goede49809d62009-06-07 12:10:39 -03003388 reg_w(sd, 0x22, 0x18);
3389 reg_w(sd, 0x23, 0xff);
3390
Hans de Goedeb282d872009-06-14 19:10:40 -03003391 if (sd->bridge == BRIDGE_OV518PLUS) {
3392 switch (sd->sensor) {
Hans de Goede859cc472010-01-07 15:42:35 -03003393 case SEN_OV7620AE:
Hans de Goedeb282d872009-06-14 19:10:40 -03003394 if (sd->gspca_dev.width == 320) {
3395 reg_w(sd, 0x20, 0x00);
3396 reg_w(sd, 0x21, 0x19);
3397 } else {
3398 reg_w(sd, 0x20, 0x60);
3399 reg_w(sd, 0x21, 0x1f);
3400 }
3401 break;
Hans de Goede859cc472010-01-07 15:42:35 -03003402 case SEN_OV7620:
3403 reg_w(sd, 0x20, 0x00);
3404 reg_w(sd, 0x21, 0x19);
3405 break;
Hans de Goedeb282d872009-06-14 19:10:40 -03003406 default:
3407 reg_w(sd, 0x21, 0x19);
3408 }
3409 } else
Hans de Goede49809d62009-06-07 12:10:39 -03003410 reg_w(sd, 0x71, 0x17); /* Compression-related? */
3411
3412 /* FIXME: Sensor-specific */
3413 /* Bit 5 is what matters here. Of course, it is "reserved" */
3414 i2c_w(sd, 0x54, 0x23);
3415
3416 reg_w(sd, 0x2f, 0x80);
3417
3418 if (sd->bridge == BRIDGE_OV518PLUS) {
3419 reg_w(sd, 0x24, 0x94);
3420 reg_w(sd, 0x25, 0x90);
3421 ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */
3422 ov518_reg_w32(sd, 0xc6, 540, 2); /* 21ch */
3423 ov518_reg_w32(sd, 0xc7, 540, 2); /* 21ch */
3424 ov518_reg_w32(sd, 0xc8, 108, 2); /* 6ch */
3425 ov518_reg_w32(sd, 0xca, 131098, 3); /* 2001ah */
3426 ov518_reg_w32(sd, 0xcb, 532, 2); /* 214h */
3427 ov518_reg_w32(sd, 0xcc, 2400, 2); /* 960h */
3428 ov518_reg_w32(sd, 0xcd, 32, 2); /* 20h */
3429 ov518_reg_w32(sd, 0xce, 608, 2); /* 260h */
3430 } else {
3431 reg_w(sd, 0x24, 0x9f);
3432 reg_w(sd, 0x25, 0x90);
3433 ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */
3434 ov518_reg_w32(sd, 0xc6, 381, 2); /* 17dh */
3435 ov518_reg_w32(sd, 0xc7, 381, 2); /* 17dh */
3436 ov518_reg_w32(sd, 0xc8, 128, 2); /* 80h */
3437 ov518_reg_w32(sd, 0xca, 183331, 3); /* 2cc23h */
3438 ov518_reg_w32(sd, 0xcb, 746, 2); /* 2eah */
3439 ov518_reg_w32(sd, 0xcc, 1750, 2); /* 6d6h */
3440 ov518_reg_w32(sd, 0xcd, 45, 2); /* 2dh */
3441 ov518_reg_w32(sd, 0xce, 851, 2); /* 353h */
3442 }
3443
3444 reg_w(sd, 0x2f, 0x80);
3445
3446 return 0;
3447}
3448
3449
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003450/* Sets up the OV519 with the given image parameters
3451 *
3452 * OV519 needs a completely different approach, until we can figure out what
3453 * the individual registers do.
3454 *
3455 * Do not put any sensor-specific code in here (including I2C I/O functions)
3456 */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003457static int ov519_mode_init_regs(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003458{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003459 static const struct ov_regvals mode_init_519_ov7670[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003460 { 0x5d, 0x03 }, /* Turn off suspend mode */
3461 { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
3462 { 0x54, 0x0f }, /* bit2 (jpeg enable) */
3463 { 0xa2, 0x20 }, /* a2-a5 are undocumented */
3464 { 0xa3, 0x18 },
3465 { 0xa4, 0x04 },
3466 { 0xa5, 0x28 },
3467 { 0x37, 0x00 }, /* SetUsbInit */
3468 { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
3469 /* Enable both fields, YUV Input, disable defect comp (why?) */
3470 { 0x20, 0x0c },
3471 { 0x21, 0x38 },
3472 { 0x22, 0x1d },
3473 { 0x17, 0x50 }, /* undocumented */
3474 { 0x37, 0x00 }, /* undocumented */
3475 { 0x40, 0xff }, /* I2C timeout counter */
3476 { 0x46, 0x00 }, /* I2C clock prescaler */
3477 { 0x59, 0x04 }, /* new from windrv 090403 */
3478 { 0xff, 0x00 }, /* undocumented */
3479 /* windows reads 0x55 at this point, why? */
3480 };
3481
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003482 static const struct ov_regvals mode_init_519[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003483 { 0x5d, 0x03 }, /* Turn off suspend mode */
3484 { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
3485 { 0x54, 0x0f }, /* bit2 (jpeg enable) */
3486 { 0xa2, 0x20 }, /* a2-a5 are undocumented */
3487 { 0xa3, 0x18 },
3488 { 0xa4, 0x04 },
3489 { 0xa5, 0x28 },
3490 { 0x37, 0x00 }, /* SetUsbInit */
3491 { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
3492 /* Enable both fields, YUV Input, disable defect comp (why?) */
3493 { 0x22, 0x1d },
3494 { 0x17, 0x50 }, /* undocumented */
3495 { 0x37, 0x00 }, /* undocumented */
3496 { 0x40, 0xff }, /* I2C timeout counter */
3497 { 0x46, 0x00 }, /* I2C clock prescaler */
3498 { 0x59, 0x04 }, /* new from windrv 090403 */
3499 { 0xff, 0x00 }, /* undocumented */
3500 /* windows reads 0x55 at this point, why? */
3501 };
3502
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003503 /******** Set the mode ********/
3504 if (sd->sensor != SEN_OV7670) {
3505 if (write_regvals(sd, mode_init_519,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003506 ARRAY_SIZE(mode_init_519)))
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003507 return -EIO;
Hans de Goede035d3a32010-01-09 08:14:43 -03003508 if (sd->sensor == SEN_OV7640 ||
3509 sd->sensor == SEN_OV7648) {
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003510 /* Select 8-bit input mode */
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003511 reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10);
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003512 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003513 } else {
3514 if (write_regvals(sd, mode_init_519_ov7670,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003515 ARRAY_SIZE(mode_init_519_ov7670)))
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003516 return -EIO;
3517 }
3518
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003519 reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4);
3520 reg_w(sd, OV519_R11_V_SIZE, sd->gspca_dev.height >> 3);
Hans de Goede80142ef2009-06-14 06:26:49 -03003521 if (sd->sensor == SEN_OV7670 &&
3522 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
3523 reg_w(sd, OV519_R12_X_OFFSETL, 0x04);
Hans de Goede035d3a32010-01-09 08:14:43 -03003524 else if (sd->sensor == SEN_OV7648 &&
3525 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
3526 reg_w(sd, OV519_R12_X_OFFSETL, 0x01);
Hans de Goede80142ef2009-06-14 06:26:49 -03003527 else
3528 reg_w(sd, OV519_R12_X_OFFSETL, 0x00);
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003529 reg_w(sd, OV519_R13_X_OFFSETH, 0x00);
3530 reg_w(sd, OV519_R14_Y_OFFSETL, 0x00);
3531 reg_w(sd, OV519_R15_Y_OFFSETH, 0x00);
3532 reg_w(sd, OV519_R16_DIVIDER, 0x00);
3533 reg_w(sd, OV519_R25_FORMAT, 0x03); /* YUV422 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003534 reg_w(sd, 0x26, 0x00); /* Undocumented */
3535
3536 /******** Set the framerate ********/
3537 if (frame_rate > 0)
3538 sd->frame_rate = frame_rate;
3539
3540/* FIXME: These are only valid at the max resolution. */
3541 sd->clockdiv = 0;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003542 switch (sd->sensor) {
3543 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003544 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003545 switch (sd->frame_rate) {
Jean-Francois Moine53e74512008-11-08 06:10:19 -03003546 default:
3547/* case 30: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003548 reg_w(sd, 0xa4, 0x0c);
3549 reg_w(sd, 0x23, 0xff);
3550 break;
3551 case 25:
3552 reg_w(sd, 0xa4, 0x0c);
3553 reg_w(sd, 0x23, 0x1f);
3554 break;
3555 case 20:
3556 reg_w(sd, 0xa4, 0x0c);
3557 reg_w(sd, 0x23, 0x1b);
3558 break;
Jean-Francois Moine53e74512008-11-08 06:10:19 -03003559 case 15:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003560 reg_w(sd, 0xa4, 0x04);
3561 reg_w(sd, 0x23, 0xff);
3562 sd->clockdiv = 1;
3563 break;
3564 case 10:
3565 reg_w(sd, 0xa4, 0x04);
3566 reg_w(sd, 0x23, 0x1f);
3567 sd->clockdiv = 1;
3568 break;
3569 case 5:
3570 reg_w(sd, 0xa4, 0x04);
3571 reg_w(sd, 0x23, 0x1b);
3572 sd->clockdiv = 1;
3573 break;
3574 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003575 break;
3576 case SEN_OV8610:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003577 switch (sd->frame_rate) {
3578 default: /* 15 fps */
3579/* case 15: */
3580 reg_w(sd, 0xa4, 0x06);
3581 reg_w(sd, 0x23, 0xff);
3582 break;
3583 case 10:
3584 reg_w(sd, 0xa4, 0x06);
3585 reg_w(sd, 0x23, 0x1f);
3586 break;
3587 case 5:
3588 reg_w(sd, 0xa4, 0x06);
3589 reg_w(sd, 0x23, 0x1b);
3590 break;
3591 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003592 break;
3593 case SEN_OV7670: /* guesses, based on 7640 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003594 PDEBUG(D_STREAM, "Setting framerate to %d fps",
3595 (sd->frame_rate == 0) ? 15 : sd->frame_rate);
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003596 reg_w(sd, 0xa4, 0x10);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003597 switch (sd->frame_rate) {
3598 case 30:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003599 reg_w(sd, 0x23, 0xff);
3600 break;
3601 case 20:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003602 reg_w(sd, 0x23, 0x1b);
3603 break;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003604 default:
3605/* case 15: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003606 reg_w(sd, 0x23, 0xff);
3607 sd->clockdiv = 1;
3608 break;
3609 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003610 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003611 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003612 return 0;
3613}
3614
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003615static int mode_init_ov_sensor_regs(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003616{
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003617 struct gspca_dev *gspca_dev;
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003618 int qvga, xstart, xend, ystart, yend;
3619 __u8 v;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003620
3621 gspca_dev = &sd->gspca_dev;
Hans de Goede124cc9c2009-06-14 05:48:00 -03003622 qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003623
3624 /******** Mode (VGA/QVGA) and sensor specific regs ********/
3625 switch (sd->sensor) {
Hans de Goede635118d2009-10-11 09:49:03 -03003626 case SEN_OV2610:
3627 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3628 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
3629 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
3630 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
3631 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
3632 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
3633 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
3634 return 0;
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003635 case SEN_OV3610:
Hans de Goede635118d2009-10-11 09:49:03 -03003636 if (qvga) {
3637 xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003638 ystart = (776 - gspca_dev->height) / 2;
Hans de Goede635118d2009-10-11 09:49:03 -03003639 } else {
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003640 xstart = (2076 - gspca_dev->width) / 2 + (0x10 << 4);
Hans de Goede635118d2009-10-11 09:49:03 -03003641 ystart = (1544 - gspca_dev->height) / 2;
3642 }
3643 xend = xstart + gspca_dev->width;
3644 yend = ystart + gspca_dev->height;
3645 /* Writing to the COMH register resets the other windowing regs
3646 to their default values, so we must do this first. */
3647 i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0xf0);
3648 i2c_w_mask(sd, 0x32,
3649 (((xend >> 1) & 7) << 3) | ((xstart >> 1) & 7),
3650 0x3f);
3651 i2c_w_mask(sd, 0x03,
3652 (((yend >> 1) & 3) << 2) | ((ystart >> 1) & 3),
3653 0x0f);
3654 i2c_w(sd, 0x17, xstart >> 4);
3655 i2c_w(sd, 0x18, xend >> 4);
3656 i2c_w(sd, 0x19, ystart >> 3);
3657 i2c_w(sd, 0x1a, yend >> 3);
3658 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003659 case SEN_OV8610:
3660 /* For OV8610 qvga means qsvga */
3661 i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003662 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3663 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3664 i2c_w_mask(sd, 0x2d, 0x00, 0x40); /* from windrv 090403 */
3665 i2c_w_mask(sd, 0x28, 0x20, 0x20); /* progressive mode on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003666 break;
3667 case SEN_OV7610:
3668 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003669 i2c_w(sd, 0x35, qvga?0x1e:0x9e);
3670 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3671 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003672 break;
3673 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03003674 case SEN_OV7620AE:
Hans de Goedeb282d872009-06-14 19:10:40 -03003675 case SEN_OV76BE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003676 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3677 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
3678 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
3679 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
3680 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
Hans de Goedeb282d872009-06-14 19:10:40 -03003681 i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003682 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003683 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3684 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3685 if (sd->sensor == SEN_OV76BE)
3686 i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003687 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003688 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003689 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003690 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3691 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
Hans de Goede035d3a32010-01-09 08:14:43 -03003692 /* The following 5 lines where commented out before with a
3693 comment wondering if they did anything. This was because
3694 the old driver did only 640x480, at 320x240 these 5 writes
3695 *significantly* improve the image quality. */
3696 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
3697 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
3698 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
3699 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
3700 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003701 i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003702 break;
3703 case SEN_OV7670:
3704 /* set COM7_FMT_VGA or COM7_FMT_QVGA
3705 * do we need to set anything else?
3706 * HSTART etc are set in set_ov_sensor_window itself */
3707 i2c_w_mask(sd, OV7670_REG_COM7,
3708 qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA,
3709 OV7670_COM7_FMT_MASK);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003710 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3711 i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB,
3712 OV7670_COM8_AWB);
3713 if (qvga) { /* QVGA from ov7670.c by
3714 * Jonathan Corbet */
3715 xstart = 164;
3716 xend = 28;
3717 ystart = 14;
3718 yend = 494;
3719 } else { /* VGA */
3720 xstart = 158;
3721 xend = 14;
3722 ystart = 10;
3723 yend = 490;
3724 }
3725 /* OV7670 hardware window registers are split across
3726 * multiple locations */
3727 i2c_w(sd, OV7670_REG_HSTART, xstart >> 3);
3728 i2c_w(sd, OV7670_REG_HSTOP, xend >> 3);
3729 v = i2c_r(sd, OV7670_REG_HREF);
3730 v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07);
3731 msleep(10); /* need to sleep between read and write to
3732 * same reg! */
3733 i2c_w(sd, OV7670_REG_HREF, v);
3734
3735 i2c_w(sd, OV7670_REG_VSTART, ystart >> 2);
3736 i2c_w(sd, OV7670_REG_VSTOP, yend >> 2);
3737 v = i2c_r(sd, OV7670_REG_VREF);
3738 v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03);
3739 msleep(10); /* need to sleep between read and write to
3740 * same reg! */
3741 i2c_w(sd, OV7670_REG_VREF, v);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003742 break;
3743 case SEN_OV6620:
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003744 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3745 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3746 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3747 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003748 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03003749 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003750 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003751 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003752 break;
3753 default:
3754 return -EINVAL;
3755 }
3756
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003757 /******** Clock programming ********/
Hans de Goedeae49c402009-06-14 19:15:07 -03003758 i2c_w(sd, 0x11, sd->clockdiv);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003759
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003760 return 0;
3761}
3762
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003763static void sethvflip(struct sd *sd)
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003764{
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003765 if (sd->sensor != SEN_OV7670)
3766 return;
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003767 if (sd->gspca_dev.streaming)
3768 ov51x_stop(sd);
3769 i2c_w_mask(sd, OV7670_REG_MVFP,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003770 OV7670_MVFP_MIRROR * sd->hflip
3771 | OV7670_MVFP_VFLIP * sd->vflip,
3772 OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP);
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003773 if (sd->gspca_dev.streaming)
3774 ov51x_restart(sd);
3775}
3776
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003777static int set_ov_sensor_window(struct sd *sd)
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003778{
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003779 struct gspca_dev *gspca_dev;
Hans de Goede124cc9c2009-06-14 05:48:00 -03003780 int qvga, crop;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003781 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003782 int ret;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003783
Hans de Goede635118d2009-10-11 09:49:03 -03003784 /* mode setup is fully handled in mode_init_ov_sensor_regs for these */
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003785 if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610 ||
3786 sd->sensor == SEN_OV7670)
Hans de Goede635118d2009-10-11 09:49:03 -03003787 return mode_init_ov_sensor_regs(sd);
3788
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003789 gspca_dev = &sd->gspca_dev;
Hans de Goede124cc9c2009-06-14 05:48:00 -03003790 qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
3791 crop = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 2;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003792
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003793 /* The different sensor ICs handle setting up of window differently.
3794 * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */
3795 switch (sd->sensor) {
3796 case SEN_OV8610:
3797 hwsbase = 0x1e;
3798 hwebase = 0x1e;
3799 vwsbase = 0x02;
3800 vwebase = 0x02;
3801 break;
3802 case SEN_OV7610:
3803 case SEN_OV76BE:
3804 hwsbase = 0x38;
3805 hwebase = 0x3a;
3806 vwsbase = vwebase = 0x05;
3807 break;
3808 case SEN_OV6620:
3809 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03003810 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003811 hwsbase = 0x38;
3812 hwebase = 0x3a;
3813 vwsbase = 0x05;
3814 vwebase = 0x06;
Hans de Goede7d971372009-06-14 05:28:17 -03003815 if (sd->sensor == SEN_OV66308AF && qvga)
Hans de Goede49809d62009-06-07 12:10:39 -03003816 /* HDG: this fixes U and V getting swapped */
Hans de Goede7d971372009-06-14 05:28:17 -03003817 hwsbase++;
Hans de Goede124cc9c2009-06-14 05:48:00 -03003818 if (crop) {
3819 hwsbase += 8;
3820 hwebase += 8;
3821 vwsbase += 11;
3822 vwebase += 11;
3823 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003824 break;
3825 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03003826 case SEN_OV7620AE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003827 hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */
3828 hwebase = 0x2f;
3829 vwsbase = vwebase = 0x05;
3830 break;
3831 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003832 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003833 hwsbase = 0x1a;
3834 hwebase = 0x1a;
3835 vwsbase = vwebase = 0x03;
3836 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003837 default:
3838 return -EINVAL;
3839 }
3840
3841 switch (sd->sensor) {
3842 case SEN_OV6620:
3843 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03003844 case SEN_OV66308AF:
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003845 if (qvga) { /* QCIF */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003846 hwscale = 0;
3847 vwscale = 0;
3848 } else { /* CIF */
3849 hwscale = 1;
3850 vwscale = 1; /* The datasheet says 0;
3851 * it's wrong */
3852 }
3853 break;
3854 case SEN_OV8610:
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003855 if (qvga) { /* QSVGA */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003856 hwscale = 1;
3857 vwscale = 1;
3858 } else { /* SVGA */
3859 hwscale = 2;
3860 vwscale = 2;
3861 }
3862 break;
3863 default: /* SEN_OV7xx0 */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003864 if (qvga) { /* QVGA */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003865 hwscale = 1;
3866 vwscale = 0;
3867 } else { /* VGA */
3868 hwscale = 2;
3869 vwscale = 1;
3870 }
3871 }
3872
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003873 ret = mode_init_ov_sensor_regs(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003874 if (ret < 0)
3875 return ret;
3876
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003877 i2c_w(sd, 0x17, hwsbase);
Hans de Goedea511ba92009-10-16 07:13:07 -03003878 i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale));
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003879 i2c_w(sd, 0x19, vwsbase);
Hans de Goedea511ba92009-10-16 07:13:07 -03003880 i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale));
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003881
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003882 return 0;
3883}
3884
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003885/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03003886static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003887{
3888 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goede49809d62009-06-07 12:10:39 -03003889 int ret = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003890
Hans de Goedea511ba92009-10-16 07:13:07 -03003891 /* Default for most bridges, allow bridge_mode_init_regs to override */
3892 sd->sensor_width = sd->gspca_dev.width;
3893 sd->sensor_height = sd->gspca_dev.height;
3894
Hans de Goede49809d62009-06-07 12:10:39 -03003895 switch (sd->bridge) {
Hans de Goede1876bb92009-06-14 06:45:50 -03003896 case BRIDGE_OV511:
3897 case BRIDGE_OV511PLUS:
3898 ret = ov511_mode_init_regs(sd);
3899 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003900 case BRIDGE_OV518:
3901 case BRIDGE_OV518PLUS:
3902 ret = ov518_mode_init_regs(sd);
3903 break;
3904 case BRIDGE_OV519:
3905 ret = ov519_mode_init_regs(sd);
3906 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003907 /* case BRIDGE_OVFX2: nothing to do */
Hans de Goedea511ba92009-10-16 07:13:07 -03003908 case BRIDGE_W9968CF:
3909 ret = w9968cf_mode_init_regs(sd);
3910 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003911 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003912 if (ret < 0)
3913 goto out;
Hans de Goede49809d62009-06-07 12:10:39 -03003914
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003915 ret = set_ov_sensor_window(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003916 if (ret < 0)
3917 goto out;
3918
Hans de Goede49809d62009-06-07 12:10:39 -03003919 setcontrast(gspca_dev);
3920 setbrightness(gspca_dev);
3921 setcolors(gspca_dev);
Hans de Goede02ab18b2009-06-14 04:32:04 -03003922 sethvflip(sd);
3923 setautobrightness(sd);
3924 setfreq(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03003925
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003926 ret = ov51x_restart(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003927 if (ret < 0)
3928 goto out;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003929 ov51x_led_control(sd, 1);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03003930 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003931out:
3932 PDEBUG(D_ERR, "camera start error:%d", ret);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03003933 return ret;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003934}
3935
3936static void sd_stopN(struct gspca_dev *gspca_dev)
3937{
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003938 struct sd *sd = (struct sd *) gspca_dev;
3939
3940 ov51x_stop(sd);
3941 ov51x_led_control(sd, 0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003942}
3943
Hans de Goede79b35902009-10-19 06:08:01 -03003944static void sd_stop0(struct gspca_dev *gspca_dev)
3945{
3946 struct sd *sd = (struct sd *) gspca_dev;
3947
3948 if (sd->bridge == BRIDGE_W9968CF)
3949 w9968cf_stop0(sd);
3950}
3951
Hans de Goede1876bb92009-06-14 06:45:50 -03003952static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03003953 u8 *in, /* isoc packet */
3954 int len) /* iso packet length */
Hans de Goede1876bb92009-06-14 06:45:50 -03003955{
3956 struct sd *sd = (struct sd *) gspca_dev;
3957
3958 /* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th
3959 * byte non-zero. The EOF packet has image width/height in the
3960 * 10th and 11th bytes. The 9th byte is given as follows:
3961 *
3962 * bit 7: EOF
3963 * 6: compression enabled
3964 * 5: 422/420/400 modes
3965 * 4: 422/420/400 modes
3966 * 3: 1
3967 * 2: snapshot button on
3968 * 1: snapshot frame
3969 * 0: even/odd field
3970 */
3971 if (!(in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) &&
3972 (in[8] & 0x08)) {
3973 if (in[8] & 0x80) {
3974 /* Frame end */
3975 if ((in[9] + 1) * 8 != gspca_dev->width ||
3976 (in[10] + 1) * 8 != gspca_dev->height) {
3977 PDEBUG(D_ERR, "Invalid frame size, got: %dx%d,"
3978 " requested: %dx%d\n",
3979 (in[9] + 1) * 8, (in[10] + 1) * 8,
3980 gspca_dev->width, gspca_dev->height);
3981 gspca_dev->last_packet_type = DISCARD_PACKET;
3982 return;
3983 }
3984 /* Add 11 byte footer to frame, might be usefull */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03003985 gspca_frame_add(gspca_dev, LAST_PACKET, in, 11);
Hans de Goede1876bb92009-06-14 06:45:50 -03003986 return;
3987 } else {
3988 /* Frame start */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03003989 gspca_frame_add(gspca_dev, FIRST_PACKET, in, 0);
Hans de Goede1876bb92009-06-14 06:45:50 -03003990 sd->packet_nr = 0;
3991 }
3992 }
3993
3994 /* Ignore the packet number */
3995 len--;
3996
3997 /* intermediate packet */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03003998 gspca_frame_add(gspca_dev, INTER_PACKET, in, len);
Hans de Goede1876bb92009-06-14 06:45:50 -03003999}
4000
Hans de Goede49809d62009-06-07 12:10:39 -03004001static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004002 u8 *data, /* isoc packet */
Hans de Goede49809d62009-06-07 12:10:39 -03004003 int len) /* iso packet length */
4004{
Hans de Goede92918a52009-06-14 06:21:35 -03004005 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goede49809d62009-06-07 12:10:39 -03004006
4007 /* A false positive here is likely, until OVT gives me
4008 * the definitive SOF/EOF format */
4009 if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004010 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
4011 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
Hans de Goede92918a52009-06-14 06:21:35 -03004012 sd->packet_nr = 0;
4013 }
4014
4015 if (gspca_dev->last_packet_type == DISCARD_PACKET)
4016 return;
4017
4018 /* Does this device use packet numbers ? */
4019 if (len & 7) {
4020 len--;
4021 if (sd->packet_nr == data[len])
4022 sd->packet_nr++;
4023 /* The last few packets of the frame (which are all 0's
4024 except that they may contain part of the footer), are
4025 numbered 0 */
4026 else if (sd->packet_nr == 0 || data[len]) {
4027 PDEBUG(D_ERR, "Invalid packet nr: %d (expect: %d)",
4028 (int)data[len], (int)sd->packet_nr);
4029 gspca_dev->last_packet_type = DISCARD_PACKET;
4030 return;
4031 }
Hans de Goede49809d62009-06-07 12:10:39 -03004032 }
4033
4034 /* intermediate packet */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004035 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004036}
4037
4038static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004039 u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004040 int len) /* iso packet length */
4041{
4042 /* Header of ov519 is 16 bytes:
4043 * Byte Value Description
4044 * 0 0xff magic
4045 * 1 0xff magic
4046 * 2 0xff magic
4047 * 3 0xXX 0x50 = SOF, 0x51 = EOF
4048 * 9 0xXX 0x01 initial frame without data,
4049 * 0x00 standard frame with image
4050 * 14 Lo in EOF: length of image data / 8
4051 * 15 Hi
4052 */
4053
4054 if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) {
4055 switch (data[3]) {
4056 case 0x50: /* start of frame */
4057#define HDRSZ 16
4058 data += HDRSZ;
4059 len -= HDRSZ;
4060#undef HDRSZ
4061 if (data[0] == 0xff || data[1] == 0xd8)
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004062 gspca_frame_add(gspca_dev, FIRST_PACKET,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004063 data, len);
4064 else
4065 gspca_dev->last_packet_type = DISCARD_PACKET;
4066 return;
4067 case 0x51: /* end of frame */
4068 if (data[9] != 0)
4069 gspca_dev->last_packet_type = DISCARD_PACKET;
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004070 gspca_frame_add(gspca_dev, LAST_PACKET,
4071 NULL, 0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004072 return;
4073 }
4074 }
4075
4076 /* intermediate packet */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004077 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004078}
4079
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004080static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004081 u8 *data, /* isoc packet */
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004082 int len) /* iso packet length */
4083{
4084 /* A short read signals EOF */
4085 if (len < OVFX2_BULK_SIZE) {
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004086 gspca_frame_add(gspca_dev, LAST_PACKET, data, len);
4087 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004088 return;
4089 }
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004090 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004091}
4092
Hans de Goede49809d62009-06-07 12:10:39 -03004093static void sd_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004094 u8 *data, /* isoc packet */
Hans de Goede49809d62009-06-07 12:10:39 -03004095 int len) /* iso packet length */
4096{
4097 struct sd *sd = (struct sd *) gspca_dev;
4098
4099 switch (sd->bridge) {
4100 case BRIDGE_OV511:
4101 case BRIDGE_OV511PLUS:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004102 ov511_pkt_scan(gspca_dev, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004103 break;
4104 case BRIDGE_OV518:
4105 case BRIDGE_OV518PLUS:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004106 ov518_pkt_scan(gspca_dev, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004107 break;
4108 case BRIDGE_OV519:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004109 ov519_pkt_scan(gspca_dev, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004110 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004111 case BRIDGE_OVFX2:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004112 ovfx2_pkt_scan(gspca_dev, data, len);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004113 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03004114 case BRIDGE_W9968CF:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004115 w9968cf_pkt_scan(gspca_dev, data, len);
Hans de Goedea511ba92009-10-16 07:13:07 -03004116 break;
Hans de Goede49809d62009-06-07 12:10:39 -03004117 }
4118}
4119
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004120/* -- management routines -- */
4121
4122static void setbrightness(struct gspca_dev *gspca_dev)
4123{
4124 struct sd *sd = (struct sd *) gspca_dev;
4125 int val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004126
4127 val = sd->brightness;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004128 switch (sd->sensor) {
4129 case SEN_OV8610:
4130 case SEN_OV7610:
4131 case SEN_OV76BE:
4132 case SEN_OV6620:
4133 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004134 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004135 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03004136 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004137 i2c_w(sd, OV7610_REG_BRT, val);
4138 break;
4139 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03004140 case SEN_OV7620AE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004141 /* 7620 doesn't like manual changes when in auto mode */
Hans de Goede02ab18b2009-06-14 04:32:04 -03004142 if (!sd->autobrightness)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004143 i2c_w(sd, OV7610_REG_BRT, val);
4144 break;
4145 case SEN_OV7670:
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004146/*win trace
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004147 * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */
4148 i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val));
4149 break;
4150 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004151}
4152
4153static void setcontrast(struct gspca_dev *gspca_dev)
4154{
4155 struct sd *sd = (struct sd *) gspca_dev;
4156 int val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004157
4158 val = sd->contrast;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004159 switch (sd->sensor) {
4160 case SEN_OV7610:
4161 case SEN_OV6620:
4162 i2c_w(sd, OV7610_REG_CNT, val);
4163 break;
4164 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004165 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004166 i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f);
Hans de Goede49809d62009-06-07 12:10:39 -03004167 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004168 case SEN_OV8610: {
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03004169 static const __u8 ctab[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004170 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f
4171 };
4172
4173 /* Use Y gamma control instead. Bit 0 enables it. */
4174 i2c_w(sd, 0x64, ctab[val >> 5]);
4175 break;
4176 }
Hans de Goede859cc472010-01-07 15:42:35 -03004177 case SEN_OV7620:
4178 case SEN_OV7620AE: {
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03004179 static const __u8 ctab[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004180 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
4181 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
4182 };
4183
4184 /* Use Y gamma control instead. Bit 0 enables it. */
4185 i2c_w(sd, 0x64, ctab[val >> 4]);
4186 break;
4187 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004188 case SEN_OV7670:
4189 /* check that this isn't just the same as ov7610 */
4190 i2c_w(sd, OV7670_REG_CONTRAS, val >> 1);
4191 break;
4192 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004193}
4194
4195static void setcolors(struct gspca_dev *gspca_dev)
4196{
4197 struct sd *sd = (struct sd *) gspca_dev;
4198 int val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004199
4200 val = sd->colors;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004201 switch (sd->sensor) {
4202 case SEN_OV8610:
4203 case SEN_OV7610:
4204 case SEN_OV76BE:
4205 case SEN_OV6620:
4206 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004207 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004208 i2c_w(sd, OV7610_REG_SAT, val);
4209 break;
4210 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03004211 case SEN_OV7620AE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004212 /* Use UV gamma control instead. Bits 0 & 7 are reserved. */
4213/* rc = ov_i2c_write(sd->dev, 0x62, (val >> 9) & 0x7e);
4214 if (rc < 0)
4215 goto out; */
4216 i2c_w(sd, OV7610_REG_SAT, val);
4217 break;
4218 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03004219 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004220 i2c_w(sd, OV7610_REG_SAT, val & 0xf0);
4221 break;
4222 case SEN_OV7670:
4223 /* supported later once I work out how to do it
4224 * transparently fail now! */
4225 /* set REG_COM13 values for UV sat auto mode */
4226 break;
4227 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004228}
4229
Hans de Goede02ab18b2009-06-14 04:32:04 -03004230static void setautobrightness(struct sd *sd)
4231{
Hans de Goede035d3a32010-01-09 08:14:43 -03004232 if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7648 ||
4233 sd->sensor == SEN_OV7670 ||
Hans de Goede635118d2009-10-11 09:49:03 -03004234 sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
Hans de Goede02ab18b2009-06-14 04:32:04 -03004235 return;
4236
4237 i2c_w_mask(sd, 0x2d, sd->autobrightness ? 0x10 : 0x00, 0x10);
4238}
4239
4240static void setfreq(struct sd *sd)
4241{
Hans de Goede635118d2009-10-11 09:49:03 -03004242 if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
4243 return;
4244
Hans de Goede02ab18b2009-06-14 04:32:04 -03004245 if (sd->sensor == SEN_OV7670) {
4246 switch (sd->freq) {
4247 case 0: /* Banding filter disabled */
4248 i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_BFILT);
4249 break;
4250 case 1: /* 50 hz */
4251 i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT,
4252 OV7670_COM8_BFILT);
4253 i2c_w_mask(sd, OV7670_REG_COM11, 0x08, 0x18);
4254 break;
4255 case 2: /* 60 hz */
4256 i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT,
4257 OV7670_COM8_BFILT);
4258 i2c_w_mask(sd, OV7670_REG_COM11, 0x00, 0x18);
4259 break;
4260 case 3: /* Auto hz */
4261 i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT,
4262 OV7670_COM8_BFILT);
4263 i2c_w_mask(sd, OV7670_REG_COM11, OV7670_COM11_HZAUTO,
4264 0x18);
4265 break;
4266 }
4267 } else {
4268 switch (sd->freq) {
4269 case 0: /* Banding filter disabled */
4270 i2c_w_mask(sd, 0x2d, 0x00, 0x04);
4271 i2c_w_mask(sd, 0x2a, 0x00, 0x80);
4272 break;
4273 case 1: /* 50 hz (filter on and framerate adj) */
4274 i2c_w_mask(sd, 0x2d, 0x04, 0x04);
4275 i2c_w_mask(sd, 0x2a, 0x80, 0x80);
4276 /* 20 fps -> 16.667 fps */
4277 if (sd->sensor == SEN_OV6620 ||
Hans de Goede7d971372009-06-14 05:28:17 -03004278 sd->sensor == SEN_OV6630 ||
4279 sd->sensor == SEN_OV66308AF)
Hans de Goede02ab18b2009-06-14 04:32:04 -03004280 i2c_w(sd, 0x2b, 0x5e);
4281 else
4282 i2c_w(sd, 0x2b, 0xac);
4283 break;
4284 case 2: /* 60 hz (filter on, ...) */
4285 i2c_w_mask(sd, 0x2d, 0x04, 0x04);
4286 if (sd->sensor == SEN_OV6620 ||
Hans de Goede7d971372009-06-14 05:28:17 -03004287 sd->sensor == SEN_OV6630 ||
4288 sd->sensor == SEN_OV66308AF) {
Hans de Goede02ab18b2009-06-14 04:32:04 -03004289 /* 20 fps -> 15 fps */
4290 i2c_w_mask(sd, 0x2a, 0x80, 0x80);
4291 i2c_w(sd, 0x2b, 0xa8);
4292 } else {
4293 /* no framerate adj. */
4294 i2c_w_mask(sd, 0x2a, 0x00, 0x80);
4295 }
4296 break;
4297 }
4298 }
4299}
4300
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004301static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
4302{
4303 struct sd *sd = (struct sd *) gspca_dev;
4304
4305 sd->brightness = val;
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004306 if (gspca_dev->streaming)
4307 setbrightness(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004308 return 0;
4309}
4310
4311static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
4312{
4313 struct sd *sd = (struct sd *) gspca_dev;
4314
4315 *val = sd->brightness;
4316 return 0;
4317}
4318
4319static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
4320{
4321 struct sd *sd = (struct sd *) gspca_dev;
4322
4323 sd->contrast = val;
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004324 if (gspca_dev->streaming)
4325 setcontrast(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004326 return 0;
4327}
4328
4329static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
4330{
4331 struct sd *sd = (struct sd *) gspca_dev;
4332
4333 *val = sd->contrast;
4334 return 0;
4335}
4336
4337static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
4338{
4339 struct sd *sd = (struct sd *) gspca_dev;
4340
4341 sd->colors = val;
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004342 if (gspca_dev->streaming)
4343 setcolors(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004344 return 0;
4345}
4346
4347static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
4348{
4349 struct sd *sd = (struct sd *) gspca_dev;
4350
4351 *val = sd->colors;
4352 return 0;
4353}
4354
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03004355static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
4356{
4357 struct sd *sd = (struct sd *) gspca_dev;
4358
4359 sd->hflip = val;
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004360 if (gspca_dev->streaming)
4361 sethvflip(sd);
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03004362 return 0;
4363}
4364
4365static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
4366{
4367 struct sd *sd = (struct sd *) gspca_dev;
4368
4369 *val = sd->hflip;
4370 return 0;
4371}
4372
4373static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
4374{
4375 struct sd *sd = (struct sd *) gspca_dev;
4376
4377 sd->vflip = val;
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004378 if (gspca_dev->streaming)
4379 sethvflip(sd);
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03004380 return 0;
4381}
4382
4383static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
4384{
4385 struct sd *sd = (struct sd *) gspca_dev;
4386
4387 *val = sd->vflip;
4388 return 0;
4389}
4390
Hans de Goede02ab18b2009-06-14 04:32:04 -03004391static int sd_setautobrightness(struct gspca_dev *gspca_dev, __s32 val)
4392{
4393 struct sd *sd = (struct sd *) gspca_dev;
4394
4395 sd->autobrightness = val;
4396 if (gspca_dev->streaming)
4397 setautobrightness(sd);
4398 return 0;
4399}
4400
4401static int sd_getautobrightness(struct gspca_dev *gspca_dev, __s32 *val)
4402{
4403 struct sd *sd = (struct sd *) gspca_dev;
4404
4405 *val = sd->autobrightness;
4406 return 0;
4407}
4408
4409static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
4410{
4411 struct sd *sd = (struct sd *) gspca_dev;
4412
4413 sd->freq = val;
Hans de Goedea511ba92009-10-16 07:13:07 -03004414 if (gspca_dev->streaming) {
Hans de Goede02ab18b2009-06-14 04:32:04 -03004415 setfreq(sd);
Hans de Goedea511ba92009-10-16 07:13:07 -03004416 /* Ugly but necessary */
4417 if (sd->bridge == BRIDGE_W9968CF)
4418 w9968cf_set_crop_window(sd);
4419 }
Hans de Goede02ab18b2009-06-14 04:32:04 -03004420 return 0;
4421}
4422
4423static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
4424{
4425 struct sd *sd = (struct sd *) gspca_dev;
4426
4427 *val = sd->freq;
4428 return 0;
4429}
4430
4431static int sd_querymenu(struct gspca_dev *gspca_dev,
4432 struct v4l2_querymenu *menu)
4433{
4434 struct sd *sd = (struct sd *) gspca_dev;
4435
4436 switch (menu->id) {
4437 case V4L2_CID_POWER_LINE_FREQUENCY:
4438 switch (menu->index) {
4439 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
4440 strcpy((char *) menu->name, "NoFliker");
4441 return 0;
4442 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
4443 strcpy((char *) menu->name, "50 Hz");
4444 return 0;
4445 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
4446 strcpy((char *) menu->name, "60 Hz");
4447 return 0;
4448 case 3:
4449 if (sd->sensor != SEN_OV7670)
4450 return -EINVAL;
4451
4452 strcpy((char *) menu->name, "Automatic");
4453 return 0;
4454 }
4455 break;
4456 }
4457 return -EINVAL;
4458}
4459
Hans de Goede79b35902009-10-19 06:08:01 -03004460static int sd_get_jcomp(struct gspca_dev *gspca_dev,
4461 struct v4l2_jpegcompression *jcomp)
4462{
4463 struct sd *sd = (struct sd *) gspca_dev;
4464
4465 if (sd->bridge != BRIDGE_W9968CF)
4466 return -EINVAL;
4467
4468 memset(jcomp, 0, sizeof *jcomp);
4469 jcomp->quality = sd->quality;
4470 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT |
4471 V4L2_JPEG_MARKER_DRI;
4472 return 0;
4473}
4474
4475static int sd_set_jcomp(struct gspca_dev *gspca_dev,
4476 struct v4l2_jpegcompression *jcomp)
4477{
4478 struct sd *sd = (struct sd *) gspca_dev;
4479
4480 if (sd->bridge != BRIDGE_W9968CF)
4481 return -EINVAL;
4482
4483 if (gspca_dev->streaming)
4484 return -EBUSY;
4485
4486 if (jcomp->quality < QUALITY_MIN)
4487 sd->quality = QUALITY_MIN;
4488 else if (jcomp->quality > QUALITY_MAX)
4489 sd->quality = QUALITY_MAX;
4490 else
4491 sd->quality = jcomp->quality;
4492
4493 /* Return resulting jcomp params to app */
4494 sd_get_jcomp(gspca_dev, jcomp);
4495
4496 return 0;
4497}
4498
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004499/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03004500static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004501 .name = MODULE_NAME,
4502 .ctrls = sd_ctrls,
4503 .nctrls = ARRAY_SIZE(sd_ctrls),
4504 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03004505 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004506 .start = sd_start,
4507 .stopN = sd_stopN,
Hans de Goede79b35902009-10-19 06:08:01 -03004508 .stop0 = sd_stop0,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004509 .pkt_scan = sd_pkt_scan,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004510 .querymenu = sd_querymenu,
Hans de Goede79b35902009-10-19 06:08:01 -03004511 .get_jcomp = sd_get_jcomp,
4512 .set_jcomp = sd_set_jcomp,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004513};
4514
4515/* -- module initialisation -- */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03004516static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goedea511ba92009-10-16 07:13:07 -03004517 {USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF },
Hans de Goede49809d62009-06-07 12:10:39 -03004518 {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 },
4519 {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
4520 {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
4521 {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
Hans de Goede9e4d8252009-06-14 06:25:06 -03004522 {USB_DEVICE(0x041e, 0x4064),
4523 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
Rafal Milecki518c8df2009-10-02 03:54:44 -03004524 {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 },
Hans de Goede9e4d8252009-06-14 06:25:06 -03004525 {USB_DEVICE(0x041e, 0x4068),
4526 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
Hans de Goede49809d62009-06-07 12:10:39 -03004527 {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
4528 {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
Hans de Goede98184f72010-01-07 12:06:00 -03004529 {USB_DEVICE(0x054c, 0x0155),
4530 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
Hans de Goede1876bb92009-06-14 06:45:50 -03004531 {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 },
Hans de Goede49809d62009-06-07 12:10:39 -03004532 {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
4533 {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
4534 {USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 },
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004535 {USB_DEVICE(0x05a9, 0x2800), .driver_info = BRIDGE_OVFX2 },
Hans de Goede49809d62009-06-07 12:10:39 -03004536 {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 },
4537 {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 },
Hans de Goede1876bb92009-06-14 06:45:50 -03004538 {USB_DEVICE(0x05a9, 0xa511), .driver_info = BRIDGE_OV511PLUS },
Hans de Goede49809d62009-06-07 12:10:39 -03004539 {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS },
Hans de Goede1876bb92009-06-14 06:45:50 -03004540 {USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS },
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004541 {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 },
4542 {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 },
Hans de Goedea511ba92009-10-16 07:13:07 -03004543 {USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF },
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004544 {USB_DEVICE(0x8020, 0xEF04), .driver_info = BRIDGE_OVFX2 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004545 {}
4546};
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004547
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004548MODULE_DEVICE_TABLE(usb, device_table);
4549
4550/* -- device connect -- */
4551static int sd_probe(struct usb_interface *intf,
4552 const struct usb_device_id *id)
4553{
4554 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
4555 THIS_MODULE);
4556}
4557
4558static struct usb_driver sd_driver = {
4559 .name = MODULE_NAME,
4560 .id_table = device_table,
4561 .probe = sd_probe,
4562 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03004563#ifdef CONFIG_PM
4564 .suspend = gspca_suspend,
4565 .resume = gspca_resume,
4566#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004567};
4568
4569/* -- module insert / remove -- */
4570static int __init sd_mod_init(void)
4571{
Alexey Klimovf69e9522009-01-01 13:02:07 -03004572 int ret;
4573 ret = usb_register(&sd_driver);
4574 if (ret < 0)
Alexey Klimove6b14842009-01-01 13:04:58 -03004575 return ret;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03004576 PDEBUG(D_PROBE, "registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004577 return 0;
4578}
4579static void __exit sd_mod_exit(void)
4580{
4581 usb_deregister(&sd_driver);
4582 PDEBUG(D_PROBE, "deregistered");
4583}
4584
4585module_init(sd_mod_init);
4586module_exit(sd_mod_exit);
4587
4588module_param(frame_rate, int, 0644);
4589MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)");