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
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
22 #include <linux/input.h>
28 #include <media/v4l2-chip-ident.h>
29 #include <linux/dmi.h>
31 MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, "
32 "microdia project <microdia@googlegroups.com>");
33 MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
34 MODULE_LICENSE("GPL");
36 #define MODULE_NAME "sn9c20x"
39 #define MODE_JPEG 0x20
40 #define MODE_SXGA 0x80
42 #define SENSOR_OV9650 0
43 #define SENSOR_OV9655 1
44 #define SENSOR_SOI968 2
45 #define SENSOR_OV7660 3
46 #define SENSOR_OV7670 4
47 #define SENSOR_MT9V011 5
48 #define SENSOR_MT9V111 6
49 #define SENSOR_MT9V112 7
50 #define SENSOR_MT9M001 8
51 #define SENSOR_MT9M111 9
52 #define SENSOR_MT9M112 10
53 #define SENSOR_HV7131R 11
54 #define SENSOR_MT9VPRB 20
57 #define HAS_NO_BUTTON 0x1
58 #define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
59 #define FLIP_DETECT 0x4
61 /* specific webcam descriptor */
63 struct gspca_dev gspca_dev;
65 #define MIN_AVG_LUM 80
66 #define MAX_AVG_LUM 130
91 u8 jpeg_hdr[JPEG_HDR_SZ];
107 static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val);
108 static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val);
109 static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val);
110 static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val);
111 static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val);
112 static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val);
113 static int sd_sethue(struct gspca_dev *gspca_dev, s32 val);
114 static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val);
115 static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val);
116 static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val);
117 static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val);
118 static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val);
119 static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val);
120 static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val);
121 static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val);
122 static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val);
123 static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val);
124 static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val);
125 static int sd_setgain(struct gspca_dev *gspca_dev, s32 val);
126 static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val);
127 static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val);
128 static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val);
129 static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val);
130 static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val);
132 static const struct dmi_system_id flip_dmi_table[] = {
134 .ident = "MSI MS-1034",
136 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
137 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1034"),
138 DMI_MATCH(DMI_PRODUCT_VERSION, "0341")
142 .ident = "MSI MS-1632",
144 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
145 DMI_MATCH(DMI_BOARD_NAME, "MS-1632")
149 .ident = "MSI MS-1635X",
151 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
152 DMI_MATCH(DMI_BOARD_NAME, "MS-1635X")
156 .ident = "ASUSTeK W7J",
158 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
159 DMI_MATCH(DMI_BOARD_NAME, "W7J ")
165 static const struct ctrl sd_ctrls[] = {
167 #define BRIGHTNESS_IDX 0
169 .id = V4L2_CID_BRIGHTNESS,
170 .type = V4L2_CTRL_TYPE_INTEGER,
171 .name = "Brightness",
175 #define BRIGHTNESS_DEFAULT 0x7f
176 .default_value = BRIGHTNESS_DEFAULT,
178 .set = sd_setbrightness,
179 .get = sd_getbrightness,
182 #define CONTRAST_IDX 1
184 .id = V4L2_CID_CONTRAST,
185 .type = V4L2_CTRL_TYPE_INTEGER,
190 #define CONTRAST_DEFAULT 0x7f
191 .default_value = CONTRAST_DEFAULT,
193 .set = sd_setcontrast,
194 .get = sd_getcontrast,
197 #define SATURATION_IDX 2
199 .id = V4L2_CID_SATURATION,
200 .type = V4L2_CTRL_TYPE_INTEGER,
201 .name = "Saturation",
205 #define SATURATION_DEFAULT 0x7f
206 .default_value = SATURATION_DEFAULT,
208 .set = sd_setsaturation,
209 .get = sd_getsaturation,
215 .type = V4L2_CTRL_TYPE_INTEGER,
220 #define HUE_DEFAULT 0
221 .default_value = HUE_DEFAULT,
229 .id = V4L2_CID_GAMMA,
230 .type = V4L2_CTRL_TYPE_INTEGER,
235 #define GAMMA_DEFAULT 0x10
236 .default_value = GAMMA_DEFAULT,
244 .id = V4L2_CID_BLUE_BALANCE,
245 .type = V4L2_CTRL_TYPE_INTEGER,
246 .name = "Blue Balance",
250 #define BLUE_DEFAULT 0x28
251 .default_value = BLUE_DEFAULT,
253 .set = sd_setbluebalance,
254 .get = sd_getbluebalance,
259 .id = V4L2_CID_RED_BALANCE,
260 .type = V4L2_CTRL_TYPE_INTEGER,
261 .name = "Red Balance",
265 #define RED_DEFAULT 0x28
266 .default_value = RED_DEFAULT,
268 .set = sd_setredbalance,
269 .get = sd_getredbalance,
274 .id = V4L2_CID_HFLIP,
275 .type = V4L2_CTRL_TYPE_BOOLEAN,
276 .name = "Horizontal Flip",
280 #define HFLIP_DEFAULT 0
281 .default_value = HFLIP_DEFAULT,
289 .id = V4L2_CID_VFLIP,
290 .type = V4L2_CTRL_TYPE_BOOLEAN,
291 .name = "Vertical Flip",
295 #define VFLIP_DEFAULT 0
296 .default_value = VFLIP_DEFAULT,
302 #define EXPOSURE_IDX 9
304 .id = V4L2_CID_EXPOSURE,
305 .type = V4L2_CTRL_TYPE_INTEGER,
310 #define EXPOSURE_DEFAULT 0x33
311 .default_value = EXPOSURE_DEFAULT,
313 .set = sd_setexposure,
314 .get = sd_getexposure,
320 .type = V4L2_CTRL_TYPE_INTEGER,
325 #define GAIN_DEFAULT 0x00
326 .default_value = GAIN_DEFAULT,
332 #define AUTOGAIN_IDX 11
334 .id = V4L2_CID_AUTOGAIN,
335 .type = V4L2_CTRL_TYPE_BOOLEAN,
336 .name = "Auto Exposure",
340 #define AUTO_EXPOSURE_DEFAULT 1
341 .default_value = AUTO_EXPOSURE_DEFAULT,
343 .set = sd_setautoexposure,
344 .get = sd_getautoexposure,
348 static const struct v4l2_pix_format vga_mode[] = {
349 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
351 .sizeimage = 240 * 120,
352 .colorspace = V4L2_COLORSPACE_JPEG,
353 .priv = 0 | MODE_JPEG},
354 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
356 .sizeimage = 160 * 120,
357 .colorspace = V4L2_COLORSPACE_SRGB,
358 .priv = 0 | MODE_RAW},
359 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
361 .sizeimage = 240 * 120,
362 .colorspace = V4L2_COLORSPACE_SRGB,
364 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
366 .sizeimage = 480 * 240 ,
367 .colorspace = V4L2_COLORSPACE_JPEG,
368 .priv = 1 | MODE_JPEG},
369 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
371 .sizeimage = 320 * 240 ,
372 .colorspace = V4L2_COLORSPACE_SRGB,
373 .priv = 1 | MODE_RAW},
374 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
376 .sizeimage = 480 * 240 ,
377 .colorspace = V4L2_COLORSPACE_SRGB,
379 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
381 .sizeimage = 960 * 480,
382 .colorspace = V4L2_COLORSPACE_JPEG,
383 .priv = 2 | MODE_JPEG},
384 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
386 .sizeimage = 640 * 480,
387 .colorspace = V4L2_COLORSPACE_SRGB,
388 .priv = 2 | MODE_RAW},
389 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
391 .sizeimage = 960 * 480,
392 .colorspace = V4L2_COLORSPACE_SRGB,
396 static const struct v4l2_pix_format sxga_mode[] = {
397 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
399 .sizeimage = 240 * 120,
400 .colorspace = V4L2_COLORSPACE_JPEG,
401 .priv = 0 | MODE_JPEG},
402 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
404 .sizeimage = 160 * 120,
405 .colorspace = V4L2_COLORSPACE_SRGB,
406 .priv = 0 | MODE_RAW},
407 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
409 .sizeimage = 240 * 120,
410 .colorspace = V4L2_COLORSPACE_SRGB,
412 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
414 .sizeimage = 480 * 240 ,
415 .colorspace = V4L2_COLORSPACE_JPEG,
416 .priv = 1 | MODE_JPEG},
417 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
419 .sizeimage = 320 * 240 ,
420 .colorspace = V4L2_COLORSPACE_SRGB,
421 .priv = 1 | MODE_RAW},
422 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
424 .sizeimage = 480 * 240 ,
425 .colorspace = V4L2_COLORSPACE_SRGB,
427 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
429 .sizeimage = 960 * 480,
430 .colorspace = V4L2_COLORSPACE_JPEG,
431 .priv = 2 | MODE_JPEG},
432 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
434 .sizeimage = 640 * 480,
435 .colorspace = V4L2_COLORSPACE_SRGB,
436 .priv = 2 | MODE_RAW},
437 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
439 .sizeimage = 960 * 480,
440 .colorspace = V4L2_COLORSPACE_SRGB,
442 {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
443 .bytesperline = 1280,
444 .sizeimage = (1280 * 1024) + 64,
445 .colorspace = V4L2_COLORSPACE_SRGB,
446 .priv = 3 | MODE_RAW | MODE_SXGA},
449 static const s16 hsv_red_x[] = {
450 41, 44, 46, 48, 50, 52, 54, 56,
451 58, 60, 62, 64, 66, 68, 70, 72,
452 74, 76, 78, 80, 81, 83, 85, 87,
453 88, 90, 92, 93, 95, 97, 98, 100,
454 101, 102, 104, 105, 107, 108, 109, 110,
455 112, 113, 114, 115, 116, 117, 118, 119,
456 120, 121, 122, 123, 123, 124, 125, 125,
457 126, 127, 127, 128, 128, 129, 129, 129,
458 130, 130, 130, 130, 131, 131, 131, 131,
459 131, 131, 131, 131, 130, 130, 130, 130,
460 129, 129, 129, 128, 128, 127, 127, 126,
461 125, 125, 124, 123, 122, 122, 121, 120,
462 119, 118, 117, 116, 115, 114, 112, 111,
463 110, 109, 107, 106, 105, 103, 102, 101,
464 99, 98, 96, 94, 93, 91, 90, 88,
465 86, 84, 83, 81, 79, 77, 75, 74,
466 72, 70, 68, 66, 64, 62, 60, 58,
467 56, 54, 52, 49, 47, 45, 43, 41,
468 39, 36, 34, 32, 30, 28, 25, 23,
469 21, 19, 16, 14, 12, 9, 7, 5,
470 3, 0, -1, -3, -6, -8, -10, -12,
471 -15, -17, -19, -22, -24, -26, -28, -30,
472 -33, -35, -37, -39, -41, -44, -46, -48,
473 -50, -52, -54, -56, -58, -60, -62, -64,
474 -66, -68, -70, -72, -74, -76, -78, -80,
475 -81, -83, -85, -87, -88, -90, -92, -93,
476 -95, -97, -98, -100, -101, -102, -104, -105,
477 -107, -108, -109, -110, -112, -113, -114, -115,
478 -116, -117, -118, -119, -120, -121, -122, -123,
479 -123, -124, -125, -125, -126, -127, -127, -128,
480 -128, -128, -128, -128, -128, -128, -128, -128,
481 -128, -128, -128, -128, -128, -128, -128, -128,
482 -128, -128, -128, -128, -128, -128, -128, -128,
483 -128, -127, -127, -126, -125, -125, -124, -123,
484 -122, -122, -121, -120, -119, -118, -117, -116,
485 -115, -114, -112, -111, -110, -109, -107, -106,
486 -105, -103, -102, -101, -99, -98, -96, -94,
487 -93, -91, -90, -88, -86, -84, -83, -81,
488 -79, -77, -75, -74, -72, -70, -68, -66,
489 -64, -62, -60, -58, -56, -54, -52, -49,
490 -47, -45, -43, -41, -39, -36, -34, -32,
491 -30, -28, -25, -23, -21, -19, -16, -14,
492 -12, -9, -7, -5, -3, 0, 1, 3,
493 6, 8, 10, 12, 15, 17, 19, 22,
494 24, 26, 28, 30, 33, 35, 37, 39, 41
497 static const s16 hsv_red_y[] = {
498 82, 80, 78, 76, 74, 73, 71, 69,
499 67, 65, 63, 61, 58, 56, 54, 52,
500 50, 48, 46, 44, 41, 39, 37, 35,
501 32, 30, 28, 26, 23, 21, 19, 16,
502 14, 12, 10, 7, 5, 3, 0, -1,
503 -3, -6, -8, -10, -13, -15, -17, -19,
504 -22, -24, -26, -29, -31, -33, -35, -38,
505 -40, -42, -44, -46, -48, -51, -53, -55,
506 -57, -59, -61, -63, -65, -67, -69, -71,
507 -73, -75, -77, -79, -81, -82, -84, -86,
508 -88, -89, -91, -93, -94, -96, -98, -99,
509 -101, -102, -104, -105, -106, -108, -109, -110,
510 -112, -113, -114, -115, -116, -117, -119, -120,
511 -120, -121, -122, -123, -124, -125, -126, -126,
512 -127, -128, -128, -128, -128, -128, -128, -128,
513 -128, -128, -128, -128, -128, -128, -128, -128,
514 -128, -128, -128, -128, -128, -128, -128, -128,
515 -128, -128, -128, -128, -128, -128, -128, -128,
516 -127, -127, -126, -125, -125, -124, -123, -122,
517 -121, -120, -119, -118, -117, -116, -115, -114,
518 -113, -111, -110, -109, -107, -106, -105, -103,
519 -102, -100, -99, -97, -96, -94, -92, -91,
520 -89, -87, -85, -84, -82, -80, -78, -76,
521 -74, -73, -71, -69, -67, -65, -63, -61,
522 -58, -56, -54, -52, -50, -48, -46, -44,
523 -41, -39, -37, -35, -32, -30, -28, -26,
524 -23, -21, -19, -16, -14, -12, -10, -7,
525 -5, -3, 0, 1, 3, 6, 8, 10,
526 13, 15, 17, 19, 22, 24, 26, 29,
527 31, 33, 35, 38, 40, 42, 44, 46,
528 48, 51, 53, 55, 57, 59, 61, 63,
529 65, 67, 69, 71, 73, 75, 77, 79,
530 81, 82, 84, 86, 88, 89, 91, 93,
531 94, 96, 98, 99, 101, 102, 104, 105,
532 106, 108, 109, 110, 112, 113, 114, 115,
533 116, 117, 119, 120, 120, 121, 122, 123,
534 124, 125, 126, 126, 127, 128, 128, 129,
535 129, 130, 130, 131, 131, 131, 131, 132,
536 132, 132, 132, 132, 132, 132, 132, 132,
537 132, 132, 132, 131, 131, 131, 130, 130,
538 130, 129, 129, 128, 127, 127, 126, 125,
539 125, 124, 123, 122, 121, 120, 119, 118,
540 117, 116, 115, 114, 113, 111, 110, 109,
541 107, 106, 105, 103, 102, 100, 99, 97,
542 96, 94, 92, 91, 89, 87, 85, 84, 82
545 static const s16 hsv_green_x[] = {
546 -124, -124, -125, -125, -125, -125, -125, -125,
547 -125, -126, -126, -125, -125, -125, -125, -125,
548 -125, -124, -124, -124, -123, -123, -122, -122,
549 -121, -121, -120, -120, -119, -118, -117, -117,
550 -116, -115, -114, -113, -112, -111, -110, -109,
551 -108, -107, -105, -104, -103, -102, -100, -99,
552 -98, -96, -95, -93, -92, -91, -89, -87,
553 -86, -84, -83, -81, -79, -77, -76, -74,
554 -72, -70, -69, -67, -65, -63, -61, -59,
555 -57, -55, -53, -51, -49, -47, -45, -43,
556 -41, -39, -37, -35, -33, -30, -28, -26,
557 -24, -22, -20, -18, -15, -13, -11, -9,
558 -7, -4, -2, 0, 1, 3, 6, 8,
559 10, 12, 14, 17, 19, 21, 23, 25,
560 27, 29, 32, 34, 36, 38, 40, 42,
561 44, 46, 48, 50, 52, 54, 56, 58,
562 60, 62, 64, 66, 68, 70, 71, 73,
563 75, 77, 78, 80, 82, 83, 85, 87,
564 88, 90, 91, 93, 94, 96, 97, 98,
565 100, 101, 102, 104, 105, 106, 107, 108,
566 109, 111, 112, 113, 113, 114, 115, 116,
567 117, 118, 118, 119, 120, 120, 121, 122,
568 122, 123, 123, 124, 124, 124, 125, 125,
569 125, 125, 125, 125, 125, 126, 126, 125,
570 125, 125, 125, 125, 125, 124, 124, 124,
571 123, 123, 122, 122, 121, 121, 120, 120,
572 119, 118, 117, 117, 116, 115, 114, 113,
573 112, 111, 110, 109, 108, 107, 105, 104,
574 103, 102, 100, 99, 98, 96, 95, 93,
575 92, 91, 89, 87, 86, 84, 83, 81,
576 79, 77, 76, 74, 72, 70, 69, 67,
577 65, 63, 61, 59, 57, 55, 53, 51,
578 49, 47, 45, 43, 41, 39, 37, 35,
579 33, 30, 28, 26, 24, 22, 20, 18,
580 15, 13, 11, 9, 7, 4, 2, 0,
581 -1, -3, -6, -8, -10, -12, -14, -17,
582 -19, -21, -23, -25, -27, -29, -32, -34,
583 -36, -38, -40, -42, -44, -46, -48, -50,
584 -52, -54, -56, -58, -60, -62, -64, -66,
585 -68, -70, -71, -73, -75, -77, -78, -80,
586 -82, -83, -85, -87, -88, -90, -91, -93,
587 -94, -96, -97, -98, -100, -101, -102, -104,
588 -105, -106, -107, -108, -109, -111, -112, -113,
589 -113, -114, -115, -116, -117, -118, -118, -119,
590 -120, -120, -121, -122, -122, -123, -123, -124, -124
593 static const s16 hsv_green_y[] = {
594 -100, -99, -98, -97, -95, -94, -93, -91,
595 -90, -89, -87, -86, -84, -83, -81, -80,
596 -78, -76, -75, -73, -71, -70, -68, -66,
597 -64, -63, -61, -59, -57, -55, -53, -51,
598 -49, -48, -46, -44, -42, -40, -38, -36,
599 -34, -32, -30, -27, -25, -23, -21, -19,
600 -17, -15, -13, -11, -9, -7, -4, -2,
601 0, 1, 3, 5, 7, 9, 11, 14,
602 16, 18, 20, 22, 24, 26, 28, 30,
603 32, 34, 36, 38, 40, 42, 44, 46,
604 48, 50, 52, 54, 56, 58, 59, 61,
605 63, 65, 67, 68, 70, 72, 74, 75,
606 77, 78, 80, 82, 83, 85, 86, 88,
607 89, 90, 92, 93, 95, 96, 97, 98,
608 100, 101, 102, 103, 104, 105, 106, 107,
609 108, 109, 110, 111, 112, 112, 113, 114,
610 115, 115, 116, 116, 117, 117, 118, 118,
611 119, 119, 119, 120, 120, 120, 120, 120,
612 121, 121, 121, 121, 121, 121, 120, 120,
613 120, 120, 120, 119, 119, 119, 118, 118,
614 117, 117, 116, 116, 115, 114, 114, 113,
615 112, 111, 111, 110, 109, 108, 107, 106,
616 105, 104, 103, 102, 100, 99, 98, 97,
617 95, 94, 93, 91, 90, 89, 87, 86,
618 84, 83, 81, 80, 78, 76, 75, 73,
619 71, 70, 68, 66, 64, 63, 61, 59,
620 57, 55, 53, 51, 49, 48, 46, 44,
621 42, 40, 38, 36, 34, 32, 30, 27,
622 25, 23, 21, 19, 17, 15, 13, 11,
623 9, 7, 4, 2, 0, -1, -3, -5,
624 -7, -9, -11, -14, -16, -18, -20, -22,
625 -24, -26, -28, -30, -32, -34, -36, -38,
626 -40, -42, -44, -46, -48, -50, -52, -54,
627 -56, -58, -59, -61, -63, -65, -67, -68,
628 -70, -72, -74, -75, -77, -78, -80, -82,
629 -83, -85, -86, -88, -89, -90, -92, -93,
630 -95, -96, -97, -98, -100, -101, -102, -103,
631 -104, -105, -106, -107, -108, -109, -110, -111,
632 -112, -112, -113, -114, -115, -115, -116, -116,
633 -117, -117, -118, -118, -119, -119, -119, -120,
634 -120, -120, -120, -120, -121, -121, -121, -121,
635 -121, -121, -120, -120, -120, -120, -120, -119,
636 -119, -119, -118, -118, -117, -117, -116, -116,
637 -115, -114, -114, -113, -112, -111, -111, -110,
638 -109, -108, -107, -106, -105, -104, -103, -102, -100
641 static const s16 hsv_blue_x[] = {
642 112, 113, 114, 114, 115, 116, 117, 117,
643 118, 118, 119, 119, 120, 120, 120, 121,
644 121, 121, 122, 122, 122, 122, 122, 122,
645 122, 122, 122, 122, 122, 122, 121, 121,
646 121, 120, 120, 120, 119, 119, 118, 118,
647 117, 116, 116, 115, 114, 113, 113, 112,
648 111, 110, 109, 108, 107, 106, 105, 104,
649 103, 102, 100, 99, 98, 97, 95, 94,
650 93, 91, 90, 88, 87, 85, 84, 82,
651 80, 79, 77, 76, 74, 72, 70, 69,
652 67, 65, 63, 61, 60, 58, 56, 54,
653 52, 50, 48, 46, 44, 42, 40, 38,
654 36, 34, 32, 30, 28, 26, 24, 22,
655 19, 17, 15, 13, 11, 9, 7, 5,
656 2, 0, -1, -3, -5, -7, -9, -12,
657 -14, -16, -18, -20, -22, -24, -26, -28,
658 -31, -33, -35, -37, -39, -41, -43, -45,
659 -47, -49, -51, -53, -54, -56, -58, -60,
660 -62, -64, -66, -67, -69, -71, -73, -74,
661 -76, -78, -79, -81, -83, -84, -86, -87,
662 -89, -90, -92, -93, -94, -96, -97, -98,
663 -99, -101, -102, -103, -104, -105, -106, -107,
664 -108, -109, -110, -111, -112, -113, -114, -114,
665 -115, -116, -117, -117, -118, -118, -119, -119,
666 -120, -120, -120, -121, -121, -121, -122, -122,
667 -122, -122, -122, -122, -122, -122, -122, -122,
668 -122, -122, -121, -121, -121, -120, -120, -120,
669 -119, -119, -118, -118, -117, -116, -116, -115,
670 -114, -113, -113, -112, -111, -110, -109, -108,
671 -107, -106, -105, -104, -103, -102, -100, -99,
672 -98, -97, -95, -94, -93, -91, -90, -88,
673 -87, -85, -84, -82, -80, -79, -77, -76,
674 -74, -72, -70, -69, -67, -65, -63, -61,
675 -60, -58, -56, -54, -52, -50, -48, -46,
676 -44, -42, -40, -38, -36, -34, -32, -30,
677 -28, -26, -24, -22, -19, -17, -15, -13,
678 -11, -9, -7, -5, -2, 0, 1, 3,
679 5, 7, 9, 12, 14, 16, 18, 20,
680 22, 24, 26, 28, 31, 33, 35, 37,
681 39, 41, 43, 45, 47, 49, 51, 53,
682 54, 56, 58, 60, 62, 64, 66, 67,
683 69, 71, 73, 74, 76, 78, 79, 81,
684 83, 84, 86, 87, 89, 90, 92, 93,
685 94, 96, 97, 98, 99, 101, 102, 103,
686 104, 105, 106, 107, 108, 109, 110, 111, 112
689 static const s16 hsv_blue_y[] = {
690 -11, -13, -15, -17, -19, -21, -23, -25,
691 -27, -29, -31, -33, -35, -37, -39, -41,
692 -43, -45, -46, -48, -50, -52, -54, -55,
693 -57, -59, -61, -62, -64, -66, -67, -69,
694 -71, -72, -74, -75, -77, -78, -80, -81,
695 -83, -84, -86, -87, -88, -90, -91, -92,
696 -93, -95, -96, -97, -98, -99, -100, -101,
697 -102, -103, -104, -105, -106, -106, -107, -108,
698 -109, -109, -110, -111, -111, -112, -112, -113,
699 -113, -114, -114, -114, -115, -115, -115, -115,
700 -116, -116, -116, -116, -116, -116, -116, -116,
701 -116, -115, -115, -115, -115, -114, -114, -114,
702 -113, -113, -112, -112, -111, -111, -110, -110,
703 -109, -108, -108, -107, -106, -105, -104, -103,
704 -102, -101, -100, -99, -98, -97, -96, -95,
705 -94, -93, -91, -90, -89, -88, -86, -85,
706 -84, -82, -81, -79, -78, -76, -75, -73,
707 -71, -70, -68, -67, -65, -63, -62, -60,
708 -58, -56, -55, -53, -51, -49, -47, -45,
709 -44, -42, -40, -38, -36, -34, -32, -30,
710 -28, -26, -24, -22, -20, -18, -16, -14,
711 -12, -10, -8, -6, -4, -2, 0, 1,
712 3, 5, 7, 9, 11, 13, 15, 17,
713 19, 21, 23, 25, 27, 29, 31, 33,
714 35, 37, 39, 41, 43, 45, 46, 48,
715 50, 52, 54, 55, 57, 59, 61, 62,
716 64, 66, 67, 69, 71, 72, 74, 75,
717 77, 78, 80, 81, 83, 84, 86, 87,
718 88, 90, 91, 92, 93, 95, 96, 97,
719 98, 99, 100, 101, 102, 103, 104, 105,
720 106, 106, 107, 108, 109, 109, 110, 111,
721 111, 112, 112, 113, 113, 114, 114, 114,
722 115, 115, 115, 115, 116, 116, 116, 116,
723 116, 116, 116, 116, 116, 115, 115, 115,
724 115, 114, 114, 114, 113, 113, 112, 112,
725 111, 111, 110, 110, 109, 108, 108, 107,
726 106, 105, 104, 103, 102, 101, 100, 99,
727 98, 97, 96, 95, 94, 93, 91, 90,
728 89, 88, 86, 85, 84, 82, 81, 79,
729 78, 76, 75, 73, 71, 70, 68, 67,
730 65, 63, 62, 60, 58, 56, 55, 53,
731 51, 49, 47, 45, 44, 42, 40, 38,
732 36, 34, 32, 30, 28, 26, 24, 22,
733 20, 18, 16, 14, 12, 10, 8, 6,
734 4, 2, 0, -1, -3, -5, -7, -9, -11
737 static u16 i2c_ident[] = {
746 V4L2_IDENT_MT9M001C12ST,
752 static u16 bridge_init[][2] = {
753 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
754 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
755 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
756 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
757 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
758 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
759 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
760 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
761 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
762 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
763 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
764 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
765 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
766 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
767 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
768 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
769 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
770 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
771 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
775 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
776 static u8 ov_gain[] = {
777 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
778 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
779 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
780 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
781 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
782 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
783 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
787 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
788 static u16 micron1_gain[] = {
789 /* 1x 1.25x 1.5x 1.75x */
790 0x0020, 0x0028, 0x0030, 0x0038,
791 /* 2x 2.25x 2.5x 2.75x */
792 0x00a0, 0x00a4, 0x00a8, 0x00ac,
793 /* 3x 3.25x 3.5x 3.75x */
794 0x00b0, 0x00b4, 0x00b8, 0x00bc,
795 /* 4x 4.25x 4.5x 4.75x */
796 0x00c0, 0x00c4, 0x00c8, 0x00cc,
797 /* 5x 5.25x 5.5x 5.75x */
798 0x00d0, 0x00d4, 0x00d8, 0x00dc,
799 /* 6x 6.25x 6.5x 6.75x */
800 0x00e0, 0x00e4, 0x00e8, 0x00ec,
801 /* 7x 7.25x 7.5x 7.75x */
802 0x00f0, 0x00f4, 0x00f8, 0x00fc,
807 /* mt9m001 sensor uses a different gain formula then other micron sensors */
808 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
809 static u16 micron2_gain[] = {
810 /* 1x 1.25x 1.5x 1.75x */
811 0x0008, 0x000a, 0x000c, 0x000e,
812 /* 2x 2.25x 2.5x 2.75x */
813 0x0010, 0x0012, 0x0014, 0x0016,
814 /* 3x 3.25x 3.5x 3.75x */
815 0x0018, 0x001a, 0x001c, 0x001e,
816 /* 4x 4.25x 4.5x 4.75x */
817 0x0020, 0x0051, 0x0052, 0x0053,
818 /* 5x 5.25x 5.5x 5.75x */
819 0x0054, 0x0055, 0x0056, 0x0057,
820 /* 6x 6.25x 6.5x 6.75x */
821 0x0058, 0x0059, 0x005a, 0x005b,
822 /* 7x 7.25x 7.5x 7.75x */
823 0x005c, 0x005d, 0x005e, 0x005f,
828 /* Gain = .5 + bit[7:0] / 16 */
829 static u8 hv7131r_gain[] = {
830 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
831 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
832 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
833 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
834 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
835 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
836 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
840 static struct i2c_reg_u8 soi968_init[] = {
841 {0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f},
842 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
843 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
844 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
845 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
846 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
847 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
848 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
849 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
850 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
851 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
854 static struct i2c_reg_u8 ov7660_init[] = {
855 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
856 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
857 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
858 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
859 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6},
860 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
863 static struct i2c_reg_u8 ov7670_init[] = {
864 {0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
865 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
866 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
867 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
868 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
869 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
870 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
871 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
872 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
873 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
874 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
875 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
876 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
877 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
878 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
879 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
880 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
881 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
882 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
883 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
884 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
885 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
886 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
887 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
888 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
889 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
890 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
891 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
892 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
893 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
894 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
895 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
896 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
897 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
898 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
899 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
900 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
901 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
902 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
903 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
904 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
905 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
906 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
907 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
908 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
909 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
910 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
911 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
912 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
913 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
914 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
915 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
916 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
920 static struct i2c_reg_u8 ov9650_init[] = {
921 {0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78},
922 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
923 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
924 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
925 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
926 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
927 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
928 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
929 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
930 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
931 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
932 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
933 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
934 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
935 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
936 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
937 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
938 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
939 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
940 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
941 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
942 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
943 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
944 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
945 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
946 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
947 {0xaa, 0x92}, {0xab, 0x0a},
950 static struct i2c_reg_u8 ov9655_init[] = {
951 {0x12, 0x80}, {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
952 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
953 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
954 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
955 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
956 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
957 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
958 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
959 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
960 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
961 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
962 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
963 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
964 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
965 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
966 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
967 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
968 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
969 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
970 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
971 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
972 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
973 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
974 {0x04, 0x03}, {0x00, 0x13},
977 static struct i2c_reg_u16 mt9v112_init[] = {
978 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
979 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
980 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
981 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
982 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
983 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
984 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
985 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
986 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
987 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
988 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
989 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
990 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
991 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
992 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
993 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
996 static struct i2c_reg_u16 mt9v111_init[] = {
997 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
998 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
999 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
1000 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
1001 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
1002 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
1003 {0x0e, 0x0008}, {0x20, 0x0000}
1006 static struct i2c_reg_u16 mt9v011_init[] = {
1007 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
1008 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
1009 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
1010 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
1011 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
1012 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
1013 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
1014 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
1015 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
1016 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
1017 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
1018 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
1019 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
1020 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
1021 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
1022 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
1023 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
1024 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
1025 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
1026 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
1027 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
1028 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1029 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
1030 {0x06, 0x0029}, {0x05, 0x0009},
1033 static struct i2c_reg_u16 mt9m001_init[] = {
1034 {0x0d, 0x0001}, {0x0d, 0x0000}, {0x01, 0x000e},
1035 {0x02, 0x0014}, {0x03, 0x03c1}, {0x04, 0x0501},
1036 {0x05, 0x0083}, {0x06, 0x0006}, {0x0d, 0x0002},
1037 {0x0a, 0x0000}, {0x0c, 0x0000}, {0x11, 0x0000},
1038 {0x1e, 0x8000}, {0x5f, 0x8904}, {0x60, 0x0000},
1039 {0x61, 0x0000}, {0x62, 0x0498}, {0x63, 0x0000},
1040 {0x64, 0x0000}, {0x20, 0x111d}, {0x06, 0x00f2},
1041 {0x05, 0x0013}, {0x09, 0x10f2}, {0x07, 0x0003},
1042 {0x2b, 0x002a}, {0x2d, 0x002a}, {0x2c, 0x002a},
1043 {0x2e, 0x0029}, {0x07, 0x0002},
1046 static struct i2c_reg_u16 mt9m111_init[] = {
1047 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1048 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1049 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1053 static struct i2c_reg_u16 mt9m112_init[] = {
1054 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1055 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1056 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1060 static struct i2c_reg_u8 hv7131r_init[] = {
1061 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
1062 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
1063 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
1064 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
1065 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
1066 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
1067 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
1068 {0x23, 0x09}, {0x01, 0x08},
1071 static int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
1073 struct usb_device *dev = gspca_dev->dev;
1075 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
1077 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1083 if (unlikely(result < 0 || result != length)) {
1084 err("Read register failed 0x%02X", reg);
1090 static int reg_w(struct gspca_dev *gspca_dev, u16 reg,
1091 const u8 *buffer, int length)
1093 struct usb_device *dev = gspca_dev->dev;
1095 memcpy(gspca_dev->usb_buf, buffer, length);
1096 result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1098 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1104 if (unlikely(result < 0 || result != length)) {
1105 err("Write register failed index 0x%02X", reg);
1111 static int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
1113 u8 data[1] = {value};
1114 return reg_w(gspca_dev, reg, data, 1);
1117 static int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
1120 reg_w(gspca_dev, 0x10c0, buffer, 8);
1121 for (i = 0; i < 5; i++) {
1122 reg_r(gspca_dev, 0x10c0, 1);
1123 if (gspca_dev->usb_buf[0] & 0x04) {
1124 if (gspca_dev->usb_buf[0] & 0x08)
1133 static int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1135 struct sd *sd = (struct sd *) gspca_dev;
1140 * from the point of view of the bridge, the length
1141 * includes the address
1143 row[0] = 0x81 | (2 << 4);
1144 row[1] = sd->i2c_addr;
1152 return i2c_w(gspca_dev, row);
1155 static int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1157 struct sd *sd = (struct sd *) gspca_dev;
1161 * from the point of view of the bridge, the length
1162 * includes the address
1164 row[0] = 0x81 | (3 << 4);
1165 row[1] = sd->i2c_addr;
1167 row[3] = (val >> 8) & 0xff;
1168 row[4] = val & 0xff;
1173 return i2c_w(gspca_dev, row);
1176 static int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1178 struct sd *sd = (struct sd *) gspca_dev;
1181 row[0] = 0x81 | (1 << 4);
1182 row[1] = sd->i2c_addr;
1189 if (i2c_w(gspca_dev, row) < 0)
1191 row[0] = 0x81 | (1 << 4) | 0x02;
1193 if (i2c_w(gspca_dev, row) < 0)
1195 if (reg_r(gspca_dev, 0x10c2, 5) < 0)
1197 *val = gspca_dev->usb_buf[4];
1201 static int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1203 struct sd *sd = (struct sd *) gspca_dev;
1206 row[0] = 0x81 | (1 << 4);
1207 row[1] = sd->i2c_addr;
1214 if (i2c_w(gspca_dev, row) < 0)
1216 row[0] = 0x81 | (2 << 4) | 0x02;
1218 if (i2c_w(gspca_dev, row) < 0)
1220 if (reg_r(gspca_dev, 0x10c2, 5) < 0)
1222 *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1226 static int ov9650_init_sensor(struct gspca_dev *gspca_dev)
1229 struct sd *sd = (struct sd *) gspca_dev;
1231 for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) {
1232 if (i2c_w1(gspca_dev, ov9650_init[i].reg,
1233 ov9650_init[i].val) < 0) {
1234 err("OV9650 sensor initialization failed");
1243 static int ov9655_init_sensor(struct gspca_dev *gspca_dev)
1246 struct sd *sd = (struct sd *) gspca_dev;
1248 for (i = 0; i < ARRAY_SIZE(ov9655_init); i++) {
1249 if (i2c_w1(gspca_dev, ov9655_init[i].reg,
1250 ov9655_init[i].val) < 0) {
1251 err("OV9655 sensor initialization failed");
1255 /* disable hflip and vflip */
1256 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1262 static int soi968_init_sensor(struct gspca_dev *gspca_dev)
1265 struct sd *sd = (struct sd *) gspca_dev;
1267 for (i = 0; i < ARRAY_SIZE(soi968_init); i++) {
1268 if (i2c_w1(gspca_dev, soi968_init[i].reg,
1269 soi968_init[i].val) < 0) {
1270 err("SOI968 sensor initialization failed");
1274 /* disable hflip and vflip */
1275 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << EXPOSURE_IDX);
1281 static int ov7660_init_sensor(struct gspca_dev *gspca_dev)
1284 struct sd *sd = (struct sd *) gspca_dev;
1286 for (i = 0; i < ARRAY_SIZE(ov7660_init); i++) {
1287 if (i2c_w1(gspca_dev, ov7660_init[i].reg,
1288 ov7660_init[i].val) < 0) {
1289 err("OV7660 sensor initialization failed");
1293 /* disable hflip and vflip */
1294 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1300 static int ov7670_init_sensor(struct gspca_dev *gspca_dev)
1303 struct sd *sd = (struct sd *) gspca_dev;
1305 for (i = 0; i < ARRAY_SIZE(ov7670_init); i++) {
1306 if (i2c_w1(gspca_dev, ov7670_init[i].reg,
1307 ov7670_init[i].val) < 0) {
1308 err("OV7670 sensor initialization failed");
1312 /* disable hflip and vflip */
1313 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1319 static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
1321 struct sd *sd = (struct sd *) gspca_dev;
1326 sd->i2c_addr = 0x5d;
1327 ret = i2c_r2(gspca_dev, 0xff, &value);
1328 if ((ret == 0) && (value == 0x8243)) {
1329 for (i = 0; i < ARRAY_SIZE(mt9v011_init); i++) {
1330 if (i2c_w2(gspca_dev, mt9v011_init[i].reg,
1331 mt9v011_init[i].val) < 0) {
1332 err("MT9V011 sensor initialization failed");
1338 sd->sensor = SENSOR_MT9V011;
1339 info("MT9V011 sensor detected");
1343 sd->i2c_addr = 0x5c;
1344 i2c_w2(gspca_dev, 0x01, 0x0004);
1345 ret = i2c_r2(gspca_dev, 0xff, &value);
1346 if ((ret == 0) && (value == 0x823a)) {
1347 for (i = 0; i < ARRAY_SIZE(mt9v111_init); i++) {
1348 if (i2c_w2(gspca_dev, mt9v111_init[i].reg,
1349 mt9v111_init[i].val) < 0) {
1350 err("MT9V111 sensor initialization failed");
1354 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | (1 << GAIN_IDX);
1357 sd->sensor = SENSOR_MT9V111;
1358 info("MT9V111 sensor detected");
1362 sd->i2c_addr = 0x5d;
1363 ret = i2c_w2(gspca_dev, 0xf0, 0x0000);
1365 sd->i2c_addr = 0x48;
1366 i2c_w2(gspca_dev, 0xf0, 0x0000);
1368 ret = i2c_r2(gspca_dev, 0x00, &value);
1369 if ((ret == 0) && (value == 0x1229)) {
1370 for (i = 0; i < ARRAY_SIZE(mt9v112_init); i++) {
1371 if (i2c_w2(gspca_dev, mt9v112_init[i].reg,
1372 mt9v112_init[i].val) < 0) {
1373 err("MT9V112 sensor initialization failed");
1379 sd->sensor = SENSOR_MT9V112;
1380 info("MT9V112 sensor detected");
1387 static int mt9m112_init_sensor(struct gspca_dev *gspca_dev)
1389 struct sd *sd = (struct sd *) gspca_dev;
1391 for (i = 0; i < ARRAY_SIZE(mt9m112_init); i++) {
1392 if (i2c_w2(gspca_dev, mt9m112_init[i].reg,
1393 mt9m112_init[i].val) < 0) {
1394 err("MT9M112 sensor initialization failed");
1398 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | (1 << GAIN_IDX);
1404 static int mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1406 struct sd *sd = (struct sd *) gspca_dev;
1408 for (i = 0; i < ARRAY_SIZE(mt9m111_init); i++) {
1409 if (i2c_w2(gspca_dev, mt9m111_init[i].reg,
1410 mt9m111_init[i].val) < 0) {
1411 err("MT9M111 sensor initialization failed");
1415 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | (1 << GAIN_IDX);
1421 static int mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1423 struct sd *sd = (struct sd *) gspca_dev;
1425 for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) {
1426 if (i2c_w2(gspca_dev, mt9m001_init[i].reg,
1427 mt9m001_init[i].val) < 0) {
1428 err("MT9M001 sensor initialization failed");
1432 /* disable hflip and vflip */
1433 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1439 static int hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1442 struct sd *sd = (struct sd *) gspca_dev;
1444 for (i = 0; i < ARRAY_SIZE(hv7131r_init); i++) {
1445 if (i2c_w1(gspca_dev, hv7131r_init[i].reg,
1446 hv7131r_init[i].val) < 0) {
1447 err("HV7131R Sensor initialization failed");
1456 static int set_cmatrix(struct gspca_dev *gspca_dev)
1458 struct sd *sd = (struct sd *) gspca_dev;
1459 s32 hue_coord, hue_index = 180 + sd->hue;
1462 memset(cmatrix, 0, sizeof cmatrix);
1463 cmatrix[2] = (sd->contrast * 0x25 / 0x100) + 0x26;
1464 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1465 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1466 cmatrix[18] = sd->brightness - 0x80;
1468 hue_coord = (hsv_red_x[hue_index] * sd->saturation) >> 8;
1469 cmatrix[6] = hue_coord;
1470 cmatrix[7] = (hue_coord >> 8) & 0x0f;
1472 hue_coord = (hsv_red_y[hue_index] * sd->saturation) >> 8;
1473 cmatrix[8] = hue_coord;
1474 cmatrix[9] = (hue_coord >> 8) & 0x0f;
1476 hue_coord = (hsv_green_x[hue_index] * sd->saturation) >> 8;
1477 cmatrix[10] = hue_coord;
1478 cmatrix[11] = (hue_coord >> 8) & 0x0f;
1480 hue_coord = (hsv_green_y[hue_index] * sd->saturation) >> 8;
1481 cmatrix[12] = hue_coord;
1482 cmatrix[13] = (hue_coord >> 8) & 0x0f;
1484 hue_coord = (hsv_blue_x[hue_index] * sd->saturation) >> 8;
1485 cmatrix[14] = hue_coord;
1486 cmatrix[15] = (hue_coord >> 8) & 0x0f;
1488 hue_coord = (hsv_blue_y[hue_index] * sd->saturation) >> 8;
1489 cmatrix[16] = hue_coord;
1490 cmatrix[17] = (hue_coord >> 8) & 0x0f;
1492 return reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1495 static int set_gamma(struct gspca_dev *gspca_dev)
1497 struct sd *sd = (struct sd *) gspca_dev;
1499 u8 gval = sd->gamma * 0xb8 / 0x100;
1503 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
1504 gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8);
1505 gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8);
1506 gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8);
1507 gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8);
1508 gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8);
1509 gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8);
1510 gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8);
1511 gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8);
1512 gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8);
1513 gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8);
1514 gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8);
1515 gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8);
1516 gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8);
1517 gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
1520 return reg_w(gspca_dev, 0x1190, gamma, 17);
1523 static int set_redblue(struct gspca_dev *gspca_dev)
1525 struct sd *sd = (struct sd *) gspca_dev;
1526 reg_w1(gspca_dev, 0x118c, sd->red);
1527 reg_w1(gspca_dev, 0x118f, sd->blue);
1531 static int set_hvflip(struct gspca_dev *gspca_dev)
1533 u8 value, tslb, hflip, vflip;
1535 struct sd *sd = (struct sd *) gspca_dev;
1537 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1545 switch (sd->sensor) {
1547 i2c_r1(gspca_dev, 0x1e, &value);
1556 i2c_w1(gspca_dev, 0x1e, value);
1557 i2c_w1(gspca_dev, 0x3a, tslb);
1559 case SENSOR_MT9V111:
1560 case SENSOR_MT9V011:
1561 i2c_r2(gspca_dev, 0x20, &value2);
1567 i2c_w2(gspca_dev, 0x20, value2);
1569 case SENSOR_MT9M112:
1570 case SENSOR_MT9M111:
1571 case SENSOR_MT9V112:
1572 i2c_r2(gspca_dev, 0x20, &value2);
1578 i2c_w2(gspca_dev, 0x20, value2);
1580 case SENSOR_HV7131R:
1581 i2c_r1(gspca_dev, 0x01, &value);
1587 i2c_w1(gspca_dev, 0x01, value);
1593 static int set_exposure(struct gspca_dev *gspca_dev)
1595 struct sd *sd = (struct sd *) gspca_dev;
1596 u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1597 switch (sd->sensor) {
1604 exp[3] = sd->exposure & 0xff;
1605 exp[4] = sd->exposure >> 8;
1607 case SENSOR_MT9M001:
1608 case SENSOR_MT9V112:
1609 case SENSOR_MT9V011:
1612 exp[3] = sd->exposure >> 8;
1613 exp[4] = sd->exposure & 0xff;
1615 case SENSOR_HV7131R:
1618 exp[3] = (sd->exposure >> 5) & 0xff;
1619 exp[4] = (sd->exposure << 3) & 0xff;
1625 i2c_w(gspca_dev, exp);
1629 static int set_gain(struct gspca_dev *gspca_dev)
1631 struct sd *sd = (struct sd *) gspca_dev;
1632 u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1633 switch (sd->sensor) {
1639 gain[0] |= (2 << 4);
1640 gain[3] = ov_gain[sd->gain];
1642 case SENSOR_MT9V011:
1643 gain[0] |= (3 << 4);
1645 gain[3] = micron1_gain[sd->gain] >> 8;
1646 gain[4] = micron1_gain[sd->gain] & 0xff;
1648 case SENSOR_MT9V112:
1649 gain[0] |= (3 << 4);
1651 gain[3] = micron1_gain[sd->gain] >> 8;
1652 gain[4] = micron1_gain[sd->gain] & 0xff;
1654 case SENSOR_MT9M001:
1655 gain[0] |= (3 << 4);
1657 gain[3] = micron2_gain[sd->gain] >> 8;
1658 gain[4] = micron2_gain[sd->gain] & 0xff;
1660 case SENSOR_HV7131R:
1661 gain[0] |= (2 << 4);
1663 gain[3] = hv7131r_gain[sd->gain];
1668 i2c_w(gspca_dev, gain);
1672 static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val)
1674 struct sd *sd = (struct sd *) gspca_dev;
1676 sd->brightness = val;
1677 if (gspca_dev->streaming)
1678 return set_cmatrix(gspca_dev);
1682 static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val)
1684 struct sd *sd = (struct sd *) gspca_dev;
1685 *val = sd->brightness;
1690 static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val)
1692 struct sd *sd = (struct sd *) gspca_dev;
1695 if (gspca_dev->streaming)
1696 return set_cmatrix(gspca_dev);
1700 static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val)
1702 struct sd *sd = (struct sd *) gspca_dev;
1703 *val = sd->contrast;
1707 static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val)
1709 struct sd *sd = (struct sd *) gspca_dev;
1711 sd->saturation = val;
1712 if (gspca_dev->streaming)
1713 return set_cmatrix(gspca_dev);
1717 static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val)
1719 struct sd *sd = (struct sd *) gspca_dev;
1720 *val = sd->saturation;
1724 static int sd_sethue(struct gspca_dev *gspca_dev, s32 val)
1726 struct sd *sd = (struct sd *) gspca_dev;
1729 if (gspca_dev->streaming)
1730 return set_cmatrix(gspca_dev);
1734 static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val)
1736 struct sd *sd = (struct sd *) gspca_dev;
1741 static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val)
1743 struct sd *sd = (struct sd *) gspca_dev;
1746 if (gspca_dev->streaming)
1747 return set_gamma(gspca_dev);
1751 static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val)
1753 struct sd *sd = (struct sd *) gspca_dev;
1758 static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val)
1760 struct sd *sd = (struct sd *) gspca_dev;
1763 if (gspca_dev->streaming)
1764 return set_redblue(gspca_dev);
1768 static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val)
1770 struct sd *sd = (struct sd *) gspca_dev;
1775 static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val)
1777 struct sd *sd = (struct sd *) gspca_dev;
1780 if (gspca_dev->streaming)
1781 return set_redblue(gspca_dev);
1785 static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val)
1787 struct sd *sd = (struct sd *) gspca_dev;
1792 static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val)
1794 struct sd *sd = (struct sd *) gspca_dev;
1797 if (gspca_dev->streaming)
1798 return set_hvflip(gspca_dev);
1802 static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val)
1804 struct sd *sd = (struct sd *) gspca_dev;
1809 static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val)
1811 struct sd *sd = (struct sd *) gspca_dev;
1814 if (gspca_dev->streaming)
1815 return set_hvflip(gspca_dev);
1819 static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val)
1821 struct sd *sd = (struct sd *) gspca_dev;
1826 static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val)
1828 struct sd *sd = (struct sd *) gspca_dev;
1831 if (gspca_dev->streaming)
1832 return set_exposure(gspca_dev);
1836 static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val)
1838 struct sd *sd = (struct sd *) gspca_dev;
1839 *val = sd->exposure;
1843 static int sd_setgain(struct gspca_dev *gspca_dev, s32 val)
1845 struct sd *sd = (struct sd *) gspca_dev;
1848 if (gspca_dev->streaming)
1849 return set_gain(gspca_dev);
1853 static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val)
1855 struct sd *sd = (struct sd *) gspca_dev;
1860 static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val)
1862 struct sd *sd = (struct sd *) gspca_dev;
1863 sd->auto_exposure = val;
1867 static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val)
1869 struct sd *sd = (struct sd *) gspca_dev;
1870 *val = sd->auto_exposure;
1874 #ifdef CONFIG_VIDEO_ADV_DEBUG
1875 static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1876 struct v4l2_dbg_register *reg)
1878 struct sd *sd = (struct sd *) gspca_dev;
1879 switch (reg->match.type) {
1880 case V4L2_CHIP_MATCH_HOST:
1881 if (reg->match.addr != 0)
1883 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1885 if (reg_r(gspca_dev, reg->reg, 1) < 0)
1887 reg->val = gspca_dev->usb_buf[0];
1889 case V4L2_CHIP_MATCH_I2C_ADDR:
1890 if (reg->match.addr != sd->i2c_addr)
1892 if (sd->sensor >= SENSOR_MT9V011 &&
1893 sd->sensor <= SENSOR_MT9M112) {
1894 if (i2c_r2(gspca_dev, reg->reg, (u16 *)®->val) < 0)
1897 if (i2c_r1(gspca_dev, reg->reg, (u8 *)®->val) < 0)
1905 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1906 struct v4l2_dbg_register *reg)
1908 struct sd *sd = (struct sd *) gspca_dev;
1909 switch (reg->match.type) {
1910 case V4L2_CHIP_MATCH_HOST:
1911 if (reg->match.addr != 0)
1913 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1915 if (reg_w1(gspca_dev, reg->reg, reg->val) < 0)
1918 case V4L2_CHIP_MATCH_I2C_ADDR:
1919 if (reg->match.addr != sd->i2c_addr)
1921 if (sd->sensor >= SENSOR_MT9V011 &&
1922 sd->sensor <= SENSOR_MT9M112) {
1923 if (i2c_w2(gspca_dev, reg->reg, reg->val) < 0)
1926 if (i2c_w1(gspca_dev, reg->reg, reg->val) < 0)
1935 static int sd_chip_ident(struct gspca_dev *gspca_dev,
1936 struct v4l2_dbg_chip_ident *chip)
1938 struct sd *sd = (struct sd *) gspca_dev;
1940 switch (chip->match.type) {
1941 case V4L2_CHIP_MATCH_HOST:
1942 if (chip->match.addr != 0)
1945 chip->ident = V4L2_IDENT_SN9C20X;
1947 case V4L2_CHIP_MATCH_I2C_ADDR:
1948 if (chip->match.addr != sd->i2c_addr)
1951 chip->ident = i2c_ident[sd->sensor];
1957 static int sd_config(struct gspca_dev *gspca_dev,
1958 const struct usb_device_id *id)
1960 struct sd *sd = (struct sd *) gspca_dev;
1963 cam = &gspca_dev->cam;
1965 sd->sensor = (id->driver_info >> 8) & 0xff;
1966 sd->i2c_addr = id->driver_info & 0xff;
1967 sd->flags = (id->driver_info >> 16) & 0xff;
1969 switch (sd->sensor) {
1970 case SENSOR_MT9M112:
1971 case SENSOR_MT9M111:
1974 cam->cam_mode = sxga_mode;
1975 cam->nmodes = ARRAY_SIZE(sxga_mode);
1978 cam->cam_mode = vga_mode;
1979 cam->nmodes = ARRAY_SIZE(vga_mode);
1985 sd->exposure_step = 16;
1987 sd->brightness = BRIGHTNESS_DEFAULT;
1988 sd->contrast = CONTRAST_DEFAULT;
1989 sd->saturation = SATURATION_DEFAULT;
1990 sd->hue = HUE_DEFAULT;
1991 sd->gamma = GAMMA_DEFAULT;
1992 sd->red = RED_DEFAULT;
1993 sd->blue = BLUE_DEFAULT;
1995 sd->hflip = HFLIP_DEFAULT;
1996 sd->vflip = VFLIP_DEFAULT;
1997 sd->exposure = EXPOSURE_DEFAULT;
1998 sd->gain = GAIN_DEFAULT;
1999 sd->auto_exposure = AUTO_EXPOSURE_DEFAULT;
2006 static int sd_init(struct gspca_dev *gspca_dev)
2008 struct sd *sd = (struct sd *) gspca_dev;
2012 {0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
2014 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
2015 value = bridge_init[i][1];
2016 if (reg_w(gspca_dev, bridge_init[i][0], &value, 1) < 0) {
2017 err("Device initialization failed");
2022 if (sd->flags & LED_REVERSE)
2023 reg_w1(gspca_dev, 0x1006, 0x00);
2025 reg_w1(gspca_dev, 0x1006, 0x20);
2027 if (reg_w(gspca_dev, 0x10c0, i2c_init, 9) < 0) {
2028 err("Device initialization failed");
2032 switch (sd->sensor) {
2034 if (ov9650_init_sensor(gspca_dev) < 0)
2036 info("OV9650 sensor detected");
2039 if (ov9655_init_sensor(gspca_dev) < 0)
2041 info("OV9655 sensor detected");
2044 if (soi968_init_sensor(gspca_dev) < 0)
2046 info("SOI968 sensor detected");
2049 if (ov7660_init_sensor(gspca_dev) < 0)
2051 info("OV7660 sensor detected");
2054 if (ov7670_init_sensor(gspca_dev) < 0)
2056 info("OV7670 sensor detected");
2058 case SENSOR_MT9VPRB:
2059 if (mt9v_init_sensor(gspca_dev) < 0)
2062 case SENSOR_MT9M111:
2063 if (mt9m111_init_sensor(gspca_dev) < 0)
2065 info("MT9M111 sensor detected");
2067 case SENSOR_MT9M112:
2068 if (mt9m112_init_sensor(gspca_dev) < 0)
2070 info("MT9M112 sensor detected");
2072 case SENSOR_MT9M001:
2073 if (mt9m001_init_sensor(gspca_dev) < 0)
2075 info("MT9M001 sensor detected");
2077 case SENSOR_HV7131R:
2078 if (hv7131r_init_sensor(gspca_dev) < 0)
2080 info("HV7131R sensor detected");
2083 info("Unsupported Sensor");
2090 static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
2092 struct sd *sd = (struct sd *) gspca_dev;
2094 switch (sd->sensor) {
2096 if (mode & MODE_SXGA) {
2097 i2c_w1(gspca_dev, 0x17, 0x1d);
2098 i2c_w1(gspca_dev, 0x18, 0xbd);
2099 i2c_w1(gspca_dev, 0x19, 0x01);
2100 i2c_w1(gspca_dev, 0x1a, 0x81);
2101 i2c_w1(gspca_dev, 0x12, 0x00);
2105 i2c_w1(gspca_dev, 0x17, 0x13);
2106 i2c_w1(gspca_dev, 0x18, 0x63);
2107 i2c_w1(gspca_dev, 0x19, 0x01);
2108 i2c_w1(gspca_dev, 0x1a, 0x79);
2109 i2c_w1(gspca_dev, 0x12, 0x40);
2115 if (mode & MODE_SXGA) {
2116 i2c_w1(gspca_dev, 0x17, 0x1b);
2117 i2c_w1(gspca_dev, 0x18, 0xbc);
2118 i2c_w1(gspca_dev, 0x19, 0x01);
2119 i2c_w1(gspca_dev, 0x1a, 0x82);
2120 i2c_r1(gspca_dev, 0x12, &value);
2121 i2c_w1(gspca_dev, 0x12, value & 0x07);
2123 i2c_w1(gspca_dev, 0x17, 0x24);
2124 i2c_w1(gspca_dev, 0x18, 0xc5);
2125 i2c_w1(gspca_dev, 0x19, 0x00);
2126 i2c_w1(gspca_dev, 0x1a, 0x3c);
2127 i2c_r1(gspca_dev, 0x12, &value);
2128 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
2131 case SENSOR_MT9M112:
2132 case SENSOR_MT9M111:
2133 if (mode & MODE_SXGA) {
2134 i2c_w2(gspca_dev, 0xf0, 0x0002);
2135 i2c_w2(gspca_dev, 0xc8, 0x970b);
2136 i2c_w2(gspca_dev, 0xf0, 0x0000);
2138 i2c_w2(gspca_dev, 0xf0, 0x0002);
2139 i2c_w2(gspca_dev, 0xc8, 0x8000);
2140 i2c_w2(gspca_dev, 0xf0, 0x0000);
2146 #define HW_WIN(mode, hstart, vstart) \
2147 ((const u8 []){hstart, 0, vstart, 0, \
2148 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
2149 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
2151 #define CLR_WIN(width, height) \
2153 {0, width >> 2, 0, height >> 1,\
2154 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
2156 static int sd_start(struct gspca_dev *gspca_dev)
2158 struct sd *sd = (struct sd *) gspca_dev;
2159 int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
2160 int width = gspca_dev->width;
2161 int height = gspca_dev->height;
2164 jpeg_define(sd->jpeg_hdr, height, width,
2166 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2168 if (mode & MODE_RAW)
2170 else if (mode & MODE_JPEG)
2175 switch (mode & 0x0f) {
2178 info("Set 1280x1024");
2182 info("Set 640x480");
2186 info("Set 320x240");
2190 info("Set 160x120");
2194 configure_sensor_output(gspca_dev, mode);
2195 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2196 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2197 reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2198 reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2199 reg_w1(gspca_dev, 0x1189, scale);
2200 reg_w1(gspca_dev, 0x10e0, fmt);
2202 set_cmatrix(gspca_dev);
2203 set_gamma(gspca_dev);
2204 set_redblue(gspca_dev);
2205 set_gain(gspca_dev);
2206 set_exposure(gspca_dev);
2207 set_hvflip(gspca_dev);
2209 reg_w1(gspca_dev, 0x1007, 0x20);
2211 reg_r(gspca_dev, 0x1061, 1);
2212 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] | 0x02);
2216 static void sd_stopN(struct gspca_dev *gspca_dev)
2218 reg_w1(gspca_dev, 0x1007, 0x00);
2220 reg_r(gspca_dev, 0x1061, 1);
2221 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] & ~0x02);
2224 static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2226 struct sd *sd = (struct sd *) gspca_dev;
2230 * some hardcoded values are present
2231 * like those for maximal/minimal exposure
2232 * and exposure steps
2234 if (avg_lum < MIN_AVG_LUM) {
2235 if (sd->exposure > 0x1770)
2238 new_exp = sd->exposure + sd->exposure_step;
2239 if (new_exp > 0x1770)
2243 sd->exposure = new_exp;
2244 set_exposure(gspca_dev);
2246 sd->older_step = sd->old_step;
2249 if (sd->old_step ^ sd->older_step)
2250 sd->exposure_step /= 2;
2252 sd->exposure_step += 2;
2254 if (avg_lum > MAX_AVG_LUM) {
2255 if (sd->exposure < 0x10)
2257 new_exp = sd->exposure - sd->exposure_step;
2258 if (new_exp > 0x1700)
2262 sd->exposure = new_exp;
2263 set_exposure(gspca_dev);
2264 sd->older_step = sd->old_step;
2267 if (sd->old_step ^ sd->older_step)
2268 sd->exposure_step /= 2;
2270 sd->exposure_step += 2;
2274 static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2276 struct sd *sd = (struct sd *) gspca_dev;
2278 if (avg_lum < MIN_AVG_LUM) {
2279 if (sd->gain + 1 <= 28) {
2281 set_gain(gspca_dev);
2284 if (avg_lum > MAX_AVG_LUM) {
2287 set_gain(gspca_dev);
2292 static void sd_dqcallback(struct gspca_dev *gspca_dev)
2294 struct sd *sd = (struct sd *) gspca_dev;
2297 if (!sd->auto_exposure)
2300 avg_lum = atomic_read(&sd->avg_lum);
2301 if (sd->sensor == SENSOR_SOI968)
2302 do_autogain(gspca_dev, avg_lum);
2304 do_autoexposure(gspca_dev, avg_lum);
2308 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2309 u8 *data, /* interrupt packet */
2310 int len) /* interrupt packet length */
2312 struct sd *sd = (struct sd *) gspca_dev;
2314 if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
2315 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2316 input_sync(gspca_dev->input_dev);
2317 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2318 input_sync(gspca_dev->input_dev);
2325 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2326 u8 *data, /* isoc packet */
2327 int len) /* iso packet length */
2329 struct sd *sd = (struct sd *) gspca_dev;
2331 static u8 frame_header[] =
2332 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2333 if (len == 64 && memcmp(data, frame_header, 6) == 0) {
2334 avg_lum = ((data[35] >> 2) & 3) |
2337 avg_lum += ((data[35] >> 4) & 3) |
2340 avg_lum += ((data[35] >> 6) & 3) |
2343 avg_lum += (data[36] & 3) |
2346 avg_lum += ((data[36] >> 2) & 3) |
2349 avg_lum += ((data[36] >> 4) & 3) |
2352 avg_lum += ((data[36] >> 6) & 3) |
2355 avg_lum += ((data[44] >> 4) & 3) |
2359 atomic_set(&sd->avg_lum, avg_lum);
2360 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2363 if (gspca_dev->last_packet_type == LAST_PACKET) {
2364 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv
2366 gspca_frame_add(gspca_dev, FIRST_PACKET,
2367 sd->jpeg_hdr, JPEG_HDR_SZ);
2368 gspca_frame_add(gspca_dev, INTER_PACKET,
2371 gspca_frame_add(gspca_dev, FIRST_PACKET,
2375 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2379 /* sub-driver description */
2380 static const struct sd_desc sd_desc = {
2381 .name = MODULE_NAME,
2383 .nctrls = ARRAY_SIZE(sd_ctrls),
2384 .config = sd_config,
2388 .pkt_scan = sd_pkt_scan,
2390 .int_pkt_scan = sd_int_pkt_scan,
2392 .dq_callback = sd_dqcallback,
2393 #ifdef CONFIG_VIDEO_ADV_DEBUG
2394 .set_register = sd_dbg_s_register,
2395 .get_register = sd_dbg_g_register,
2397 .get_chip_ident = sd_chip_ident,
2400 #define SN9C20X(sensor, i2c_addr, flags) \
2401 .driver_info = ((flags & 0xff) << 16) \
2402 | (SENSOR_ ## sensor << 8) \
2405 static const __devinitdata struct usb_device_id device_table[] = {
2406 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2407 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
2408 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2409 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
2410 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
2411 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
2412 (FLIP_DETECT | HAS_NO_BUTTON))},
2413 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2414 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2415 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2416 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2417 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, 0)},
2418 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2419 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2420 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2421 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2422 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
2423 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
2424 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2425 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2426 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2427 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2428 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, 0)},
2429 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, 0)},
2430 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2431 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2432 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2433 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2434 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
2435 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
2436 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2437 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2438 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2439 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2440 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
2441 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2442 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2445 MODULE_DEVICE_TABLE(usb, device_table);
2447 /* -- device connect -- */
2448 static int sd_probe(struct usb_interface *intf,
2449 const struct usb_device_id *id)
2451 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2455 static struct usb_driver sd_driver = {
2456 .name = MODULE_NAME,
2457 .id_table = device_table,
2459 .disconnect = gspca_disconnect,
2461 .suspend = gspca_suspend,
2462 .resume = gspca_resume,
2463 .reset_resume = gspca_resume,
2467 /* -- module insert / remove -- */
2468 static int __init sd_mod_init(void)
2471 ret = usb_register(&sd_driver);
2477 static void __exit sd_mod_exit(void)
2479 usb_deregister(&sd_driver);
2480 info("deregistered");
2483 module_init(sd_mod_init);
2484 module_exit(sd_mod_exit);