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