[media] gspca: Fix coding style issues
[deliverable/linux.git] / drivers / media / video / gspca / sn9c20x.c
CommitLineData
26e744b6
BJ
1/*
2 * Sonix sn9c201 sn9c202 library
3 * Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com>
4 * Copyright (C) 2009 Brian Johnson <brijohn@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
26e744b6 21#include <linux/input.h>
26e744b6 22
c15b95ed
MCC
23#include "gspca.h"
24#include "jpeg.h"
25
26#include <media/v4l2-chip-ident.h>
7ddaac7f 27#include <linux/dmi.h>
c15b95ed 28
26e744b6
BJ
29MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, "
30 "microdia project <microdia@googlegroups.com>");
31MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
32MODULE_LICENSE("GPL");
33
34#define MODULE_NAME "sn9c20x"
35
36#define MODE_RAW 0x10
37#define MODE_JPEG 0x20
38#define MODE_SXGA 0x80
39
40#define SENSOR_OV9650 0
41#define SENSOR_OV9655 1
42#define SENSOR_SOI968 2
43#define SENSOR_OV7660 3
44#define SENSOR_OV7670 4
45#define SENSOR_MT9V011 5
46#define SENSOR_MT9V111 6
47#define SENSOR_MT9V112 7
48#define SENSOR_MT9M001 8
49#define SENSOR_MT9M111 9
e99ac54d
BJ
50#define SENSOR_MT9M112 10
51#define SENSOR_HV7131R 11
26e744b6
BJ
52#define SENSOR_MT9VPRB 20
53
a39db27a 54/* camera flags */
33ddc16f 55#define HAS_NO_BUTTON 0x1
0c045eb7 56#define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
7ddaac7f 57#define FLIP_DETECT 0x4
a39db27a 58
26e744b6
BJ
59/* specific webcam descriptor */
60struct sd {
61 struct gspca_dev gspca_dev;
62
63#define MIN_AVG_LUM 80
64#define MAX_AVG_LUM 130
65 atomic_t avg_lum;
66 u8 old_step;
67 u8 older_step;
68 u8 exposure_step;
69
70 u8 brightness;
71 u8 contrast;
72 u8 saturation;
73 s16 hue;
74 u8 gamma;
75 u8 red;
76 u8 blue;
77
78 u8 hflip;
79 u8 vflip;
80 u8 gain;
81 u16 exposure;
82 u8 auto_exposure;
83
84 u8 i2c_addr;
85 u8 sensor;
86 u8 hstart;
87 u8 vstart;
88
9a731a32 89 u8 jpeg_hdr[JPEG_HDR_SZ];
26e744b6
BJ
90 u8 quality;
91
a39db27a 92 u8 flags;
26e744b6
BJ
93};
94
58aa68c2
JP
95struct i2c_reg_u8 {
96 u8 reg;
97 u8 val;
98};
99
100struct i2c_reg_u16 {
101 u8 reg;
102 u16 val;
103};
104
26e744b6
BJ
105static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val);
106static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val);
107static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val);
108static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val);
109static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val);
110static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val);
111static int sd_sethue(struct gspca_dev *gspca_dev, s32 val);
112static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val);
113static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val);
114static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val);
115static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val);
116static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val);
117static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val);
118static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val);
119static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val);
120static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val);
121static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val);
122static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val);
123static int sd_setgain(struct gspca_dev *gspca_dev, s32 val);
124static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val);
125static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val);
126static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val);
127static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val);
128static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val);
129
7ddaac7f
BJ
130static const struct dmi_system_id flip_dmi_table[] = {
131 {
132 .ident = "MSI MS-1034",
133 .matches = {
134 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
135 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1034"),
136 DMI_MATCH(DMI_PRODUCT_VERSION, "0341")
137 }
138 },
139 {
140 .ident = "MSI MS-1632",
141 .matches = {
142 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
143 DMI_MATCH(DMI_BOARD_NAME, "MS-1632")
144 }
145 },
5d26ed91
BJ
146 {
147 .ident = "MSI MS-1635X",
148 .matches = {
149 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
150 DMI_MATCH(DMI_BOARD_NAME, "MS-1635X")
151 }
152 },
e077f86b
BJ
153 {
154 .ident = "ASUSTeK W7J",
155 .matches = {
156 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
157 DMI_MATCH(DMI_BOARD_NAME, "W7J ")
158 }
159 },
7ddaac7f
BJ
160 {}
161};
162
7e64dc4c 163static const struct ctrl sd_ctrls[] = {
26e744b6
BJ
164 {
165#define BRIGHTNESS_IDX 0
166 {
167 .id = V4L2_CID_BRIGHTNESS,
168 .type = V4L2_CTRL_TYPE_INTEGER,
169 .name = "Brightness",
170 .minimum = 0,
171 .maximum = 0xff,
172 .step = 1,
173#define BRIGHTNESS_DEFAULT 0x7f
174 .default_value = BRIGHTNESS_DEFAULT,
175 },
176 .set = sd_setbrightness,
177 .get = sd_getbrightness,
178 },
179 {
180#define CONTRAST_IDX 1
181 {
182 .id = V4L2_CID_CONTRAST,
183 .type = V4L2_CTRL_TYPE_INTEGER,
184 .name = "Contrast",
185 .minimum = 0,
186 .maximum = 0xff,
187 .step = 1,
188#define CONTRAST_DEFAULT 0x7f
189 .default_value = CONTRAST_DEFAULT,
190 },
191 .set = sd_setcontrast,
192 .get = sd_getcontrast,
193 },
194 {
195#define SATURATION_IDX 2
196 {
197 .id = V4L2_CID_SATURATION,
198 .type = V4L2_CTRL_TYPE_INTEGER,
199 .name = "Saturation",
200 .minimum = 0,
201 .maximum = 0xff,
202 .step = 1,
203#define SATURATION_DEFAULT 0x7f
204 .default_value = SATURATION_DEFAULT,
205 },
206 .set = sd_setsaturation,
207 .get = sd_getsaturation,
208 },
209 {
210#define HUE_IDX 3
211 {
212 .id = V4L2_CID_HUE,
213 .type = V4L2_CTRL_TYPE_INTEGER,
214 .name = "Hue",
215 .minimum = -180,
216 .maximum = 180,
217 .step = 1,
218#define HUE_DEFAULT 0
219 .default_value = HUE_DEFAULT,
220 },
221 .set = sd_sethue,
222 .get = sd_gethue,
223 },
224 {
225#define GAMMA_IDX 4
226 {
227 .id = V4L2_CID_GAMMA,
228 .type = V4L2_CTRL_TYPE_INTEGER,
229 .name = "Gamma",
230 .minimum = 0,
231 .maximum = 0xff,
232 .step = 1,
233#define GAMMA_DEFAULT 0x10
234 .default_value = GAMMA_DEFAULT,
235 },
236 .set = sd_setgamma,
237 .get = sd_getgamma,
238 },
239 {
240#define BLUE_IDX 5
241 {
242 .id = V4L2_CID_BLUE_BALANCE,
243 .type = V4L2_CTRL_TYPE_INTEGER,
244 .name = "Blue Balance",
245 .minimum = 0,
246 .maximum = 0x7f,
247 .step = 1,
248#define BLUE_DEFAULT 0x28
249 .default_value = BLUE_DEFAULT,
250 },
251 .set = sd_setbluebalance,
252 .get = sd_getbluebalance,
253 },
254 {
255#define RED_IDX 6
256 {
257 .id = V4L2_CID_RED_BALANCE,
258 .type = V4L2_CTRL_TYPE_INTEGER,
259 .name = "Red Balance",
260 .minimum = 0,
261 .maximum = 0x7f,
262 .step = 1,
263#define RED_DEFAULT 0x28
264 .default_value = RED_DEFAULT,
265 },
266 .set = sd_setredbalance,
267 .get = sd_getredbalance,
268 },
269 {
270#define HFLIP_IDX 7
271 {
272 .id = V4L2_CID_HFLIP,
273 .type = V4L2_CTRL_TYPE_BOOLEAN,
274 .name = "Horizontal Flip",
275 .minimum = 0,
276 .maximum = 1,
277 .step = 1,
278#define HFLIP_DEFAULT 0
279 .default_value = HFLIP_DEFAULT,
280 },
281 .set = sd_sethflip,
282 .get = sd_gethflip,
283 },
284 {
285#define VFLIP_IDX 8
286 {
287 .id = V4L2_CID_VFLIP,
288 .type = V4L2_CTRL_TYPE_BOOLEAN,
289 .name = "Vertical Flip",
290 .minimum = 0,
291 .maximum = 1,
292 .step = 1,
293#define VFLIP_DEFAULT 0
294 .default_value = VFLIP_DEFAULT,
295 },
296 .set = sd_setvflip,
297 .get = sd_getvflip,
298 },
299 {
300#define EXPOSURE_IDX 9
301 {
302 .id = V4L2_CID_EXPOSURE,
303 .type = V4L2_CTRL_TYPE_INTEGER,
304 .name = "Exposure",
305 .minimum = 0,
306 .maximum = 0x1780,
307 .step = 1,
308#define EXPOSURE_DEFAULT 0x33
309 .default_value = EXPOSURE_DEFAULT,
310 },
311 .set = sd_setexposure,
312 .get = sd_getexposure,
313 },
314 {
315#define GAIN_IDX 10
316 {
317 .id = V4L2_CID_GAIN,
318 .type = V4L2_CTRL_TYPE_INTEGER,
319 .name = "Gain",
320 .minimum = 0,
321 .maximum = 28,
322 .step = 1,
323#define GAIN_DEFAULT 0x00
324 .default_value = GAIN_DEFAULT,
325 },
326 .set = sd_setgain,
327 .get = sd_getgain,
328 },
329 {
330#define AUTOGAIN_IDX 11
331 {
332 .id = V4L2_CID_AUTOGAIN,
333 .type = V4L2_CTRL_TYPE_BOOLEAN,
334 .name = "Auto Exposure",
335 .minimum = 0,
336 .maximum = 1,
337 .step = 1,
338#define AUTO_EXPOSURE_DEFAULT 1
339 .default_value = AUTO_EXPOSURE_DEFAULT,
340 },
341 .set = sd_setautoexposure,
342 .get = sd_getautoexposure,
343 },
344};
345
346static const struct v4l2_pix_format vga_mode[] = {
347 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
b1e4665b 348 .bytesperline = 160,
9b1d3cae 349 .sizeimage = 160 * 120 * 4 / 8 + 590,
26e744b6
BJ
350 .colorspace = V4L2_COLORSPACE_JPEG,
351 .priv = 0 | MODE_JPEG},
352 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
353 .bytesperline = 160,
354 .sizeimage = 160 * 120,
355 .colorspace = V4L2_COLORSPACE_SRGB,
356 .priv = 0 | MODE_RAW},
357 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
b1e4665b 358 .bytesperline = 160,
26e744b6
BJ
359 .sizeimage = 240 * 120,
360 .colorspace = V4L2_COLORSPACE_SRGB,
361 .priv = 0},
362 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
b1e4665b 363 .bytesperline = 320,
9b1d3cae 364 .sizeimage = 320 * 240 * 3 / 8 + 590,
26e744b6
BJ
365 .colorspace = V4L2_COLORSPACE_JPEG,
366 .priv = 1 | MODE_JPEG},
367 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
368 .bytesperline = 320,
369 .sizeimage = 320 * 240 ,
370 .colorspace = V4L2_COLORSPACE_SRGB,
371 .priv = 1 | MODE_RAW},
372 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
b1e4665b 373 .bytesperline = 320,
26e744b6
BJ
374 .sizeimage = 480 * 240 ,
375 .colorspace = V4L2_COLORSPACE_SRGB,
376 .priv = 1},
377 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
b1e4665b 378 .bytesperline = 640,
9b1d3cae 379 .sizeimage = 640 * 480 * 3 / 8 + 590,
26e744b6
BJ
380 .colorspace = V4L2_COLORSPACE_JPEG,
381 .priv = 2 | MODE_JPEG},
382 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
383 .bytesperline = 640,
384 .sizeimage = 640 * 480,
385 .colorspace = V4L2_COLORSPACE_SRGB,
386 .priv = 2 | MODE_RAW},
387 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
b1e4665b 388 .bytesperline = 640,
26e744b6
BJ
389 .sizeimage = 960 * 480,
390 .colorspace = V4L2_COLORSPACE_SRGB,
391 .priv = 2},
392};
393
394static const struct v4l2_pix_format sxga_mode[] = {
395 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
b1e4665b 396 .bytesperline = 160,
9b1d3cae 397 .sizeimage = 160 * 120 * 4 / 8 + 590,
26e744b6
BJ
398 .colorspace = V4L2_COLORSPACE_JPEG,
399 .priv = 0 | MODE_JPEG},
400 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
401 .bytesperline = 160,
402 .sizeimage = 160 * 120,
403 .colorspace = V4L2_COLORSPACE_SRGB,
404 .priv = 0 | MODE_RAW},
405 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
b1e4665b 406 .bytesperline = 160,
26e744b6
BJ
407 .sizeimage = 240 * 120,
408 .colorspace = V4L2_COLORSPACE_SRGB,
409 .priv = 0},
410 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
b1e4665b 411 .bytesperline = 320,
9b1d3cae 412 .sizeimage = 320 * 240 * 3 / 8 + 590,
26e744b6
BJ
413 .colorspace = V4L2_COLORSPACE_JPEG,
414 .priv = 1 | MODE_JPEG},
415 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
416 .bytesperline = 320,
417 .sizeimage = 320 * 240 ,
418 .colorspace = V4L2_COLORSPACE_SRGB,
419 .priv = 1 | MODE_RAW},
420 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
b1e4665b 421 .bytesperline = 320,
26e744b6
BJ
422 .sizeimage = 480 * 240 ,
423 .colorspace = V4L2_COLORSPACE_SRGB,
424 .priv = 1},
425 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
b1e4665b 426 .bytesperline = 640,
9b1d3cae 427 .sizeimage = 640 * 480 * 3 / 8 + 590,
26e744b6
BJ
428 .colorspace = V4L2_COLORSPACE_JPEG,
429 .priv = 2 | MODE_JPEG},
430 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
431 .bytesperline = 640,
432 .sizeimage = 640 * 480,
433 .colorspace = V4L2_COLORSPACE_SRGB,
434 .priv = 2 | MODE_RAW},
435 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
b1e4665b 436 .bytesperline = 640,
26e744b6
BJ
437 .sizeimage = 960 * 480,
438 .colorspace = V4L2_COLORSPACE_SRGB,
439 .priv = 2},
440 {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
441 .bytesperline = 1280,
9b1d3cae 442 .sizeimage = 1280 * 1024,
26e744b6
BJ
443 .colorspace = V4L2_COLORSPACE_SRGB,
444 .priv = 3 | MODE_RAW | MODE_SXGA},
445};
446
58aa68c2 447static const s16 hsv_red_x[] = {
26e744b6
BJ
448 41, 44, 46, 48, 50, 52, 54, 56,
449 58, 60, 62, 64, 66, 68, 70, 72,
450 74, 76, 78, 80, 81, 83, 85, 87,
451 88, 90, 92, 93, 95, 97, 98, 100,
452 101, 102, 104, 105, 107, 108, 109, 110,
453 112, 113, 114, 115, 116, 117, 118, 119,
454 120, 121, 122, 123, 123, 124, 125, 125,
455 126, 127, 127, 128, 128, 129, 129, 129,
456 130, 130, 130, 130, 131, 131, 131, 131,
457 131, 131, 131, 131, 130, 130, 130, 130,
458 129, 129, 129, 128, 128, 127, 127, 126,
459 125, 125, 124, 123, 122, 122, 121, 120,
460 119, 118, 117, 116, 115, 114, 112, 111,
461 110, 109, 107, 106, 105, 103, 102, 101,
462 99, 98, 96, 94, 93, 91, 90, 88,
463 86, 84, 83, 81, 79, 77, 75, 74,
464 72, 70, 68, 66, 64, 62, 60, 58,
465 56, 54, 52, 49, 47, 45, 43, 41,
466 39, 36, 34, 32, 30, 28, 25, 23,
467 21, 19, 16, 14, 12, 9, 7, 5,
468 3, 0, -1, -3, -6, -8, -10, -12,
469 -15, -17, -19, -22, -24, -26, -28, -30,
470 -33, -35, -37, -39, -41, -44, -46, -48,
471 -50, -52, -54, -56, -58, -60, -62, -64,
472 -66, -68, -70, -72, -74, -76, -78, -80,
473 -81, -83, -85, -87, -88, -90, -92, -93,
474 -95, -97, -98, -100, -101, -102, -104, -105,
475 -107, -108, -109, -110, -112, -113, -114, -115,
476 -116, -117, -118, -119, -120, -121, -122, -123,
477 -123, -124, -125, -125, -126, -127, -127, -128,
478 -128, -128, -128, -128, -128, -128, -128, -128,
479 -128, -128, -128, -128, -128, -128, -128, -128,
480 -128, -128, -128, -128, -128, -128, -128, -128,
481 -128, -127, -127, -126, -125, -125, -124, -123,
482 -122, -122, -121, -120, -119, -118, -117, -116,
483 -115, -114, -112, -111, -110, -109, -107, -106,
484 -105, -103, -102, -101, -99, -98, -96, -94,
485 -93, -91, -90, -88, -86, -84, -83, -81,
486 -79, -77, -75, -74, -72, -70, -68, -66,
487 -64, -62, -60, -58, -56, -54, -52, -49,
488 -47, -45, -43, -41, -39, -36, -34, -32,
489 -30, -28, -25, -23, -21, -19, -16, -14,
490 -12, -9, -7, -5, -3, 0, 1, 3,
491 6, 8, 10, 12, 15, 17, 19, 22,
492 24, 26, 28, 30, 33, 35, 37, 39, 41
493};
494
58aa68c2 495static const s16 hsv_red_y[] = {
26e744b6
BJ
496 82, 80, 78, 76, 74, 73, 71, 69,
497 67, 65, 63, 61, 58, 56, 54, 52,
498 50, 48, 46, 44, 41, 39, 37, 35,
499 32, 30, 28, 26, 23, 21, 19, 16,
500 14, 12, 10, 7, 5, 3, 0, -1,
501 -3, -6, -8, -10, -13, -15, -17, -19,
502 -22, -24, -26, -29, -31, -33, -35, -38,
503 -40, -42, -44, -46, -48, -51, -53, -55,
504 -57, -59, -61, -63, -65, -67, -69, -71,
505 -73, -75, -77, -79, -81, -82, -84, -86,
506 -88, -89, -91, -93, -94, -96, -98, -99,
507 -101, -102, -104, -105, -106, -108, -109, -110,
508 -112, -113, -114, -115, -116, -117, -119, -120,
509 -120, -121, -122, -123, -124, -125, -126, -126,
510 -127, -128, -128, -128, -128, -128, -128, -128,
511 -128, -128, -128, -128, -128, -128, -128, -128,
512 -128, -128, -128, -128, -128, -128, -128, -128,
513 -128, -128, -128, -128, -128, -128, -128, -128,
514 -127, -127, -126, -125, -125, -124, -123, -122,
515 -121, -120, -119, -118, -117, -116, -115, -114,
516 -113, -111, -110, -109, -107, -106, -105, -103,
517 -102, -100, -99, -97, -96, -94, -92, -91,
518 -89, -87, -85, -84, -82, -80, -78, -76,
519 -74, -73, -71, -69, -67, -65, -63, -61,
520 -58, -56, -54, -52, -50, -48, -46, -44,
521 -41, -39, -37, -35, -32, -30, -28, -26,
522 -23, -21, -19, -16, -14, -12, -10, -7,
523 -5, -3, 0, 1, 3, 6, 8, 10,
524 13, 15, 17, 19, 22, 24, 26, 29,
525 31, 33, 35, 38, 40, 42, 44, 46,
526 48, 51, 53, 55, 57, 59, 61, 63,
527 65, 67, 69, 71, 73, 75, 77, 79,
528 81, 82, 84, 86, 88, 89, 91, 93,
529 94, 96, 98, 99, 101, 102, 104, 105,
530 106, 108, 109, 110, 112, 113, 114, 115,
531 116, 117, 119, 120, 120, 121, 122, 123,
532 124, 125, 126, 126, 127, 128, 128, 129,
533 129, 130, 130, 131, 131, 131, 131, 132,
534 132, 132, 132, 132, 132, 132, 132, 132,
535 132, 132, 132, 131, 131, 131, 130, 130,
536 130, 129, 129, 128, 127, 127, 126, 125,
537 125, 124, 123, 122, 121, 120, 119, 118,
538 117, 116, 115, 114, 113, 111, 110, 109,
539 107, 106, 105, 103, 102, 100, 99, 97,
540 96, 94, 92, 91, 89, 87, 85, 84, 82
541};
542
58aa68c2 543static const s16 hsv_green_x[] = {
26e744b6
BJ
544 -124, -124, -125, -125, -125, -125, -125, -125,
545 -125, -126, -126, -125, -125, -125, -125, -125,
546 -125, -124, -124, -124, -123, -123, -122, -122,
547 -121, -121, -120, -120, -119, -118, -117, -117,
548 -116, -115, -114, -113, -112, -111, -110, -109,
549 -108, -107, -105, -104, -103, -102, -100, -99,
550 -98, -96, -95, -93, -92, -91, -89, -87,
551 -86, -84, -83, -81, -79, -77, -76, -74,
552 -72, -70, -69, -67, -65, -63, -61, -59,
553 -57, -55, -53, -51, -49, -47, -45, -43,
554 -41, -39, -37, -35, -33, -30, -28, -26,
555 -24, -22, -20, -18, -15, -13, -11, -9,
556 -7, -4, -2, 0, 1, 3, 6, 8,
557 10, 12, 14, 17, 19, 21, 23, 25,
558 27, 29, 32, 34, 36, 38, 40, 42,
559 44, 46, 48, 50, 52, 54, 56, 58,
560 60, 62, 64, 66, 68, 70, 71, 73,
561 75, 77, 78, 80, 82, 83, 85, 87,
562 88, 90, 91, 93, 94, 96, 97, 98,
563 100, 101, 102, 104, 105, 106, 107, 108,
564 109, 111, 112, 113, 113, 114, 115, 116,
565 117, 118, 118, 119, 120, 120, 121, 122,
566 122, 123, 123, 124, 124, 124, 125, 125,
567 125, 125, 125, 125, 125, 126, 126, 125,
568 125, 125, 125, 125, 125, 124, 124, 124,
569 123, 123, 122, 122, 121, 121, 120, 120,
570 119, 118, 117, 117, 116, 115, 114, 113,
571 112, 111, 110, 109, 108, 107, 105, 104,
572 103, 102, 100, 99, 98, 96, 95, 93,
573 92, 91, 89, 87, 86, 84, 83, 81,
574 79, 77, 76, 74, 72, 70, 69, 67,
575 65, 63, 61, 59, 57, 55, 53, 51,
576 49, 47, 45, 43, 41, 39, 37, 35,
577 33, 30, 28, 26, 24, 22, 20, 18,
578 15, 13, 11, 9, 7, 4, 2, 0,
579 -1, -3, -6, -8, -10, -12, -14, -17,
580 -19, -21, -23, -25, -27, -29, -32, -34,
581 -36, -38, -40, -42, -44, -46, -48, -50,
582 -52, -54, -56, -58, -60, -62, -64, -66,
583 -68, -70, -71, -73, -75, -77, -78, -80,
584 -82, -83, -85, -87, -88, -90, -91, -93,
585 -94, -96, -97, -98, -100, -101, -102, -104,
586 -105, -106, -107, -108, -109, -111, -112, -113,
587 -113, -114, -115, -116, -117, -118, -118, -119,
588 -120, -120, -121, -122, -122, -123, -123, -124, -124
589};
590
58aa68c2 591static const s16 hsv_green_y[] = {
26e744b6
BJ
592 -100, -99, -98, -97, -95, -94, -93, -91,
593 -90, -89, -87, -86, -84, -83, -81, -80,
594 -78, -76, -75, -73, -71, -70, -68, -66,
595 -64, -63, -61, -59, -57, -55, -53, -51,
596 -49, -48, -46, -44, -42, -40, -38, -36,
597 -34, -32, -30, -27, -25, -23, -21, -19,
598 -17, -15, -13, -11, -9, -7, -4, -2,
599 0, 1, 3, 5, 7, 9, 11, 14,
600 16, 18, 20, 22, 24, 26, 28, 30,
601 32, 34, 36, 38, 40, 42, 44, 46,
602 48, 50, 52, 54, 56, 58, 59, 61,
603 63, 65, 67, 68, 70, 72, 74, 75,
604 77, 78, 80, 82, 83, 85, 86, 88,
605 89, 90, 92, 93, 95, 96, 97, 98,
606 100, 101, 102, 103, 104, 105, 106, 107,
607 108, 109, 110, 111, 112, 112, 113, 114,
608 115, 115, 116, 116, 117, 117, 118, 118,
609 119, 119, 119, 120, 120, 120, 120, 120,
610 121, 121, 121, 121, 121, 121, 120, 120,
611 120, 120, 120, 119, 119, 119, 118, 118,
612 117, 117, 116, 116, 115, 114, 114, 113,
613 112, 111, 111, 110, 109, 108, 107, 106,
614 105, 104, 103, 102, 100, 99, 98, 97,
615 95, 94, 93, 91, 90, 89, 87, 86,
616 84, 83, 81, 80, 78, 76, 75, 73,
617 71, 70, 68, 66, 64, 63, 61, 59,
618 57, 55, 53, 51, 49, 48, 46, 44,
619 42, 40, 38, 36, 34, 32, 30, 27,
620 25, 23, 21, 19, 17, 15, 13, 11,
621 9, 7, 4, 2, 0, -1, -3, -5,
622 -7, -9, -11, -14, -16, -18, -20, -22,
623 -24, -26, -28, -30, -32, -34, -36, -38,
624 -40, -42, -44, -46, -48, -50, -52, -54,
625 -56, -58, -59, -61, -63, -65, -67, -68,
626 -70, -72, -74, -75, -77, -78, -80, -82,
627 -83, -85, -86, -88, -89, -90, -92, -93,
628 -95, -96, -97, -98, -100, -101, -102, -103,
629 -104, -105, -106, -107, -108, -109, -110, -111,
630 -112, -112, -113, -114, -115, -115, -116, -116,
631 -117, -117, -118, -118, -119, -119, -119, -120,
632 -120, -120, -120, -120, -121, -121, -121, -121,
633 -121, -121, -120, -120, -120, -120, -120, -119,
634 -119, -119, -118, -118, -117, -117, -116, -116,
635 -115, -114, -114, -113, -112, -111, -111, -110,
636 -109, -108, -107, -106, -105, -104, -103, -102, -100
637};
638
58aa68c2 639static const s16 hsv_blue_x[] = {
26e744b6
BJ
640 112, 113, 114, 114, 115, 116, 117, 117,
641 118, 118, 119, 119, 120, 120, 120, 121,
642 121, 121, 122, 122, 122, 122, 122, 122,
643 122, 122, 122, 122, 122, 122, 121, 121,
644 121, 120, 120, 120, 119, 119, 118, 118,
645 117, 116, 116, 115, 114, 113, 113, 112,
646 111, 110, 109, 108, 107, 106, 105, 104,
647 103, 102, 100, 99, 98, 97, 95, 94,
648 93, 91, 90, 88, 87, 85, 84, 82,
649 80, 79, 77, 76, 74, 72, 70, 69,
650 67, 65, 63, 61, 60, 58, 56, 54,
651 52, 50, 48, 46, 44, 42, 40, 38,
652 36, 34, 32, 30, 28, 26, 24, 22,
653 19, 17, 15, 13, 11, 9, 7, 5,
654 2, 0, -1, -3, -5, -7, -9, -12,
655 -14, -16, -18, -20, -22, -24, -26, -28,
656 -31, -33, -35, -37, -39, -41, -43, -45,
657 -47, -49, -51, -53, -54, -56, -58, -60,
658 -62, -64, -66, -67, -69, -71, -73, -74,
659 -76, -78, -79, -81, -83, -84, -86, -87,
660 -89, -90, -92, -93, -94, -96, -97, -98,
661 -99, -101, -102, -103, -104, -105, -106, -107,
662 -108, -109, -110, -111, -112, -113, -114, -114,
663 -115, -116, -117, -117, -118, -118, -119, -119,
664 -120, -120, -120, -121, -121, -121, -122, -122,
665 -122, -122, -122, -122, -122, -122, -122, -122,
666 -122, -122, -121, -121, -121, -120, -120, -120,
667 -119, -119, -118, -118, -117, -116, -116, -115,
668 -114, -113, -113, -112, -111, -110, -109, -108,
669 -107, -106, -105, -104, -103, -102, -100, -99,
670 -98, -97, -95, -94, -93, -91, -90, -88,
671 -87, -85, -84, -82, -80, -79, -77, -76,
672 -74, -72, -70, -69, -67, -65, -63, -61,
673 -60, -58, -56, -54, -52, -50, -48, -46,
674 -44, -42, -40, -38, -36, -34, -32, -30,
675 -28, -26, -24, -22, -19, -17, -15, -13,
676 -11, -9, -7, -5, -2, 0, 1, 3,
677 5, 7, 9, 12, 14, 16, 18, 20,
678 22, 24, 26, 28, 31, 33, 35, 37,
679 39, 41, 43, 45, 47, 49, 51, 53,
680 54, 56, 58, 60, 62, 64, 66, 67,
681 69, 71, 73, 74, 76, 78, 79, 81,
682 83, 84, 86, 87, 89, 90, 92, 93,
683 94, 96, 97, 98, 99, 101, 102, 103,
684 104, 105, 106, 107, 108, 109, 110, 111, 112
685};
686
58aa68c2 687static const s16 hsv_blue_y[] = {
26e744b6
BJ
688 -11, -13, -15, -17, -19, -21, -23, -25,
689 -27, -29, -31, -33, -35, -37, -39, -41,
690 -43, -45, -46, -48, -50, -52, -54, -55,
691 -57, -59, -61, -62, -64, -66, -67, -69,
692 -71, -72, -74, -75, -77, -78, -80, -81,
693 -83, -84, -86, -87, -88, -90, -91, -92,
694 -93, -95, -96, -97, -98, -99, -100, -101,
695 -102, -103, -104, -105, -106, -106, -107, -108,
696 -109, -109, -110, -111, -111, -112, -112, -113,
697 -113, -114, -114, -114, -115, -115, -115, -115,
698 -116, -116, -116, -116, -116, -116, -116, -116,
699 -116, -115, -115, -115, -115, -114, -114, -114,
700 -113, -113, -112, -112, -111, -111, -110, -110,
701 -109, -108, -108, -107, -106, -105, -104, -103,
702 -102, -101, -100, -99, -98, -97, -96, -95,
703 -94, -93, -91, -90, -89, -88, -86, -85,
704 -84, -82, -81, -79, -78, -76, -75, -73,
705 -71, -70, -68, -67, -65, -63, -62, -60,
706 -58, -56, -55, -53, -51, -49, -47, -45,
707 -44, -42, -40, -38, -36, -34, -32, -30,
708 -28, -26, -24, -22, -20, -18, -16, -14,
709 -12, -10, -8, -6, -4, -2, 0, 1,
710 3, 5, 7, 9, 11, 13, 15, 17,
711 19, 21, 23, 25, 27, 29, 31, 33,
712 35, 37, 39, 41, 43, 45, 46, 48,
713 50, 52, 54, 55, 57, 59, 61, 62,
714 64, 66, 67, 69, 71, 72, 74, 75,
715 77, 78, 80, 81, 83, 84, 86, 87,
716 88, 90, 91, 92, 93, 95, 96, 97,
717 98, 99, 100, 101, 102, 103, 104, 105,
718 106, 106, 107, 108, 109, 109, 110, 111,
719 111, 112, 112, 113, 113, 114, 114, 114,
720 115, 115, 115, 115, 116, 116, 116, 116,
721 116, 116, 116, 116, 116, 115, 115, 115,
722 115, 114, 114, 114, 113, 113, 112, 112,
723 111, 111, 110, 110, 109, 108, 108, 107,
724 106, 105, 104, 103, 102, 101, 100, 99,
725 98, 97, 96, 95, 94, 93, 91, 90,
726 89, 88, 86, 85, 84, 82, 81, 79,
727 78, 76, 75, 73, 71, 70, 68, 67,
728 65, 63, 62, 60, 58, 56, 55, 53,
729 51, 49, 47, 45, 44, 42, 40, 38,
730 36, 34, 32, 30, 28, 26, 24, 22,
731 20, 18, 16, 14, 12, 10, 8, 6,
732 4, 2, 0, -1, -3, -5, -7, -9, -11
733};
734
735static u16 i2c_ident[] = {
736 V4L2_IDENT_OV9650,
737 V4L2_IDENT_OV9655,
738 V4L2_IDENT_SOI968,
739 V4L2_IDENT_OV7660,
740 V4L2_IDENT_OV7670,
741 V4L2_IDENT_MT9V011,
742 V4L2_IDENT_MT9V111,
743 V4L2_IDENT_MT9V112,
744 V4L2_IDENT_MT9M001C12ST,
745 V4L2_IDENT_MT9M111,
e99ac54d 746 V4L2_IDENT_MT9M112,
26e744b6
BJ
747 V4L2_IDENT_HV7131R,
748};
749
750static u16 bridge_init[][2] = {
751 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
752 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
753 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
754 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
755 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
756 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
757 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
758 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
759 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
760 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
761 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
762 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
763 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
764 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
765 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
766 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
767 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
768 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
0c045eb7
BJ
769 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
770 {0x1007, 0x00}
26e744b6
BJ
771};
772
773/* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
774static u8 ov_gain[] = {
775 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
776 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
777 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
778 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
779 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
780 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
781 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
782 0x70 /* 8x */
783};
784
785/* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
786static u16 micron1_gain[] = {
787 /* 1x 1.25x 1.5x 1.75x */
788 0x0020, 0x0028, 0x0030, 0x0038,
789 /* 2x 2.25x 2.5x 2.75x */
790 0x00a0, 0x00a4, 0x00a8, 0x00ac,
791 /* 3x 3.25x 3.5x 3.75x */
792 0x00b0, 0x00b4, 0x00b8, 0x00bc,
793 /* 4x 4.25x 4.5x 4.75x */
794 0x00c0, 0x00c4, 0x00c8, 0x00cc,
795 /* 5x 5.25x 5.5x 5.75x */
796 0x00d0, 0x00d4, 0x00d8, 0x00dc,
797 /* 6x 6.25x 6.5x 6.75x */
798 0x00e0, 0x00e4, 0x00e8, 0x00ec,
799 /* 7x 7.25x 7.5x 7.75x */
800 0x00f0, 0x00f4, 0x00f8, 0x00fc,
801 /* 8x */
802 0x01c0
803};
804
805/* mt9m001 sensor uses a different gain formula then other micron sensors */
806/* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
807static u16 micron2_gain[] = {
808 /* 1x 1.25x 1.5x 1.75x */
809 0x0008, 0x000a, 0x000c, 0x000e,
810 /* 2x 2.25x 2.5x 2.75x */
811 0x0010, 0x0012, 0x0014, 0x0016,
812 /* 3x 3.25x 3.5x 3.75x */
813 0x0018, 0x001a, 0x001c, 0x001e,
814 /* 4x 4.25x 4.5x 4.75x */
815 0x0020, 0x0051, 0x0052, 0x0053,
816 /* 5x 5.25x 5.5x 5.75x */
817 0x0054, 0x0055, 0x0056, 0x0057,
818 /* 6x 6.25x 6.5x 6.75x */
819 0x0058, 0x0059, 0x005a, 0x005b,
820 /* 7x 7.25x 7.5x 7.75x */
821 0x005c, 0x005d, 0x005e, 0x005f,
822 /* 8x */
823 0x0060
824};
825
826/* Gain = .5 + bit[7:0] / 16 */
827static u8 hv7131r_gain[] = {
828 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
829 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
830 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
831 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
832 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
833 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
834 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
835 0x78 /* 8x */
836};
837
58aa68c2 838static struct i2c_reg_u8 soi968_init[] = {
26e744b6
BJ
839 {0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f},
840 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
841 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
842 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
843 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
844 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
e1430471 845 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
26e744b6
BJ
846 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
847 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
848 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
849 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
850};
851
58aa68c2 852static struct i2c_reg_u8 ov7660_init[] = {
26e744b6
BJ
853 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
854 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
855 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
856 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
857 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6},
858 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
859};
860
58aa68c2 861static struct i2c_reg_u8 ov7670_init[] = {
26e744b6
BJ
862 {0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
863 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
864 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
865 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
866 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
867 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
868 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
869 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
870 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
871 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
872 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
873 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
874 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
875 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
876 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
877 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
878 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
879 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
880 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
881 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
882 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
883 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
884 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
885 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
886 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
887 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
888 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
889 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
890 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
891 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
892 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
893 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
894 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
895 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
896 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
897 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
898 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
899 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
900 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
901 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
902 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
903 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
904 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
905 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
906 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
907 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
908 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
909 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
910 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
911 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
912 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
913 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
914 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
915 {0x93, 0x00},
916};
917
58aa68c2 918static struct i2c_reg_u8 ov9650_init[] = {
26e744b6
BJ
919 {0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78},
920 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
921 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
922 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
923 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
924 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
925 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
926 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
927 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
928 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
929 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
930 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
931 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
932 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
933 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
934 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
935 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
936 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
937 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
938 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
939 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
940 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
941 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
942 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
943 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
944 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
945 {0xaa, 0x92}, {0xab, 0x0a},
946};
947
58aa68c2 948static struct i2c_reg_u8 ov9655_init[] = {
cc2a8335
BJ
949 {0x12, 0x80}, {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
950 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
951 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
952 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
953 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
954 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
955 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
956 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
957 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
958 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
959 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
960 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
961 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
962 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
963 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
964 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
26e744b6 965 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
cc2a8335
BJ
966 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
967 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
26e744b6 968 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
cc2a8335
BJ
969 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
970 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
971 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
972 {0x04, 0x03}, {0x00, 0x13},
26e744b6
BJ
973};
974
58aa68c2 975static struct i2c_reg_u16 mt9v112_init[] = {
26e744b6
BJ
976 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
977 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
978 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
979 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
980 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
981 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
982 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
983 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
984 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
985 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
986 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
987 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
988 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
989 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
990 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
991 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
992};
993
58aa68c2 994static struct i2c_reg_u16 mt9v111_init[] = {
26e744b6 995 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
6ea23bd0
BJ
996 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
997 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
998 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
999 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
1000 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
1001 {0x0e, 0x0008}, {0x20, 0x0000}
26e744b6
BJ
1002};
1003
58aa68c2 1004static struct i2c_reg_u16 mt9v011_init[] = {
26e744b6
BJ
1005 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
1006 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
1007 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
1008 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
1009 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
1010 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
1011 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
1012 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
1013 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
1014 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
1015 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
1016 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
1017 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
1018 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
1019 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
1020 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
1021 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
1022 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
1023 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
1024 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
1025 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
1026 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1027 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
1028 {0x06, 0x0029}, {0x05, 0x0009},
1029};
1030
58aa68c2 1031static struct i2c_reg_u16 mt9m001_init[] = {
26e744b6
BJ
1032 {0x0d, 0x0001}, {0x0d, 0x0000}, {0x01, 0x000e},
1033 {0x02, 0x0014}, {0x03, 0x03c1}, {0x04, 0x0501},
1034 {0x05, 0x0083}, {0x06, 0x0006}, {0x0d, 0x0002},
1035 {0x0a, 0x0000}, {0x0c, 0x0000}, {0x11, 0x0000},
1036 {0x1e, 0x8000}, {0x5f, 0x8904}, {0x60, 0x0000},
1037 {0x61, 0x0000}, {0x62, 0x0498}, {0x63, 0x0000},
1038 {0x64, 0x0000}, {0x20, 0x111d}, {0x06, 0x00f2},
1039 {0x05, 0x0013}, {0x09, 0x10f2}, {0x07, 0x0003},
1040 {0x2b, 0x002a}, {0x2d, 0x002a}, {0x2c, 0x002a},
1041 {0x2e, 0x0029}, {0x07, 0x0002},
1042};
1043
58aa68c2 1044static struct i2c_reg_u16 mt9m111_init[] = {
13a84fa4
BJ
1045 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1046 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
4d708a5e
BJ
1047 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1048 {0xf0, 0x0000},
26e744b6
BJ
1049};
1050
e99ac54d
BJ
1051static struct i2c_reg_u16 mt9m112_init[] = {
1052 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1053 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1054 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1055 {0xf0, 0x0000},
1056};
1057
58aa68c2 1058static struct i2c_reg_u8 hv7131r_init[] = {
26e744b6
BJ
1059 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
1060 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
1061 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
1062 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
1063 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
1064 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
1065 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
1066 {0x23, 0x09}, {0x01, 0x08},
1067};
1068
58aa68c2 1069static int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
26e744b6
BJ
1070{
1071 struct usb_device *dev = gspca_dev->dev;
1072 int result;
1073 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
1074 0x00,
1075 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1076 reg,
1077 0x00,
1078 gspca_dev->usb_buf,
1079 length,
1080 500);
1081 if (unlikely(result < 0 || result != length)) {
1082 err("Read register failed 0x%02X", reg);
1083 return -EIO;
1084 }
1085 return 0;
1086}
1087
58aa68c2
JP
1088static int reg_w(struct gspca_dev *gspca_dev, u16 reg,
1089 const u8 *buffer, int length)
26e744b6
BJ
1090{
1091 struct usb_device *dev = gspca_dev->dev;
1092 int result;
1093 memcpy(gspca_dev->usb_buf, buffer, length);
1094 result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1095 0x08,
1096 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1097 reg,
1098 0x00,
1099 gspca_dev->usb_buf,
1100 length,
1101 500);
1102 if (unlikely(result < 0 || result != length)) {
1103 err("Write register failed index 0x%02X", reg);
1104 return -EIO;
1105 }
1106 return 0;
1107}
1108
58aa68c2 1109static int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
26e744b6
BJ
1110{
1111 u8 data[1] = {value};
1112 return reg_w(gspca_dev, reg, data, 1);
1113}
1114
58aa68c2 1115static int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
26e744b6
BJ
1116{
1117 int i;
1118 reg_w(gspca_dev, 0x10c0, buffer, 8);
1119 for (i = 0; i < 5; i++) {
1120 reg_r(gspca_dev, 0x10c0, 1);
1121 if (gspca_dev->usb_buf[0] & 0x04) {
1122 if (gspca_dev->usb_buf[0] & 0x08)
00b581ef 1123 return -EIO;
26e744b6
BJ
1124 return 0;
1125 }
1126 msleep(1);
1127 }
00b581ef 1128 return -EIO;
26e744b6
BJ
1129}
1130
58aa68c2 1131static int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
26e744b6
BJ
1132{
1133 struct sd *sd = (struct sd *) gspca_dev;
1134
1135 u8 row[8];
1136
1137 /*
1138 * from the point of view of the bridge, the length
1139 * includes the address
1140 */
1141 row[0] = 0x81 | (2 << 4);
1142 row[1] = sd->i2c_addr;
1143 row[2] = reg;
1144 row[3] = val;
1145 row[4] = 0x00;
1146 row[5] = 0x00;
1147 row[6] = 0x00;
1148 row[7] = 0x10;
1149
1150 return i2c_w(gspca_dev, row);
1151}
1152
58aa68c2 1153static int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
26e744b6
BJ
1154{
1155 struct sd *sd = (struct sd *) gspca_dev;
1156 u8 row[8];
1157
1158 /*
1159 * from the point of view of the bridge, the length
1160 * includes the address
1161 */
1162 row[0] = 0x81 | (3 << 4);
1163 row[1] = sd->i2c_addr;
1164 row[2] = reg;
1165 row[3] = (val >> 8) & 0xff;
1166 row[4] = val & 0xff;
1167 row[5] = 0x00;
1168 row[6] = 0x00;
1169 row[7] = 0x10;
1170
1171 return i2c_w(gspca_dev, row);
1172}
1173
83955556 1174static int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
26e744b6
BJ
1175{
1176 struct sd *sd = (struct sd *) gspca_dev;
1177 u8 row[8];
1178
00b581ef 1179 row[0] = 0x81 | (1 << 4);
26e744b6
BJ
1180 row[1] = sd->i2c_addr;
1181 row[2] = reg;
1182 row[3] = 0;
1183 row[4] = 0;
1184 row[5] = 0;
1185 row[6] = 0;
1186 row[7] = 0x10;
00b581ef
BJ
1187 if (i2c_w(gspca_dev, row) < 0)
1188 return -EIO;
1189 row[0] = 0x81 | (1 << 4) | 0x02;
26e744b6 1190 row[2] = 0;
00b581ef
BJ
1191 if (i2c_w(gspca_dev, row) < 0)
1192 return -EIO;
1193 if (reg_r(gspca_dev, 0x10c2, 5) < 0)
1194 return -EIO;
1195 *val = gspca_dev->usb_buf[4];
26e744b6
BJ
1196 return 0;
1197}
1198
83955556 1199static int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
26e744b6
BJ
1200{
1201 struct sd *sd = (struct sd *) gspca_dev;
1202 u8 row[8];
1203
00b581ef 1204 row[0] = 0x81 | (1 << 4);
26e744b6
BJ
1205 row[1] = sd->i2c_addr;
1206 row[2] = reg;
1207 row[3] = 0;
1208 row[4] = 0;
1209 row[5] = 0;
1210 row[6] = 0;
1211 row[7] = 0x10;
00b581ef
BJ
1212 if (i2c_w(gspca_dev, row) < 0)
1213 return -EIO;
1214 row[0] = 0x81 | (2 << 4) | 0x02;
26e744b6 1215 row[2] = 0;
00b581ef
BJ
1216 if (i2c_w(gspca_dev, row) < 0)
1217 return -EIO;
1218 if (reg_r(gspca_dev, 0x10c2, 5) < 0)
1219 return -EIO;
1220 *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
26e744b6
BJ
1221 return 0;
1222}
1223
1224static int ov9650_init_sensor(struct gspca_dev *gspca_dev)
1225{
1226 int i;
1227 struct sd *sd = (struct sd *) gspca_dev;
1228
1229 for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) {
58aa68c2
JP
1230 if (i2c_w1(gspca_dev, ov9650_init[i].reg,
1231 ov9650_init[i].val) < 0) {
26e744b6
BJ
1232 err("OV9650 sensor initialization failed");
1233 return -ENODEV;
1234 }
1235 }
1236 sd->hstart = 1;
1237 sd->vstart = 7;
1238 return 0;
1239}
1240
1241static int ov9655_init_sensor(struct gspca_dev *gspca_dev)
1242{
1243 int i;
1244 struct sd *sd = (struct sd *) gspca_dev;
1245
1246 for (i = 0; i < ARRAY_SIZE(ov9655_init); i++) {
58aa68c2
JP
1247 if (i2c_w1(gspca_dev, ov9655_init[i].reg,
1248 ov9655_init[i].val) < 0) {
26e744b6
BJ
1249 err("OV9655 sensor initialization failed");
1250 return -ENODEV;
1251 }
1252 }
1253 /* disable hflip and vflip */
1254 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
cc2a8335
BJ
1255 sd->hstart = 1;
1256 sd->vstart = 2;
26e744b6
BJ
1257 return 0;
1258}
1259
1260static int soi968_init_sensor(struct gspca_dev *gspca_dev)
1261{
1262 int i;
1263 struct sd *sd = (struct sd *) gspca_dev;
1264
1265 for (i = 0; i < ARRAY_SIZE(soi968_init); i++) {
58aa68c2
JP
1266 if (i2c_w1(gspca_dev, soi968_init[i].reg,
1267 soi968_init[i].val) < 0) {
26e744b6
BJ
1268 err("SOI968 sensor initialization failed");
1269 return -ENODEV;
1270 }
1271 }
1272 /* disable hflip and vflip */
780e3121
JFM
1273 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX)
1274 | (1 << EXPOSURE_IDX);
26e744b6
BJ
1275 sd->hstart = 60;
1276 sd->vstart = 11;
1277 return 0;
1278}
1279
1280static int ov7660_init_sensor(struct gspca_dev *gspca_dev)
1281{
1282 int i;
1283 struct sd *sd = (struct sd *) gspca_dev;
1284
1285 for (i = 0; i < ARRAY_SIZE(ov7660_init); i++) {
58aa68c2
JP
1286 if (i2c_w1(gspca_dev, ov7660_init[i].reg,
1287 ov7660_init[i].val) < 0) {
26e744b6
BJ
1288 err("OV7660 sensor initialization failed");
1289 return -ENODEV;
1290 }
1291 }
1292 /* disable hflip and vflip */
1293 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1294 sd->hstart = 1;
1295 sd->vstart = 1;
1296 return 0;
1297}
1298
1299static int ov7670_init_sensor(struct gspca_dev *gspca_dev)
1300{
1301 int i;
1302 struct sd *sd = (struct sd *) gspca_dev;
1303
1304 for (i = 0; i < ARRAY_SIZE(ov7670_init); i++) {
58aa68c2
JP
1305 if (i2c_w1(gspca_dev, ov7670_init[i].reg,
1306 ov7670_init[i].val) < 0) {
26e744b6
BJ
1307 err("OV7670 sensor initialization failed");
1308 return -ENODEV;
1309 }
1310 }
1311 /* disable hflip and vflip */
1312 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1313 sd->hstart = 0;
1314 sd->vstart = 1;
1315 return 0;
1316}
1317
1318static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
1319{
1320 struct sd *sd = (struct sd *) gspca_dev;
1321 int i;
1322 u16 value;
1323 int ret;
1324
1325 sd->i2c_addr = 0x5d;
1326 ret = i2c_r2(gspca_dev, 0xff, &value);
1327 if ((ret == 0) && (value == 0x8243)) {
1328 for (i = 0; i < ARRAY_SIZE(mt9v011_init); i++) {
58aa68c2
JP
1329 if (i2c_w2(gspca_dev, mt9v011_init[i].reg,
1330 mt9v011_init[i].val) < 0) {
26e744b6
BJ
1331 err("MT9V011 sensor initialization failed");
1332 return -ENODEV;
1333 }
1334 }
1335 sd->hstart = 2;
1336 sd->vstart = 2;
1337 sd->sensor = SENSOR_MT9V011;
1338 info("MT9V011 sensor detected");
1339 return 0;
1340 }
1341
1342 sd->i2c_addr = 0x5c;
1343 i2c_w2(gspca_dev, 0x01, 0x0004);
1344 ret = i2c_r2(gspca_dev, 0xff, &value);
1345 if ((ret == 0) && (value == 0x823a)) {
1346 for (i = 0; i < ARRAY_SIZE(mt9v111_init); i++) {
58aa68c2
JP
1347 if (i2c_w2(gspca_dev, mt9v111_init[i].reg,
1348 mt9v111_init[i].val) < 0) {
26e744b6
BJ
1349 err("MT9V111 sensor initialization failed");
1350 return -ENODEV;
1351 }
1352 }
780e3121
JFM
1353 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX)
1354 | (1 << AUTOGAIN_IDX)
1355 | (1 << GAIN_IDX);
26e744b6
BJ
1356 sd->hstart = 2;
1357 sd->vstart = 2;
1358 sd->sensor = SENSOR_MT9V111;
1359 info("MT9V111 sensor detected");
1360 return 0;
1361 }
1362
1363 sd->i2c_addr = 0x5d;
1364 ret = i2c_w2(gspca_dev, 0xf0, 0x0000);
1365 if (ret < 0) {
1366 sd->i2c_addr = 0x48;
1367 i2c_w2(gspca_dev, 0xf0, 0x0000);
1368 }
1369 ret = i2c_r2(gspca_dev, 0x00, &value);
1370 if ((ret == 0) && (value == 0x1229)) {
1371 for (i = 0; i < ARRAY_SIZE(mt9v112_init); i++) {
58aa68c2
JP
1372 if (i2c_w2(gspca_dev, mt9v112_init[i].reg,
1373 mt9v112_init[i].val) < 0) {
26e744b6
BJ
1374 err("MT9V112 sensor initialization failed");
1375 return -ENODEV;
1376 }
1377 }
1378 sd->hstart = 6;
1379 sd->vstart = 2;
1380 sd->sensor = SENSOR_MT9V112;
1381 info("MT9V112 sensor detected");
1382 return 0;
1383 }
1384
1385 return -ENODEV;
1386}
1387
e99ac54d
BJ
1388static int mt9m112_init_sensor(struct gspca_dev *gspca_dev)
1389{
1390 struct sd *sd = (struct sd *) gspca_dev;
1391 int i;
1392 for (i = 0; i < ARRAY_SIZE(mt9m112_init); i++) {
1393 if (i2c_w2(gspca_dev, mt9m112_init[i].reg,
1394 mt9m112_init[i].val) < 0) {
1395 err("MT9M112 sensor initialization failed");
1396 return -ENODEV;
1397 }
1398 }
780e3121
JFM
1399 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX)
1400 | (1 << GAIN_IDX);
e99ac54d
BJ
1401 sd->hstart = 0;
1402 sd->vstart = 2;
1403 return 0;
1404}
1405
26e744b6
BJ
1406static int mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1407{
1408 struct sd *sd = (struct sd *) gspca_dev;
1409 int i;
1410 for (i = 0; i < ARRAY_SIZE(mt9m111_init); i++) {
58aa68c2
JP
1411 if (i2c_w2(gspca_dev, mt9m111_init[i].reg,
1412 mt9m111_init[i].val) < 0) {
26e744b6
BJ
1413 err("MT9M111 sensor initialization failed");
1414 return -ENODEV;
1415 }
1416 }
780e3121
JFM
1417 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX)
1418 | (1 << GAIN_IDX);
26e744b6
BJ
1419 sd->hstart = 0;
1420 sd->vstart = 2;
1421 return 0;
1422}
1423
1424static int mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1425{
1426 struct sd *sd = (struct sd *) gspca_dev;
1427 int i;
1428 for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) {
58aa68c2
JP
1429 if (i2c_w2(gspca_dev, mt9m001_init[i].reg,
1430 mt9m001_init[i].val) < 0) {
26e744b6
BJ
1431 err("MT9M001 sensor initialization failed");
1432 return -ENODEV;
1433 }
1434 }
1435 /* disable hflip and vflip */
1436 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1437 sd->hstart = 2;
1438 sd->vstart = 2;
1439 return 0;
1440}
1441
1442static int hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1443{
1444 int i;
1445 struct sd *sd = (struct sd *) gspca_dev;
1446
1447 for (i = 0; i < ARRAY_SIZE(hv7131r_init); i++) {
58aa68c2
JP
1448 if (i2c_w1(gspca_dev, hv7131r_init[i].reg,
1449 hv7131r_init[i].val) < 0) {
26e744b6
BJ
1450 err("HV7131R Sensor initialization failed");
1451 return -ENODEV;
1452 }
1453 }
1454 sd->hstart = 0;
1455 sd->vstart = 1;
1456 return 0;
1457}
1458
26e744b6
BJ
1459static int set_cmatrix(struct gspca_dev *gspca_dev)
1460{
1461 struct sd *sd = (struct sd *) gspca_dev;
1462 s32 hue_coord, hue_index = 180 + sd->hue;
1463 u8 cmatrix[21];
26e744b6 1464
de2d1549 1465 memset(cmatrix, 0, sizeof cmatrix);
26e744b6
BJ
1466 cmatrix[2] = (sd->contrast * 0x25 / 0x100) + 0x26;
1467 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1468 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1469 cmatrix[18] = sd->brightness - 0x80;
1470
1471 hue_coord = (hsv_red_x[hue_index] * sd->saturation) >> 8;
de2d1549
JFM
1472 cmatrix[6] = hue_coord;
1473 cmatrix[7] = (hue_coord >> 8) & 0x0f;
26e744b6
BJ
1474
1475 hue_coord = (hsv_red_y[hue_index] * sd->saturation) >> 8;
de2d1549
JFM
1476 cmatrix[8] = hue_coord;
1477 cmatrix[9] = (hue_coord >> 8) & 0x0f;
26e744b6
BJ
1478
1479 hue_coord = (hsv_green_x[hue_index] * sd->saturation) >> 8;
de2d1549
JFM
1480 cmatrix[10] = hue_coord;
1481 cmatrix[11] = (hue_coord >> 8) & 0x0f;
26e744b6
BJ
1482
1483 hue_coord = (hsv_green_y[hue_index] * sd->saturation) >> 8;
de2d1549
JFM
1484 cmatrix[12] = hue_coord;
1485 cmatrix[13] = (hue_coord >> 8) & 0x0f;
26e744b6
BJ
1486
1487 hue_coord = (hsv_blue_x[hue_index] * sd->saturation) >> 8;
de2d1549
JFM
1488 cmatrix[14] = hue_coord;
1489 cmatrix[15] = (hue_coord >> 8) & 0x0f;
26e744b6
BJ
1490
1491 hue_coord = (hsv_blue_y[hue_index] * sd->saturation) >> 8;
de2d1549
JFM
1492 cmatrix[16] = hue_coord;
1493 cmatrix[17] = (hue_coord >> 8) & 0x0f;
26e744b6
BJ
1494
1495 return reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1496}
1497
1498static int set_gamma(struct gspca_dev *gspca_dev)
1499{
1500 struct sd *sd = (struct sd *) gspca_dev;
1501 u8 gamma[17];
1502 u8 gval = sd->gamma * 0xb8 / 0x100;
1503
1504
1505 gamma[0] = 0x0a;
1506 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
1507 gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8);
1508 gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8);
1509 gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8);
1510 gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8);
1511 gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8);
1512 gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8);
1513 gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8);
1514 gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8);
1515 gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8);
1516 gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8);
1517 gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8);
1518 gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8);
1519 gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8);
1520 gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
1521 gamma[16] = 0xf5;
1522
1523 return reg_w(gspca_dev, 0x1190, gamma, 17);
1524}
1525
1526static int set_redblue(struct gspca_dev *gspca_dev)
1527{
1528 struct sd *sd = (struct sd *) gspca_dev;
1529 reg_w1(gspca_dev, 0x118c, sd->red);
1530 reg_w1(gspca_dev, 0x118f, sd->blue);
1531 return 0;
1532}
1533
1534static int set_hvflip(struct gspca_dev *gspca_dev)
1535{
7ddaac7f 1536 u8 value, tslb, hflip, vflip;
26e744b6
BJ
1537 u16 value2;
1538 struct sd *sd = (struct sd *) gspca_dev;
7ddaac7f
BJ
1539
1540 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1541 hflip = !sd->hflip;
1542 vflip = !sd->vflip;
1543 } else {
1544 hflip = sd->hflip;
1545 vflip = sd->vflip;
1546 }
1547
26e744b6
BJ
1548 switch (sd->sensor) {
1549 case SENSOR_OV9650:
1550 i2c_r1(gspca_dev, 0x1e, &value);
1551 value &= ~0x30;
1552 tslb = 0x01;
7ddaac7f 1553 if (hflip)
26e744b6 1554 value |= 0x20;
7ddaac7f 1555 if (vflip) {
26e744b6
BJ
1556 value |= 0x10;
1557 tslb = 0x49;
1558 }
1559 i2c_w1(gspca_dev, 0x1e, value);
1560 i2c_w1(gspca_dev, 0x3a, tslb);
1561 break;
1562 case SENSOR_MT9V111:
1563 case SENSOR_MT9V011:
1564 i2c_r2(gspca_dev, 0x20, &value2);
1565 value2 &= ~0xc0a0;
7ddaac7f 1566 if (hflip)
26e744b6 1567 value2 |= 0x8080;
7ddaac7f 1568 if (vflip)
26e744b6
BJ
1569 value2 |= 0x4020;
1570 i2c_w2(gspca_dev, 0x20, value2);
1571 break;
e99ac54d 1572 case SENSOR_MT9M112:
26e744b6
BJ
1573 case SENSOR_MT9M111:
1574 case SENSOR_MT9V112:
1575 i2c_r2(gspca_dev, 0x20, &value2);
1576 value2 &= ~0x0003;
7ddaac7f 1577 if (hflip)
26e744b6 1578 value2 |= 0x0002;
7ddaac7f 1579 if (vflip)
26e744b6
BJ
1580 value2 |= 0x0001;
1581 i2c_w2(gspca_dev, 0x20, value2);
1582 break;
1583 case SENSOR_HV7131R:
1584 i2c_r1(gspca_dev, 0x01, &value);
1585 value &= ~0x03;
7ddaac7f 1586 if (vflip)
26e744b6 1587 value |= 0x01;
7ddaac7f 1588 if (hflip)
26e744b6
BJ
1589 value |= 0x02;
1590 i2c_w1(gspca_dev, 0x01, value);
1591 break;
1592 }
1593 return 0;
1594}
1595
1596static int set_exposure(struct gspca_dev *gspca_dev)
1597{
1598 struct sd *sd = (struct sd *) gspca_dev;
1599 u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1600 switch (sd->sensor) {
1601 case SENSOR_OV7660:
1602 case SENSOR_OV7670:
26e744b6
BJ
1603 case SENSOR_OV9655:
1604 case SENSOR_OV9650:
1605 exp[0] |= (3 << 4);
1606 exp[2] = 0x2d;
1607 exp[3] = sd->exposure & 0xff;
1608 exp[4] = sd->exposure >> 8;
1609 break;
1610 case SENSOR_MT9M001:
26e744b6 1611 case SENSOR_MT9V112:
26e744b6
BJ
1612 case SENSOR_MT9V011:
1613 exp[0] |= (3 << 4);
1614 exp[2] = 0x09;
1615 exp[3] = sd->exposure >> 8;
1616 exp[4] = sd->exposure & 0xff;
1617 break;
1618 case SENSOR_HV7131R:
1619 exp[0] |= (4 << 4);
1620 exp[2] = 0x25;
e10f7319
GG
1621 exp[3] = (sd->exposure >> 5) & 0xff;
1622 exp[4] = (sd->exposure << 3) & 0xff;
1623 exp[5] = 0;
26e744b6 1624 break;
e1430471
BJ
1625 default:
1626 return 0;
26e744b6
BJ
1627 }
1628 i2c_w(gspca_dev, exp);
1629 return 0;
1630}
1631
1632static int set_gain(struct gspca_dev *gspca_dev)
1633{
1634 struct sd *sd = (struct sd *) gspca_dev;
1635 u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1636 switch (sd->sensor) {
1637 case SENSOR_OV7660:
1638 case SENSOR_OV7670:
1639 case SENSOR_SOI968:
1640 case SENSOR_OV9655:
1641 case SENSOR_OV9650:
1642 gain[0] |= (2 << 4);
1643 gain[3] = ov_gain[sd->gain];
1644 break;
1645 case SENSOR_MT9V011:
26e744b6
BJ
1646 gain[0] |= (3 << 4);
1647 gain[2] = 0x35;
1648 gain[3] = micron1_gain[sd->gain] >> 8;
1649 gain[4] = micron1_gain[sd->gain] & 0xff;
1650 break;
1651 case SENSOR_MT9V112:
26e744b6
BJ
1652 gain[0] |= (3 << 4);
1653 gain[2] = 0x2f;
1654 gain[3] = micron1_gain[sd->gain] >> 8;
1655 gain[4] = micron1_gain[sd->gain] & 0xff;
1656 break;
1657 case SENSOR_MT9M001:
1658 gain[0] |= (3 << 4);
1659 gain[2] = 0x2f;
1660 gain[3] = micron2_gain[sd->gain] >> 8;
1661 gain[4] = micron2_gain[sd->gain] & 0xff;
1662 break;
1663 case SENSOR_HV7131R:
1664 gain[0] |= (2 << 4);
1665 gain[2] = 0x30;
1666 gain[3] = hv7131r_gain[sd->gain];
1667 break;
e1430471
BJ
1668 default:
1669 return 0;
26e744b6
BJ
1670 }
1671 i2c_w(gspca_dev, gain);
1672 return 0;
1673}
1674
1675static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val)
1676{
1677 struct sd *sd = (struct sd *) gspca_dev;
1678
1679 sd->brightness = val;
1680 if (gspca_dev->streaming)
1681 return set_cmatrix(gspca_dev);
1682 return 0;
1683}
1684
1685static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val)
1686{
1687 struct sd *sd = (struct sd *) gspca_dev;
1688 *val = sd->brightness;
1689 return 0;
1690}
1691
1692
1693static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val)
1694{
1695 struct sd *sd = (struct sd *) gspca_dev;
1696
1697 sd->contrast = val;
1698 if (gspca_dev->streaming)
1699 return set_cmatrix(gspca_dev);
1700 return 0;
1701}
1702
1703static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val)
1704{
1705 struct sd *sd = (struct sd *) gspca_dev;
1706 *val = sd->contrast;
1707 return 0;
1708}
1709
1710static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val)
1711{
1712 struct sd *sd = (struct sd *) gspca_dev;
1713
1714 sd->saturation = val;
1715 if (gspca_dev->streaming)
1716 return set_cmatrix(gspca_dev);
1717 return 0;
1718}
1719
1720static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val)
1721{
1722 struct sd *sd = (struct sd *) gspca_dev;
1723 *val = sd->saturation;
1724 return 0;
1725}
1726
1727static int sd_sethue(struct gspca_dev *gspca_dev, s32 val)
1728{
1729 struct sd *sd = (struct sd *) gspca_dev;
1730
1731 sd->hue = val;
1732 if (gspca_dev->streaming)
1733 return set_cmatrix(gspca_dev);
1734 return 0;
1735}
1736
1737static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val)
1738{
1739 struct sd *sd = (struct sd *) gspca_dev;
1740 *val = sd->hue;
1741 return 0;
1742}
1743
1744static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val)
1745{
1746 struct sd *sd = (struct sd *) gspca_dev;
1747
1748 sd->gamma = val;
1749 if (gspca_dev->streaming)
1750 return set_gamma(gspca_dev);
1751 return 0;
1752}
1753
1754static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val)
1755{
1756 struct sd *sd = (struct sd *) gspca_dev;
1757 *val = sd->gamma;
1758 return 0;
1759}
1760
1761static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val)
1762{
1763 struct sd *sd = (struct sd *) gspca_dev;
1764
1765 sd->red = val;
1766 if (gspca_dev->streaming)
1767 return set_redblue(gspca_dev);
1768 return 0;
1769}
1770
1771static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val)
1772{
1773 struct sd *sd = (struct sd *) gspca_dev;
1774 *val = sd->red;
1775 return 0;
1776}
1777
1778static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val)
1779{
1780 struct sd *sd = (struct sd *) gspca_dev;
1781
1782 sd->blue = val;
1783 if (gspca_dev->streaming)
1784 return set_redblue(gspca_dev);
1785 return 0;
1786}
1787
1788static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val)
1789{
1790 struct sd *sd = (struct sd *) gspca_dev;
1791 *val = sd->blue;
1792 return 0;
1793}
1794
1795static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val)
1796{
1797 struct sd *sd = (struct sd *) gspca_dev;
1798
1799 sd->hflip = val;
1800 if (gspca_dev->streaming)
1801 return set_hvflip(gspca_dev);
1802 return 0;
1803}
1804
1805static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val)
1806{
1807 struct sd *sd = (struct sd *) gspca_dev;
1808 *val = sd->hflip;
1809 return 0;
1810}
1811
1812static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val)
1813{
1814 struct sd *sd = (struct sd *) gspca_dev;
1815
1816 sd->vflip = val;
1817 if (gspca_dev->streaming)
1818 return set_hvflip(gspca_dev);
1819 return 0;
1820}
1821
1822static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val)
1823{
1824 struct sd *sd = (struct sd *) gspca_dev;
1825 *val = sd->vflip;
1826 return 0;
1827}
1828
1829static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val)
1830{
1831 struct sd *sd = (struct sd *) gspca_dev;
1832
1833 sd->exposure = val;
1834 if (gspca_dev->streaming)
1835 return set_exposure(gspca_dev);
1836 return 0;
1837}
1838
1839static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val)
1840{
1841 struct sd *sd = (struct sd *) gspca_dev;
1842 *val = sd->exposure;
1843 return 0;
1844}
1845
1846static int sd_setgain(struct gspca_dev *gspca_dev, s32 val)
1847{
1848 struct sd *sd = (struct sd *) gspca_dev;
1849
1850 sd->gain = val;
1851 if (gspca_dev->streaming)
1852 return set_gain(gspca_dev);
1853 return 0;
1854}
1855
1856static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val)
1857{
1858 struct sd *sd = (struct sd *) gspca_dev;
1859 *val = sd->gain;
1860 return 0;
1861}
1862
1863static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val)
1864{
1865 struct sd *sd = (struct sd *) gspca_dev;
1866 sd->auto_exposure = val;
1867 return 0;
1868}
1869
1870static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val)
1871{
1872 struct sd *sd = (struct sd *) gspca_dev;
1873 *val = sd->auto_exposure;
1874 return 0;
1875}
1876
1877#ifdef CONFIG_VIDEO_ADV_DEBUG
1878static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1879 struct v4l2_dbg_register *reg)
1880{
1881 struct sd *sd = (struct sd *) gspca_dev;
1882 switch (reg->match.type) {
1883 case V4L2_CHIP_MATCH_HOST:
1884 if (reg->match.addr != 0)
1885 return -EINVAL;
1886 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1887 return -EINVAL;
1888 if (reg_r(gspca_dev, reg->reg, 1) < 0)
1889 return -EINVAL;
1890 reg->val = gspca_dev->usb_buf[0];
1891 return 0;
1892 case V4L2_CHIP_MATCH_I2C_ADDR:
1893 if (reg->match.addr != sd->i2c_addr)
1894 return -EINVAL;
1895 if (sd->sensor >= SENSOR_MT9V011 &&
e99ac54d 1896 sd->sensor <= SENSOR_MT9M112) {
26e744b6
BJ
1897 if (i2c_r2(gspca_dev, reg->reg, (u16 *)&reg->val) < 0)
1898 return -EINVAL;
1899 } else {
1900 if (i2c_r1(gspca_dev, reg->reg, (u8 *)&reg->val) < 0)
1901 return -EINVAL;
1902 }
1903 return 0;
1904 }
1905 return -EINVAL;
1906}
1907
1908static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1909 struct v4l2_dbg_register *reg)
1910{
1911 struct sd *sd = (struct sd *) gspca_dev;
1912 switch (reg->match.type) {
1913 case V4L2_CHIP_MATCH_HOST:
1914 if (reg->match.addr != 0)
1915 return -EINVAL;
1916 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1917 return -EINVAL;
1918 if (reg_w1(gspca_dev, reg->reg, reg->val) < 0)
1919 return -EINVAL;
1920 return 0;
1921 case V4L2_CHIP_MATCH_I2C_ADDR:
1922 if (reg->match.addr != sd->i2c_addr)
1923 return -EINVAL;
1924 if (sd->sensor >= SENSOR_MT9V011 &&
e99ac54d 1925 sd->sensor <= SENSOR_MT9M112) {
26e744b6
BJ
1926 if (i2c_w2(gspca_dev, reg->reg, reg->val) < 0)
1927 return -EINVAL;
1928 } else {
1929 if (i2c_w1(gspca_dev, reg->reg, reg->val) < 0)
1930 return -EINVAL;
1931 }
1932 return 0;
1933 }
1934 return -EINVAL;
1935}
1936#endif
1937
1938static int sd_chip_ident(struct gspca_dev *gspca_dev,
1939 struct v4l2_dbg_chip_ident *chip)
1940{
1941 struct sd *sd = (struct sd *) gspca_dev;
1942
1943 switch (chip->match.type) {
1944 case V4L2_CHIP_MATCH_HOST:
1945 if (chip->match.addr != 0)
1946 return -EINVAL;
1947 chip->revision = 0;
1948 chip->ident = V4L2_IDENT_SN9C20X;
1949 return 0;
1950 case V4L2_CHIP_MATCH_I2C_ADDR:
1951 if (chip->match.addr != sd->i2c_addr)
1952 return -EINVAL;
1953 chip->revision = 0;
1954 chip->ident = i2c_ident[sd->sensor];
1955 return 0;
1956 }
1957 return -EINVAL;
1958}
1959
1960static int sd_config(struct gspca_dev *gspca_dev,
1961 const struct usb_device_id *id)
1962{
1963 struct sd *sd = (struct sd *) gspca_dev;
1964 struct cam *cam;
1965
1966 cam = &gspca_dev->cam;
1967
1968 sd->sensor = (id->driver_info >> 8) & 0xff;
1969 sd->i2c_addr = id->driver_info & 0xff;
a39db27a 1970 sd->flags = (id->driver_info >> 16) & 0xff;
26e744b6
BJ
1971
1972 switch (sd->sensor) {
e99ac54d 1973 case SENSOR_MT9M112:
4d708a5e 1974 case SENSOR_MT9M111:
26e744b6 1975 case SENSOR_OV9650:
e8b7acc1 1976 case SENSOR_SOI968:
26e744b6
BJ
1977 cam->cam_mode = sxga_mode;
1978 cam->nmodes = ARRAY_SIZE(sxga_mode);
1979 break;
1980 default:
1981 cam->cam_mode = vga_mode;
1982 cam->nmodes = ARRAY_SIZE(vga_mode);
de2d1549 1983 break;
26e744b6
BJ
1984 }
1985
1986 sd->old_step = 0;
1987 sd->older_step = 0;
1988 sd->exposure_step = 16;
1989
1990 sd->brightness = BRIGHTNESS_DEFAULT;
1991 sd->contrast = CONTRAST_DEFAULT;
1992 sd->saturation = SATURATION_DEFAULT;
1993 sd->hue = HUE_DEFAULT;
1994 sd->gamma = GAMMA_DEFAULT;
1995 sd->red = RED_DEFAULT;
1996 sd->blue = BLUE_DEFAULT;
1997
1998 sd->hflip = HFLIP_DEFAULT;
1999 sd->vflip = VFLIP_DEFAULT;
2000 sd->exposure = EXPOSURE_DEFAULT;
2001 sd->gain = GAIN_DEFAULT;
2002 sd->auto_exposure = AUTO_EXPOSURE_DEFAULT;
2003
2004 sd->quality = 95;
2005
26e744b6
BJ
2006 return 0;
2007}
2008
2009static int sd_init(struct gspca_dev *gspca_dev)
2010{
2011 struct sd *sd = (struct sd *) gspca_dev;
2012 int i;
2013 u8 value;
2014 u8 i2c_init[9] =
2015 {0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
2016
2017 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
2018 value = bridge_init[i][1];
2019 if (reg_w(gspca_dev, bridge_init[i][0], &value, 1) < 0) {
2020 err("Device initialization failed");
2021 return -ENODEV;
2022 }
2023 }
2024
0c045eb7
BJ
2025 if (sd->flags & LED_REVERSE)
2026 reg_w1(gspca_dev, 0x1006, 0x00);
2027 else
2028 reg_w1(gspca_dev, 0x1006, 0x20);
2029
26e744b6
BJ
2030 if (reg_w(gspca_dev, 0x10c0, i2c_init, 9) < 0) {
2031 err("Device initialization failed");
2032 return -ENODEV;
2033 }
2034
2035 switch (sd->sensor) {
2036 case SENSOR_OV9650:
2037 if (ov9650_init_sensor(gspca_dev) < 0)
2038 return -ENODEV;
2039 info("OV9650 sensor detected");
2040 break;
2041 case SENSOR_OV9655:
2042 if (ov9655_init_sensor(gspca_dev) < 0)
2043 return -ENODEV;
2044 info("OV9655 sensor detected");
2045 break;
2046 case SENSOR_SOI968:
2047 if (soi968_init_sensor(gspca_dev) < 0)
2048 return -ENODEV;
2049 info("SOI968 sensor detected");
2050 break;
2051 case SENSOR_OV7660:
2052 if (ov7660_init_sensor(gspca_dev) < 0)
2053 return -ENODEV;
2054 info("OV7660 sensor detected");
2055 break;
2056 case SENSOR_OV7670:
2057 if (ov7670_init_sensor(gspca_dev) < 0)
2058 return -ENODEV;
2059 info("OV7670 sensor detected");
2060 break;
2061 case SENSOR_MT9VPRB:
2062 if (mt9v_init_sensor(gspca_dev) < 0)
2063 return -ENODEV;
2064 break;
2065 case SENSOR_MT9M111:
2066 if (mt9m111_init_sensor(gspca_dev) < 0)
2067 return -ENODEV;
2068 info("MT9M111 sensor detected");
2069 break;
e99ac54d
BJ
2070 case SENSOR_MT9M112:
2071 if (mt9m112_init_sensor(gspca_dev) < 0)
2072 return -ENODEV;
2073 info("MT9M112 sensor detected");
2074 break;
26e744b6
BJ
2075 case SENSOR_MT9M001:
2076 if (mt9m001_init_sensor(gspca_dev) < 0)
2077 return -ENODEV;
2078 info("MT9M001 sensor detected");
2079 break;
2080 case SENSOR_HV7131R:
2081 if (hv7131r_init_sensor(gspca_dev) < 0)
2082 return -ENODEV;
2083 info("HV7131R sensor detected");
2084 break;
2085 default:
2086 info("Unsupported Sensor");
2087 return -ENODEV;
2088 }
2089
2090 return 0;
2091}
2092
2093static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
2094{
2095 struct sd *sd = (struct sd *) gspca_dev;
2096 u8 value;
2097 switch (sd->sensor) {
e8b7acc1
BJ
2098 case SENSOR_SOI968:
2099 if (mode & MODE_SXGA) {
2100 i2c_w1(gspca_dev, 0x17, 0x1d);
2101 i2c_w1(gspca_dev, 0x18, 0xbd);
2102 i2c_w1(gspca_dev, 0x19, 0x01);
2103 i2c_w1(gspca_dev, 0x1a, 0x81);
2104 i2c_w1(gspca_dev, 0x12, 0x00);
2105 sd->hstart = 140;
2106 sd->vstart = 19;
2107 } else {
2108 i2c_w1(gspca_dev, 0x17, 0x13);
2109 i2c_w1(gspca_dev, 0x18, 0x63);
2110 i2c_w1(gspca_dev, 0x19, 0x01);
2111 i2c_w1(gspca_dev, 0x1a, 0x79);
2112 i2c_w1(gspca_dev, 0x12, 0x40);
2113 sd->hstart = 60;
2114 sd->vstart = 11;
2115 }
2116 break;
26e744b6
BJ
2117 case SENSOR_OV9650:
2118 if (mode & MODE_SXGA) {
2119 i2c_w1(gspca_dev, 0x17, 0x1b);
2120 i2c_w1(gspca_dev, 0x18, 0xbc);
2121 i2c_w1(gspca_dev, 0x19, 0x01);
2122 i2c_w1(gspca_dev, 0x1a, 0x82);
2123 i2c_r1(gspca_dev, 0x12, &value);
2124 i2c_w1(gspca_dev, 0x12, value & 0x07);
2125 } else {
2126 i2c_w1(gspca_dev, 0x17, 0x24);
2127 i2c_w1(gspca_dev, 0x18, 0xc5);
2128 i2c_w1(gspca_dev, 0x19, 0x00);
2129 i2c_w1(gspca_dev, 0x1a, 0x3c);
2130 i2c_r1(gspca_dev, 0x12, &value);
2131 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
2132 }
2133 break;
e99ac54d 2134 case SENSOR_MT9M112:
4d708a5e
BJ
2135 case SENSOR_MT9M111:
2136 if (mode & MODE_SXGA) {
2137 i2c_w2(gspca_dev, 0xf0, 0x0002);
2138 i2c_w2(gspca_dev, 0xc8, 0x970b);
2139 i2c_w2(gspca_dev, 0xf0, 0x0000);
2140 } else {
2141 i2c_w2(gspca_dev, 0xf0, 0x0002);
2142 i2c_w2(gspca_dev, 0xc8, 0x8000);
2143 i2c_w2(gspca_dev, 0xf0, 0x0000);
2144 }
2145 break;
26e744b6
BJ
2146 }
2147}
2148
2149#define HW_WIN(mode, hstart, vstart) \
83955556 2150((const u8 []){hstart, 0, vstart, 0, \
26e744b6
BJ
2151(mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
2152(mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
2153
2154#define CLR_WIN(width, height) \
2155((const u8 [])\
2156{0, width >> 2, 0, height >> 1,\
2157((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
2158
2159static int sd_start(struct gspca_dev *gspca_dev)
2160{
2161 struct sd *sd = (struct sd *) gspca_dev;
2162 int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
2163 int width = gspca_dev->width;
2164 int height = gspca_dev->height;
2165 u8 fmt, scale = 0;
2166
26e744b6
BJ
2167 jpeg_define(sd->jpeg_hdr, height, width,
2168 0x21);
2169 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2170
2171 if (mode & MODE_RAW)
2172 fmt = 0x2d;
2173 else if (mode & MODE_JPEG)
2174 fmt = 0x2c;
2175 else
2176 fmt = 0x2f;
2177
2178 switch (mode & 0x0f) {
2179 case 3:
2180 scale = 0xc0;
2181 info("Set 1280x1024");
2182 break;
2183 case 2:
2184 scale = 0x80;
2185 info("Set 640x480");
2186 break;
2187 case 1:
2188 scale = 0x90;
2189 info("Set 320x240");
2190 break;
2191 case 0:
2192 scale = 0xa0;
2193 info("Set 160x120");
2194 break;
2195 }
2196
2197 configure_sensor_output(gspca_dev, mode);
9a731a32
JFM
2198 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2199 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
26e744b6
BJ
2200 reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2201 reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2202 reg_w1(gspca_dev, 0x1189, scale);
2203 reg_w1(gspca_dev, 0x10e0, fmt);
2204
2205 set_cmatrix(gspca_dev);
2206 set_gamma(gspca_dev);
2207 set_redblue(gspca_dev);
2208 set_gain(gspca_dev);
2209 set_exposure(gspca_dev);
2210 set_hvflip(gspca_dev);
2211
0c045eb7
BJ
2212 reg_w1(gspca_dev, 0x1007, 0x20);
2213
26e744b6
BJ
2214 reg_r(gspca_dev, 0x1061, 1);
2215 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] | 0x02);
2216 return 0;
2217}
2218
2219static void sd_stopN(struct gspca_dev *gspca_dev)
2220{
0c045eb7
BJ
2221 reg_w1(gspca_dev, 0x1007, 0x00);
2222
26e744b6
BJ
2223 reg_r(gspca_dev, 0x1061, 1);
2224 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] & ~0x02);
2225}
2226
e1430471 2227static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
26e744b6
BJ
2228{
2229 struct sd *sd = (struct sd *) gspca_dev;
e1430471 2230 s16 new_exp;
26e744b6
BJ
2231
2232 /*
2233 * some hardcoded values are present
2234 * like those for maximal/minimal exposure
2235 * and exposure steps
2236 */
2237 if (avg_lum < MIN_AVG_LUM) {
2238 if (sd->exposure > 0x1770)
2239 return;
2240
2241 new_exp = sd->exposure + sd->exposure_step;
2242 if (new_exp > 0x1770)
2243 new_exp = 0x1770;
2244 if (new_exp < 0x10)
2245 new_exp = 0x10;
2246 sd->exposure = new_exp;
2247 set_exposure(gspca_dev);
2248
2249 sd->older_step = sd->old_step;
2250 sd->old_step = 1;
2251
2252 if (sd->old_step ^ sd->older_step)
2253 sd->exposure_step /= 2;
2254 else
2255 sd->exposure_step += 2;
2256 }
2257 if (avg_lum > MAX_AVG_LUM) {
2258 if (sd->exposure < 0x10)
2259 return;
2260 new_exp = sd->exposure - sd->exposure_step;
2261 if (new_exp > 0x1700)
2262 new_exp = 0x1770;
2263 if (new_exp < 0x10)
2264 new_exp = 0x10;
2265 sd->exposure = new_exp;
2266 set_exposure(gspca_dev);
2267 sd->older_step = sd->old_step;
2268 sd->old_step = 0;
2269
2270 if (sd->old_step ^ sd->older_step)
2271 sd->exposure_step /= 2;
2272 else
2273 sd->exposure_step += 2;
2274 }
2275}
2276
e1430471
BJ
2277static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2278{
2279 struct sd *sd = (struct sd *) gspca_dev;
2280
2281 if (avg_lum < MIN_AVG_LUM) {
2282 if (sd->gain + 1 <= 28) {
2283 sd->gain++;
2284 set_gain(gspca_dev);
2285 }
2286 }
2287 if (avg_lum > MAX_AVG_LUM) {
de2d1549 2288 if (sd->gain > 0) {
e1430471
BJ
2289 sd->gain--;
2290 set_gain(gspca_dev);
2291 }
2292 }
2293}
2294
2295static void sd_dqcallback(struct gspca_dev *gspca_dev)
2296{
2297 struct sd *sd = (struct sd *) gspca_dev;
2298 int avg_lum;
2299
2300 if (!sd->auto_exposure)
2301 return;
2302
2303 avg_lum = atomic_read(&sd->avg_lum);
2304 if (sd->sensor == SENSOR_SOI968)
2305 do_autogain(gspca_dev, avg_lum);
2306 else
2307 do_autoexposure(gspca_dev, avg_lum);
2308}
2309
2856643e 2310#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
a39db27a
MCC
2311static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2312 u8 *data, /* interrupt packet */
2313 int len) /* interrupt packet length */
2314{
2315 struct sd *sd = (struct sd *) gspca_dev;
2316 int ret = -EINVAL;
33ddc16f 2317 if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
a39db27a
MCC
2318 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2319 input_sync(gspca_dev->input_dev);
2320 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2321 input_sync(gspca_dev->input_dev);
2322 ret = 0;
2323 }
2324 return ret;
2325}
2326#endif
2327
26e744b6 2328static void sd_pkt_scan(struct gspca_dev *gspca_dev,
26e744b6
BJ
2329 u8 *data, /* isoc packet */
2330 int len) /* iso packet length */
2331{
2332 struct sd *sd = (struct sd *) gspca_dev;
2333 int avg_lum;
de2d1549 2334 static u8 frame_header[] =
26e744b6
BJ
2335 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2336 if (len == 64 && memcmp(data, frame_header, 6) == 0) {
2337 avg_lum = ((data[35] >> 2) & 3) |
2338 (data[20] << 2) |
2339 (data[19] << 10);
2340 avg_lum += ((data[35] >> 4) & 3) |
2341 (data[22] << 2) |
2342 (data[21] << 10);
2343 avg_lum += ((data[35] >> 6) & 3) |
2344 (data[24] << 2) |
2345 (data[23] << 10);
2346 avg_lum += (data[36] & 3) |
2347 (data[26] << 2) |
2348 (data[25] << 10);
2349 avg_lum += ((data[36] >> 2) & 3) |
2350 (data[28] << 2) |
2351 (data[27] << 10);
2352 avg_lum += ((data[36] >> 4) & 3) |
2353 (data[30] << 2) |
2354 (data[29] << 10);
2355 avg_lum += ((data[36] >> 6) & 3) |
2356 (data[32] << 2) |
2357 (data[31] << 10);
2358 avg_lum += ((data[44] >> 4) & 3) |
2359 (data[34] << 2) |
2360 (data[33] << 10);
2361 avg_lum >>= 9;
2362 atomic_set(&sd->avg_lum, avg_lum);
04d174e9 2363 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
26e744b6
BJ
2364 return;
2365 }
2366 if (gspca_dev->last_packet_type == LAST_PACKET) {
2367 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv
2368 & MODE_JPEG) {
76dd272b 2369 gspca_frame_add(gspca_dev, FIRST_PACKET,
26e744b6 2370 sd->jpeg_hdr, JPEG_HDR_SZ);
76dd272b 2371 gspca_frame_add(gspca_dev, INTER_PACKET,
26e744b6
BJ
2372 data, len);
2373 } else {
76dd272b 2374 gspca_frame_add(gspca_dev, FIRST_PACKET,
26e744b6
BJ
2375 data, len);
2376 }
2377 } else {
76dd272b 2378 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
26e744b6
BJ
2379 }
2380}
2381
2382/* sub-driver description */
2383static const struct sd_desc sd_desc = {
2384 .name = MODULE_NAME,
2385 .ctrls = sd_ctrls,
2386 .nctrls = ARRAY_SIZE(sd_ctrls),
2387 .config = sd_config,
2388 .init = sd_init,
2389 .start = sd_start,
2390 .stopN = sd_stopN,
26e744b6 2391 .pkt_scan = sd_pkt_scan,
2856643e 2392#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
a39db27a
MCC
2393 .int_pkt_scan = sd_int_pkt_scan,
2394#endif
e1430471 2395 .dq_callback = sd_dqcallback,
26e744b6
BJ
2396#ifdef CONFIG_VIDEO_ADV_DEBUG
2397 .set_register = sd_dbg_s_register,
2398 .get_register = sd_dbg_g_register,
2399#endif
2400 .get_chip_ident = sd_chip_ident,
2401};
2402
a39db27a 2403#define SN9C20X(sensor, i2c_addr, flags) \
0c045eb7 2404 .driver_info = ((flags & 0xff) << 16) \
26e744b6
BJ
2405 | (SENSOR_ ## sensor << 8) \
2406 | (i2c_addr)
2407
2408static const __devinitdata struct usb_device_id device_table[] = {
2409 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2410 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
2411 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
e99ac54d 2412 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
33ddc16f
BJ
2413 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
2414 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
2415 (FLIP_DETECT | HAS_NO_BUTTON))},
26e744b6
BJ
2416 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2417 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2418 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2419 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2420 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, 0)},
2421 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2422 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2423 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2424 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
33ddc16f 2425 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
e99ac54d 2426 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
26e744b6
BJ
2427 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2428 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2429 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2430 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2431 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, 0)},
33ddc16f 2432 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, 0)},
26e744b6
BJ
2433 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2434 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2435 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2436 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
e99ac54d
BJ
2437 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
2438 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
26e744b6
BJ
2439 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2440 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2441 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2442 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
33ddc16f 2443 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
26e744b6
BJ
2444 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2445 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2446 {}
2447};
2448MODULE_DEVICE_TABLE(usb, device_table);
2449
2450/* -- device connect -- */
2451static int sd_probe(struct usb_interface *intf,
2452 const struct usb_device_id *id)
2453{
2454 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2455 THIS_MODULE);
2456}
2457
26e744b6
BJ
2458static struct usb_driver sd_driver = {
2459 .name = MODULE_NAME,
2460 .id_table = device_table,
2461 .probe = sd_probe,
a39db27a 2462 .disconnect = gspca_disconnect,
26e744b6
BJ
2463#ifdef CONFIG_PM
2464 .suspend = gspca_suspend,
2465 .resume = gspca_resume,
2466 .reset_resume = gspca_resume,
2467#endif
2468};
2469
2470/* -- module insert / remove -- */
2471static int __init sd_mod_init(void)
2472{
54826437 2473 return usb_register(&sd_driver);
26e744b6
BJ
2474}
2475static void __exit sd_mod_exit(void)
2476{
2477 usb_deregister(&sd_driver);
26e744b6
BJ
2478}
2479
2480module_init(sd_mod_init);
2481module_exit(sd_mod_exit);
This page took 0.263384 seconds and 5 git commands to generate.