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>
23 #include <linux/slab.h>
29 #include <media/v4l2-chip-ident.h>
30 #include <linux/dmi.h>
32 MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, "
33 "microdia project <microdia@googlegroups.com>");
34 MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
35 MODULE_LICENSE("GPL");
37 #define MODULE_NAME "sn9c20x"
40 #define MODE_JPEG 0x20
41 #define MODE_SXGA 0x80
43 #define SENSOR_OV9650 0
44 #define SENSOR_OV9655 1
45 #define SENSOR_SOI968 2
46 #define SENSOR_OV7660 3
47 #define SENSOR_OV7670 4
48 #define SENSOR_MT9V011 5
49 #define SENSOR_MT9V111 6
50 #define SENSOR_MT9V112 7
51 #define SENSOR_MT9M001 8
52 #define SENSOR_MT9M111 9
53 #define SENSOR_MT9M112 10
54 #define SENSOR_HV7131R 11
55 #define SENSOR_MT9VPRB 20
58 #define HAS_NO_BUTTON 0x1
59 #define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
60 #define FLIP_DETECT 0x4
62 /* specific webcam descriptor */
64 struct gspca_dev gspca_dev;
66 #define MIN_AVG_LUM 80
67 #define MAX_AVG_LUM 130
108 static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val);
109 static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val);
110 static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val);
111 static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val);
112 static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val);
113 static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val);
114 static int sd_sethue(struct gspca_dev *gspca_dev, s32 val);
115 static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val);
116 static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val);
117 static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val);
118 static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val);
119 static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val);
120 static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val);
121 static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val);
122 static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val);
123 static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val);
124 static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val);
125 static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val);
126 static int sd_setgain(struct gspca_dev *gspca_dev, s32 val);
127 static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val);
128 static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val);
129 static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val);
130 static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val);
131 static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val);
133 static const struct dmi_system_id flip_dmi_table[] = {
135 .ident = "MSI MS-1034",
137 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
138 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1034"),
139 DMI_MATCH(DMI_PRODUCT_VERSION, "0341")
143 .ident = "MSI MS-1632",
145 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
146 DMI_MATCH(DMI_BOARD_NAME, "MS-1632")
150 .ident = "MSI MS-1635X",
152 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
153 DMI_MATCH(DMI_BOARD_NAME, "MS-1635X")
157 .ident = "ASUSTeK W7J",
159 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
160 DMI_MATCH(DMI_BOARD_NAME, "W7J ")
166 static const struct ctrl sd_ctrls[] = {
168 #define BRIGHTNESS_IDX 0
170 .id = V4L2_CID_BRIGHTNESS,
171 .type = V4L2_CTRL_TYPE_INTEGER,
172 .name = "Brightness",
176 #define BRIGHTNESS_DEFAULT 0x7f
177 .default_value = BRIGHTNESS_DEFAULT,
179 .set = sd_setbrightness,
180 .get = sd_getbrightness,
183 #define CONTRAST_IDX 1
185 .id = V4L2_CID_CONTRAST,
186 .type = V4L2_CTRL_TYPE_INTEGER,
191 #define CONTRAST_DEFAULT 0x7f
192 .default_value = CONTRAST_DEFAULT,
194 .set = sd_setcontrast,
195 .get = sd_getcontrast,
198 #define SATURATION_IDX 2
200 .id = V4L2_CID_SATURATION,
201 .type = V4L2_CTRL_TYPE_INTEGER,
202 .name = "Saturation",
206 #define SATURATION_DEFAULT 0x7f
207 .default_value = SATURATION_DEFAULT,
209 .set = sd_setsaturation,
210 .get = sd_getsaturation,
216 .type = V4L2_CTRL_TYPE_INTEGER,
221 #define HUE_DEFAULT 0
222 .default_value = HUE_DEFAULT,
230 .id = V4L2_CID_GAMMA,
231 .type = V4L2_CTRL_TYPE_INTEGER,
236 #define GAMMA_DEFAULT 0x10
237 .default_value = GAMMA_DEFAULT,
245 .id = V4L2_CID_BLUE_BALANCE,
246 .type = V4L2_CTRL_TYPE_INTEGER,
247 .name = "Blue Balance",
251 #define BLUE_DEFAULT 0x28
252 .default_value = BLUE_DEFAULT,
254 .set = sd_setbluebalance,
255 .get = sd_getbluebalance,
260 .id = V4L2_CID_RED_BALANCE,
261 .type = V4L2_CTRL_TYPE_INTEGER,
262 .name = "Red Balance",
266 #define RED_DEFAULT 0x28
267 .default_value = RED_DEFAULT,
269 .set = sd_setredbalance,
270 .get = sd_getredbalance,
275 .id = V4L2_CID_HFLIP,
276 .type = V4L2_CTRL_TYPE_BOOLEAN,
277 .name = "Horizontal Flip",
281 #define HFLIP_DEFAULT 0
282 .default_value = HFLIP_DEFAULT,
290 .id = V4L2_CID_VFLIP,
291 .type = V4L2_CTRL_TYPE_BOOLEAN,
292 .name = "Vertical Flip",
296 #define VFLIP_DEFAULT 0
297 .default_value = VFLIP_DEFAULT,
303 #define EXPOSURE_IDX 9
305 .id = V4L2_CID_EXPOSURE,
306 .type = V4L2_CTRL_TYPE_INTEGER,
311 #define EXPOSURE_DEFAULT 0x33
312 .default_value = EXPOSURE_DEFAULT,
314 .set = sd_setexposure,
315 .get = sd_getexposure,
321 .type = V4L2_CTRL_TYPE_INTEGER,
326 #define GAIN_DEFAULT 0x00
327 .default_value = GAIN_DEFAULT,
333 #define AUTOGAIN_IDX 11
335 .id = V4L2_CID_AUTOGAIN,
336 .type = V4L2_CTRL_TYPE_BOOLEAN,
337 .name = "Auto Exposure",
341 #define AUTO_EXPOSURE_DEFAULT 1
342 .default_value = AUTO_EXPOSURE_DEFAULT,
344 .set = sd_setautoexposure,
345 .get = sd_getautoexposure,
349 static const struct v4l2_pix_format vga_mode[] = {
350 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
352 .sizeimage = 240 * 120,
353 .colorspace = V4L2_COLORSPACE_JPEG,
354 .priv = 0 | MODE_JPEG},
355 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
357 .sizeimage = 160 * 120,
358 .colorspace = V4L2_COLORSPACE_SRGB,
359 .priv = 0 | MODE_RAW},
360 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
362 .sizeimage = 240 * 120,
363 .colorspace = V4L2_COLORSPACE_SRGB,
365 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
367 .sizeimage = 480 * 240 ,
368 .colorspace = V4L2_COLORSPACE_JPEG,
369 .priv = 1 | MODE_JPEG},
370 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
372 .sizeimage = 320 * 240 ,
373 .colorspace = V4L2_COLORSPACE_SRGB,
374 .priv = 1 | MODE_RAW},
375 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
377 .sizeimage = 480 * 240 ,
378 .colorspace = V4L2_COLORSPACE_SRGB,
380 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
382 .sizeimage = 960 * 480,
383 .colorspace = V4L2_COLORSPACE_JPEG,
384 .priv = 2 | MODE_JPEG},
385 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
387 .sizeimage = 640 * 480,
388 .colorspace = V4L2_COLORSPACE_SRGB,
389 .priv = 2 | MODE_RAW},
390 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
392 .sizeimage = 960 * 480,
393 .colorspace = V4L2_COLORSPACE_SRGB,
397 static const struct v4l2_pix_format sxga_mode[] = {
398 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
400 .sizeimage = 240 * 120,
401 .colorspace = V4L2_COLORSPACE_JPEG,
402 .priv = 0 | MODE_JPEG},
403 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
405 .sizeimage = 160 * 120,
406 .colorspace = V4L2_COLORSPACE_SRGB,
407 .priv = 0 | MODE_RAW},
408 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
410 .sizeimage = 240 * 120,
411 .colorspace = V4L2_COLORSPACE_SRGB,
413 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
415 .sizeimage = 480 * 240 ,
416 .colorspace = V4L2_COLORSPACE_JPEG,
417 .priv = 1 | MODE_JPEG},
418 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
420 .sizeimage = 320 * 240 ,
421 .colorspace = V4L2_COLORSPACE_SRGB,
422 .priv = 1 | MODE_RAW},
423 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
425 .sizeimage = 480 * 240 ,
426 .colorspace = V4L2_COLORSPACE_SRGB,
428 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
430 .sizeimage = 960 * 480,
431 .colorspace = V4L2_COLORSPACE_JPEG,
432 .priv = 2 | MODE_JPEG},
433 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
435 .sizeimage = 640 * 480,
436 .colorspace = V4L2_COLORSPACE_SRGB,
437 .priv = 2 | MODE_RAW},
438 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
440 .sizeimage = 960 * 480,
441 .colorspace = V4L2_COLORSPACE_SRGB,
443 {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
444 .bytesperline = 1280,
445 .sizeimage = (1280 * 1024) + 64,
446 .colorspace = V4L2_COLORSPACE_SRGB,
447 .priv = 3 | MODE_RAW | MODE_SXGA},
450 static const s16 hsv_red_x[] = {
451 41, 44, 46, 48, 50, 52, 54, 56,
452 58, 60, 62, 64, 66, 68, 70, 72,
453 74, 76, 78, 80, 81, 83, 85, 87,
454 88, 90, 92, 93, 95, 97, 98, 100,
455 101, 102, 104, 105, 107, 108, 109, 110,
456 112, 113, 114, 115, 116, 117, 118, 119,
457 120, 121, 122, 123, 123, 124, 125, 125,
458 126, 127, 127, 128, 128, 129, 129, 129,
459 130, 130, 130, 130, 131, 131, 131, 131,
460 131, 131, 131, 131, 130, 130, 130, 130,
461 129, 129, 129, 128, 128, 127, 127, 126,
462 125, 125, 124, 123, 122, 122, 121, 120,
463 119, 118, 117, 116, 115, 114, 112, 111,
464 110, 109, 107, 106, 105, 103, 102, 101,
465 99, 98, 96, 94, 93, 91, 90, 88,
466 86, 84, 83, 81, 79, 77, 75, 74,
467 72, 70, 68, 66, 64, 62, 60, 58,
468 56, 54, 52, 49, 47, 45, 43, 41,
469 39, 36, 34, 32, 30, 28, 25, 23,
470 21, 19, 16, 14, 12, 9, 7, 5,
471 3, 0, -1, -3, -6, -8, -10, -12,
472 -15, -17, -19, -22, -24, -26, -28, -30,
473 -33, -35, -37, -39, -41, -44, -46, -48,
474 -50, -52, -54, -56, -58, -60, -62, -64,
475 -66, -68, -70, -72, -74, -76, -78, -80,
476 -81, -83, -85, -87, -88, -90, -92, -93,
477 -95, -97, -98, -100, -101, -102, -104, -105,
478 -107, -108, -109, -110, -112, -113, -114, -115,
479 -116, -117, -118, -119, -120, -121, -122, -123,
480 -123, -124, -125, -125, -126, -127, -127, -128,
481 -128, -128, -128, -128, -128, -128, -128, -128,
482 -128, -128, -128, -128, -128, -128, -128, -128,
483 -128, -128, -128, -128, -128, -128, -128, -128,
484 -128, -127, -127, -126, -125, -125, -124, -123,
485 -122, -122, -121, -120, -119, -118, -117, -116,
486 -115, -114, -112, -111, -110, -109, -107, -106,
487 -105, -103, -102, -101, -99, -98, -96, -94,
488 -93, -91, -90, -88, -86, -84, -83, -81,
489 -79, -77, -75, -74, -72, -70, -68, -66,
490 -64, -62, -60, -58, -56, -54, -52, -49,
491 -47, -45, -43, -41, -39, -36, -34, -32,
492 -30, -28, -25, -23, -21, -19, -16, -14,
493 -12, -9, -7, -5, -3, 0, 1, 3,
494 6, 8, 10, 12, 15, 17, 19, 22,
495 24, 26, 28, 30, 33, 35, 37, 39, 41
498 static const s16 hsv_red_y[] = {
499 82, 80, 78, 76, 74, 73, 71, 69,
500 67, 65, 63, 61, 58, 56, 54, 52,
501 50, 48, 46, 44, 41, 39, 37, 35,
502 32, 30, 28, 26, 23, 21, 19, 16,
503 14, 12, 10, 7, 5, 3, 0, -1,
504 -3, -6, -8, -10, -13, -15, -17, -19,
505 -22, -24, -26, -29, -31, -33, -35, -38,
506 -40, -42, -44, -46, -48, -51, -53, -55,
507 -57, -59, -61, -63, -65, -67, -69, -71,
508 -73, -75, -77, -79, -81, -82, -84, -86,
509 -88, -89, -91, -93, -94, -96, -98, -99,
510 -101, -102, -104, -105, -106, -108, -109, -110,
511 -112, -113, -114, -115, -116, -117, -119, -120,
512 -120, -121, -122, -123, -124, -125, -126, -126,
513 -127, -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 -128, -128, -128, -128, -128, -128, -128, -128,
517 -127, -127, -126, -125, -125, -124, -123, -122,
518 -121, -120, -119, -118, -117, -116, -115, -114,
519 -113, -111, -110, -109, -107, -106, -105, -103,
520 -102, -100, -99, -97, -96, -94, -92, -91,
521 -89, -87, -85, -84, -82, -80, -78, -76,
522 -74, -73, -71, -69, -67, -65, -63, -61,
523 -58, -56, -54, -52, -50, -48, -46, -44,
524 -41, -39, -37, -35, -32, -30, -28, -26,
525 -23, -21, -19, -16, -14, -12, -10, -7,
526 -5, -3, 0, 1, 3, 6, 8, 10,
527 13, 15, 17, 19, 22, 24, 26, 29,
528 31, 33, 35, 38, 40, 42, 44, 46,
529 48, 51, 53, 55, 57, 59, 61, 63,
530 65, 67, 69, 71, 73, 75, 77, 79,
531 81, 82, 84, 86, 88, 89, 91, 93,
532 94, 96, 98, 99, 101, 102, 104, 105,
533 106, 108, 109, 110, 112, 113, 114, 115,
534 116, 117, 119, 120, 120, 121, 122, 123,
535 124, 125, 126, 126, 127, 128, 128, 129,
536 129, 130, 130, 131, 131, 131, 131, 132,
537 132, 132, 132, 132, 132, 132, 132, 132,
538 132, 132, 132, 131, 131, 131, 130, 130,
539 130, 129, 129, 128, 127, 127, 126, 125,
540 125, 124, 123, 122, 121, 120, 119, 118,
541 117, 116, 115, 114, 113, 111, 110, 109,
542 107, 106, 105, 103, 102, 100, 99, 97,
543 96, 94, 92, 91, 89, 87, 85, 84, 82
546 static const s16 hsv_green_x[] = {
547 -124, -124, -125, -125, -125, -125, -125, -125,
548 -125, -126, -126, -125, -125, -125, -125, -125,
549 -125, -124, -124, -124, -123, -123, -122, -122,
550 -121, -121, -120, -120, -119, -118, -117, -117,
551 -116, -115, -114, -113, -112, -111, -110, -109,
552 -108, -107, -105, -104, -103, -102, -100, -99,
553 -98, -96, -95, -93, -92, -91, -89, -87,
554 -86, -84, -83, -81, -79, -77, -76, -74,
555 -72, -70, -69, -67, -65, -63, -61, -59,
556 -57, -55, -53, -51, -49, -47, -45, -43,
557 -41, -39, -37, -35, -33, -30, -28, -26,
558 -24, -22, -20, -18, -15, -13, -11, -9,
559 -7, -4, -2, 0, 1, 3, 6, 8,
560 10, 12, 14, 17, 19, 21, 23, 25,
561 27, 29, 32, 34, 36, 38, 40, 42,
562 44, 46, 48, 50, 52, 54, 56, 58,
563 60, 62, 64, 66, 68, 70, 71, 73,
564 75, 77, 78, 80, 82, 83, 85, 87,
565 88, 90, 91, 93, 94, 96, 97, 98,
566 100, 101, 102, 104, 105, 106, 107, 108,
567 109, 111, 112, 113, 113, 114, 115, 116,
568 117, 118, 118, 119, 120, 120, 121, 122,
569 122, 123, 123, 124, 124, 124, 125, 125,
570 125, 125, 125, 125, 125, 126, 126, 125,
571 125, 125, 125, 125, 125, 124, 124, 124,
572 123, 123, 122, 122, 121, 121, 120, 120,
573 119, 118, 117, 117, 116, 115, 114, 113,
574 112, 111, 110, 109, 108, 107, 105, 104,
575 103, 102, 100, 99, 98, 96, 95, 93,
576 92, 91, 89, 87, 86, 84, 83, 81,
577 79, 77, 76, 74, 72, 70, 69, 67,
578 65, 63, 61, 59, 57, 55, 53, 51,
579 49, 47, 45, 43, 41, 39, 37, 35,
580 33, 30, 28, 26, 24, 22, 20, 18,
581 15, 13, 11, 9, 7, 4, 2, 0,
582 -1, -3, -6, -8, -10, -12, -14, -17,
583 -19, -21, -23, -25, -27, -29, -32, -34,
584 -36, -38, -40, -42, -44, -46, -48, -50,
585 -52, -54, -56, -58, -60, -62, -64, -66,
586 -68, -70, -71, -73, -75, -77, -78, -80,
587 -82, -83, -85, -87, -88, -90, -91, -93,
588 -94, -96, -97, -98, -100, -101, -102, -104,
589 -105, -106, -107, -108, -109, -111, -112, -113,
590 -113, -114, -115, -116, -117, -118, -118, -119,
591 -120, -120, -121, -122, -122, -123, -123, -124, -124
594 static const s16 hsv_green_y[] = {
595 -100, -99, -98, -97, -95, -94, -93, -91,
596 -90, -89, -87, -86, -84, -83, -81, -80,
597 -78, -76, -75, -73, -71, -70, -68, -66,
598 -64, -63, -61, -59, -57, -55, -53, -51,
599 -49, -48, -46, -44, -42, -40, -38, -36,
600 -34, -32, -30, -27, -25, -23, -21, -19,
601 -17, -15, -13, -11, -9, -7, -4, -2,
602 0, 1, 3, 5, 7, 9, 11, 14,
603 16, 18, 20, 22, 24, 26, 28, 30,
604 32, 34, 36, 38, 40, 42, 44, 46,
605 48, 50, 52, 54, 56, 58, 59, 61,
606 63, 65, 67, 68, 70, 72, 74, 75,
607 77, 78, 80, 82, 83, 85, 86, 88,
608 89, 90, 92, 93, 95, 96, 97, 98,
609 100, 101, 102, 103, 104, 105, 106, 107,
610 108, 109, 110, 111, 112, 112, 113, 114,
611 115, 115, 116, 116, 117, 117, 118, 118,
612 119, 119, 119, 120, 120, 120, 120, 120,
613 121, 121, 121, 121, 121, 121, 120, 120,
614 120, 120, 120, 119, 119, 119, 118, 118,
615 117, 117, 116, 116, 115, 114, 114, 113,
616 112, 111, 111, 110, 109, 108, 107, 106,
617 105, 104, 103, 102, 100, 99, 98, 97,
618 95, 94, 93, 91, 90, 89, 87, 86,
619 84, 83, 81, 80, 78, 76, 75, 73,
620 71, 70, 68, 66, 64, 63, 61, 59,
621 57, 55, 53, 51, 49, 48, 46, 44,
622 42, 40, 38, 36, 34, 32, 30, 27,
623 25, 23, 21, 19, 17, 15, 13, 11,
624 9, 7, 4, 2, 0, -1, -3, -5,
625 -7, -9, -11, -14, -16, -18, -20, -22,
626 -24, -26, -28, -30, -32, -34, -36, -38,
627 -40, -42, -44, -46, -48, -50, -52, -54,
628 -56, -58, -59, -61, -63, -65, -67, -68,
629 -70, -72, -74, -75, -77, -78, -80, -82,
630 -83, -85, -86, -88, -89, -90, -92, -93,
631 -95, -96, -97, -98, -100, -101, -102, -103,
632 -104, -105, -106, -107, -108, -109, -110, -111,
633 -112, -112, -113, -114, -115, -115, -116, -116,
634 -117, -117, -118, -118, -119, -119, -119, -120,
635 -120, -120, -120, -120, -121, -121, -121, -121,
636 -121, -121, -120, -120, -120, -120, -120, -119,
637 -119, -119, -118, -118, -117, -117, -116, -116,
638 -115, -114, -114, -113, -112, -111, -111, -110,
639 -109, -108, -107, -106, -105, -104, -103, -102, -100
642 static const s16 hsv_blue_x[] = {
643 112, 113, 114, 114, 115, 116, 117, 117,
644 118, 118, 119, 119, 120, 120, 120, 121,
645 121, 121, 122, 122, 122, 122, 122, 122,
646 122, 122, 122, 122, 122, 122, 121, 121,
647 121, 120, 120, 120, 119, 119, 118, 118,
648 117, 116, 116, 115, 114, 113, 113, 112,
649 111, 110, 109, 108, 107, 106, 105, 104,
650 103, 102, 100, 99, 98, 97, 95, 94,
651 93, 91, 90, 88, 87, 85, 84, 82,
652 80, 79, 77, 76, 74, 72, 70, 69,
653 67, 65, 63, 61, 60, 58, 56, 54,
654 52, 50, 48, 46, 44, 42, 40, 38,
655 36, 34, 32, 30, 28, 26, 24, 22,
656 19, 17, 15, 13, 11, 9, 7, 5,
657 2, 0, -1, -3, -5, -7, -9, -12,
658 -14, -16, -18, -20, -22, -24, -26, -28,
659 -31, -33, -35, -37, -39, -41, -43, -45,
660 -47, -49, -51, -53, -54, -56, -58, -60,
661 -62, -64, -66, -67, -69, -71, -73, -74,
662 -76, -78, -79, -81, -83, -84, -86, -87,
663 -89, -90, -92, -93, -94, -96, -97, -98,
664 -99, -101, -102, -103, -104, -105, -106, -107,
665 -108, -109, -110, -111, -112, -113, -114, -114,
666 -115, -116, -117, -117, -118, -118, -119, -119,
667 -120, -120, -120, -121, -121, -121, -122, -122,
668 -122, -122, -122, -122, -122, -122, -122, -122,
669 -122, -122, -121, -121, -121, -120, -120, -120,
670 -119, -119, -118, -118, -117, -116, -116, -115,
671 -114, -113, -113, -112, -111, -110, -109, -108,
672 -107, -106, -105, -104, -103, -102, -100, -99,
673 -98, -97, -95, -94, -93, -91, -90, -88,
674 -87, -85, -84, -82, -80, -79, -77, -76,
675 -74, -72, -70, -69, -67, -65, -63, -61,
676 -60, -58, -56, -54, -52, -50, -48, -46,
677 -44, -42, -40, -38, -36, -34, -32, -30,
678 -28, -26, -24, -22, -19, -17, -15, -13,
679 -11, -9, -7, -5, -2, 0, 1, 3,
680 5, 7, 9, 12, 14, 16, 18, 20,
681 22, 24, 26, 28, 31, 33, 35, 37,
682 39, 41, 43, 45, 47, 49, 51, 53,
683 54, 56, 58, 60, 62, 64, 66, 67,
684 69, 71, 73, 74, 76, 78, 79, 81,
685 83, 84, 86, 87, 89, 90, 92, 93,
686 94, 96, 97, 98, 99, 101, 102, 103,
687 104, 105, 106, 107, 108, 109, 110, 111, 112
690 static const s16 hsv_blue_y[] = {
691 -11, -13, -15, -17, -19, -21, -23, -25,
692 -27, -29, -31, -33, -35, -37, -39, -41,
693 -43, -45, -46, -48, -50, -52, -54, -55,
694 -57, -59, -61, -62, -64, -66, -67, -69,
695 -71, -72, -74, -75, -77, -78, -80, -81,
696 -83, -84, -86, -87, -88, -90, -91, -92,
697 -93, -95, -96, -97, -98, -99, -100, -101,
698 -102, -103, -104, -105, -106, -106, -107, -108,
699 -109, -109, -110, -111, -111, -112, -112, -113,
700 -113, -114, -114, -114, -115, -115, -115, -115,
701 -116, -116, -116, -116, -116, -116, -116, -116,
702 -116, -115, -115, -115, -115, -114, -114, -114,
703 -113, -113, -112, -112, -111, -111, -110, -110,
704 -109, -108, -108, -107, -106, -105, -104, -103,
705 -102, -101, -100, -99, -98, -97, -96, -95,
706 -94, -93, -91, -90, -89, -88, -86, -85,
707 -84, -82, -81, -79, -78, -76, -75, -73,
708 -71, -70, -68, -67, -65, -63, -62, -60,
709 -58, -56, -55, -53, -51, -49, -47, -45,
710 -44, -42, -40, -38, -36, -34, -32, -30,
711 -28, -26, -24, -22, -20, -18, -16, -14,
712 -12, -10, -8, -6, -4, -2, 0, 1,
713 3, 5, 7, 9, 11, 13, 15, 17,
714 19, 21, 23, 25, 27, 29, 31, 33,
715 35, 37, 39, 41, 43, 45, 46, 48,
716 50, 52, 54, 55, 57, 59, 61, 62,
717 64, 66, 67, 69, 71, 72, 74, 75,
718 77, 78, 80, 81, 83, 84, 86, 87,
719 88, 90, 91, 92, 93, 95, 96, 97,
720 98, 99, 100, 101, 102, 103, 104, 105,
721 106, 106, 107, 108, 109, 109, 110, 111,
722 111, 112, 112, 113, 113, 114, 114, 114,
723 115, 115, 115, 115, 116, 116, 116, 116,
724 116, 116, 116, 116, 116, 115, 115, 115,
725 115, 114, 114, 114, 113, 113, 112, 112,
726 111, 111, 110, 110, 109, 108, 108, 107,
727 106, 105, 104, 103, 102, 101, 100, 99,
728 98, 97, 96, 95, 94, 93, 91, 90,
729 89, 88, 86, 85, 84, 82, 81, 79,
730 78, 76, 75, 73, 71, 70, 68, 67,
731 65, 63, 62, 60, 58, 56, 55, 53,
732 51, 49, 47, 45, 44, 42, 40, 38,
733 36, 34, 32, 30, 28, 26, 24, 22,
734 20, 18, 16, 14, 12, 10, 8, 6,
735 4, 2, 0, -1, -3, -5, -7, -9, -11
738 static u16 i2c_ident[] = {
747 V4L2_IDENT_MT9M001C12ST,
753 static u16 bridge_init[][2] = {
754 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
755 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
756 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
757 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
758 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
759 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
760 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
761 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
762 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
763 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
764 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
765 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
766 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
767 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
768 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
769 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
770 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
771 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
772 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
776 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
777 static u8 ov_gain[] = {
778 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
779 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
780 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
781 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
782 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
783 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
784 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
788 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
789 static u16 micron1_gain[] = {
790 /* 1x 1.25x 1.5x 1.75x */
791 0x0020, 0x0028, 0x0030, 0x0038,
792 /* 2x 2.25x 2.5x 2.75x */
793 0x00a0, 0x00a4, 0x00a8, 0x00ac,
794 /* 3x 3.25x 3.5x 3.75x */
795 0x00b0, 0x00b4, 0x00b8, 0x00bc,
796 /* 4x 4.25x 4.5x 4.75x */
797 0x00c0, 0x00c4, 0x00c8, 0x00cc,
798 /* 5x 5.25x 5.5x 5.75x */
799 0x00d0, 0x00d4, 0x00d8, 0x00dc,
800 /* 6x 6.25x 6.5x 6.75x */
801 0x00e0, 0x00e4, 0x00e8, 0x00ec,
802 /* 7x 7.25x 7.5x 7.75x */
803 0x00f0, 0x00f4, 0x00f8, 0x00fc,
808 /* mt9m001 sensor uses a different gain formula then other micron sensors */
809 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
810 static u16 micron2_gain[] = {
811 /* 1x 1.25x 1.5x 1.75x */
812 0x0008, 0x000a, 0x000c, 0x000e,
813 /* 2x 2.25x 2.5x 2.75x */
814 0x0010, 0x0012, 0x0014, 0x0016,
815 /* 3x 3.25x 3.5x 3.75x */
816 0x0018, 0x001a, 0x001c, 0x001e,
817 /* 4x 4.25x 4.5x 4.75x */
818 0x0020, 0x0051, 0x0052, 0x0053,
819 /* 5x 5.25x 5.5x 5.75x */
820 0x0054, 0x0055, 0x0056, 0x0057,
821 /* 6x 6.25x 6.5x 6.75x */
822 0x0058, 0x0059, 0x005a, 0x005b,
823 /* 7x 7.25x 7.5x 7.75x */
824 0x005c, 0x005d, 0x005e, 0x005f,
829 /* Gain = .5 + bit[7:0] / 16 */
830 static u8 hv7131r_gain[] = {
831 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
832 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
833 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
834 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
835 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
836 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
837 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
841 static struct i2c_reg_u8 soi968_init[] = {
842 {0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f},
843 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
844 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
845 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
846 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
847 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
848 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
849 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
850 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
851 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
852 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
855 static struct i2c_reg_u8 ov7660_init[] = {
856 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
857 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
858 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
859 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
860 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6},
861 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
864 static struct i2c_reg_u8 ov7670_init[] = {
865 {0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
866 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
867 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
868 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
869 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
870 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
871 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
872 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
873 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
874 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
875 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
876 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
877 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
878 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
879 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
880 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
881 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
882 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
883 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
884 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
885 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
886 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
887 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
888 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
889 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
890 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
891 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
892 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
893 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
894 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
895 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
896 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
897 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
898 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
899 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
900 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
901 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
902 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
903 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
904 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
905 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
906 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
907 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
908 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
909 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
910 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
911 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
912 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
913 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
914 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
915 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
916 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
917 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
921 static struct i2c_reg_u8 ov9650_init[] = {
922 {0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78},
923 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
924 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
925 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
926 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
927 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
928 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
929 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
930 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
931 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
932 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
933 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
934 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
935 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
936 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
937 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
938 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
939 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
940 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
941 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
942 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
943 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
944 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
945 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
946 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
947 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
948 {0xaa, 0x92}, {0xab, 0x0a},
951 static struct i2c_reg_u8 ov9655_init[] = {
952 {0x12, 0x80}, {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
953 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
954 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
955 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
956 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
957 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
958 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
959 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
960 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
961 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
962 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
963 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
964 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
965 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
966 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
967 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
968 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
969 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
970 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
971 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
972 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
973 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
974 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
975 {0x04, 0x03}, {0x00, 0x13},
978 static struct i2c_reg_u16 mt9v112_init[] = {
979 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
980 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
981 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
982 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
983 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
984 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
985 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
986 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
987 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
988 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
989 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
990 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
991 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
992 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
993 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
994 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
997 static struct i2c_reg_u16 mt9v111_init[] = {
998 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
999 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
1000 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
1001 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
1002 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
1003 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
1004 {0x0e, 0x0008}, {0x20, 0x0000}
1007 static struct i2c_reg_u16 mt9v011_init[] = {
1008 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
1009 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
1010 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
1011 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
1012 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
1013 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
1014 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
1015 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
1016 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
1017 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
1018 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
1019 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
1020 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
1021 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
1022 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
1023 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
1024 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
1025 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
1026 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
1027 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
1028 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
1029 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1030 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
1031 {0x06, 0x0029}, {0x05, 0x0009},
1034 static struct i2c_reg_u16 mt9m001_init[] = {
1035 {0x0d, 0x0001}, {0x0d, 0x0000}, {0x01, 0x000e},
1036 {0x02, 0x0014}, {0x03, 0x03c1}, {0x04, 0x0501},
1037 {0x05, 0x0083}, {0x06, 0x0006}, {0x0d, 0x0002},
1038 {0x0a, 0x0000}, {0x0c, 0x0000}, {0x11, 0x0000},
1039 {0x1e, 0x8000}, {0x5f, 0x8904}, {0x60, 0x0000},
1040 {0x61, 0x0000}, {0x62, 0x0498}, {0x63, 0x0000},
1041 {0x64, 0x0000}, {0x20, 0x111d}, {0x06, 0x00f2},
1042 {0x05, 0x0013}, {0x09, 0x10f2}, {0x07, 0x0003},
1043 {0x2b, 0x002a}, {0x2d, 0x002a}, {0x2c, 0x002a},
1044 {0x2e, 0x0029}, {0x07, 0x0002},
1047 static struct i2c_reg_u16 mt9m111_init[] = {
1048 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1049 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1050 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1054 static struct i2c_reg_u16 mt9m112_init[] = {
1055 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1056 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1057 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1061 static struct i2c_reg_u8 hv7131r_init[] = {
1062 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
1063 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
1064 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
1065 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
1066 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
1067 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
1068 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
1069 {0x23, 0x09}, {0x01, 0x08},
1072 static int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
1074 struct usb_device *dev = gspca_dev->dev;
1076 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
1078 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1084 if (unlikely(result < 0 || result != length)) {
1085 err("Read register failed 0x%02X", reg);
1091 static int reg_w(struct gspca_dev *gspca_dev, u16 reg,
1092 const u8 *buffer, int length)
1094 struct usb_device *dev = gspca_dev->dev;
1096 memcpy(gspca_dev->usb_buf, buffer, length);
1097 result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1099 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1105 if (unlikely(result < 0 || result != length)) {
1106 err("Write register failed index 0x%02X", reg);
1112 static int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
1114 u8 data[1] = {value};
1115 return reg_w(gspca_dev, reg, data, 1);
1118 static int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
1121 reg_w(gspca_dev, 0x10c0, buffer, 8);
1122 for (i = 0; i < 5; i++) {
1123 reg_r(gspca_dev, 0x10c0, 1);
1124 if (gspca_dev->usb_buf[0] & 0x04) {
1125 if (gspca_dev->usb_buf[0] & 0x08)
1134 static int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1136 struct sd *sd = (struct sd *) gspca_dev;
1141 * from the point of view of the bridge, the length
1142 * includes the address
1144 row[0] = 0x81 | (2 << 4);
1145 row[1] = sd->i2c_addr;
1153 return i2c_w(gspca_dev, row);
1156 static int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1158 struct sd *sd = (struct sd *) gspca_dev;
1162 * from the point of view of the bridge, the length
1163 * includes the address
1165 row[0] = 0x81 | (3 << 4);
1166 row[1] = sd->i2c_addr;
1168 row[3] = (val >> 8) & 0xff;
1169 row[4] = val & 0xff;
1174 return i2c_w(gspca_dev, row);
1177 static int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1179 struct sd *sd = (struct sd *) gspca_dev;
1182 row[0] = 0x81 | (1 << 4);
1183 row[1] = sd->i2c_addr;
1190 if (i2c_w(gspca_dev, row) < 0)
1192 row[0] = 0x81 | (1 << 4) | 0x02;
1194 if (i2c_w(gspca_dev, row) < 0)
1196 if (reg_r(gspca_dev, 0x10c2, 5) < 0)
1198 *val = gspca_dev->usb_buf[4];
1202 static int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1204 struct sd *sd = (struct sd *) gspca_dev;
1207 row[0] = 0x81 | (1 << 4);
1208 row[1] = sd->i2c_addr;
1215 if (i2c_w(gspca_dev, row) < 0)
1217 row[0] = 0x81 | (2 << 4) | 0x02;
1219 if (i2c_w(gspca_dev, row) < 0)
1221 if (reg_r(gspca_dev, 0x10c2, 5) < 0)
1223 *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1227 static int ov9650_init_sensor(struct gspca_dev *gspca_dev)
1230 struct sd *sd = (struct sd *) gspca_dev;
1232 for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) {
1233 if (i2c_w1(gspca_dev, ov9650_init[i].reg,
1234 ov9650_init[i].val) < 0) {
1235 err("OV9650 sensor initialization failed");
1244 static int ov9655_init_sensor(struct gspca_dev *gspca_dev)
1247 struct sd *sd = (struct sd *) gspca_dev;
1249 for (i = 0; i < ARRAY_SIZE(ov9655_init); i++) {
1250 if (i2c_w1(gspca_dev, ov9655_init[i].reg,
1251 ov9655_init[i].val) < 0) {
1252 err("OV9655 sensor initialization failed");
1256 /* disable hflip and vflip */
1257 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1263 static int soi968_init_sensor(struct gspca_dev *gspca_dev)
1266 struct sd *sd = (struct sd *) gspca_dev;
1268 for (i = 0; i < ARRAY_SIZE(soi968_init); i++) {
1269 if (i2c_w1(gspca_dev, soi968_init[i].reg,
1270 soi968_init[i].val) < 0) {
1271 err("SOI968 sensor initialization failed");
1275 /* disable hflip and vflip */
1276 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << EXPOSURE_IDX);
1282 static int ov7660_init_sensor(struct gspca_dev *gspca_dev)
1285 struct sd *sd = (struct sd *) gspca_dev;
1287 for (i = 0; i < ARRAY_SIZE(ov7660_init); i++) {
1288 if (i2c_w1(gspca_dev, ov7660_init[i].reg,
1289 ov7660_init[i].val) < 0) {
1290 err("OV7660 sensor initialization failed");
1294 /* disable hflip and vflip */
1295 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1301 static int ov7670_init_sensor(struct gspca_dev *gspca_dev)
1304 struct sd *sd = (struct sd *) gspca_dev;
1306 for (i = 0; i < ARRAY_SIZE(ov7670_init); i++) {
1307 if (i2c_w1(gspca_dev, ov7670_init[i].reg,
1308 ov7670_init[i].val) < 0) {
1309 err("OV7670 sensor initialization failed");
1313 /* disable hflip and vflip */
1314 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1320 static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
1322 struct sd *sd = (struct sd *) gspca_dev;
1327 sd->i2c_addr = 0x5d;
1328 ret = i2c_r2(gspca_dev, 0xff, &value);
1329 if ((ret == 0) && (value == 0x8243)) {
1330 for (i = 0; i < ARRAY_SIZE(mt9v011_init); i++) {
1331 if (i2c_w2(gspca_dev, mt9v011_init[i].reg,
1332 mt9v011_init[i].val) < 0) {
1333 err("MT9V011 sensor initialization failed");
1339 sd->sensor = SENSOR_MT9V011;
1340 info("MT9V011 sensor detected");
1344 sd->i2c_addr = 0x5c;
1345 i2c_w2(gspca_dev, 0x01, 0x0004);
1346 ret = i2c_r2(gspca_dev, 0xff, &value);
1347 if ((ret == 0) && (value == 0x823a)) {
1348 for (i = 0; i < ARRAY_SIZE(mt9v111_init); i++) {
1349 if (i2c_w2(gspca_dev, mt9v111_init[i].reg,
1350 mt9v111_init[i].val) < 0) {
1351 err("MT9V111 sensor initialization failed");
1355 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | (1 << GAIN_IDX);
1358 sd->sensor = SENSOR_MT9V111;
1359 info("MT9V111 sensor detected");
1363 sd->i2c_addr = 0x5d;
1364 ret = i2c_w2(gspca_dev, 0xf0, 0x0000);
1366 sd->i2c_addr = 0x48;
1367 i2c_w2(gspca_dev, 0xf0, 0x0000);
1369 ret = i2c_r2(gspca_dev, 0x00, &value);
1370 if ((ret == 0) && (value == 0x1229)) {
1371 for (i = 0; i < ARRAY_SIZE(mt9v112_init); i++) {
1372 if (i2c_w2(gspca_dev, mt9v112_init[i].reg,
1373 mt9v112_init[i].val) < 0) {
1374 err("MT9V112 sensor initialization failed");
1380 sd->sensor = SENSOR_MT9V112;
1381 info("MT9V112 sensor detected");
1388 static int mt9m112_init_sensor(struct gspca_dev *gspca_dev)
1390 struct sd *sd = (struct sd *) gspca_dev;
1392 for (i = 0; i < ARRAY_SIZE(mt9m112_init); i++) {
1393 if (i2c_w2(gspca_dev, mt9m112_init[i].reg,
1394 mt9m112_init[i].val) < 0) {
1395 err("MT9M112 sensor initialization failed");
1399 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | (1 << GAIN_IDX);
1405 static int mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1407 struct sd *sd = (struct sd *) gspca_dev;
1409 for (i = 0; i < ARRAY_SIZE(mt9m111_init); i++) {
1410 if (i2c_w2(gspca_dev, mt9m111_init[i].reg,
1411 mt9m111_init[i].val) < 0) {
1412 err("MT9M111 sensor initialization failed");
1416 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | (1 << GAIN_IDX);
1422 static int mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1424 struct sd *sd = (struct sd *) gspca_dev;
1426 for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) {
1427 if (i2c_w2(gspca_dev, mt9m001_init[i].reg,
1428 mt9m001_init[i].val) < 0) {
1429 err("MT9M001 sensor initialization failed");
1433 /* disable hflip and vflip */
1434 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1440 static int hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1443 struct sd *sd = (struct sd *) gspca_dev;
1445 for (i = 0; i < ARRAY_SIZE(hv7131r_init); i++) {
1446 if (i2c_w1(gspca_dev, hv7131r_init[i].reg,
1447 hv7131r_init[i].val) < 0) {
1448 err("HV7131R Sensor initialization failed");
1457 static int set_cmatrix(struct gspca_dev *gspca_dev)
1459 struct sd *sd = (struct sd *) gspca_dev;
1460 s32 hue_coord, hue_index = 180 + sd->hue;
1463 memset(cmatrix, 0, sizeof cmatrix);
1464 cmatrix[2] = (sd->contrast * 0x25 / 0x100) + 0x26;
1465 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1466 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1467 cmatrix[18] = sd->brightness - 0x80;
1469 hue_coord = (hsv_red_x[hue_index] * sd->saturation) >> 8;
1470 cmatrix[6] = hue_coord;
1471 cmatrix[7] = (hue_coord >> 8) & 0x0f;
1473 hue_coord = (hsv_red_y[hue_index] * sd->saturation) >> 8;
1474 cmatrix[8] = hue_coord;
1475 cmatrix[9] = (hue_coord >> 8) & 0x0f;
1477 hue_coord = (hsv_green_x[hue_index] * sd->saturation) >> 8;
1478 cmatrix[10] = hue_coord;
1479 cmatrix[11] = (hue_coord >> 8) & 0x0f;
1481 hue_coord = (hsv_green_y[hue_index] * sd->saturation) >> 8;
1482 cmatrix[12] = hue_coord;
1483 cmatrix[13] = (hue_coord >> 8) & 0x0f;
1485 hue_coord = (hsv_blue_x[hue_index] * sd->saturation) >> 8;
1486 cmatrix[14] = hue_coord;
1487 cmatrix[15] = (hue_coord >> 8) & 0x0f;
1489 hue_coord = (hsv_blue_y[hue_index] * sd->saturation) >> 8;
1490 cmatrix[16] = hue_coord;
1491 cmatrix[17] = (hue_coord >> 8) & 0x0f;
1493 return reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1496 static int set_gamma(struct gspca_dev *gspca_dev)
1498 struct sd *sd = (struct sd *) gspca_dev;
1500 u8 gval = sd->gamma * 0xb8 / 0x100;
1504 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
1505 gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8);
1506 gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8);
1507 gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8);
1508 gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8);
1509 gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8);
1510 gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8);
1511 gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8);
1512 gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8);
1513 gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8);
1514 gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8);
1515 gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8);
1516 gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8);
1517 gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8);
1518 gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
1521 return reg_w(gspca_dev, 0x1190, gamma, 17);
1524 static int set_redblue(struct gspca_dev *gspca_dev)
1526 struct sd *sd = (struct sd *) gspca_dev;
1527 reg_w1(gspca_dev, 0x118c, sd->red);
1528 reg_w1(gspca_dev, 0x118f, sd->blue);
1532 static int set_hvflip(struct gspca_dev *gspca_dev)
1534 u8 value, tslb, hflip, vflip;
1536 struct sd *sd = (struct sd *) gspca_dev;
1538 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1546 switch (sd->sensor) {
1548 i2c_r1(gspca_dev, 0x1e, &value);
1557 i2c_w1(gspca_dev, 0x1e, value);
1558 i2c_w1(gspca_dev, 0x3a, tslb);
1560 case SENSOR_MT9V111:
1561 case SENSOR_MT9V011:
1562 i2c_r2(gspca_dev, 0x20, &value2);
1568 i2c_w2(gspca_dev, 0x20, value2);
1570 case SENSOR_MT9M112:
1571 case SENSOR_MT9M111:
1572 case SENSOR_MT9V112:
1573 i2c_r2(gspca_dev, 0x20, &value2);
1579 i2c_w2(gspca_dev, 0x20, value2);
1581 case SENSOR_HV7131R:
1582 i2c_r1(gspca_dev, 0x01, &value);
1588 i2c_w1(gspca_dev, 0x01, value);
1594 static int set_exposure(struct gspca_dev *gspca_dev)
1596 struct sd *sd = (struct sd *) gspca_dev;
1597 u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1598 switch (sd->sensor) {
1605 exp[3] = sd->exposure & 0xff;
1606 exp[4] = sd->exposure >> 8;
1608 case SENSOR_MT9M001:
1609 case SENSOR_MT9V112:
1610 case SENSOR_MT9V011:
1613 exp[3] = sd->exposure >> 8;
1614 exp[4] = sd->exposure & 0xff;
1616 case SENSOR_HV7131R:
1619 exp[3] = (sd->exposure >> 5) & 0xff;
1620 exp[4] = (sd->exposure << 3) & 0xff;
1626 i2c_w(gspca_dev, exp);
1630 static int set_gain(struct gspca_dev *gspca_dev)
1632 struct sd *sd = (struct sd *) gspca_dev;
1633 u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1634 switch (sd->sensor) {
1640 gain[0] |= (2 << 4);
1641 gain[3] = ov_gain[sd->gain];
1643 case SENSOR_MT9V011:
1644 gain[0] |= (3 << 4);
1646 gain[3] = micron1_gain[sd->gain] >> 8;
1647 gain[4] = micron1_gain[sd->gain] & 0xff;
1649 case SENSOR_MT9V112:
1650 gain[0] |= (3 << 4);
1652 gain[3] = micron1_gain[sd->gain] >> 8;
1653 gain[4] = micron1_gain[sd->gain] & 0xff;
1655 case SENSOR_MT9M001:
1656 gain[0] |= (3 << 4);
1658 gain[3] = micron2_gain[sd->gain] >> 8;
1659 gain[4] = micron2_gain[sd->gain] & 0xff;
1661 case SENSOR_HV7131R:
1662 gain[0] |= (2 << 4);
1664 gain[3] = hv7131r_gain[sd->gain];
1669 i2c_w(gspca_dev, gain);
1673 static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val)
1675 struct sd *sd = (struct sd *) gspca_dev;
1677 sd->brightness = val;
1678 if (gspca_dev->streaming)
1679 return set_cmatrix(gspca_dev);
1683 static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val)
1685 struct sd *sd = (struct sd *) gspca_dev;
1686 *val = sd->brightness;
1691 static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val)
1693 struct sd *sd = (struct sd *) gspca_dev;
1696 if (gspca_dev->streaming)
1697 return set_cmatrix(gspca_dev);
1701 static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val)
1703 struct sd *sd = (struct sd *) gspca_dev;
1704 *val = sd->contrast;
1708 static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val)
1710 struct sd *sd = (struct sd *) gspca_dev;
1712 sd->saturation = val;
1713 if (gspca_dev->streaming)
1714 return set_cmatrix(gspca_dev);
1718 static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val)
1720 struct sd *sd = (struct sd *) gspca_dev;
1721 *val = sd->saturation;
1725 static int sd_sethue(struct gspca_dev *gspca_dev, s32 val)
1727 struct sd *sd = (struct sd *) gspca_dev;
1730 if (gspca_dev->streaming)
1731 return set_cmatrix(gspca_dev);
1735 static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val)
1737 struct sd *sd = (struct sd *) gspca_dev;
1742 static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val)
1744 struct sd *sd = (struct sd *) gspca_dev;
1747 if (gspca_dev->streaming)
1748 return set_gamma(gspca_dev);
1752 static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val)
1754 struct sd *sd = (struct sd *) gspca_dev;
1759 static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val)
1761 struct sd *sd = (struct sd *) gspca_dev;
1764 if (gspca_dev->streaming)
1765 return set_redblue(gspca_dev);
1769 static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val)
1771 struct sd *sd = (struct sd *) gspca_dev;
1776 static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val)
1778 struct sd *sd = (struct sd *) gspca_dev;
1781 if (gspca_dev->streaming)
1782 return set_redblue(gspca_dev);
1786 static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val)
1788 struct sd *sd = (struct sd *) gspca_dev;
1793 static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val)
1795 struct sd *sd = (struct sd *) gspca_dev;
1798 if (gspca_dev->streaming)
1799 return set_hvflip(gspca_dev);
1803 static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val)
1805 struct sd *sd = (struct sd *) gspca_dev;
1810 static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val)
1812 struct sd *sd = (struct sd *) gspca_dev;
1815 if (gspca_dev->streaming)
1816 return set_hvflip(gspca_dev);
1820 static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val)
1822 struct sd *sd = (struct sd *) gspca_dev;
1827 static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val)
1829 struct sd *sd = (struct sd *) gspca_dev;
1832 if (gspca_dev->streaming)
1833 return set_exposure(gspca_dev);
1837 static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val)
1839 struct sd *sd = (struct sd *) gspca_dev;
1840 *val = sd->exposure;
1844 static int sd_setgain(struct gspca_dev *gspca_dev, s32 val)
1846 struct sd *sd = (struct sd *) gspca_dev;
1849 if (gspca_dev->streaming)
1850 return set_gain(gspca_dev);
1854 static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val)
1856 struct sd *sd = (struct sd *) gspca_dev;
1861 static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val)
1863 struct sd *sd = (struct sd *) gspca_dev;
1864 sd->auto_exposure = val;
1868 static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val)
1870 struct sd *sd = (struct sd *) gspca_dev;
1871 *val = sd->auto_exposure;
1875 #ifdef CONFIG_VIDEO_ADV_DEBUG
1876 static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1877 struct v4l2_dbg_register *reg)
1879 struct sd *sd = (struct sd *) gspca_dev;
1880 switch (reg->match.type) {
1881 case V4L2_CHIP_MATCH_HOST:
1882 if (reg->match.addr != 0)
1884 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1886 if (reg_r(gspca_dev, reg->reg, 1) < 0)
1888 reg->val = gspca_dev->usb_buf[0];
1890 case V4L2_CHIP_MATCH_I2C_ADDR:
1891 if (reg->match.addr != sd->i2c_addr)
1893 if (sd->sensor >= SENSOR_MT9V011 &&
1894 sd->sensor <= SENSOR_MT9M112) {
1895 if (i2c_r2(gspca_dev, reg->reg, (u16 *)®->val) < 0)
1898 if (i2c_r1(gspca_dev, reg->reg, (u8 *)®->val) < 0)
1906 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1907 struct v4l2_dbg_register *reg)
1909 struct sd *sd = (struct sd *) gspca_dev;
1910 switch (reg->match.type) {
1911 case V4L2_CHIP_MATCH_HOST:
1912 if (reg->match.addr != 0)
1914 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1916 if (reg_w1(gspca_dev, reg->reg, reg->val) < 0)
1919 case V4L2_CHIP_MATCH_I2C_ADDR:
1920 if (reg->match.addr != sd->i2c_addr)
1922 if (sd->sensor >= SENSOR_MT9V011 &&
1923 sd->sensor <= SENSOR_MT9M112) {
1924 if (i2c_w2(gspca_dev, reg->reg, reg->val) < 0)
1927 if (i2c_w1(gspca_dev, reg->reg, reg->val) < 0)
1936 static int sd_chip_ident(struct gspca_dev *gspca_dev,
1937 struct v4l2_dbg_chip_ident *chip)
1939 struct sd *sd = (struct sd *) gspca_dev;
1941 switch (chip->match.type) {
1942 case V4L2_CHIP_MATCH_HOST:
1943 if (chip->match.addr != 0)
1946 chip->ident = V4L2_IDENT_SN9C20X;
1948 case V4L2_CHIP_MATCH_I2C_ADDR:
1949 if (chip->match.addr != sd->i2c_addr)
1952 chip->ident = i2c_ident[sd->sensor];
1958 static int sd_config(struct gspca_dev *gspca_dev,
1959 const struct usb_device_id *id)
1961 struct sd *sd = (struct sd *) gspca_dev;
1964 cam = &gspca_dev->cam;
1966 sd->sensor = (id->driver_info >> 8) & 0xff;
1967 sd->i2c_addr = id->driver_info & 0xff;
1968 sd->flags = (id->driver_info >> 16) & 0xff;
1970 switch (sd->sensor) {
1971 case SENSOR_MT9M112:
1972 case SENSOR_MT9M111:
1975 cam->cam_mode = sxga_mode;
1976 cam->nmodes = ARRAY_SIZE(sxga_mode);
1979 cam->cam_mode = vga_mode;
1980 cam->nmodes = ARRAY_SIZE(vga_mode);
1986 sd->exposure_step = 16;
1988 sd->brightness = BRIGHTNESS_DEFAULT;
1989 sd->contrast = CONTRAST_DEFAULT;
1990 sd->saturation = SATURATION_DEFAULT;
1991 sd->hue = HUE_DEFAULT;
1992 sd->gamma = GAMMA_DEFAULT;
1993 sd->red = RED_DEFAULT;
1994 sd->blue = BLUE_DEFAULT;
1996 sd->hflip = HFLIP_DEFAULT;
1997 sd->vflip = VFLIP_DEFAULT;
1998 sd->exposure = EXPOSURE_DEFAULT;
1999 sd->gain = GAIN_DEFAULT;
2000 sd->auto_exposure = AUTO_EXPOSURE_DEFAULT;
2007 static int sd_init(struct gspca_dev *gspca_dev)
2009 struct sd *sd = (struct sd *) gspca_dev;
2013 {0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
2015 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
2016 value = bridge_init[i][1];
2017 if (reg_w(gspca_dev, bridge_init[i][0], &value, 1) < 0) {
2018 err("Device initialization failed");
2023 if (sd->flags & LED_REVERSE)
2024 reg_w1(gspca_dev, 0x1006, 0x00);
2026 reg_w1(gspca_dev, 0x1006, 0x20);
2028 if (reg_w(gspca_dev, 0x10c0, i2c_init, 9) < 0) {
2029 err("Device initialization failed");
2033 switch (sd->sensor) {
2035 if (ov9650_init_sensor(gspca_dev) < 0)
2037 info("OV9650 sensor detected");
2040 if (ov9655_init_sensor(gspca_dev) < 0)
2042 info("OV9655 sensor detected");
2045 if (soi968_init_sensor(gspca_dev) < 0)
2047 info("SOI968 sensor detected");
2050 if (ov7660_init_sensor(gspca_dev) < 0)
2052 info("OV7660 sensor detected");
2055 if (ov7670_init_sensor(gspca_dev) < 0)
2057 info("OV7670 sensor detected");
2059 case SENSOR_MT9VPRB:
2060 if (mt9v_init_sensor(gspca_dev) < 0)
2063 case SENSOR_MT9M111:
2064 if (mt9m111_init_sensor(gspca_dev) < 0)
2066 info("MT9M111 sensor detected");
2068 case SENSOR_MT9M112:
2069 if (mt9m112_init_sensor(gspca_dev) < 0)
2071 info("MT9M112 sensor detected");
2073 case SENSOR_MT9M001:
2074 if (mt9m001_init_sensor(gspca_dev) < 0)
2076 info("MT9M001 sensor detected");
2078 case SENSOR_HV7131R:
2079 if (hv7131r_init_sensor(gspca_dev) < 0)
2081 info("HV7131R sensor detected");
2084 info("Unsupported Sensor");
2091 static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
2093 struct sd *sd = (struct sd *) gspca_dev;
2095 switch (sd->sensor) {
2097 if (mode & MODE_SXGA) {
2098 i2c_w1(gspca_dev, 0x17, 0x1d);
2099 i2c_w1(gspca_dev, 0x18, 0xbd);
2100 i2c_w1(gspca_dev, 0x19, 0x01);
2101 i2c_w1(gspca_dev, 0x1a, 0x81);
2102 i2c_w1(gspca_dev, 0x12, 0x00);
2106 i2c_w1(gspca_dev, 0x17, 0x13);
2107 i2c_w1(gspca_dev, 0x18, 0x63);
2108 i2c_w1(gspca_dev, 0x19, 0x01);
2109 i2c_w1(gspca_dev, 0x1a, 0x79);
2110 i2c_w1(gspca_dev, 0x12, 0x40);
2116 if (mode & MODE_SXGA) {
2117 i2c_w1(gspca_dev, 0x17, 0x1b);
2118 i2c_w1(gspca_dev, 0x18, 0xbc);
2119 i2c_w1(gspca_dev, 0x19, 0x01);
2120 i2c_w1(gspca_dev, 0x1a, 0x82);
2121 i2c_r1(gspca_dev, 0x12, &value);
2122 i2c_w1(gspca_dev, 0x12, value & 0x07);
2124 i2c_w1(gspca_dev, 0x17, 0x24);
2125 i2c_w1(gspca_dev, 0x18, 0xc5);
2126 i2c_w1(gspca_dev, 0x19, 0x00);
2127 i2c_w1(gspca_dev, 0x1a, 0x3c);
2128 i2c_r1(gspca_dev, 0x12, &value);
2129 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
2132 case SENSOR_MT9M112:
2133 case SENSOR_MT9M111:
2134 if (mode & MODE_SXGA) {
2135 i2c_w2(gspca_dev, 0xf0, 0x0002);
2136 i2c_w2(gspca_dev, 0xc8, 0x970b);
2137 i2c_w2(gspca_dev, 0xf0, 0x0000);
2139 i2c_w2(gspca_dev, 0xf0, 0x0002);
2140 i2c_w2(gspca_dev, 0xc8, 0x8000);
2141 i2c_w2(gspca_dev, 0xf0, 0x0000);
2147 #define HW_WIN(mode, hstart, vstart) \
2148 ((const u8 []){hstart, 0, vstart, 0, \
2149 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
2150 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
2152 #define CLR_WIN(width, height) \
2154 {0, width >> 2, 0, height >> 1,\
2155 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
2157 static int sd_start(struct gspca_dev *gspca_dev)
2159 struct sd *sd = (struct sd *) gspca_dev;
2160 int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
2161 int width = gspca_dev->width;
2162 int height = gspca_dev->height;
2165 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
2166 if (sd->jpeg_hdr == NULL)
2169 jpeg_define(sd->jpeg_hdr, height, width,
2171 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2173 if (mode & MODE_RAW)
2175 else if (mode & MODE_JPEG)
2180 switch (mode & 0x0f) {
2183 info("Set 1280x1024");
2187 info("Set 640x480");
2191 info("Set 320x240");
2195 info("Set 160x120");
2199 configure_sensor_output(gspca_dev, mode);
2200 reg_w(gspca_dev, 0x1100, sd->jpeg_hdr + JPEG_QT0_OFFSET, 64);
2201 reg_w(gspca_dev, 0x1140, sd->jpeg_hdr + JPEG_QT1_OFFSET, 64);
2202 reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2203 reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2204 reg_w1(gspca_dev, 0x1189, scale);
2205 reg_w1(gspca_dev, 0x10e0, fmt);
2207 set_cmatrix(gspca_dev);
2208 set_gamma(gspca_dev);
2209 set_redblue(gspca_dev);
2210 set_gain(gspca_dev);
2211 set_exposure(gspca_dev);
2212 set_hvflip(gspca_dev);
2214 reg_w1(gspca_dev, 0x1007, 0x20);
2216 reg_r(gspca_dev, 0x1061, 1);
2217 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] | 0x02);
2221 static void sd_stopN(struct gspca_dev *gspca_dev)
2223 reg_w1(gspca_dev, 0x1007, 0x00);
2225 reg_r(gspca_dev, 0x1061, 1);
2226 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] & ~0x02);
2229 static void sd_stop0(struct gspca_dev *gspca_dev)
2231 struct sd *sd = (struct sd *) gspca_dev;
2232 kfree(sd->jpeg_hdr);
2235 static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2237 struct sd *sd = (struct sd *) gspca_dev;
2241 * some hardcoded values are present
2242 * like those for maximal/minimal exposure
2243 * and exposure steps
2245 if (avg_lum < MIN_AVG_LUM) {
2246 if (sd->exposure > 0x1770)
2249 new_exp = sd->exposure + sd->exposure_step;
2250 if (new_exp > 0x1770)
2254 sd->exposure = new_exp;
2255 set_exposure(gspca_dev);
2257 sd->older_step = sd->old_step;
2260 if (sd->old_step ^ sd->older_step)
2261 sd->exposure_step /= 2;
2263 sd->exposure_step += 2;
2265 if (avg_lum > MAX_AVG_LUM) {
2266 if (sd->exposure < 0x10)
2268 new_exp = sd->exposure - sd->exposure_step;
2269 if (new_exp > 0x1700)
2273 sd->exposure = new_exp;
2274 set_exposure(gspca_dev);
2275 sd->older_step = sd->old_step;
2278 if (sd->old_step ^ sd->older_step)
2279 sd->exposure_step /= 2;
2281 sd->exposure_step += 2;
2285 static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2287 struct sd *sd = (struct sd *) gspca_dev;
2289 if (avg_lum < MIN_AVG_LUM) {
2290 if (sd->gain + 1 <= 28) {
2292 set_gain(gspca_dev);
2295 if (avg_lum > MAX_AVG_LUM) {
2298 set_gain(gspca_dev);
2303 static void sd_dqcallback(struct gspca_dev *gspca_dev)
2305 struct sd *sd = (struct sd *) gspca_dev;
2308 if (!sd->auto_exposure)
2311 avg_lum = atomic_read(&sd->avg_lum);
2312 if (sd->sensor == SENSOR_SOI968)
2313 do_autogain(gspca_dev, avg_lum);
2315 do_autoexposure(gspca_dev, avg_lum);
2319 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2320 u8 *data, /* interrupt packet */
2321 int len) /* interrupt packet length */
2323 struct sd *sd = (struct sd *) gspca_dev;
2325 if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
2326 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2327 input_sync(gspca_dev->input_dev);
2328 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2329 input_sync(gspca_dev->input_dev);
2336 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2337 u8 *data, /* isoc packet */
2338 int len) /* iso packet length */
2340 struct sd *sd = (struct sd *) gspca_dev;
2342 static u8 frame_header[] =
2343 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2344 if (len == 64 && memcmp(data, frame_header, 6) == 0) {
2345 avg_lum = ((data[35] >> 2) & 3) |
2348 avg_lum += ((data[35] >> 4) & 3) |
2351 avg_lum += ((data[35] >> 6) & 3) |
2354 avg_lum += (data[36] & 3) |
2357 avg_lum += ((data[36] >> 2) & 3) |
2360 avg_lum += ((data[36] >> 4) & 3) |
2363 avg_lum += ((data[36] >> 6) & 3) |
2366 avg_lum += ((data[44] >> 4) & 3) |
2370 atomic_set(&sd->avg_lum, avg_lum);
2371 gspca_frame_add(gspca_dev, LAST_PACKET,
2375 if (gspca_dev->last_packet_type == LAST_PACKET) {
2376 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv
2378 gspca_frame_add(gspca_dev, FIRST_PACKET,
2379 sd->jpeg_hdr, JPEG_HDR_SZ);
2380 gspca_frame_add(gspca_dev, INTER_PACKET,
2383 gspca_frame_add(gspca_dev, FIRST_PACKET,
2387 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2391 /* sub-driver description */
2392 static const struct sd_desc sd_desc = {
2393 .name = MODULE_NAME,
2395 .nctrls = ARRAY_SIZE(sd_ctrls),
2396 .config = sd_config,
2401 .pkt_scan = sd_pkt_scan,
2403 .int_pkt_scan = sd_int_pkt_scan,
2405 .dq_callback = sd_dqcallback,
2406 #ifdef CONFIG_VIDEO_ADV_DEBUG
2407 .set_register = sd_dbg_s_register,
2408 .get_register = sd_dbg_g_register,
2410 .get_chip_ident = sd_chip_ident,
2413 #define SN9C20X(sensor, i2c_addr, flags) \
2414 .driver_info = ((flags & 0xff) << 16) \
2415 | (SENSOR_ ## sensor << 8) \
2418 static const __devinitdata struct usb_device_id device_table[] = {
2419 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2420 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
2421 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2422 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
2423 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
2424 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
2425 (FLIP_DETECT | HAS_NO_BUTTON))},
2426 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2427 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2428 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2429 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2430 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, 0)},
2431 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2432 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2433 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2434 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2435 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
2436 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
2437 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2438 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2439 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2440 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2441 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, 0)},
2442 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, 0)},
2443 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2444 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2445 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2446 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2447 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
2448 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
2449 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2450 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2451 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2452 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2453 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
2454 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2455 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2458 MODULE_DEVICE_TABLE(usb, device_table);
2460 /* -- device connect -- */
2461 static int sd_probe(struct usb_interface *intf,
2462 const struct usb_device_id *id)
2464 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2468 static struct usb_driver sd_driver = {
2469 .name = MODULE_NAME,
2470 .id_table = device_table,
2472 .disconnect = gspca_disconnect,
2474 .suspend = gspca_suspend,
2475 .resume = gspca_resume,
2476 .reset_resume = gspca_resume,
2480 /* -- module insert / remove -- */
2481 static int __init sd_mod_init(void)
2484 ret = usb_register(&sd_driver);
2490 static void __exit sd_mod_exit(void)
2492 usb_deregister(&sd_driver);
2493 info("deregistered");
2496 module_init(sd_mod_init);
2497 module_exit(sd_mod_exit);