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
21 #include <linux/input.h>
26 #include <media/v4l2-chip-ident.h>
27 #include <linux/dmi.h>
29 MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, "
30 "microdia project <microdia@googlegroups.com>");
31 MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
32 MODULE_LICENSE("GPL");
34 #define MODULE_NAME "sn9c20x"
37 #define MODE_JPEG 0x20
38 #define MODE_SXGA 0x80
40 #define SENSOR_OV9650 0
41 #define SENSOR_OV9655 1
42 #define SENSOR_SOI968 2
43 #define SENSOR_OV7660 3
44 #define SENSOR_OV7670 4
45 #define SENSOR_MT9V011 5
46 #define SENSOR_MT9V111 6
47 #define SENSOR_MT9V112 7
48 #define SENSOR_MT9M001 8
49 #define SENSOR_MT9M111 9
50 #define SENSOR_MT9M112 10
51 #define SENSOR_HV7131R 11
52 #define SENSOR_MT9VPRB 20
55 #define HAS_NO_BUTTON 0x1
56 #define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
57 #define FLIP_DETECT 0x4
59 /* specific webcam descriptor */
61 struct gspca_dev gspca_dev;
63 #define MIN_AVG_LUM 80
64 #define MAX_AVG_LUM 130
89 u8 jpeg_hdr[JPEG_HDR_SZ];
105 static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val);
106 static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val);
107 static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val);
108 static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val);
109 static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val);
110 static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val);
111 static int sd_sethue(struct gspca_dev *gspca_dev, s32 val);
112 static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val);
113 static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val);
114 static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val);
115 static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val);
116 static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val);
117 static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val);
118 static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val);
119 static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val);
120 static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val);
121 static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val);
122 static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val);
123 static int sd_setgain(struct gspca_dev *gspca_dev, s32 val);
124 static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val);
125 static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val);
126 static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val);
127 static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val);
128 static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val);
130 static const struct dmi_system_id flip_dmi_table[] = {
132 .ident = "MSI MS-1034",
134 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
135 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1034"),
136 DMI_MATCH(DMI_PRODUCT_VERSION, "0341")
140 .ident = "MSI MS-1632",
142 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
143 DMI_MATCH(DMI_BOARD_NAME, "MS-1632")
147 .ident = "MSI MS-1635X",
149 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
150 DMI_MATCH(DMI_BOARD_NAME, "MS-1635X")
154 .ident = "ASUSTeK W7J",
156 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
157 DMI_MATCH(DMI_BOARD_NAME, "W7J ")
163 static const struct ctrl sd_ctrls[] = {
165 #define BRIGHTNESS_IDX 0
167 .id = V4L2_CID_BRIGHTNESS,
168 .type = V4L2_CTRL_TYPE_INTEGER,
169 .name = "Brightness",
173 #define BRIGHTNESS_DEFAULT 0x7f
174 .default_value = BRIGHTNESS_DEFAULT,
176 .set = sd_setbrightness,
177 .get = sd_getbrightness,
180 #define CONTRAST_IDX 1
182 .id = V4L2_CID_CONTRAST,
183 .type = V4L2_CTRL_TYPE_INTEGER,
188 #define CONTRAST_DEFAULT 0x7f
189 .default_value = CONTRAST_DEFAULT,
191 .set = sd_setcontrast,
192 .get = sd_getcontrast,
195 #define SATURATION_IDX 2
197 .id = V4L2_CID_SATURATION,
198 .type = V4L2_CTRL_TYPE_INTEGER,
199 .name = "Saturation",
203 #define SATURATION_DEFAULT 0x7f
204 .default_value = SATURATION_DEFAULT,
206 .set = sd_setsaturation,
207 .get = sd_getsaturation,
213 .type = V4L2_CTRL_TYPE_INTEGER,
218 #define HUE_DEFAULT 0
219 .default_value = HUE_DEFAULT,
227 .id = V4L2_CID_GAMMA,
228 .type = V4L2_CTRL_TYPE_INTEGER,
233 #define GAMMA_DEFAULT 0x10
234 .default_value = GAMMA_DEFAULT,
242 .id = V4L2_CID_BLUE_BALANCE,
243 .type = V4L2_CTRL_TYPE_INTEGER,
244 .name = "Blue Balance",
248 #define BLUE_DEFAULT 0x28
249 .default_value = BLUE_DEFAULT,
251 .set = sd_setbluebalance,
252 .get = sd_getbluebalance,
257 .id = V4L2_CID_RED_BALANCE,
258 .type = V4L2_CTRL_TYPE_INTEGER,
259 .name = "Red Balance",
263 #define RED_DEFAULT 0x28
264 .default_value = RED_DEFAULT,
266 .set = sd_setredbalance,
267 .get = sd_getredbalance,
272 .id = V4L2_CID_HFLIP,
273 .type = V4L2_CTRL_TYPE_BOOLEAN,
274 .name = "Horizontal Flip",
278 #define HFLIP_DEFAULT 0
279 .default_value = HFLIP_DEFAULT,
287 .id = V4L2_CID_VFLIP,
288 .type = V4L2_CTRL_TYPE_BOOLEAN,
289 .name = "Vertical Flip",
293 #define VFLIP_DEFAULT 0
294 .default_value = VFLIP_DEFAULT,
300 #define EXPOSURE_IDX 9
302 .id = V4L2_CID_EXPOSURE,
303 .type = V4L2_CTRL_TYPE_INTEGER,
308 #define EXPOSURE_DEFAULT 0x33
309 .default_value = EXPOSURE_DEFAULT,
311 .set = sd_setexposure,
312 .get = sd_getexposure,
318 .type = V4L2_CTRL_TYPE_INTEGER,
323 #define GAIN_DEFAULT 0x00
324 .default_value = GAIN_DEFAULT,
330 #define AUTOGAIN_IDX 11
332 .id = V4L2_CID_AUTOGAIN,
333 .type = V4L2_CTRL_TYPE_BOOLEAN,
334 .name = "Auto Exposure",
338 #define AUTO_EXPOSURE_DEFAULT 1
339 .default_value = AUTO_EXPOSURE_DEFAULT,
341 .set = sd_setautoexposure,
342 .get = sd_getautoexposure,
346 static const struct v4l2_pix_format vga_mode[] = {
347 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
349 .sizeimage = 160 * 120 * 4 / 8 + 590,
350 .colorspace = V4L2_COLORSPACE_JPEG,
351 .priv = 0 | MODE_JPEG},
352 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
354 .sizeimage = 160 * 120,
355 .colorspace = V4L2_COLORSPACE_SRGB,
356 .priv = 0 | MODE_RAW},
357 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
359 .sizeimage = 240 * 120,
360 .colorspace = V4L2_COLORSPACE_SRGB,
362 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
364 .sizeimage = 320 * 240 * 3 / 8 + 590,
365 .colorspace = V4L2_COLORSPACE_JPEG,
366 .priv = 1 | MODE_JPEG},
367 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
369 .sizeimage = 320 * 240 ,
370 .colorspace = V4L2_COLORSPACE_SRGB,
371 .priv = 1 | MODE_RAW},
372 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
374 .sizeimage = 480 * 240 ,
375 .colorspace = V4L2_COLORSPACE_SRGB,
377 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
379 .sizeimage = 640 * 480 * 3 / 8 + 590,
380 .colorspace = V4L2_COLORSPACE_JPEG,
381 .priv = 2 | MODE_JPEG},
382 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
384 .sizeimage = 640 * 480,
385 .colorspace = V4L2_COLORSPACE_SRGB,
386 .priv = 2 | MODE_RAW},
387 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
389 .sizeimage = 960 * 480,
390 .colorspace = V4L2_COLORSPACE_SRGB,
394 static const struct v4l2_pix_format sxga_mode[] = {
395 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
397 .sizeimage = 160 * 120 * 4 / 8 + 590,
398 .colorspace = V4L2_COLORSPACE_JPEG,
399 .priv = 0 | MODE_JPEG},
400 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
402 .sizeimage = 160 * 120,
403 .colorspace = V4L2_COLORSPACE_SRGB,
404 .priv = 0 | MODE_RAW},
405 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
407 .sizeimage = 240 * 120,
408 .colorspace = V4L2_COLORSPACE_SRGB,
410 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
412 .sizeimage = 320 * 240 * 3 / 8 + 590,
413 .colorspace = V4L2_COLORSPACE_JPEG,
414 .priv = 1 | MODE_JPEG},
415 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
417 .sizeimage = 320 * 240 ,
418 .colorspace = V4L2_COLORSPACE_SRGB,
419 .priv = 1 | MODE_RAW},
420 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
422 .sizeimage = 480 * 240 ,
423 .colorspace = V4L2_COLORSPACE_SRGB,
425 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
427 .sizeimage = 640 * 480 * 3 / 8 + 590,
428 .colorspace = V4L2_COLORSPACE_JPEG,
429 .priv = 2 | MODE_JPEG},
430 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
432 .sizeimage = 640 * 480,
433 .colorspace = V4L2_COLORSPACE_SRGB,
434 .priv = 2 | MODE_RAW},
435 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
437 .sizeimage = 960 * 480,
438 .colorspace = V4L2_COLORSPACE_SRGB,
440 {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
441 .bytesperline = 1280,
442 .sizeimage = 1280 * 1024,
443 .colorspace = V4L2_COLORSPACE_SRGB,
444 .priv = 3 | MODE_RAW | MODE_SXGA},
447 static const s16 hsv_red_x[] = {
448 41, 44, 46, 48, 50, 52, 54, 56,
449 58, 60, 62, 64, 66, 68, 70, 72,
450 74, 76, 78, 80, 81, 83, 85, 87,
451 88, 90, 92, 93, 95, 97, 98, 100,
452 101, 102, 104, 105, 107, 108, 109, 110,
453 112, 113, 114, 115, 116, 117, 118, 119,
454 120, 121, 122, 123, 123, 124, 125, 125,
455 126, 127, 127, 128, 128, 129, 129, 129,
456 130, 130, 130, 130, 131, 131, 131, 131,
457 131, 131, 131, 131, 130, 130, 130, 130,
458 129, 129, 129, 128, 128, 127, 127, 126,
459 125, 125, 124, 123, 122, 122, 121, 120,
460 119, 118, 117, 116, 115, 114, 112, 111,
461 110, 109, 107, 106, 105, 103, 102, 101,
462 99, 98, 96, 94, 93, 91, 90, 88,
463 86, 84, 83, 81, 79, 77, 75, 74,
464 72, 70, 68, 66, 64, 62, 60, 58,
465 56, 54, 52, 49, 47, 45, 43, 41,
466 39, 36, 34, 32, 30, 28, 25, 23,
467 21, 19, 16, 14, 12, 9, 7, 5,
468 3, 0, -1, -3, -6, -8, -10, -12,
469 -15, -17, -19, -22, -24, -26, -28, -30,
470 -33, -35, -37, -39, -41, -44, -46, -48,
471 -50, -52, -54, -56, -58, -60, -62, -64,
472 -66, -68, -70, -72, -74, -76, -78, -80,
473 -81, -83, -85, -87, -88, -90, -92, -93,
474 -95, -97, -98, -100, -101, -102, -104, -105,
475 -107, -108, -109, -110, -112, -113, -114, -115,
476 -116, -117, -118, -119, -120, -121, -122, -123,
477 -123, -124, -125, -125, -126, -127, -127, -128,
478 -128, -128, -128, -128, -128, -128, -128, -128,
479 -128, -128, -128, -128, -128, -128, -128, -128,
480 -128, -128, -128, -128, -128, -128, -128, -128,
481 -128, -127, -127, -126, -125, -125, -124, -123,
482 -122, -122, -121, -120, -119, -118, -117, -116,
483 -115, -114, -112, -111, -110, -109, -107, -106,
484 -105, -103, -102, -101, -99, -98, -96, -94,
485 -93, -91, -90, -88, -86, -84, -83, -81,
486 -79, -77, -75, -74, -72, -70, -68, -66,
487 -64, -62, -60, -58, -56, -54, -52, -49,
488 -47, -45, -43, -41, -39, -36, -34, -32,
489 -30, -28, -25, -23, -21, -19, -16, -14,
490 -12, -9, -7, -5, -3, 0, 1, 3,
491 6, 8, 10, 12, 15, 17, 19, 22,
492 24, 26, 28, 30, 33, 35, 37, 39, 41
495 static const s16 hsv_red_y[] = {
496 82, 80, 78, 76, 74, 73, 71, 69,
497 67, 65, 63, 61, 58, 56, 54, 52,
498 50, 48, 46, 44, 41, 39, 37, 35,
499 32, 30, 28, 26, 23, 21, 19, 16,
500 14, 12, 10, 7, 5, 3, 0, -1,
501 -3, -6, -8, -10, -13, -15, -17, -19,
502 -22, -24, -26, -29, -31, -33, -35, -38,
503 -40, -42, -44, -46, -48, -51, -53, -55,
504 -57, -59, -61, -63, -65, -67, -69, -71,
505 -73, -75, -77, -79, -81, -82, -84, -86,
506 -88, -89, -91, -93, -94, -96, -98, -99,
507 -101, -102, -104, -105, -106, -108, -109, -110,
508 -112, -113, -114, -115, -116, -117, -119, -120,
509 -120, -121, -122, -123, -124, -125, -126, -126,
510 -127, -128, -128, -128, -128, -128, -128, -128,
511 -128, -128, -128, -128, -128, -128, -128, -128,
512 -128, -128, -128, -128, -128, -128, -128, -128,
513 -128, -128, -128, -128, -128, -128, -128, -128,
514 -127, -127, -126, -125, -125, -124, -123, -122,
515 -121, -120, -119, -118, -117, -116, -115, -114,
516 -113, -111, -110, -109, -107, -106, -105, -103,
517 -102, -100, -99, -97, -96, -94, -92, -91,
518 -89, -87, -85, -84, -82, -80, -78, -76,
519 -74, -73, -71, -69, -67, -65, -63, -61,
520 -58, -56, -54, -52, -50, -48, -46, -44,
521 -41, -39, -37, -35, -32, -30, -28, -26,
522 -23, -21, -19, -16, -14, -12, -10, -7,
523 -5, -3, 0, 1, 3, 6, 8, 10,
524 13, 15, 17, 19, 22, 24, 26, 29,
525 31, 33, 35, 38, 40, 42, 44, 46,
526 48, 51, 53, 55, 57, 59, 61, 63,
527 65, 67, 69, 71, 73, 75, 77, 79,
528 81, 82, 84, 86, 88, 89, 91, 93,
529 94, 96, 98, 99, 101, 102, 104, 105,
530 106, 108, 109, 110, 112, 113, 114, 115,
531 116, 117, 119, 120, 120, 121, 122, 123,
532 124, 125, 126, 126, 127, 128, 128, 129,
533 129, 130, 130, 131, 131, 131, 131, 132,
534 132, 132, 132, 132, 132, 132, 132, 132,
535 132, 132, 132, 131, 131, 131, 130, 130,
536 130, 129, 129, 128, 127, 127, 126, 125,
537 125, 124, 123, 122, 121, 120, 119, 118,
538 117, 116, 115, 114, 113, 111, 110, 109,
539 107, 106, 105, 103, 102, 100, 99, 97,
540 96, 94, 92, 91, 89, 87, 85, 84, 82
543 static const s16 hsv_green_x[] = {
544 -124, -124, -125, -125, -125, -125, -125, -125,
545 -125, -126, -126, -125, -125, -125, -125, -125,
546 -125, -124, -124, -124, -123, -123, -122, -122,
547 -121, -121, -120, -120, -119, -118, -117, -117,
548 -116, -115, -114, -113, -112, -111, -110, -109,
549 -108, -107, -105, -104, -103, -102, -100, -99,
550 -98, -96, -95, -93, -92, -91, -89, -87,
551 -86, -84, -83, -81, -79, -77, -76, -74,
552 -72, -70, -69, -67, -65, -63, -61, -59,
553 -57, -55, -53, -51, -49, -47, -45, -43,
554 -41, -39, -37, -35, -33, -30, -28, -26,
555 -24, -22, -20, -18, -15, -13, -11, -9,
556 -7, -4, -2, 0, 1, 3, 6, 8,
557 10, 12, 14, 17, 19, 21, 23, 25,
558 27, 29, 32, 34, 36, 38, 40, 42,
559 44, 46, 48, 50, 52, 54, 56, 58,
560 60, 62, 64, 66, 68, 70, 71, 73,
561 75, 77, 78, 80, 82, 83, 85, 87,
562 88, 90, 91, 93, 94, 96, 97, 98,
563 100, 101, 102, 104, 105, 106, 107, 108,
564 109, 111, 112, 113, 113, 114, 115, 116,
565 117, 118, 118, 119, 120, 120, 121, 122,
566 122, 123, 123, 124, 124, 124, 125, 125,
567 125, 125, 125, 125, 125, 126, 126, 125,
568 125, 125, 125, 125, 125, 124, 124, 124,
569 123, 123, 122, 122, 121, 121, 120, 120,
570 119, 118, 117, 117, 116, 115, 114, 113,
571 112, 111, 110, 109, 108, 107, 105, 104,
572 103, 102, 100, 99, 98, 96, 95, 93,
573 92, 91, 89, 87, 86, 84, 83, 81,
574 79, 77, 76, 74, 72, 70, 69, 67,
575 65, 63, 61, 59, 57, 55, 53, 51,
576 49, 47, 45, 43, 41, 39, 37, 35,
577 33, 30, 28, 26, 24, 22, 20, 18,
578 15, 13, 11, 9, 7, 4, 2, 0,
579 -1, -3, -6, -8, -10, -12, -14, -17,
580 -19, -21, -23, -25, -27, -29, -32, -34,
581 -36, -38, -40, -42, -44, -46, -48, -50,
582 -52, -54, -56, -58, -60, -62, -64, -66,
583 -68, -70, -71, -73, -75, -77, -78, -80,
584 -82, -83, -85, -87, -88, -90, -91, -93,
585 -94, -96, -97, -98, -100, -101, -102, -104,
586 -105, -106, -107, -108, -109, -111, -112, -113,
587 -113, -114, -115, -116, -117, -118, -118, -119,
588 -120, -120, -121, -122, -122, -123, -123, -124, -124
591 static const s16 hsv_green_y[] = {
592 -100, -99, -98, -97, -95, -94, -93, -91,
593 -90, -89, -87, -86, -84, -83, -81, -80,
594 -78, -76, -75, -73, -71, -70, -68, -66,
595 -64, -63, -61, -59, -57, -55, -53, -51,
596 -49, -48, -46, -44, -42, -40, -38, -36,
597 -34, -32, -30, -27, -25, -23, -21, -19,
598 -17, -15, -13, -11, -9, -7, -4, -2,
599 0, 1, 3, 5, 7, 9, 11, 14,
600 16, 18, 20, 22, 24, 26, 28, 30,
601 32, 34, 36, 38, 40, 42, 44, 46,
602 48, 50, 52, 54, 56, 58, 59, 61,
603 63, 65, 67, 68, 70, 72, 74, 75,
604 77, 78, 80, 82, 83, 85, 86, 88,
605 89, 90, 92, 93, 95, 96, 97, 98,
606 100, 101, 102, 103, 104, 105, 106, 107,
607 108, 109, 110, 111, 112, 112, 113, 114,
608 115, 115, 116, 116, 117, 117, 118, 118,
609 119, 119, 119, 120, 120, 120, 120, 120,
610 121, 121, 121, 121, 121, 121, 120, 120,
611 120, 120, 120, 119, 119, 119, 118, 118,
612 117, 117, 116, 116, 115, 114, 114, 113,
613 112, 111, 111, 110, 109, 108, 107, 106,
614 105, 104, 103, 102, 100, 99, 98, 97,
615 95, 94, 93, 91, 90, 89, 87, 86,
616 84, 83, 81, 80, 78, 76, 75, 73,
617 71, 70, 68, 66, 64, 63, 61, 59,
618 57, 55, 53, 51, 49, 48, 46, 44,
619 42, 40, 38, 36, 34, 32, 30, 27,
620 25, 23, 21, 19, 17, 15, 13, 11,
621 9, 7, 4, 2, 0, -1, -3, -5,
622 -7, -9, -11, -14, -16, -18, -20, -22,
623 -24, -26, -28, -30, -32, -34, -36, -38,
624 -40, -42, -44, -46, -48, -50, -52, -54,
625 -56, -58, -59, -61, -63, -65, -67, -68,
626 -70, -72, -74, -75, -77, -78, -80, -82,
627 -83, -85, -86, -88, -89, -90, -92, -93,
628 -95, -96, -97, -98, -100, -101, -102, -103,
629 -104, -105, -106, -107, -108, -109, -110, -111,
630 -112, -112, -113, -114, -115, -115, -116, -116,
631 -117, -117, -118, -118, -119, -119, -119, -120,
632 -120, -120, -120, -120, -121, -121, -121, -121,
633 -121, -121, -120, -120, -120, -120, -120, -119,
634 -119, -119, -118, -118, -117, -117, -116, -116,
635 -115, -114, -114, -113, -112, -111, -111, -110,
636 -109, -108, -107, -106, -105, -104, -103, -102, -100
639 static const s16 hsv_blue_x[] = {
640 112, 113, 114, 114, 115, 116, 117, 117,
641 118, 118, 119, 119, 120, 120, 120, 121,
642 121, 121, 122, 122, 122, 122, 122, 122,
643 122, 122, 122, 122, 122, 122, 121, 121,
644 121, 120, 120, 120, 119, 119, 118, 118,
645 117, 116, 116, 115, 114, 113, 113, 112,
646 111, 110, 109, 108, 107, 106, 105, 104,
647 103, 102, 100, 99, 98, 97, 95, 94,
648 93, 91, 90, 88, 87, 85, 84, 82,
649 80, 79, 77, 76, 74, 72, 70, 69,
650 67, 65, 63, 61, 60, 58, 56, 54,
651 52, 50, 48, 46, 44, 42, 40, 38,
652 36, 34, 32, 30, 28, 26, 24, 22,
653 19, 17, 15, 13, 11, 9, 7, 5,
654 2, 0, -1, -3, -5, -7, -9, -12,
655 -14, -16, -18, -20, -22, -24, -26, -28,
656 -31, -33, -35, -37, -39, -41, -43, -45,
657 -47, -49, -51, -53, -54, -56, -58, -60,
658 -62, -64, -66, -67, -69, -71, -73, -74,
659 -76, -78, -79, -81, -83, -84, -86, -87,
660 -89, -90, -92, -93, -94, -96, -97, -98,
661 -99, -101, -102, -103, -104, -105, -106, -107,
662 -108, -109, -110, -111, -112, -113, -114, -114,
663 -115, -116, -117, -117, -118, -118, -119, -119,
664 -120, -120, -120, -121, -121, -121, -122, -122,
665 -122, -122, -122, -122, -122, -122, -122, -122,
666 -122, -122, -121, -121, -121, -120, -120, -120,
667 -119, -119, -118, -118, -117, -116, -116, -115,
668 -114, -113, -113, -112, -111, -110, -109, -108,
669 -107, -106, -105, -104, -103, -102, -100, -99,
670 -98, -97, -95, -94, -93, -91, -90, -88,
671 -87, -85, -84, -82, -80, -79, -77, -76,
672 -74, -72, -70, -69, -67, -65, -63, -61,
673 -60, -58, -56, -54, -52, -50, -48, -46,
674 -44, -42, -40, -38, -36, -34, -32, -30,
675 -28, -26, -24, -22, -19, -17, -15, -13,
676 -11, -9, -7, -5, -2, 0, 1, 3,
677 5, 7, 9, 12, 14, 16, 18, 20,
678 22, 24, 26, 28, 31, 33, 35, 37,
679 39, 41, 43, 45, 47, 49, 51, 53,
680 54, 56, 58, 60, 62, 64, 66, 67,
681 69, 71, 73, 74, 76, 78, 79, 81,
682 83, 84, 86, 87, 89, 90, 92, 93,
683 94, 96, 97, 98, 99, 101, 102, 103,
684 104, 105, 106, 107, 108, 109, 110, 111, 112
687 static const s16 hsv_blue_y[] = {
688 -11, -13, -15, -17, -19, -21, -23, -25,
689 -27, -29, -31, -33, -35, -37, -39, -41,
690 -43, -45, -46, -48, -50, -52, -54, -55,
691 -57, -59, -61, -62, -64, -66, -67, -69,
692 -71, -72, -74, -75, -77, -78, -80, -81,
693 -83, -84, -86, -87, -88, -90, -91, -92,
694 -93, -95, -96, -97, -98, -99, -100, -101,
695 -102, -103, -104, -105, -106, -106, -107, -108,
696 -109, -109, -110, -111, -111, -112, -112, -113,
697 -113, -114, -114, -114, -115, -115, -115, -115,
698 -116, -116, -116, -116, -116, -116, -116, -116,
699 -116, -115, -115, -115, -115, -114, -114, -114,
700 -113, -113, -112, -112, -111, -111, -110, -110,
701 -109, -108, -108, -107, -106, -105, -104, -103,
702 -102, -101, -100, -99, -98, -97, -96, -95,
703 -94, -93, -91, -90, -89, -88, -86, -85,
704 -84, -82, -81, -79, -78, -76, -75, -73,
705 -71, -70, -68, -67, -65, -63, -62, -60,
706 -58, -56, -55, -53, -51, -49, -47, -45,
707 -44, -42, -40, -38, -36, -34, -32, -30,
708 -28, -26, -24, -22, -20, -18, -16, -14,
709 -12, -10, -8, -6, -4, -2, 0, 1,
710 3, 5, 7, 9, 11, 13, 15, 17,
711 19, 21, 23, 25, 27, 29, 31, 33,
712 35, 37, 39, 41, 43, 45, 46, 48,
713 50, 52, 54, 55, 57, 59, 61, 62,
714 64, 66, 67, 69, 71, 72, 74, 75,
715 77, 78, 80, 81, 83, 84, 86, 87,
716 88, 90, 91, 92, 93, 95, 96, 97,
717 98, 99, 100, 101, 102, 103, 104, 105,
718 106, 106, 107, 108, 109, 109, 110, 111,
719 111, 112, 112, 113, 113, 114, 114, 114,
720 115, 115, 115, 115, 116, 116, 116, 116,
721 116, 116, 116, 116, 116, 115, 115, 115,
722 115, 114, 114, 114, 113, 113, 112, 112,
723 111, 111, 110, 110, 109, 108, 108, 107,
724 106, 105, 104, 103, 102, 101, 100, 99,
725 98, 97, 96, 95, 94, 93, 91, 90,
726 89, 88, 86, 85, 84, 82, 81, 79,
727 78, 76, 75, 73, 71, 70, 68, 67,
728 65, 63, 62, 60, 58, 56, 55, 53,
729 51, 49, 47, 45, 44, 42, 40, 38,
730 36, 34, 32, 30, 28, 26, 24, 22,
731 20, 18, 16, 14, 12, 10, 8, 6,
732 4, 2, 0, -1, -3, -5, -7, -9, -11
735 static u16 i2c_ident[] = {
744 V4L2_IDENT_MT9M001C12ST,
750 static u16 bridge_init[][2] = {
751 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
752 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
753 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
754 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
755 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
756 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
757 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
758 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
759 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
760 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
761 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
762 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
763 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
764 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
765 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
766 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
767 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
768 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
769 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
773 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
774 static u8 ov_gain[] = {
775 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
776 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
777 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
778 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
779 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
780 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
781 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
785 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
786 static u16 micron1_gain[] = {
787 /* 1x 1.25x 1.5x 1.75x */
788 0x0020, 0x0028, 0x0030, 0x0038,
789 /* 2x 2.25x 2.5x 2.75x */
790 0x00a0, 0x00a4, 0x00a8, 0x00ac,
791 /* 3x 3.25x 3.5x 3.75x */
792 0x00b0, 0x00b4, 0x00b8, 0x00bc,
793 /* 4x 4.25x 4.5x 4.75x */
794 0x00c0, 0x00c4, 0x00c8, 0x00cc,
795 /* 5x 5.25x 5.5x 5.75x */
796 0x00d0, 0x00d4, 0x00d8, 0x00dc,
797 /* 6x 6.25x 6.5x 6.75x */
798 0x00e0, 0x00e4, 0x00e8, 0x00ec,
799 /* 7x 7.25x 7.5x 7.75x */
800 0x00f0, 0x00f4, 0x00f8, 0x00fc,
805 /* mt9m001 sensor uses a different gain formula then other micron sensors */
806 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
807 static u16 micron2_gain[] = {
808 /* 1x 1.25x 1.5x 1.75x */
809 0x0008, 0x000a, 0x000c, 0x000e,
810 /* 2x 2.25x 2.5x 2.75x */
811 0x0010, 0x0012, 0x0014, 0x0016,
812 /* 3x 3.25x 3.5x 3.75x */
813 0x0018, 0x001a, 0x001c, 0x001e,
814 /* 4x 4.25x 4.5x 4.75x */
815 0x0020, 0x0051, 0x0052, 0x0053,
816 /* 5x 5.25x 5.5x 5.75x */
817 0x0054, 0x0055, 0x0056, 0x0057,
818 /* 6x 6.25x 6.5x 6.75x */
819 0x0058, 0x0059, 0x005a, 0x005b,
820 /* 7x 7.25x 7.5x 7.75x */
821 0x005c, 0x005d, 0x005e, 0x005f,
826 /* Gain = .5 + bit[7:0] / 16 */
827 static u8 hv7131r_gain[] = {
828 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
829 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
830 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
831 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
832 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
833 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
834 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
838 static struct i2c_reg_u8 soi968_init[] = {
839 {0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f},
840 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
841 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
842 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
843 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
844 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
845 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
846 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
847 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
848 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
849 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
852 static struct i2c_reg_u8 ov7660_init[] = {
853 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
854 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
855 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
856 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
857 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6},
858 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
861 static struct i2c_reg_u8 ov7670_init[] = {
862 {0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
863 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
864 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
865 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
866 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
867 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
868 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
869 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
870 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
871 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
872 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
873 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
874 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
875 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
876 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
877 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
878 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
879 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
880 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
881 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
882 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
883 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
884 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
885 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
886 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
887 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
888 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
889 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
890 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
891 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
892 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
893 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
894 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
895 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
896 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
897 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
898 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
899 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
900 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
901 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
902 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
903 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
904 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
905 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
906 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
907 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
908 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
909 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
910 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
911 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
912 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
913 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
914 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
918 static struct i2c_reg_u8 ov9650_init[] = {
919 {0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78},
920 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
921 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
922 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
923 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
924 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
925 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
926 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
927 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
928 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
929 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
930 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
931 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
932 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
933 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
934 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
935 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
936 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
937 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
938 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
939 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
940 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
941 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
942 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
943 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
944 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
945 {0xaa, 0x92}, {0xab, 0x0a},
948 static struct i2c_reg_u8 ov9655_init[] = {
949 {0x12, 0x80}, {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
950 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
951 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
952 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
953 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
954 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
955 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
956 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
957 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
958 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
959 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
960 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
961 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
962 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
963 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
964 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
965 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
966 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
967 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
968 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
969 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
970 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
971 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
972 {0x04, 0x03}, {0x00, 0x13},
975 static struct i2c_reg_u16 mt9v112_init[] = {
976 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
977 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
978 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
979 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
980 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
981 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
982 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
983 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
984 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
985 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
986 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
987 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
988 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
989 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
990 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
991 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
994 static struct i2c_reg_u16 mt9v111_init[] = {
995 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
996 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
997 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
998 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
999 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
1000 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
1001 {0x0e, 0x0008}, {0x20, 0x0000}
1004 static struct i2c_reg_u16 mt9v011_init[] = {
1005 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
1006 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
1007 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
1008 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
1009 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
1010 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
1011 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
1012 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
1013 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
1014 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
1015 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
1016 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
1017 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
1018 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
1019 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
1020 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
1021 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
1022 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
1023 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
1024 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
1025 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
1026 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1027 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
1028 {0x06, 0x0029}, {0x05, 0x0009},
1031 static struct i2c_reg_u16 mt9m001_init[] = {
1032 {0x0d, 0x0001}, {0x0d, 0x0000}, {0x01, 0x000e},
1033 {0x02, 0x0014}, {0x03, 0x03c1}, {0x04, 0x0501},
1034 {0x05, 0x0083}, {0x06, 0x0006}, {0x0d, 0x0002},
1035 {0x0a, 0x0000}, {0x0c, 0x0000}, {0x11, 0x0000},
1036 {0x1e, 0x8000}, {0x5f, 0x8904}, {0x60, 0x0000},
1037 {0x61, 0x0000}, {0x62, 0x0498}, {0x63, 0x0000},
1038 {0x64, 0x0000}, {0x20, 0x111d}, {0x06, 0x00f2},
1039 {0x05, 0x0013}, {0x09, 0x10f2}, {0x07, 0x0003},
1040 {0x2b, 0x002a}, {0x2d, 0x002a}, {0x2c, 0x002a},
1041 {0x2e, 0x0029}, {0x07, 0x0002},
1044 static struct i2c_reg_u16 mt9m111_init[] = {
1045 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1046 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1047 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1051 static struct i2c_reg_u16 mt9m112_init[] = {
1052 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1053 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1054 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1058 static struct i2c_reg_u8 hv7131r_init[] = {
1059 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
1060 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
1061 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
1062 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
1063 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
1064 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
1065 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
1066 {0x23, 0x09}, {0x01, 0x08},
1069 static int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
1071 struct usb_device *dev = gspca_dev->dev;
1073 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
1075 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1081 if (unlikely(result < 0 || result != length)) {
1082 err("Read register failed 0x%02X", reg);
1088 static int reg_w(struct gspca_dev *gspca_dev, u16 reg,
1089 const u8 *buffer, int length)
1091 struct usb_device *dev = gspca_dev->dev;
1093 memcpy(gspca_dev->usb_buf, buffer, length);
1094 result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1096 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1102 if (unlikely(result < 0 || result != length)) {
1103 err("Write register failed index 0x%02X", reg);
1109 static int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
1111 u8 data[1] = {value};
1112 return reg_w(gspca_dev, reg, data, 1);
1115 static int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
1118 reg_w(gspca_dev, 0x10c0, buffer, 8);
1119 for (i = 0; i < 5; i++) {
1120 reg_r(gspca_dev, 0x10c0, 1);
1121 if (gspca_dev->usb_buf[0] & 0x04) {
1122 if (gspca_dev->usb_buf[0] & 0x08)
1131 static int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1133 struct sd *sd = (struct sd *) gspca_dev;
1138 * from the point of view of the bridge, the length
1139 * includes the address
1141 row[0] = 0x81 | (2 << 4);
1142 row[1] = sd->i2c_addr;
1150 return i2c_w(gspca_dev, row);
1153 static int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1155 struct sd *sd = (struct sd *) gspca_dev;
1159 * from the point of view of the bridge, the length
1160 * includes the address
1162 row[0] = 0x81 | (3 << 4);
1163 row[1] = sd->i2c_addr;
1165 row[3] = (val >> 8) & 0xff;
1166 row[4] = val & 0xff;
1171 return i2c_w(gspca_dev, row);
1174 static int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1176 struct sd *sd = (struct sd *) gspca_dev;
1179 row[0] = 0x81 | (1 << 4);
1180 row[1] = sd->i2c_addr;
1187 if (i2c_w(gspca_dev, row) < 0)
1189 row[0] = 0x81 | (1 << 4) | 0x02;
1191 if (i2c_w(gspca_dev, row) < 0)
1193 if (reg_r(gspca_dev, 0x10c2, 5) < 0)
1195 *val = gspca_dev->usb_buf[4];
1199 static int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1201 struct sd *sd = (struct sd *) gspca_dev;
1204 row[0] = 0x81 | (1 << 4);
1205 row[1] = sd->i2c_addr;
1212 if (i2c_w(gspca_dev, row) < 0)
1214 row[0] = 0x81 | (2 << 4) | 0x02;
1216 if (i2c_w(gspca_dev, row) < 0)
1218 if (reg_r(gspca_dev, 0x10c2, 5) < 0)
1220 *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1224 static int ov9650_init_sensor(struct gspca_dev *gspca_dev)
1227 struct sd *sd = (struct sd *) gspca_dev;
1229 for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) {
1230 if (i2c_w1(gspca_dev, ov9650_init[i].reg,
1231 ov9650_init[i].val) < 0) {
1232 err("OV9650 sensor initialization failed");
1241 static int ov9655_init_sensor(struct gspca_dev *gspca_dev)
1244 struct sd *sd = (struct sd *) gspca_dev;
1246 for (i = 0; i < ARRAY_SIZE(ov9655_init); i++) {
1247 if (i2c_w1(gspca_dev, ov9655_init[i].reg,
1248 ov9655_init[i].val) < 0) {
1249 err("OV9655 sensor initialization failed");
1253 /* disable hflip and vflip */
1254 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1260 static int soi968_init_sensor(struct gspca_dev *gspca_dev)
1263 struct sd *sd = (struct sd *) gspca_dev;
1265 for (i = 0; i < ARRAY_SIZE(soi968_init); i++) {
1266 if (i2c_w1(gspca_dev, soi968_init[i].reg,
1267 soi968_init[i].val) < 0) {
1268 err("SOI968 sensor initialization failed");
1272 /* disable hflip and vflip */
1273 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX)
1274 | (1 << EXPOSURE_IDX);
1280 static int ov7660_init_sensor(struct gspca_dev *gspca_dev)
1283 struct sd *sd = (struct sd *) gspca_dev;
1285 for (i = 0; i < ARRAY_SIZE(ov7660_init); i++) {
1286 if (i2c_w1(gspca_dev, ov7660_init[i].reg,
1287 ov7660_init[i].val) < 0) {
1288 err("OV7660 sensor initialization failed");
1292 /* disable hflip and vflip */
1293 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1299 static int ov7670_init_sensor(struct gspca_dev *gspca_dev)
1302 struct sd *sd = (struct sd *) gspca_dev;
1304 for (i = 0; i < ARRAY_SIZE(ov7670_init); i++) {
1305 if (i2c_w1(gspca_dev, ov7670_init[i].reg,
1306 ov7670_init[i].val) < 0) {
1307 err("OV7670 sensor initialization failed");
1311 /* disable hflip and vflip */
1312 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1318 static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
1320 struct sd *sd = (struct sd *) gspca_dev;
1325 sd->i2c_addr = 0x5d;
1326 ret = i2c_r2(gspca_dev, 0xff, &value);
1327 if ((ret == 0) && (value == 0x8243)) {
1328 for (i = 0; i < ARRAY_SIZE(mt9v011_init); i++) {
1329 if (i2c_w2(gspca_dev, mt9v011_init[i].reg,
1330 mt9v011_init[i].val) < 0) {
1331 err("MT9V011 sensor initialization failed");
1337 sd->sensor = SENSOR_MT9V011;
1338 info("MT9V011 sensor detected");
1342 sd->i2c_addr = 0x5c;
1343 i2c_w2(gspca_dev, 0x01, 0x0004);
1344 ret = i2c_r2(gspca_dev, 0xff, &value);
1345 if ((ret == 0) && (value == 0x823a)) {
1346 for (i = 0; i < ARRAY_SIZE(mt9v111_init); i++) {
1347 if (i2c_w2(gspca_dev, mt9v111_init[i].reg,
1348 mt9v111_init[i].val) < 0) {
1349 err("MT9V111 sensor initialization failed");
1353 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX)
1354 | (1 << AUTOGAIN_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)
1406 static int mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1408 struct sd *sd = (struct sd *) gspca_dev;
1410 for (i = 0; i < ARRAY_SIZE(mt9m111_init); i++) {
1411 if (i2c_w2(gspca_dev, mt9m111_init[i].reg,
1412 mt9m111_init[i].val) < 0) {
1413 err("MT9M111 sensor initialization failed");
1417 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX)
1424 static int mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1426 struct sd *sd = (struct sd *) gspca_dev;
1428 for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) {
1429 if (i2c_w2(gspca_dev, mt9m001_init[i].reg,
1430 mt9m001_init[i].val) < 0) {
1431 err("MT9M001 sensor initialization failed");
1435 /* disable hflip and vflip */
1436 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1442 static int hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1445 struct sd *sd = (struct sd *) gspca_dev;
1447 for (i = 0; i < ARRAY_SIZE(hv7131r_init); i++) {
1448 if (i2c_w1(gspca_dev, hv7131r_init[i].reg,
1449 hv7131r_init[i].val) < 0) {
1450 err("HV7131R Sensor initialization failed");
1459 static int set_cmatrix(struct gspca_dev *gspca_dev)
1461 struct sd *sd = (struct sd *) gspca_dev;
1462 s32 hue_coord, hue_index = 180 + sd->hue;
1465 memset(cmatrix, 0, sizeof cmatrix);
1466 cmatrix[2] = (sd->contrast * 0x25 / 0x100) + 0x26;
1467 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1468 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1469 cmatrix[18] = sd->brightness - 0x80;
1471 hue_coord = (hsv_red_x[hue_index] * sd->saturation) >> 8;
1472 cmatrix[6] = hue_coord;
1473 cmatrix[7] = (hue_coord >> 8) & 0x0f;
1475 hue_coord = (hsv_red_y[hue_index] * sd->saturation) >> 8;
1476 cmatrix[8] = hue_coord;
1477 cmatrix[9] = (hue_coord >> 8) & 0x0f;
1479 hue_coord = (hsv_green_x[hue_index] * sd->saturation) >> 8;
1480 cmatrix[10] = hue_coord;
1481 cmatrix[11] = (hue_coord >> 8) & 0x0f;
1483 hue_coord = (hsv_green_y[hue_index] * sd->saturation) >> 8;
1484 cmatrix[12] = hue_coord;
1485 cmatrix[13] = (hue_coord >> 8) & 0x0f;
1487 hue_coord = (hsv_blue_x[hue_index] * sd->saturation) >> 8;
1488 cmatrix[14] = hue_coord;
1489 cmatrix[15] = (hue_coord >> 8) & 0x0f;
1491 hue_coord = (hsv_blue_y[hue_index] * sd->saturation) >> 8;
1492 cmatrix[16] = hue_coord;
1493 cmatrix[17] = (hue_coord >> 8) & 0x0f;
1495 return reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1498 static int set_gamma(struct gspca_dev *gspca_dev)
1500 struct sd *sd = (struct sd *) gspca_dev;
1502 u8 gval = sd->gamma * 0xb8 / 0x100;
1506 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
1507 gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8);
1508 gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8);
1509 gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8);
1510 gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8);
1511 gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8);
1512 gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8);
1513 gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8);
1514 gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8);
1515 gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8);
1516 gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8);
1517 gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8);
1518 gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8);
1519 gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8);
1520 gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
1523 return reg_w(gspca_dev, 0x1190, gamma, 17);
1526 static int set_redblue(struct gspca_dev *gspca_dev)
1528 struct sd *sd = (struct sd *) gspca_dev;
1529 reg_w1(gspca_dev, 0x118c, sd->red);
1530 reg_w1(gspca_dev, 0x118f, sd->blue);
1534 static int set_hvflip(struct gspca_dev *gspca_dev)
1536 u8 value, tslb, hflip, vflip;
1538 struct sd *sd = (struct sd *) gspca_dev;
1540 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1548 switch (sd->sensor) {
1550 i2c_r1(gspca_dev, 0x1e, &value);
1559 i2c_w1(gspca_dev, 0x1e, value);
1560 i2c_w1(gspca_dev, 0x3a, tslb);
1562 case SENSOR_MT9V111:
1563 case SENSOR_MT9V011:
1564 i2c_r2(gspca_dev, 0x20, &value2);
1570 i2c_w2(gspca_dev, 0x20, value2);
1572 case SENSOR_MT9M112:
1573 case SENSOR_MT9M111:
1574 case SENSOR_MT9V112:
1575 i2c_r2(gspca_dev, 0x20, &value2);
1581 i2c_w2(gspca_dev, 0x20, value2);
1583 case SENSOR_HV7131R:
1584 i2c_r1(gspca_dev, 0x01, &value);
1590 i2c_w1(gspca_dev, 0x01, value);
1596 static int set_exposure(struct gspca_dev *gspca_dev)
1598 struct sd *sd = (struct sd *) gspca_dev;
1599 u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1600 switch (sd->sensor) {
1607 exp[3] = sd->exposure & 0xff;
1608 exp[4] = sd->exposure >> 8;
1610 case SENSOR_MT9M001:
1611 case SENSOR_MT9V112:
1612 case SENSOR_MT9V011:
1615 exp[3] = sd->exposure >> 8;
1616 exp[4] = sd->exposure & 0xff;
1618 case SENSOR_HV7131R:
1621 exp[3] = (sd->exposure >> 5) & 0xff;
1622 exp[4] = (sd->exposure << 3) & 0xff;
1628 i2c_w(gspca_dev, exp);
1632 static int set_gain(struct gspca_dev *gspca_dev)
1634 struct sd *sd = (struct sd *) gspca_dev;
1635 u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1636 switch (sd->sensor) {
1642 gain[0] |= (2 << 4);
1643 gain[3] = ov_gain[sd->gain];
1645 case SENSOR_MT9V011:
1646 gain[0] |= (3 << 4);
1648 gain[3] = micron1_gain[sd->gain] >> 8;
1649 gain[4] = micron1_gain[sd->gain] & 0xff;
1651 case SENSOR_MT9V112:
1652 gain[0] |= (3 << 4);
1654 gain[3] = micron1_gain[sd->gain] >> 8;
1655 gain[4] = micron1_gain[sd->gain] & 0xff;
1657 case SENSOR_MT9M001:
1658 gain[0] |= (3 << 4);
1660 gain[3] = micron2_gain[sd->gain] >> 8;
1661 gain[4] = micron2_gain[sd->gain] & 0xff;
1663 case SENSOR_HV7131R:
1664 gain[0] |= (2 << 4);
1666 gain[3] = hv7131r_gain[sd->gain];
1671 i2c_w(gspca_dev, gain);
1675 static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val)
1677 struct sd *sd = (struct sd *) gspca_dev;
1679 sd->brightness = val;
1680 if (gspca_dev->streaming)
1681 return set_cmatrix(gspca_dev);
1685 static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val)
1687 struct sd *sd = (struct sd *) gspca_dev;
1688 *val = sd->brightness;
1693 static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val)
1695 struct sd *sd = (struct sd *) gspca_dev;
1698 if (gspca_dev->streaming)
1699 return set_cmatrix(gspca_dev);
1703 static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val)
1705 struct sd *sd = (struct sd *) gspca_dev;
1706 *val = sd->contrast;
1710 static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val)
1712 struct sd *sd = (struct sd *) gspca_dev;
1714 sd->saturation = val;
1715 if (gspca_dev->streaming)
1716 return set_cmatrix(gspca_dev);
1720 static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val)
1722 struct sd *sd = (struct sd *) gspca_dev;
1723 *val = sd->saturation;
1727 static int sd_sethue(struct gspca_dev *gspca_dev, s32 val)
1729 struct sd *sd = (struct sd *) gspca_dev;
1732 if (gspca_dev->streaming)
1733 return set_cmatrix(gspca_dev);
1737 static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val)
1739 struct sd *sd = (struct sd *) gspca_dev;
1744 static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val)
1746 struct sd *sd = (struct sd *) gspca_dev;
1749 if (gspca_dev->streaming)
1750 return set_gamma(gspca_dev);
1754 static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val)
1756 struct sd *sd = (struct sd *) gspca_dev;
1761 static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val)
1763 struct sd *sd = (struct sd *) gspca_dev;
1766 if (gspca_dev->streaming)
1767 return set_redblue(gspca_dev);
1771 static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val)
1773 struct sd *sd = (struct sd *) gspca_dev;
1778 static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val)
1780 struct sd *sd = (struct sd *) gspca_dev;
1783 if (gspca_dev->streaming)
1784 return set_redblue(gspca_dev);
1788 static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val)
1790 struct sd *sd = (struct sd *) gspca_dev;
1795 static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val)
1797 struct sd *sd = (struct sd *) gspca_dev;
1800 if (gspca_dev->streaming)
1801 return set_hvflip(gspca_dev);
1805 static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val)
1807 struct sd *sd = (struct sd *) gspca_dev;
1812 static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val)
1814 struct sd *sd = (struct sd *) gspca_dev;
1817 if (gspca_dev->streaming)
1818 return set_hvflip(gspca_dev);
1822 static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val)
1824 struct sd *sd = (struct sd *) gspca_dev;
1829 static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val)
1831 struct sd *sd = (struct sd *) gspca_dev;
1834 if (gspca_dev->streaming)
1835 return set_exposure(gspca_dev);
1839 static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val)
1841 struct sd *sd = (struct sd *) gspca_dev;
1842 *val = sd->exposure;
1846 static int sd_setgain(struct gspca_dev *gspca_dev, s32 val)
1848 struct sd *sd = (struct sd *) gspca_dev;
1851 if (gspca_dev->streaming)
1852 return set_gain(gspca_dev);
1856 static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val)
1858 struct sd *sd = (struct sd *) gspca_dev;
1863 static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val)
1865 struct sd *sd = (struct sd *) gspca_dev;
1866 sd->auto_exposure = val;
1870 static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val)
1872 struct sd *sd = (struct sd *) gspca_dev;
1873 *val = sd->auto_exposure;
1877 #ifdef CONFIG_VIDEO_ADV_DEBUG
1878 static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1879 struct v4l2_dbg_register *reg)
1881 struct sd *sd = (struct sd *) gspca_dev;
1882 switch (reg->match.type) {
1883 case V4L2_CHIP_MATCH_HOST:
1884 if (reg->match.addr != 0)
1886 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1888 if (reg_r(gspca_dev, reg->reg, 1) < 0)
1890 reg->val = gspca_dev->usb_buf[0];
1892 case V4L2_CHIP_MATCH_I2C_ADDR:
1893 if (reg->match.addr != sd->i2c_addr)
1895 if (sd->sensor >= SENSOR_MT9V011 &&
1896 sd->sensor <= SENSOR_MT9M112) {
1897 if (i2c_r2(gspca_dev, reg->reg, (u16 *)®->val) < 0)
1900 if (i2c_r1(gspca_dev, reg->reg, (u8 *)®->val) < 0)
1908 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1909 struct v4l2_dbg_register *reg)
1911 struct sd *sd = (struct sd *) gspca_dev;
1912 switch (reg->match.type) {
1913 case V4L2_CHIP_MATCH_HOST:
1914 if (reg->match.addr != 0)
1916 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1918 if (reg_w1(gspca_dev, reg->reg, reg->val) < 0)
1921 case V4L2_CHIP_MATCH_I2C_ADDR:
1922 if (reg->match.addr != sd->i2c_addr)
1924 if (sd->sensor >= SENSOR_MT9V011 &&
1925 sd->sensor <= SENSOR_MT9M112) {
1926 if (i2c_w2(gspca_dev, reg->reg, reg->val) < 0)
1929 if (i2c_w1(gspca_dev, reg->reg, reg->val) < 0)
1938 static int sd_chip_ident(struct gspca_dev *gspca_dev,
1939 struct v4l2_dbg_chip_ident *chip)
1941 struct sd *sd = (struct sd *) gspca_dev;
1943 switch (chip->match.type) {
1944 case V4L2_CHIP_MATCH_HOST:
1945 if (chip->match.addr != 0)
1948 chip->ident = V4L2_IDENT_SN9C20X;
1950 case V4L2_CHIP_MATCH_I2C_ADDR:
1951 if (chip->match.addr != sd->i2c_addr)
1954 chip->ident = i2c_ident[sd->sensor];
1960 static int sd_config(struct gspca_dev *gspca_dev,
1961 const struct usb_device_id *id)
1963 struct sd *sd = (struct sd *) gspca_dev;
1966 cam = &gspca_dev->cam;
1968 sd->sensor = (id->driver_info >> 8) & 0xff;
1969 sd->i2c_addr = id->driver_info & 0xff;
1970 sd->flags = (id->driver_info >> 16) & 0xff;
1972 switch (sd->sensor) {
1973 case SENSOR_MT9M112:
1974 case SENSOR_MT9M111:
1977 cam->cam_mode = sxga_mode;
1978 cam->nmodes = ARRAY_SIZE(sxga_mode);
1981 cam->cam_mode = vga_mode;
1982 cam->nmodes = ARRAY_SIZE(vga_mode);
1988 sd->exposure_step = 16;
1990 sd->brightness = BRIGHTNESS_DEFAULT;
1991 sd->contrast = CONTRAST_DEFAULT;
1992 sd->saturation = SATURATION_DEFAULT;
1993 sd->hue = HUE_DEFAULT;
1994 sd->gamma = GAMMA_DEFAULT;
1995 sd->red = RED_DEFAULT;
1996 sd->blue = BLUE_DEFAULT;
1998 sd->hflip = HFLIP_DEFAULT;
1999 sd->vflip = VFLIP_DEFAULT;
2000 sd->exposure = EXPOSURE_DEFAULT;
2001 sd->gain = GAIN_DEFAULT;
2002 sd->auto_exposure = AUTO_EXPOSURE_DEFAULT;
2009 static int sd_init(struct gspca_dev *gspca_dev)
2011 struct sd *sd = (struct sd *) gspca_dev;
2015 {0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
2017 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
2018 value = bridge_init[i][1];
2019 if (reg_w(gspca_dev, bridge_init[i][0], &value, 1) < 0) {
2020 err("Device initialization failed");
2025 if (sd->flags & LED_REVERSE)
2026 reg_w1(gspca_dev, 0x1006, 0x00);
2028 reg_w1(gspca_dev, 0x1006, 0x20);
2030 if (reg_w(gspca_dev, 0x10c0, i2c_init, 9) < 0) {
2031 err("Device initialization failed");
2035 switch (sd->sensor) {
2037 if (ov9650_init_sensor(gspca_dev) < 0)
2039 info("OV9650 sensor detected");
2042 if (ov9655_init_sensor(gspca_dev) < 0)
2044 info("OV9655 sensor detected");
2047 if (soi968_init_sensor(gspca_dev) < 0)
2049 info("SOI968 sensor detected");
2052 if (ov7660_init_sensor(gspca_dev) < 0)
2054 info("OV7660 sensor detected");
2057 if (ov7670_init_sensor(gspca_dev) < 0)
2059 info("OV7670 sensor detected");
2061 case SENSOR_MT9VPRB:
2062 if (mt9v_init_sensor(gspca_dev) < 0)
2065 case SENSOR_MT9M111:
2066 if (mt9m111_init_sensor(gspca_dev) < 0)
2068 info("MT9M111 sensor detected");
2070 case SENSOR_MT9M112:
2071 if (mt9m112_init_sensor(gspca_dev) < 0)
2073 info("MT9M112 sensor detected");
2075 case SENSOR_MT9M001:
2076 if (mt9m001_init_sensor(gspca_dev) < 0)
2078 info("MT9M001 sensor detected");
2080 case SENSOR_HV7131R:
2081 if (hv7131r_init_sensor(gspca_dev) < 0)
2083 info("HV7131R sensor detected");
2086 info("Unsupported Sensor");
2093 static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
2095 struct sd *sd = (struct sd *) gspca_dev;
2097 switch (sd->sensor) {
2099 if (mode & MODE_SXGA) {
2100 i2c_w1(gspca_dev, 0x17, 0x1d);
2101 i2c_w1(gspca_dev, 0x18, 0xbd);
2102 i2c_w1(gspca_dev, 0x19, 0x01);
2103 i2c_w1(gspca_dev, 0x1a, 0x81);
2104 i2c_w1(gspca_dev, 0x12, 0x00);
2108 i2c_w1(gspca_dev, 0x17, 0x13);
2109 i2c_w1(gspca_dev, 0x18, 0x63);
2110 i2c_w1(gspca_dev, 0x19, 0x01);
2111 i2c_w1(gspca_dev, 0x1a, 0x79);
2112 i2c_w1(gspca_dev, 0x12, 0x40);
2118 if (mode & MODE_SXGA) {
2119 i2c_w1(gspca_dev, 0x17, 0x1b);
2120 i2c_w1(gspca_dev, 0x18, 0xbc);
2121 i2c_w1(gspca_dev, 0x19, 0x01);
2122 i2c_w1(gspca_dev, 0x1a, 0x82);
2123 i2c_r1(gspca_dev, 0x12, &value);
2124 i2c_w1(gspca_dev, 0x12, value & 0x07);
2126 i2c_w1(gspca_dev, 0x17, 0x24);
2127 i2c_w1(gspca_dev, 0x18, 0xc5);
2128 i2c_w1(gspca_dev, 0x19, 0x00);
2129 i2c_w1(gspca_dev, 0x1a, 0x3c);
2130 i2c_r1(gspca_dev, 0x12, &value);
2131 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
2134 case SENSOR_MT9M112:
2135 case SENSOR_MT9M111:
2136 if (mode & MODE_SXGA) {
2137 i2c_w2(gspca_dev, 0xf0, 0x0002);
2138 i2c_w2(gspca_dev, 0xc8, 0x970b);
2139 i2c_w2(gspca_dev, 0xf0, 0x0000);
2141 i2c_w2(gspca_dev, 0xf0, 0x0002);
2142 i2c_w2(gspca_dev, 0xc8, 0x8000);
2143 i2c_w2(gspca_dev, 0xf0, 0x0000);
2149 #define HW_WIN(mode, hstart, vstart) \
2150 ((const u8 []){hstart, 0, vstart, 0, \
2151 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
2152 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
2154 #define CLR_WIN(width, height) \
2156 {0, width >> 2, 0, height >> 1,\
2157 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
2159 static int sd_start(struct gspca_dev *gspca_dev)
2161 struct sd *sd = (struct sd *) gspca_dev;
2162 int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
2163 int width = gspca_dev->width;
2164 int height = gspca_dev->height;
2167 jpeg_define(sd->jpeg_hdr, height, width,
2169 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2171 if (mode & MODE_RAW)
2173 else if (mode & MODE_JPEG)
2178 switch (mode & 0x0f) {
2181 info("Set 1280x1024");
2185 info("Set 640x480");
2189 info("Set 320x240");
2193 info("Set 160x120");
2197 configure_sensor_output(gspca_dev, mode);
2198 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2199 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2200 reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2201 reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2202 reg_w1(gspca_dev, 0x1189, scale);
2203 reg_w1(gspca_dev, 0x10e0, fmt);
2205 set_cmatrix(gspca_dev);
2206 set_gamma(gspca_dev);
2207 set_redblue(gspca_dev);
2208 set_gain(gspca_dev);
2209 set_exposure(gspca_dev);
2210 set_hvflip(gspca_dev);
2212 reg_w1(gspca_dev, 0x1007, 0x20);
2214 reg_r(gspca_dev, 0x1061, 1);
2215 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] | 0x02);
2219 static void sd_stopN(struct gspca_dev *gspca_dev)
2221 reg_w1(gspca_dev, 0x1007, 0x00);
2223 reg_r(gspca_dev, 0x1061, 1);
2224 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] & ~0x02);
2227 static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2229 struct sd *sd = (struct sd *) gspca_dev;
2233 * some hardcoded values are present
2234 * like those for maximal/minimal exposure
2235 * and exposure steps
2237 if (avg_lum < MIN_AVG_LUM) {
2238 if (sd->exposure > 0x1770)
2241 new_exp = sd->exposure + sd->exposure_step;
2242 if (new_exp > 0x1770)
2246 sd->exposure = new_exp;
2247 set_exposure(gspca_dev);
2249 sd->older_step = sd->old_step;
2252 if (sd->old_step ^ sd->older_step)
2253 sd->exposure_step /= 2;
2255 sd->exposure_step += 2;
2257 if (avg_lum > MAX_AVG_LUM) {
2258 if (sd->exposure < 0x10)
2260 new_exp = sd->exposure - sd->exposure_step;
2261 if (new_exp > 0x1700)
2265 sd->exposure = new_exp;
2266 set_exposure(gspca_dev);
2267 sd->older_step = sd->old_step;
2270 if (sd->old_step ^ sd->older_step)
2271 sd->exposure_step /= 2;
2273 sd->exposure_step += 2;
2277 static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2279 struct sd *sd = (struct sd *) gspca_dev;
2281 if (avg_lum < MIN_AVG_LUM) {
2282 if (sd->gain + 1 <= 28) {
2284 set_gain(gspca_dev);
2287 if (avg_lum > MAX_AVG_LUM) {
2290 set_gain(gspca_dev);
2295 static void sd_dqcallback(struct gspca_dev *gspca_dev)
2297 struct sd *sd = (struct sd *) gspca_dev;
2300 if (!sd->auto_exposure)
2303 avg_lum = atomic_read(&sd->avg_lum);
2304 if (sd->sensor == SENSOR_SOI968)
2305 do_autogain(gspca_dev, avg_lum);
2307 do_autoexposure(gspca_dev, avg_lum);
2310 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2311 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2312 u8 *data, /* interrupt packet */
2313 int len) /* interrupt packet length */
2315 struct sd *sd = (struct sd *) gspca_dev;
2317 if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
2318 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2319 input_sync(gspca_dev->input_dev);
2320 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2321 input_sync(gspca_dev->input_dev);
2328 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2329 u8 *data, /* isoc packet */
2330 int len) /* iso packet length */
2332 struct sd *sd = (struct sd *) gspca_dev;
2334 static u8 frame_header[] =
2335 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2336 if (len == 64 && memcmp(data, frame_header, 6) == 0) {
2337 avg_lum = ((data[35] >> 2) & 3) |
2340 avg_lum += ((data[35] >> 4) & 3) |
2343 avg_lum += ((data[35] >> 6) & 3) |
2346 avg_lum += (data[36] & 3) |
2349 avg_lum += ((data[36] >> 2) & 3) |
2352 avg_lum += ((data[36] >> 4) & 3) |
2355 avg_lum += ((data[36] >> 6) & 3) |
2358 avg_lum += ((data[44] >> 4) & 3) |
2362 atomic_set(&sd->avg_lum, avg_lum);
2363 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2366 if (gspca_dev->last_packet_type == LAST_PACKET) {
2367 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv
2369 gspca_frame_add(gspca_dev, FIRST_PACKET,
2370 sd->jpeg_hdr, JPEG_HDR_SZ);
2371 gspca_frame_add(gspca_dev, INTER_PACKET,
2374 gspca_frame_add(gspca_dev, FIRST_PACKET,
2378 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2382 /* sub-driver description */
2383 static const struct sd_desc sd_desc = {
2384 .name = MODULE_NAME,
2386 .nctrls = ARRAY_SIZE(sd_ctrls),
2387 .config = sd_config,
2391 .pkt_scan = sd_pkt_scan,
2392 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2393 .int_pkt_scan = sd_int_pkt_scan,
2395 .dq_callback = sd_dqcallback,
2396 #ifdef CONFIG_VIDEO_ADV_DEBUG
2397 .set_register = sd_dbg_s_register,
2398 .get_register = sd_dbg_g_register,
2400 .get_chip_ident = sd_chip_ident,
2403 #define SN9C20X(sensor, i2c_addr, flags) \
2404 .driver_info = ((flags & 0xff) << 16) \
2405 | (SENSOR_ ## sensor << 8) \
2408 static const __devinitdata struct usb_device_id device_table[] = {
2409 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2410 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
2411 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2412 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
2413 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
2414 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
2415 (FLIP_DETECT | HAS_NO_BUTTON))},
2416 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2417 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2418 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2419 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2420 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, 0)},
2421 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2422 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2423 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2424 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2425 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
2426 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
2427 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2428 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2429 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2430 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2431 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, 0)},
2432 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, 0)},
2433 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2434 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2435 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2436 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2437 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
2438 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
2439 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2440 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2441 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2442 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2443 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
2444 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2445 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2448 MODULE_DEVICE_TABLE(usb, device_table);
2450 /* -- device connect -- */
2451 static int sd_probe(struct usb_interface *intf,
2452 const struct usb_device_id *id)
2454 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2458 static struct usb_driver sd_driver = {
2459 .name = MODULE_NAME,
2460 .id_table = device_table,
2462 .disconnect = gspca_disconnect,
2464 .suspend = gspca_suspend,
2465 .resume = gspca_resume,
2466 .reset_resume = gspca_resume,
2470 /* -- module insert / remove -- */
2471 static int __init sd_mod_init(void)
2473 return usb_register(&sd_driver);
2475 static void __exit sd_mod_exit(void)
2477 usb_deregister(&sd_driver);
2480 module_init(sd_mod_init);
2481 module_exit(sd_mod_exit);