V4L/DVB: gspca - many subdrivers: Handle the buttons when CONFIG_INPUT=m
[linux-2.6.git] / drivers / media / video / gspca / sn9c20x.c
blob57673891c2c2ce27c9c907c59fd380603c3aaf57
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"
36 #define MODE_RAW 0x10
37 #define MODE_JPEG 0x20
38 #define MODE_SXGA 0x80
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
50 #define SENSOR_MT9M112 10
51 #define SENSOR_HV7131R 11
52 #define SENSOR_MT9VPRB 20
54 /* camera flags */
55 #define HAS_NO_BUTTON 0x1
56 #define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
57 #define FLIP_DETECT 0x4
59 /* specific webcam descriptor */
60 struct sd {
61 struct gspca_dev gspca_dev;
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;
70 u8 brightness;
71 u8 contrast;
72 u8 saturation;
73 s16 hue;
74 u8 gamma;
75 u8 red;
76 u8 blue;
78 u8 hflip;
79 u8 vflip;
80 u8 gain;
81 u16 exposure;
82 u8 auto_exposure;
84 u8 i2c_addr;
85 u8 sensor;
86 u8 hstart;
87 u8 vstart;
89 u8 jpeg_hdr[JPEG_HDR_SZ];
90 u8 quality;
92 u8 flags;
95 struct i2c_reg_u8 {
96 u8 reg;
97 u8 val;
100 struct i2c_reg_u16 {
101 u8 reg;
102 u16 val;
105 static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val);
106 static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val);
107 static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val);
108 static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val);
109 static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val);
110 static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val);
111 static int sd_sethue(struct gspca_dev *gspca_dev, s32 val);
112 static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val);
113 static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val);
114 static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val);
115 static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val);
116 static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val);
117 static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val);
118 static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val);
119 static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val);
120 static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val);
121 static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val);
122 static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val);
123 static int sd_setgain(struct gspca_dev *gspca_dev, s32 val);
124 static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val);
125 static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val);
126 static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val);
127 static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val);
128 static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val);
130 static const struct dmi_system_id flip_dmi_table[] = {
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")
140 .ident = "MSI MS-1632",
141 .matches = {
142 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
143 DMI_MATCH(DMI_BOARD_NAME, "MS-1632")
147 .ident = "MSI MS-1635X",
148 .matches = {
149 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
150 DMI_MATCH(DMI_BOARD_NAME, "MS-1635X")
154 .ident = "ASUSTeK W7J",
155 .matches = {
156 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
157 DMI_MATCH(DMI_BOARD_NAME, "W7J ")
163 static const struct ctrl sd_ctrls[] = {
165 #define BRIGHTNESS_IDX 0
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,
176 .set = sd_setbrightness,
177 .get = sd_getbrightness,
180 #define CONTRAST_IDX 1
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,
191 .set = sd_setcontrast,
192 .get = sd_getcontrast,
195 #define SATURATION_IDX 2
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,
206 .set = sd_setsaturation,
207 .get = sd_getsaturation,
210 #define HUE_IDX 3
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,
221 .set = sd_sethue,
222 .get = sd_gethue,
225 #define GAMMA_IDX 4
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,
236 .set = sd_setgamma,
237 .get = sd_getgamma,
240 #define BLUE_IDX 5
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,
251 .set = sd_setbluebalance,
252 .get = sd_getbluebalance,
255 #define RED_IDX 6
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,
266 .set = sd_setredbalance,
267 .get = sd_getredbalance,
270 #define HFLIP_IDX 7
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,
281 .set = sd_sethflip,
282 .get = sd_gethflip,
285 #define VFLIP_IDX 8
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,
296 .set = sd_setvflip,
297 .get = sd_getvflip,
300 #define EXPOSURE_IDX 9
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,
311 .set = sd_setexposure,
312 .get = sd_getexposure,
315 #define GAIN_IDX 10
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,
326 .set = sd_setgain,
327 .get = sd_getgain,
330 #define AUTOGAIN_IDX 11
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,
341 .set = sd_setautoexposure,
342 .get = sd_getautoexposure,
346 static const struct v4l2_pix_format vga_mode[] = {
347 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
348 .bytesperline = 160,
349 .sizeimage = 160 * 120 * 4 / 8 + 590,
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,
358 .bytesperline = 160,
359 .sizeimage = 240 * 120,
360 .colorspace = V4L2_COLORSPACE_SRGB,
361 .priv = 0},
362 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
363 .bytesperline = 320,
364 .sizeimage = 320 * 240 * 3 / 8 + 590,
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,
373 .bytesperline = 320,
374 .sizeimage = 480 * 240 ,
375 .colorspace = V4L2_COLORSPACE_SRGB,
376 .priv = 1},
377 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
378 .bytesperline = 640,
379 .sizeimage = 640 * 480 * 3 / 8 + 590,
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,
388 .bytesperline = 640,
389 .sizeimage = 960 * 480,
390 .colorspace = V4L2_COLORSPACE_SRGB,
391 .priv = 2},
394 static const struct v4l2_pix_format sxga_mode[] = {
395 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
396 .bytesperline = 160,
397 .sizeimage = 160 * 120 * 4 / 8 + 590,
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,
406 .bytesperline = 160,
407 .sizeimage = 240 * 120,
408 .colorspace = V4L2_COLORSPACE_SRGB,
409 .priv = 0},
410 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
411 .bytesperline = 320,
412 .sizeimage = 320 * 240 * 3 / 8 + 590,
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,
421 .bytesperline = 320,
422 .sizeimage = 480 * 240 ,
423 .colorspace = V4L2_COLORSPACE_SRGB,
424 .priv = 1},
425 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
426 .bytesperline = 640,
427 .sizeimage = 640 * 480 * 3 / 8 + 590,
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,
436 .bytesperline = 640,
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,
442 .sizeimage = 1280 * 1024,
443 .colorspace = V4L2_COLORSPACE_SRGB,
444 .priv = 3 | MODE_RAW | MODE_SXGA},
447 static const s16 hsv_red_x[] = {
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
495 static const s16 hsv_red_y[] = {
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
543 static const s16 hsv_green_x[] = {
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
591 static const s16 hsv_green_y[] = {
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
639 static const s16 hsv_blue_x[] = {
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
687 static const s16 hsv_blue_y[] = {
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
735 static 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,
746 V4L2_IDENT_MT9M112,
747 V4L2_IDENT_HV7131R,
750 static 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},
769 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
770 {0x1007, 0x00}
773 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
774 static 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 */
785 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
786 static 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
805 /* mt9m001 sensor uses a different gain formula then other micron sensors */
806 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
807 static 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
826 /* Gain = .5 + bit[7:0] / 16 */
827 static 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 */
838 static struct i2c_reg_u8 soi968_init[] = {
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},
845 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
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},
852 static struct i2c_reg_u8 ov7660_init[] = {
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},
861 static struct i2c_reg_u8 ov7670_init[] = {
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},
918 static struct i2c_reg_u8 ov9650_init[] = {
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},
948 static struct i2c_reg_u8 ov9655_init[] = {
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},
965 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
966 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
967 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
968 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
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},
975 static struct i2c_reg_u16 mt9v112_init[] = {
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},
994 static struct i2c_reg_u16 mt9v111_init[] = {
995 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
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}
1004 static struct i2c_reg_u16 mt9v011_init[] = {
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},
1031 static struct i2c_reg_u16 mt9m001_init[] = {
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},
1044 static struct i2c_reg_u16 mt9m111_init[] = {
1045 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1046 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1047 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1048 {0xf0, 0x0000},
1051 static 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},
1058 static struct i2c_reg_u8 hv7131r_init[] = {
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},
1069 static int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
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;
1085 return 0;
1088 static int reg_w(struct gspca_dev *gspca_dev, u16 reg,
1089 const u8 *buffer, int length)
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;
1106 return 0;
1109 static int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
1111 u8 data[1] = {value};
1112 return reg_w(gspca_dev, reg, data, 1);
1115 static int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
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)
1123 return -EIO;
1124 return 0;
1126 msleep(1);
1128 return -EIO;
1131 static int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1133 struct sd *sd = (struct sd *) gspca_dev;
1135 u8 row[8];
1138 * from the point of view of the bridge, the length
1139 * includes the address
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;
1150 return i2c_w(gspca_dev, row);
1153 static int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1155 struct sd *sd = (struct sd *) gspca_dev;
1156 u8 row[8];
1159 * from the point of view of the bridge, the length
1160 * includes the address
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;
1171 return i2c_w(gspca_dev, row);
1174 static int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1176 struct sd *sd = (struct sd *) gspca_dev;
1177 u8 row[8];
1179 row[0] = 0x81 | (1 << 4);
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;
1187 if (i2c_w(gspca_dev, row) < 0)
1188 return -EIO;
1189 row[0] = 0x81 | (1 << 4) | 0x02;
1190 row[2] = 0;
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];
1196 return 0;
1199 static int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1201 struct sd *sd = (struct sd *) gspca_dev;
1202 u8 row[8];
1204 row[0] = 0x81 | (1 << 4);
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;
1212 if (i2c_w(gspca_dev, row) < 0)
1213 return -EIO;
1214 row[0] = 0x81 | (2 << 4) | 0x02;
1215 row[2] = 0;
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];
1221 return 0;
1224 static int ov9650_init_sensor(struct gspca_dev *gspca_dev)
1226 int i;
1227 struct sd *sd = (struct sd *) gspca_dev;
1229 for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) {
1230 if (i2c_w1(gspca_dev, ov9650_init[i].reg,
1231 ov9650_init[i].val) < 0) {
1232 err("OV9650 sensor initialization failed");
1233 return -ENODEV;
1236 sd->hstart = 1;
1237 sd->vstart = 7;
1238 return 0;
1241 static int ov9655_init_sensor(struct gspca_dev *gspca_dev)
1243 int i;
1244 struct sd *sd = (struct sd *) gspca_dev;
1246 for (i = 0; i < ARRAY_SIZE(ov9655_init); i++) {
1247 if (i2c_w1(gspca_dev, ov9655_init[i].reg,
1248 ov9655_init[i].val) < 0) {
1249 err("OV9655 sensor initialization failed");
1250 return -ENODEV;
1253 /* disable hflip and vflip */
1254 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1255 sd->hstart = 1;
1256 sd->vstart = 2;
1257 return 0;
1260 static int soi968_init_sensor(struct gspca_dev *gspca_dev)
1262 int i;
1263 struct sd *sd = (struct sd *) gspca_dev;
1265 for (i = 0; i < ARRAY_SIZE(soi968_init); i++) {
1266 if (i2c_w1(gspca_dev, soi968_init[i].reg,
1267 soi968_init[i].val) < 0) {
1268 err("SOI968 sensor initialization failed");
1269 return -ENODEV;
1272 /* disable hflip and vflip */
1273 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << EXPOSURE_IDX);
1274 sd->hstart = 60;
1275 sd->vstart = 11;
1276 return 0;
1279 static int ov7660_init_sensor(struct gspca_dev *gspca_dev)
1281 int i;
1282 struct sd *sd = (struct sd *) gspca_dev;
1284 for (i = 0; i < ARRAY_SIZE(ov7660_init); i++) {
1285 if (i2c_w1(gspca_dev, ov7660_init[i].reg,
1286 ov7660_init[i].val) < 0) {
1287 err("OV7660 sensor initialization failed");
1288 return -ENODEV;
1291 /* disable hflip and vflip */
1292 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1293 sd->hstart = 1;
1294 sd->vstart = 1;
1295 return 0;
1298 static int ov7670_init_sensor(struct gspca_dev *gspca_dev)
1300 int i;
1301 struct sd *sd = (struct sd *) gspca_dev;
1303 for (i = 0; i < ARRAY_SIZE(ov7670_init); i++) {
1304 if (i2c_w1(gspca_dev, ov7670_init[i].reg,
1305 ov7670_init[i].val) < 0) {
1306 err("OV7670 sensor initialization failed");
1307 return -ENODEV;
1310 /* disable hflip and vflip */
1311 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1312 sd->hstart = 0;
1313 sd->vstart = 1;
1314 return 0;
1317 static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
1319 struct sd *sd = (struct sd *) gspca_dev;
1320 int i;
1321 u16 value;
1322 int ret;
1324 sd->i2c_addr = 0x5d;
1325 ret = i2c_r2(gspca_dev, 0xff, &value);
1326 if ((ret == 0) && (value == 0x8243)) {
1327 for (i = 0; i < ARRAY_SIZE(mt9v011_init); i++) {
1328 if (i2c_w2(gspca_dev, mt9v011_init[i].reg,
1329 mt9v011_init[i].val) < 0) {
1330 err("MT9V011 sensor initialization failed");
1331 return -ENODEV;
1334 sd->hstart = 2;
1335 sd->vstart = 2;
1336 sd->sensor = SENSOR_MT9V011;
1337 info("MT9V011 sensor detected");
1338 return 0;
1341 sd->i2c_addr = 0x5c;
1342 i2c_w2(gspca_dev, 0x01, 0x0004);
1343 ret = i2c_r2(gspca_dev, 0xff, &value);
1344 if ((ret == 0) && (value == 0x823a)) {
1345 for (i = 0; i < ARRAY_SIZE(mt9v111_init); i++) {
1346 if (i2c_w2(gspca_dev, mt9v111_init[i].reg,
1347 mt9v111_init[i].val) < 0) {
1348 err("MT9V111 sensor initialization failed");
1349 return -ENODEV;
1352 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | (1 << GAIN_IDX);
1353 sd->hstart = 2;
1354 sd->vstart = 2;
1355 sd->sensor = SENSOR_MT9V111;
1356 info("MT9V111 sensor detected");
1357 return 0;
1360 sd->i2c_addr = 0x5d;
1361 ret = i2c_w2(gspca_dev, 0xf0, 0x0000);
1362 if (ret < 0) {
1363 sd->i2c_addr = 0x48;
1364 i2c_w2(gspca_dev, 0xf0, 0x0000);
1366 ret = i2c_r2(gspca_dev, 0x00, &value);
1367 if ((ret == 0) && (value == 0x1229)) {
1368 for (i = 0; i < ARRAY_SIZE(mt9v112_init); i++) {
1369 if (i2c_w2(gspca_dev, mt9v112_init[i].reg,
1370 mt9v112_init[i].val) < 0) {
1371 err("MT9V112 sensor initialization failed");
1372 return -ENODEV;
1375 sd->hstart = 6;
1376 sd->vstart = 2;
1377 sd->sensor = SENSOR_MT9V112;
1378 info("MT9V112 sensor detected");
1379 return 0;
1382 return -ENODEV;
1385 static int mt9m112_init_sensor(struct gspca_dev *gspca_dev)
1387 struct sd *sd = (struct sd *) gspca_dev;
1388 int i;
1389 for (i = 0; i < ARRAY_SIZE(mt9m112_init); i++) {
1390 if (i2c_w2(gspca_dev, mt9m112_init[i].reg,
1391 mt9m112_init[i].val) < 0) {
1392 err("MT9M112 sensor initialization failed");
1393 return -ENODEV;
1396 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | (1 << GAIN_IDX);
1397 sd->hstart = 0;
1398 sd->vstart = 2;
1399 return 0;
1402 static int mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1404 struct sd *sd = (struct sd *) gspca_dev;
1405 int i;
1406 for (i = 0; i < ARRAY_SIZE(mt9m111_init); i++) {
1407 if (i2c_w2(gspca_dev, mt9m111_init[i].reg,
1408 mt9m111_init[i].val) < 0) {
1409 err("MT9M111 sensor initialization failed");
1410 return -ENODEV;
1413 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | (1 << GAIN_IDX);
1414 sd->hstart = 0;
1415 sd->vstart = 2;
1416 return 0;
1419 static int mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1421 struct sd *sd = (struct sd *) gspca_dev;
1422 int i;
1423 for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) {
1424 if (i2c_w2(gspca_dev, mt9m001_init[i].reg,
1425 mt9m001_init[i].val) < 0) {
1426 err("MT9M001 sensor initialization failed");
1427 return -ENODEV;
1430 /* disable hflip and vflip */
1431 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1432 sd->hstart = 2;
1433 sd->vstart = 2;
1434 return 0;
1437 static int hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1439 int i;
1440 struct sd *sd = (struct sd *) gspca_dev;
1442 for (i = 0; i < ARRAY_SIZE(hv7131r_init); i++) {
1443 if (i2c_w1(gspca_dev, hv7131r_init[i].reg,
1444 hv7131r_init[i].val) < 0) {
1445 err("HV7131R Sensor initialization failed");
1446 return -ENODEV;
1449 sd->hstart = 0;
1450 sd->vstart = 1;
1451 return 0;
1454 static int set_cmatrix(struct gspca_dev *gspca_dev)
1456 struct sd *sd = (struct sd *) gspca_dev;
1457 s32 hue_coord, hue_index = 180 + sd->hue;
1458 u8 cmatrix[21];
1460 memset(cmatrix, 0, sizeof cmatrix);
1461 cmatrix[2] = (sd->contrast * 0x25 / 0x100) + 0x26;
1462 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1463 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1464 cmatrix[18] = sd->brightness - 0x80;
1466 hue_coord = (hsv_red_x[hue_index] * sd->saturation) >> 8;
1467 cmatrix[6] = hue_coord;
1468 cmatrix[7] = (hue_coord >> 8) & 0x0f;
1470 hue_coord = (hsv_red_y[hue_index] * sd->saturation) >> 8;
1471 cmatrix[8] = hue_coord;
1472 cmatrix[9] = (hue_coord >> 8) & 0x0f;
1474 hue_coord = (hsv_green_x[hue_index] * sd->saturation) >> 8;
1475 cmatrix[10] = hue_coord;
1476 cmatrix[11] = (hue_coord >> 8) & 0x0f;
1478 hue_coord = (hsv_green_y[hue_index] * sd->saturation) >> 8;
1479 cmatrix[12] = hue_coord;
1480 cmatrix[13] = (hue_coord >> 8) & 0x0f;
1482 hue_coord = (hsv_blue_x[hue_index] * sd->saturation) >> 8;
1483 cmatrix[14] = hue_coord;
1484 cmatrix[15] = (hue_coord >> 8) & 0x0f;
1486 hue_coord = (hsv_blue_y[hue_index] * sd->saturation) >> 8;
1487 cmatrix[16] = hue_coord;
1488 cmatrix[17] = (hue_coord >> 8) & 0x0f;
1490 return reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1493 static int set_gamma(struct gspca_dev *gspca_dev)
1495 struct sd *sd = (struct sd *) gspca_dev;
1496 u8 gamma[17];
1497 u8 gval = sd->gamma * 0xb8 / 0x100;
1500 gamma[0] = 0x0a;
1501 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
1502 gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8);
1503 gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8);
1504 gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8);
1505 gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8);
1506 gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8);
1507 gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8);
1508 gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8);
1509 gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8);
1510 gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8);
1511 gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8);
1512 gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8);
1513 gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8);
1514 gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8);
1515 gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
1516 gamma[16] = 0xf5;
1518 return reg_w(gspca_dev, 0x1190, gamma, 17);
1521 static int set_redblue(struct gspca_dev *gspca_dev)
1523 struct sd *sd = (struct sd *) gspca_dev;
1524 reg_w1(gspca_dev, 0x118c, sd->red);
1525 reg_w1(gspca_dev, 0x118f, sd->blue);
1526 return 0;
1529 static int set_hvflip(struct gspca_dev *gspca_dev)
1531 u8 value, tslb, hflip, vflip;
1532 u16 value2;
1533 struct sd *sd = (struct sd *) gspca_dev;
1535 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1536 hflip = !sd->hflip;
1537 vflip = !sd->vflip;
1538 } else {
1539 hflip = sd->hflip;
1540 vflip = sd->vflip;
1543 switch (sd->sensor) {
1544 case SENSOR_OV9650:
1545 i2c_r1(gspca_dev, 0x1e, &value);
1546 value &= ~0x30;
1547 tslb = 0x01;
1548 if (hflip)
1549 value |= 0x20;
1550 if (vflip) {
1551 value |= 0x10;
1552 tslb = 0x49;
1554 i2c_w1(gspca_dev, 0x1e, value);
1555 i2c_w1(gspca_dev, 0x3a, tslb);
1556 break;
1557 case SENSOR_MT9V111:
1558 case SENSOR_MT9V011:
1559 i2c_r2(gspca_dev, 0x20, &value2);
1560 value2 &= ~0xc0a0;
1561 if (hflip)
1562 value2 |= 0x8080;
1563 if (vflip)
1564 value2 |= 0x4020;
1565 i2c_w2(gspca_dev, 0x20, value2);
1566 break;
1567 case SENSOR_MT9M112:
1568 case SENSOR_MT9M111:
1569 case SENSOR_MT9V112:
1570 i2c_r2(gspca_dev, 0x20, &value2);
1571 value2 &= ~0x0003;
1572 if (hflip)
1573 value2 |= 0x0002;
1574 if (vflip)
1575 value2 |= 0x0001;
1576 i2c_w2(gspca_dev, 0x20, value2);
1577 break;
1578 case SENSOR_HV7131R:
1579 i2c_r1(gspca_dev, 0x01, &value);
1580 value &= ~0x03;
1581 if (vflip)
1582 value |= 0x01;
1583 if (hflip)
1584 value |= 0x02;
1585 i2c_w1(gspca_dev, 0x01, value);
1586 break;
1588 return 0;
1591 static int set_exposure(struct gspca_dev *gspca_dev)
1593 struct sd *sd = (struct sd *) gspca_dev;
1594 u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1595 switch (sd->sensor) {
1596 case SENSOR_OV7660:
1597 case SENSOR_OV7670:
1598 case SENSOR_OV9655:
1599 case SENSOR_OV9650:
1600 exp[0] |= (3 << 4);
1601 exp[2] = 0x2d;
1602 exp[3] = sd->exposure & 0xff;
1603 exp[4] = sd->exposure >> 8;
1604 break;
1605 case SENSOR_MT9M001:
1606 case SENSOR_MT9V112:
1607 case SENSOR_MT9V011:
1608 exp[0] |= (3 << 4);
1609 exp[2] = 0x09;
1610 exp[3] = sd->exposure >> 8;
1611 exp[4] = sd->exposure & 0xff;
1612 break;
1613 case SENSOR_HV7131R:
1614 exp[0] |= (4 << 4);
1615 exp[2] = 0x25;
1616 exp[3] = (sd->exposure >> 5) & 0xff;
1617 exp[4] = (sd->exposure << 3) & 0xff;
1618 exp[5] = 0;
1619 break;
1620 default:
1621 return 0;
1623 i2c_w(gspca_dev, exp);
1624 return 0;
1627 static int set_gain(struct gspca_dev *gspca_dev)
1629 struct sd *sd = (struct sd *) gspca_dev;
1630 u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1631 switch (sd->sensor) {
1632 case SENSOR_OV7660:
1633 case SENSOR_OV7670:
1634 case SENSOR_SOI968:
1635 case SENSOR_OV9655:
1636 case SENSOR_OV9650:
1637 gain[0] |= (2 << 4);
1638 gain[3] = ov_gain[sd->gain];
1639 break;
1640 case SENSOR_MT9V011:
1641 gain[0] |= (3 << 4);
1642 gain[2] = 0x35;
1643 gain[3] = micron1_gain[sd->gain] >> 8;
1644 gain[4] = micron1_gain[sd->gain] & 0xff;
1645 break;
1646 case SENSOR_MT9V112:
1647 gain[0] |= (3 << 4);
1648 gain[2] = 0x2f;
1649 gain[3] = micron1_gain[sd->gain] >> 8;
1650 gain[4] = micron1_gain[sd->gain] & 0xff;
1651 break;
1652 case SENSOR_MT9M001:
1653 gain[0] |= (3 << 4);
1654 gain[2] = 0x2f;
1655 gain[3] = micron2_gain[sd->gain] >> 8;
1656 gain[4] = micron2_gain[sd->gain] & 0xff;
1657 break;
1658 case SENSOR_HV7131R:
1659 gain[0] |= (2 << 4);
1660 gain[2] = 0x30;
1661 gain[3] = hv7131r_gain[sd->gain];
1662 break;
1663 default:
1664 return 0;
1666 i2c_w(gspca_dev, gain);
1667 return 0;
1670 static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val)
1672 struct sd *sd = (struct sd *) gspca_dev;
1674 sd->brightness = val;
1675 if (gspca_dev->streaming)
1676 return set_cmatrix(gspca_dev);
1677 return 0;
1680 static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val)
1682 struct sd *sd = (struct sd *) gspca_dev;
1683 *val = sd->brightness;
1684 return 0;
1688 static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val)
1690 struct sd *sd = (struct sd *) gspca_dev;
1692 sd->contrast = val;
1693 if (gspca_dev->streaming)
1694 return set_cmatrix(gspca_dev);
1695 return 0;
1698 static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val)
1700 struct sd *sd = (struct sd *) gspca_dev;
1701 *val = sd->contrast;
1702 return 0;
1705 static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val)
1707 struct sd *sd = (struct sd *) gspca_dev;
1709 sd->saturation = val;
1710 if (gspca_dev->streaming)
1711 return set_cmatrix(gspca_dev);
1712 return 0;
1715 static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val)
1717 struct sd *sd = (struct sd *) gspca_dev;
1718 *val = sd->saturation;
1719 return 0;
1722 static int sd_sethue(struct gspca_dev *gspca_dev, s32 val)
1724 struct sd *sd = (struct sd *) gspca_dev;
1726 sd->hue = val;
1727 if (gspca_dev->streaming)
1728 return set_cmatrix(gspca_dev);
1729 return 0;
1732 static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val)
1734 struct sd *sd = (struct sd *) gspca_dev;
1735 *val = sd->hue;
1736 return 0;
1739 static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val)
1741 struct sd *sd = (struct sd *) gspca_dev;
1743 sd->gamma = val;
1744 if (gspca_dev->streaming)
1745 return set_gamma(gspca_dev);
1746 return 0;
1749 static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val)
1751 struct sd *sd = (struct sd *) gspca_dev;
1752 *val = sd->gamma;
1753 return 0;
1756 static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val)
1758 struct sd *sd = (struct sd *) gspca_dev;
1760 sd->red = val;
1761 if (gspca_dev->streaming)
1762 return set_redblue(gspca_dev);
1763 return 0;
1766 static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val)
1768 struct sd *sd = (struct sd *) gspca_dev;
1769 *val = sd->red;
1770 return 0;
1773 static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val)
1775 struct sd *sd = (struct sd *) gspca_dev;
1777 sd->blue = val;
1778 if (gspca_dev->streaming)
1779 return set_redblue(gspca_dev);
1780 return 0;
1783 static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val)
1785 struct sd *sd = (struct sd *) gspca_dev;
1786 *val = sd->blue;
1787 return 0;
1790 static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val)
1792 struct sd *sd = (struct sd *) gspca_dev;
1794 sd->hflip = val;
1795 if (gspca_dev->streaming)
1796 return set_hvflip(gspca_dev);
1797 return 0;
1800 static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val)
1802 struct sd *sd = (struct sd *) gspca_dev;
1803 *val = sd->hflip;
1804 return 0;
1807 static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val)
1809 struct sd *sd = (struct sd *) gspca_dev;
1811 sd->vflip = val;
1812 if (gspca_dev->streaming)
1813 return set_hvflip(gspca_dev);
1814 return 0;
1817 static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val)
1819 struct sd *sd = (struct sd *) gspca_dev;
1820 *val = sd->vflip;
1821 return 0;
1824 static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val)
1826 struct sd *sd = (struct sd *) gspca_dev;
1828 sd->exposure = val;
1829 if (gspca_dev->streaming)
1830 return set_exposure(gspca_dev);
1831 return 0;
1834 static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val)
1836 struct sd *sd = (struct sd *) gspca_dev;
1837 *val = sd->exposure;
1838 return 0;
1841 static int sd_setgain(struct gspca_dev *gspca_dev, s32 val)
1843 struct sd *sd = (struct sd *) gspca_dev;
1845 sd->gain = val;
1846 if (gspca_dev->streaming)
1847 return set_gain(gspca_dev);
1848 return 0;
1851 static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val)
1853 struct sd *sd = (struct sd *) gspca_dev;
1854 *val = sd->gain;
1855 return 0;
1858 static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val)
1860 struct sd *sd = (struct sd *) gspca_dev;
1861 sd->auto_exposure = val;
1862 return 0;
1865 static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val)
1867 struct sd *sd = (struct sd *) gspca_dev;
1868 *val = sd->auto_exposure;
1869 return 0;
1872 #ifdef CONFIG_VIDEO_ADV_DEBUG
1873 static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1874 struct v4l2_dbg_register *reg)
1876 struct sd *sd = (struct sd *) gspca_dev;
1877 switch (reg->match.type) {
1878 case V4L2_CHIP_MATCH_HOST:
1879 if (reg->match.addr != 0)
1880 return -EINVAL;
1881 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1882 return -EINVAL;
1883 if (reg_r(gspca_dev, reg->reg, 1) < 0)
1884 return -EINVAL;
1885 reg->val = gspca_dev->usb_buf[0];
1886 return 0;
1887 case V4L2_CHIP_MATCH_I2C_ADDR:
1888 if (reg->match.addr != sd->i2c_addr)
1889 return -EINVAL;
1890 if (sd->sensor >= SENSOR_MT9V011 &&
1891 sd->sensor <= SENSOR_MT9M112) {
1892 if (i2c_r2(gspca_dev, reg->reg, (u16 *)&reg->val) < 0)
1893 return -EINVAL;
1894 } else {
1895 if (i2c_r1(gspca_dev, reg->reg, (u8 *)&reg->val) < 0)
1896 return -EINVAL;
1898 return 0;
1900 return -EINVAL;
1903 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1904 struct v4l2_dbg_register *reg)
1906 struct sd *sd = (struct sd *) gspca_dev;
1907 switch (reg->match.type) {
1908 case V4L2_CHIP_MATCH_HOST:
1909 if (reg->match.addr != 0)
1910 return -EINVAL;
1911 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1912 return -EINVAL;
1913 if (reg_w1(gspca_dev, reg->reg, reg->val) < 0)
1914 return -EINVAL;
1915 return 0;
1916 case V4L2_CHIP_MATCH_I2C_ADDR:
1917 if (reg->match.addr != sd->i2c_addr)
1918 return -EINVAL;
1919 if (sd->sensor >= SENSOR_MT9V011 &&
1920 sd->sensor <= SENSOR_MT9M112) {
1921 if (i2c_w2(gspca_dev, reg->reg, reg->val) < 0)
1922 return -EINVAL;
1923 } else {
1924 if (i2c_w1(gspca_dev, reg->reg, reg->val) < 0)
1925 return -EINVAL;
1927 return 0;
1929 return -EINVAL;
1931 #endif
1933 static int sd_chip_ident(struct gspca_dev *gspca_dev,
1934 struct v4l2_dbg_chip_ident *chip)
1936 struct sd *sd = (struct sd *) gspca_dev;
1938 switch (chip->match.type) {
1939 case V4L2_CHIP_MATCH_HOST:
1940 if (chip->match.addr != 0)
1941 return -EINVAL;
1942 chip->revision = 0;
1943 chip->ident = V4L2_IDENT_SN9C20X;
1944 return 0;
1945 case V4L2_CHIP_MATCH_I2C_ADDR:
1946 if (chip->match.addr != sd->i2c_addr)
1947 return -EINVAL;
1948 chip->revision = 0;
1949 chip->ident = i2c_ident[sd->sensor];
1950 return 0;
1952 return -EINVAL;
1955 static int sd_config(struct gspca_dev *gspca_dev,
1956 const struct usb_device_id *id)
1958 struct sd *sd = (struct sd *) gspca_dev;
1959 struct cam *cam;
1961 cam = &gspca_dev->cam;
1963 sd->sensor = (id->driver_info >> 8) & 0xff;
1964 sd->i2c_addr = id->driver_info & 0xff;
1965 sd->flags = (id->driver_info >> 16) & 0xff;
1967 switch (sd->sensor) {
1968 case SENSOR_MT9M112:
1969 case SENSOR_MT9M111:
1970 case SENSOR_OV9650:
1971 case SENSOR_SOI968:
1972 cam->cam_mode = sxga_mode;
1973 cam->nmodes = ARRAY_SIZE(sxga_mode);
1974 break;
1975 default:
1976 cam->cam_mode = vga_mode;
1977 cam->nmodes = ARRAY_SIZE(vga_mode);
1978 break;
1981 sd->old_step = 0;
1982 sd->older_step = 0;
1983 sd->exposure_step = 16;
1985 sd->brightness = BRIGHTNESS_DEFAULT;
1986 sd->contrast = CONTRAST_DEFAULT;
1987 sd->saturation = SATURATION_DEFAULT;
1988 sd->hue = HUE_DEFAULT;
1989 sd->gamma = GAMMA_DEFAULT;
1990 sd->red = RED_DEFAULT;
1991 sd->blue = BLUE_DEFAULT;
1993 sd->hflip = HFLIP_DEFAULT;
1994 sd->vflip = VFLIP_DEFAULT;
1995 sd->exposure = EXPOSURE_DEFAULT;
1996 sd->gain = GAIN_DEFAULT;
1997 sd->auto_exposure = AUTO_EXPOSURE_DEFAULT;
1999 sd->quality = 95;
2001 return 0;
2004 static int sd_init(struct gspca_dev *gspca_dev)
2006 struct sd *sd = (struct sd *) gspca_dev;
2007 int i;
2008 u8 value;
2009 u8 i2c_init[9] =
2010 {0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
2012 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
2013 value = bridge_init[i][1];
2014 if (reg_w(gspca_dev, bridge_init[i][0], &value, 1) < 0) {
2015 err("Device initialization failed");
2016 return -ENODEV;
2020 if (sd->flags & LED_REVERSE)
2021 reg_w1(gspca_dev, 0x1006, 0x00);
2022 else
2023 reg_w1(gspca_dev, 0x1006, 0x20);
2025 if (reg_w(gspca_dev, 0x10c0, i2c_init, 9) < 0) {
2026 err("Device initialization failed");
2027 return -ENODEV;
2030 switch (sd->sensor) {
2031 case SENSOR_OV9650:
2032 if (ov9650_init_sensor(gspca_dev) < 0)
2033 return -ENODEV;
2034 info("OV9650 sensor detected");
2035 break;
2036 case SENSOR_OV9655:
2037 if (ov9655_init_sensor(gspca_dev) < 0)
2038 return -ENODEV;
2039 info("OV9655 sensor detected");
2040 break;
2041 case SENSOR_SOI968:
2042 if (soi968_init_sensor(gspca_dev) < 0)
2043 return -ENODEV;
2044 info("SOI968 sensor detected");
2045 break;
2046 case SENSOR_OV7660:
2047 if (ov7660_init_sensor(gspca_dev) < 0)
2048 return -ENODEV;
2049 info("OV7660 sensor detected");
2050 break;
2051 case SENSOR_OV7670:
2052 if (ov7670_init_sensor(gspca_dev) < 0)
2053 return -ENODEV;
2054 info("OV7670 sensor detected");
2055 break;
2056 case SENSOR_MT9VPRB:
2057 if (mt9v_init_sensor(gspca_dev) < 0)
2058 return -ENODEV;
2059 break;
2060 case SENSOR_MT9M111:
2061 if (mt9m111_init_sensor(gspca_dev) < 0)
2062 return -ENODEV;
2063 info("MT9M111 sensor detected");
2064 break;
2065 case SENSOR_MT9M112:
2066 if (mt9m112_init_sensor(gspca_dev) < 0)
2067 return -ENODEV;
2068 info("MT9M112 sensor detected");
2069 break;
2070 case SENSOR_MT9M001:
2071 if (mt9m001_init_sensor(gspca_dev) < 0)
2072 return -ENODEV;
2073 info("MT9M001 sensor detected");
2074 break;
2075 case SENSOR_HV7131R:
2076 if (hv7131r_init_sensor(gspca_dev) < 0)
2077 return -ENODEV;
2078 info("HV7131R sensor detected");
2079 break;
2080 default:
2081 info("Unsupported Sensor");
2082 return -ENODEV;
2085 return 0;
2088 static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
2090 struct sd *sd = (struct sd *) gspca_dev;
2091 u8 value;
2092 switch (sd->sensor) {
2093 case SENSOR_SOI968:
2094 if (mode & MODE_SXGA) {
2095 i2c_w1(gspca_dev, 0x17, 0x1d);
2096 i2c_w1(gspca_dev, 0x18, 0xbd);
2097 i2c_w1(gspca_dev, 0x19, 0x01);
2098 i2c_w1(gspca_dev, 0x1a, 0x81);
2099 i2c_w1(gspca_dev, 0x12, 0x00);
2100 sd->hstart = 140;
2101 sd->vstart = 19;
2102 } else {
2103 i2c_w1(gspca_dev, 0x17, 0x13);
2104 i2c_w1(gspca_dev, 0x18, 0x63);
2105 i2c_w1(gspca_dev, 0x19, 0x01);
2106 i2c_w1(gspca_dev, 0x1a, 0x79);
2107 i2c_w1(gspca_dev, 0x12, 0x40);
2108 sd->hstart = 60;
2109 sd->vstart = 11;
2111 break;
2112 case SENSOR_OV9650:
2113 if (mode & MODE_SXGA) {
2114 i2c_w1(gspca_dev, 0x17, 0x1b);
2115 i2c_w1(gspca_dev, 0x18, 0xbc);
2116 i2c_w1(gspca_dev, 0x19, 0x01);
2117 i2c_w1(gspca_dev, 0x1a, 0x82);
2118 i2c_r1(gspca_dev, 0x12, &value);
2119 i2c_w1(gspca_dev, 0x12, value & 0x07);
2120 } else {
2121 i2c_w1(gspca_dev, 0x17, 0x24);
2122 i2c_w1(gspca_dev, 0x18, 0xc5);
2123 i2c_w1(gspca_dev, 0x19, 0x00);
2124 i2c_w1(gspca_dev, 0x1a, 0x3c);
2125 i2c_r1(gspca_dev, 0x12, &value);
2126 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
2128 break;
2129 case SENSOR_MT9M112:
2130 case SENSOR_MT9M111:
2131 if (mode & MODE_SXGA) {
2132 i2c_w2(gspca_dev, 0xf0, 0x0002);
2133 i2c_w2(gspca_dev, 0xc8, 0x970b);
2134 i2c_w2(gspca_dev, 0xf0, 0x0000);
2135 } else {
2136 i2c_w2(gspca_dev, 0xf0, 0x0002);
2137 i2c_w2(gspca_dev, 0xc8, 0x8000);
2138 i2c_w2(gspca_dev, 0xf0, 0x0000);
2140 break;
2144 #define HW_WIN(mode, hstart, vstart) \
2145 ((const u8 []){hstart, 0, vstart, 0, \
2146 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
2147 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
2149 #define CLR_WIN(width, height) \
2150 ((const u8 [])\
2151 {0, width >> 2, 0, height >> 1,\
2152 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
2154 static int sd_start(struct gspca_dev *gspca_dev)
2156 struct sd *sd = (struct sd *) gspca_dev;
2157 int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
2158 int width = gspca_dev->width;
2159 int height = gspca_dev->height;
2160 u8 fmt, scale = 0;
2162 jpeg_define(sd->jpeg_hdr, height, width,
2163 0x21);
2164 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2166 if (mode & MODE_RAW)
2167 fmt = 0x2d;
2168 else if (mode & MODE_JPEG)
2169 fmt = 0x2c;
2170 else
2171 fmt = 0x2f;
2173 switch (mode & 0x0f) {
2174 case 3:
2175 scale = 0xc0;
2176 info("Set 1280x1024");
2177 break;
2178 case 2:
2179 scale = 0x80;
2180 info("Set 640x480");
2181 break;
2182 case 1:
2183 scale = 0x90;
2184 info("Set 320x240");
2185 break;
2186 case 0:
2187 scale = 0xa0;
2188 info("Set 160x120");
2189 break;
2192 configure_sensor_output(gspca_dev, mode);
2193 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2194 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2195 reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2196 reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2197 reg_w1(gspca_dev, 0x1189, scale);
2198 reg_w1(gspca_dev, 0x10e0, fmt);
2200 set_cmatrix(gspca_dev);
2201 set_gamma(gspca_dev);
2202 set_redblue(gspca_dev);
2203 set_gain(gspca_dev);
2204 set_exposure(gspca_dev);
2205 set_hvflip(gspca_dev);
2207 reg_w1(gspca_dev, 0x1007, 0x20);
2209 reg_r(gspca_dev, 0x1061, 1);
2210 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] | 0x02);
2211 return 0;
2214 static void sd_stopN(struct gspca_dev *gspca_dev)
2216 reg_w1(gspca_dev, 0x1007, 0x00);
2218 reg_r(gspca_dev, 0x1061, 1);
2219 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] & ~0x02);
2222 static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2224 struct sd *sd = (struct sd *) gspca_dev;
2225 s16 new_exp;
2228 * some hardcoded values are present
2229 * like those for maximal/minimal exposure
2230 * and exposure steps
2232 if (avg_lum < MIN_AVG_LUM) {
2233 if (sd->exposure > 0x1770)
2234 return;
2236 new_exp = sd->exposure + sd->exposure_step;
2237 if (new_exp > 0x1770)
2238 new_exp = 0x1770;
2239 if (new_exp < 0x10)
2240 new_exp = 0x10;
2241 sd->exposure = new_exp;
2242 set_exposure(gspca_dev);
2244 sd->older_step = sd->old_step;
2245 sd->old_step = 1;
2247 if (sd->old_step ^ sd->older_step)
2248 sd->exposure_step /= 2;
2249 else
2250 sd->exposure_step += 2;
2252 if (avg_lum > MAX_AVG_LUM) {
2253 if (sd->exposure < 0x10)
2254 return;
2255 new_exp = sd->exposure - sd->exposure_step;
2256 if (new_exp > 0x1700)
2257 new_exp = 0x1770;
2258 if (new_exp < 0x10)
2259 new_exp = 0x10;
2260 sd->exposure = new_exp;
2261 set_exposure(gspca_dev);
2262 sd->older_step = sd->old_step;
2263 sd->old_step = 0;
2265 if (sd->old_step ^ sd->older_step)
2266 sd->exposure_step /= 2;
2267 else
2268 sd->exposure_step += 2;
2272 static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2274 struct sd *sd = (struct sd *) gspca_dev;
2276 if (avg_lum < MIN_AVG_LUM) {
2277 if (sd->gain + 1 <= 28) {
2278 sd->gain++;
2279 set_gain(gspca_dev);
2282 if (avg_lum > MAX_AVG_LUM) {
2283 if (sd->gain > 0) {
2284 sd->gain--;
2285 set_gain(gspca_dev);
2290 static void sd_dqcallback(struct gspca_dev *gspca_dev)
2292 struct sd *sd = (struct sd *) gspca_dev;
2293 int avg_lum;
2295 if (!sd->auto_exposure)
2296 return;
2298 avg_lum = atomic_read(&sd->avg_lum);
2299 if (sd->sensor == SENSOR_SOI968)
2300 do_autogain(gspca_dev, avg_lum);
2301 else
2302 do_autoexposure(gspca_dev, avg_lum);
2305 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2306 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2307 u8 *data, /* interrupt packet */
2308 int len) /* interrupt packet length */
2310 struct sd *sd = (struct sd *) gspca_dev;
2311 int ret = -EINVAL;
2312 if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
2313 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2314 input_sync(gspca_dev->input_dev);
2315 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2316 input_sync(gspca_dev->input_dev);
2317 ret = 0;
2319 return ret;
2321 #endif
2323 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2324 u8 *data, /* isoc packet */
2325 int len) /* iso packet length */
2327 struct sd *sd = (struct sd *) gspca_dev;
2328 int avg_lum;
2329 static u8 frame_header[] =
2330 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2331 if (len == 64 && memcmp(data, frame_header, 6) == 0) {
2332 avg_lum = ((data[35] >> 2) & 3) |
2333 (data[20] << 2) |
2334 (data[19] << 10);
2335 avg_lum += ((data[35] >> 4) & 3) |
2336 (data[22] << 2) |
2337 (data[21] << 10);
2338 avg_lum += ((data[35] >> 6) & 3) |
2339 (data[24] << 2) |
2340 (data[23] << 10);
2341 avg_lum += (data[36] & 3) |
2342 (data[26] << 2) |
2343 (data[25] << 10);
2344 avg_lum += ((data[36] >> 2) & 3) |
2345 (data[28] << 2) |
2346 (data[27] << 10);
2347 avg_lum += ((data[36] >> 4) & 3) |
2348 (data[30] << 2) |
2349 (data[29] << 10);
2350 avg_lum += ((data[36] >> 6) & 3) |
2351 (data[32] << 2) |
2352 (data[31] << 10);
2353 avg_lum += ((data[44] >> 4) & 3) |
2354 (data[34] << 2) |
2355 (data[33] << 10);
2356 avg_lum >>= 9;
2357 atomic_set(&sd->avg_lum, avg_lum);
2358 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2359 return;
2361 if (gspca_dev->last_packet_type == LAST_PACKET) {
2362 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv
2363 & MODE_JPEG) {
2364 gspca_frame_add(gspca_dev, FIRST_PACKET,
2365 sd->jpeg_hdr, JPEG_HDR_SZ);
2366 gspca_frame_add(gspca_dev, INTER_PACKET,
2367 data, len);
2368 } else {
2369 gspca_frame_add(gspca_dev, FIRST_PACKET,
2370 data, len);
2372 } else {
2373 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2377 /* sub-driver description */
2378 static const struct sd_desc sd_desc = {
2379 .name = MODULE_NAME,
2380 .ctrls = sd_ctrls,
2381 .nctrls = ARRAY_SIZE(sd_ctrls),
2382 .config = sd_config,
2383 .init = sd_init,
2384 .start = sd_start,
2385 .stopN = sd_stopN,
2386 .pkt_scan = sd_pkt_scan,
2387 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2388 .int_pkt_scan = sd_int_pkt_scan,
2389 #endif
2390 .dq_callback = sd_dqcallback,
2391 #ifdef CONFIG_VIDEO_ADV_DEBUG
2392 .set_register = sd_dbg_s_register,
2393 .get_register = sd_dbg_g_register,
2394 #endif
2395 .get_chip_ident = sd_chip_ident,
2398 #define SN9C20X(sensor, i2c_addr, flags) \
2399 .driver_info = ((flags & 0xff) << 16) \
2400 | (SENSOR_ ## sensor << 8) \
2401 | (i2c_addr)
2403 static const __devinitdata struct usb_device_id device_table[] = {
2404 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2405 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
2406 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2407 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
2408 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
2409 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
2410 (FLIP_DETECT | HAS_NO_BUTTON))},
2411 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2412 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2413 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2414 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2415 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, 0)},
2416 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2417 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2418 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2419 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2420 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
2421 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
2422 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2423 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2424 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2425 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2426 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, 0)},
2427 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, 0)},
2428 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2429 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2430 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2431 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2432 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
2433 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
2434 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2435 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2436 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2437 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2438 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
2439 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2440 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2443 MODULE_DEVICE_TABLE(usb, device_table);
2445 /* -- device connect -- */
2446 static int sd_probe(struct usb_interface *intf,
2447 const struct usb_device_id *id)
2449 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2450 THIS_MODULE);
2453 static struct usb_driver sd_driver = {
2454 .name = MODULE_NAME,
2455 .id_table = device_table,
2456 .probe = sd_probe,
2457 .disconnect = gspca_disconnect,
2458 #ifdef CONFIG_PM
2459 .suspend = gspca_suspend,
2460 .resume = gspca_resume,
2461 .reset_resume = gspca_resume,
2462 #endif
2465 /* -- module insert / remove -- */
2466 static int __init sd_mod_init(void)
2468 return usb_register(&sd_driver);
2470 static void __exit sd_mod_exit(void)
2472 usb_deregister(&sd_driver);
2475 module_init(sd_mod_init);
2476 module_exit(sd_mod_exit);