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}, {0x02, 0x0016}, {0x03, 0x01e1},
1000 {0x04, 0x0281}, {0x05, 0x0004}, {0x07, 0x3002},
1001 {0x21, 0x0000}, {0x25, 0x4024}, {0x26, 0xff03},
1002 {0x27, 0xff10}, {0x2b, 0x7828}, {0x2c, 0xb43c},
1003 {0x2d, 0xf0a0}, {0x2e, 0x0c64}, {0x2f, 0x0064},
1004 {0x67, 0x4010}, {0x06, 0x301e}, {0x08, 0x0480},
1005 {0x01, 0x0004}, {0x02, 0x0016}, {0x03, 0x01e6},
1006 {0x04, 0x0286}, {0x05, 0x0004}, {0x06, 0x0000},
1007 {0x07, 0x3002}, {0x08, 0x0008}, {0x0c, 0x0000},
1008 {0x0d, 0x0000}, {0x0e, 0x0000}, {0x0f, 0x0000},
1009 {0x10, 0x0000}, {0x11, 0x0000}, {0x12, 0x00b0},
1010 {0x13, 0x007c}, {0x14, 0x0000}, {0x15, 0x0000},
1011 {0x16, 0x0000}, {0x17, 0x0000}, {0x18, 0x0000},
1012 {0x19, 0x0000}, {0x1a, 0x0000}, {0x1b, 0x0000},
1013 {0x1c, 0x0000}, {0x1d, 0x0000}, {0x30, 0x0000},
1014 {0x30, 0x0005}, {0x31, 0x0000}, {0x02, 0x0016},
1015 {0x03, 0x01e1}, {0x04, 0x0281}, {0x05, 0x0004},
1016 {0x06, 0x0000}, {0x07, 0x3002}, {0x06, 0x002d},
1017 {0x05, 0x0004}, {0x09, 0x0064}, {0x2b, 0x00a0},
1018 {0x2c, 0x00a0}, {0x2d, 0x00a0}, {0x2e, 0x00a0},
1019 {0x02, 0x0016}, {0x03, 0x01e1}, {0x04, 0x0281},
1020 {0x05, 0x0004}, {0x06, 0x002d}, {0x07, 0x3002},
1021 {0x0e, 0x0008}, {0x06, 0x002d}, {0x05, 0x0004},
1024 static struct i2c_reg_u16 mt9v011_init[] = {
1025 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
1026 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
1027 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
1028 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
1029 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
1030 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
1031 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
1032 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
1033 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
1034 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
1035 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
1036 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
1037 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
1038 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
1039 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
1040 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
1041 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
1042 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
1043 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
1044 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
1045 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
1046 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1047 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
1048 {0x06, 0x0029}, {0x05, 0x0009},
1051 static struct i2c_reg_u16 mt9m001_init[] = {
1052 {0x0d, 0x0001}, {0x0d, 0x0000}, {0x01, 0x000e},
1053 {0x02, 0x0014}, {0x03, 0x03c1}, {0x04, 0x0501},
1054 {0x05, 0x0083}, {0x06, 0x0006}, {0x0d, 0x0002},
1055 {0x0a, 0x0000}, {0x0c, 0x0000}, {0x11, 0x0000},
1056 {0x1e, 0x8000}, {0x5f, 0x8904}, {0x60, 0x0000},
1057 {0x61, 0x0000}, {0x62, 0x0498}, {0x63, 0x0000},
1058 {0x64, 0x0000}, {0x20, 0x111d}, {0x06, 0x00f2},
1059 {0x05, 0x0013}, {0x09, 0x10f2}, {0x07, 0x0003},
1060 {0x2b, 0x002a}, {0x2d, 0x002a}, {0x2c, 0x002a},
1061 {0x2e, 0x0029}, {0x07, 0x0002},
1064 static struct i2c_reg_u16 mt9m111_init[] = {
1065 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1066 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1067 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1071 static struct i2c_reg_u16 mt9m112_init[] = {
1072 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1073 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1074 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1078 static struct i2c_reg_u8 hv7131r_init[] = {
1079 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
1080 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
1081 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
1082 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
1083 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
1084 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
1085 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
1086 {0x23, 0x09}, {0x01, 0x08},
1089 static int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
1091 struct usb_device *dev = gspca_dev->dev;
1093 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
1095 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1101 if (unlikely(result < 0 || result != length)) {
1102 err("Read register failed 0x%02X", reg);
1108 static int reg_w(struct gspca_dev *gspca_dev, u16 reg,
1109 const u8 *buffer, int length)
1111 struct usb_device *dev = gspca_dev->dev;
1113 memcpy(gspca_dev->usb_buf, buffer, length);
1114 result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1116 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1122 if (unlikely(result < 0 || result != length)) {
1123 err("Write register failed index 0x%02X", reg);
1129 static int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
1131 u8 data[1] = {value};
1132 return reg_w(gspca_dev, reg, data, 1);
1135 static int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
1138 reg_w(gspca_dev, 0x10c0, buffer, 8);
1139 for (i = 0; i < 5; i++) {
1140 reg_r(gspca_dev, 0x10c0, 1);
1141 if (gspca_dev->usb_buf[0] & 0x04) {
1142 if (gspca_dev->usb_buf[0] & 0x08)
1151 static int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1153 struct sd *sd = (struct sd *) gspca_dev;
1158 * from the point of view of the bridge, the length
1159 * includes the address
1161 row[0] = 0x81 | (2 << 4);
1162 row[1] = sd->i2c_addr;
1170 return i2c_w(gspca_dev, row);
1173 static int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1175 struct sd *sd = (struct sd *) gspca_dev;
1179 * from the point of view of the bridge, the length
1180 * includes the address
1182 row[0] = 0x81 | (3 << 4);
1183 row[1] = sd->i2c_addr;
1185 row[3] = (val >> 8) & 0xff;
1186 row[4] = val & 0xff;
1191 return i2c_w(gspca_dev, row);
1194 static int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1196 struct sd *sd = (struct sd *) gspca_dev;
1199 row[0] = 0x81 | (1 << 4);
1200 row[1] = sd->i2c_addr;
1207 if (i2c_w(gspca_dev, row) < 0)
1209 row[0] = 0x81 | (1 << 4) | 0x02;
1211 if (i2c_w(gspca_dev, row) < 0)
1213 if (reg_r(gspca_dev, 0x10c2, 5) < 0)
1215 *val = gspca_dev->usb_buf[4];
1219 static int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1221 struct sd *sd = (struct sd *) gspca_dev;
1224 row[0] = 0x81 | (1 << 4);
1225 row[1] = sd->i2c_addr;
1232 if (i2c_w(gspca_dev, row) < 0)
1234 row[0] = 0x81 | (2 << 4) | 0x02;
1236 if (i2c_w(gspca_dev, row) < 0)
1238 if (reg_r(gspca_dev, 0x10c2, 5) < 0)
1240 *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1244 static int ov9650_init_sensor(struct gspca_dev *gspca_dev)
1247 struct sd *sd = (struct sd *) gspca_dev;
1249 for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) {
1250 if (i2c_w1(gspca_dev, ov9650_init[i].reg,
1251 ov9650_init[i].val) < 0) {
1252 err("OV9650 sensor initialization failed");
1261 static int ov9655_init_sensor(struct gspca_dev *gspca_dev)
1264 struct sd *sd = (struct sd *) gspca_dev;
1266 for (i = 0; i < ARRAY_SIZE(ov9655_init); i++) {
1267 if (i2c_w1(gspca_dev, ov9655_init[i].reg,
1268 ov9655_init[i].val) < 0) {
1269 err("OV9655 sensor initialization failed");
1273 /* disable hflip and vflip */
1274 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1280 static int soi968_init_sensor(struct gspca_dev *gspca_dev)
1283 struct sd *sd = (struct sd *) gspca_dev;
1285 for (i = 0; i < ARRAY_SIZE(soi968_init); i++) {
1286 if (i2c_w1(gspca_dev, soi968_init[i].reg,
1287 soi968_init[i].val) < 0) {
1288 err("SOI968 sensor initialization failed");
1292 /* disable hflip and vflip */
1293 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << EXPOSURE_IDX);
1299 static int ov7660_init_sensor(struct gspca_dev *gspca_dev)
1302 struct sd *sd = (struct sd *) gspca_dev;
1304 for (i = 0; i < ARRAY_SIZE(ov7660_init); i++) {
1305 if (i2c_w1(gspca_dev, ov7660_init[i].reg,
1306 ov7660_init[i].val) < 0) {
1307 err("OV7660 sensor initialization failed");
1311 /* disable hflip and vflip */
1312 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1318 static int ov7670_init_sensor(struct gspca_dev *gspca_dev)
1321 struct sd *sd = (struct sd *) gspca_dev;
1323 for (i = 0; i < ARRAY_SIZE(ov7670_init); i++) {
1324 if (i2c_w1(gspca_dev, ov7670_init[i].reg,
1325 ov7670_init[i].val) < 0) {
1326 err("OV7670 sensor initialization failed");
1330 /* disable hflip and vflip */
1331 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1337 static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
1339 struct sd *sd = (struct sd *) gspca_dev;
1344 sd->i2c_addr = 0x5d;
1345 ret = i2c_r2(gspca_dev, 0xff, &value);
1346 if ((ret == 0) && (value == 0x8243)) {
1347 for (i = 0; i < ARRAY_SIZE(mt9v011_init); i++) {
1348 if (i2c_w2(gspca_dev, mt9v011_init[i].reg,
1349 mt9v011_init[i].val) < 0) {
1350 err("MT9V011 sensor initialization failed");
1356 sd->sensor = SENSOR_MT9V011;
1357 info("MT9V011 sensor detected");
1361 sd->i2c_addr = 0x5c;
1362 i2c_w2(gspca_dev, 0x01, 0x0004);
1363 ret = i2c_r2(gspca_dev, 0xff, &value);
1364 if ((ret == 0) && (value == 0x823a)) {
1365 for (i = 0; i < ARRAY_SIZE(mt9v111_init); i++) {
1366 if (i2c_w2(gspca_dev, mt9v111_init[i].reg,
1367 mt9v111_init[i].val) < 0) {
1368 err("MT9V111 sensor initialization failed");
1374 sd->sensor = SENSOR_MT9V111;
1375 info("MT9V111 sensor detected");
1379 sd->i2c_addr = 0x5d;
1380 ret = i2c_w2(gspca_dev, 0xf0, 0x0000);
1382 sd->i2c_addr = 0x48;
1383 i2c_w2(gspca_dev, 0xf0, 0x0000);
1385 ret = i2c_r2(gspca_dev, 0x00, &value);
1386 if ((ret == 0) && (value == 0x1229)) {
1387 for (i = 0; i < ARRAY_SIZE(mt9v112_init); i++) {
1388 if (i2c_w2(gspca_dev, mt9v112_init[i].reg,
1389 mt9v112_init[i].val) < 0) {
1390 err("MT9V112 sensor initialization failed");
1396 sd->sensor = SENSOR_MT9V112;
1397 info("MT9V112 sensor detected");
1404 static int mt9m112_init_sensor(struct gspca_dev *gspca_dev)
1406 struct sd *sd = (struct sd *) gspca_dev;
1408 for (i = 0; i < ARRAY_SIZE(mt9m112_init); i++) {
1409 if (i2c_w2(gspca_dev, mt9m112_init[i].reg,
1410 mt9m112_init[i].val) < 0) {
1411 err("MT9M112 sensor initialization failed");
1415 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | (1 << GAIN_IDX);
1421 static int mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1423 struct sd *sd = (struct sd *) gspca_dev;
1425 for (i = 0; i < ARRAY_SIZE(mt9m111_init); i++) {
1426 if (i2c_w2(gspca_dev, mt9m111_init[i].reg,
1427 mt9m111_init[i].val) < 0) {
1428 err("MT9M111 sensor initialization failed");
1432 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | (1 << GAIN_IDX);
1438 static int mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1440 struct sd *sd = (struct sd *) gspca_dev;
1442 for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) {
1443 if (i2c_w2(gspca_dev, mt9m001_init[i].reg,
1444 mt9m001_init[i].val) < 0) {
1445 err("MT9M001 sensor initialization failed");
1449 /* disable hflip and vflip */
1450 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1456 static int hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1459 struct sd *sd = (struct sd *) gspca_dev;
1461 for (i = 0; i < ARRAY_SIZE(hv7131r_init); i++) {
1462 if (i2c_w1(gspca_dev, hv7131r_init[i].reg,
1463 hv7131r_init[i].val) < 0) {
1464 err("HV7131R Sensor initialization failed");
1473 static int set_cmatrix(struct gspca_dev *gspca_dev)
1475 struct sd *sd = (struct sd *) gspca_dev;
1476 s32 hue_coord, hue_index = 180 + sd->hue;
1479 memset(cmatrix, 0, sizeof cmatrix);
1480 cmatrix[2] = (sd->contrast * 0x25 / 0x100) + 0x26;
1481 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1482 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1483 cmatrix[18] = sd->brightness - 0x80;
1485 hue_coord = (hsv_red_x[hue_index] * sd->saturation) >> 8;
1486 cmatrix[6] = hue_coord;
1487 cmatrix[7] = (hue_coord >> 8) & 0x0f;
1489 hue_coord = (hsv_red_y[hue_index] * sd->saturation) >> 8;
1490 cmatrix[8] = hue_coord;
1491 cmatrix[9] = (hue_coord >> 8) & 0x0f;
1493 hue_coord = (hsv_green_x[hue_index] * sd->saturation) >> 8;
1494 cmatrix[10] = hue_coord;
1495 cmatrix[11] = (hue_coord >> 8) & 0x0f;
1497 hue_coord = (hsv_green_y[hue_index] * sd->saturation) >> 8;
1498 cmatrix[12] = hue_coord;
1499 cmatrix[13] = (hue_coord >> 8) & 0x0f;
1501 hue_coord = (hsv_blue_x[hue_index] * sd->saturation) >> 8;
1502 cmatrix[14] = hue_coord;
1503 cmatrix[15] = (hue_coord >> 8) & 0x0f;
1505 hue_coord = (hsv_blue_y[hue_index] * sd->saturation) >> 8;
1506 cmatrix[16] = hue_coord;
1507 cmatrix[17] = (hue_coord >> 8) & 0x0f;
1509 return reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1512 static int set_gamma(struct gspca_dev *gspca_dev)
1514 struct sd *sd = (struct sd *) gspca_dev;
1516 u8 gval = sd->gamma * 0xb8 / 0x100;
1520 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
1521 gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8);
1522 gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8);
1523 gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8);
1524 gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8);
1525 gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8);
1526 gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8);
1527 gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8);
1528 gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8);
1529 gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8);
1530 gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8);
1531 gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8);
1532 gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8);
1533 gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8);
1534 gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
1537 return reg_w(gspca_dev, 0x1190, gamma, 17);
1540 static int set_redblue(struct gspca_dev *gspca_dev)
1542 struct sd *sd = (struct sd *) gspca_dev;
1543 reg_w1(gspca_dev, 0x118c, sd->red);
1544 reg_w1(gspca_dev, 0x118f, sd->blue);
1548 static int set_hvflip(struct gspca_dev *gspca_dev)
1550 u8 value, tslb, hflip, vflip;
1552 struct sd *sd = (struct sd *) gspca_dev;
1554 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1562 switch (sd->sensor) {
1564 i2c_r1(gspca_dev, 0x1e, &value);
1573 i2c_w1(gspca_dev, 0x1e, value);
1574 i2c_w1(gspca_dev, 0x3a, tslb);
1576 case SENSOR_MT9V111:
1577 case SENSOR_MT9V011:
1578 i2c_r2(gspca_dev, 0x20, &value2);
1584 i2c_w2(gspca_dev, 0x20, value2);
1586 case SENSOR_MT9M112:
1587 case SENSOR_MT9M111:
1588 case SENSOR_MT9V112:
1589 i2c_r2(gspca_dev, 0x20, &value2);
1595 i2c_w2(gspca_dev, 0x20, value2);
1597 case SENSOR_HV7131R:
1598 i2c_r1(gspca_dev, 0x01, &value);
1604 i2c_w1(gspca_dev, 0x01, value);
1610 static int set_exposure(struct gspca_dev *gspca_dev)
1612 struct sd *sd = (struct sd *) gspca_dev;
1613 u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1614 switch (sd->sensor) {
1621 exp[3] = sd->exposure & 0xff;
1622 exp[4] = sd->exposure >> 8;
1624 case SENSOR_MT9M001:
1625 case SENSOR_MT9V112:
1626 case SENSOR_MT9V111:
1627 case SENSOR_MT9V011:
1630 exp[3] = sd->exposure >> 8;
1631 exp[4] = sd->exposure & 0xff;
1633 case SENSOR_HV7131R:
1636 exp[3] = (sd->exposure >> 5) & 0xff;
1637 exp[4] = (sd->exposure << 3) & 0xff;
1643 i2c_w(gspca_dev, exp);
1647 static int set_gain(struct gspca_dev *gspca_dev)
1649 struct sd *sd = (struct sd *) gspca_dev;
1650 u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1651 switch (sd->sensor) {
1657 gain[0] |= (2 << 4);
1658 gain[3] = ov_gain[sd->gain];
1660 case SENSOR_MT9V011:
1661 case SENSOR_MT9V111:
1662 gain[0] |= (3 << 4);
1664 gain[3] = micron1_gain[sd->gain] >> 8;
1665 gain[4] = micron1_gain[sd->gain] & 0xff;
1667 case SENSOR_MT9V112:
1668 gain[0] |= (3 << 4);
1670 gain[3] = micron1_gain[sd->gain] >> 8;
1671 gain[4] = micron1_gain[sd->gain] & 0xff;
1673 case SENSOR_MT9M001:
1674 gain[0] |= (3 << 4);
1676 gain[3] = micron2_gain[sd->gain] >> 8;
1677 gain[4] = micron2_gain[sd->gain] & 0xff;
1679 case SENSOR_HV7131R:
1680 gain[0] |= (2 << 4);
1682 gain[3] = hv7131r_gain[sd->gain];
1687 i2c_w(gspca_dev, gain);
1691 static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val)
1693 struct sd *sd = (struct sd *) gspca_dev;
1695 sd->brightness = val;
1696 if (gspca_dev->streaming)
1697 return set_cmatrix(gspca_dev);
1701 static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val)
1703 struct sd *sd = (struct sd *) gspca_dev;
1704 *val = sd->brightness;
1709 static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val)
1711 struct sd *sd = (struct sd *) gspca_dev;
1714 if (gspca_dev->streaming)
1715 return set_cmatrix(gspca_dev);
1719 static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val)
1721 struct sd *sd = (struct sd *) gspca_dev;
1722 *val = sd->contrast;
1726 static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val)
1728 struct sd *sd = (struct sd *) gspca_dev;
1730 sd->saturation = val;
1731 if (gspca_dev->streaming)
1732 return set_cmatrix(gspca_dev);
1736 static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val)
1738 struct sd *sd = (struct sd *) gspca_dev;
1739 *val = sd->saturation;
1743 static int sd_sethue(struct gspca_dev *gspca_dev, s32 val)
1745 struct sd *sd = (struct sd *) gspca_dev;
1748 if (gspca_dev->streaming)
1749 return set_cmatrix(gspca_dev);
1753 static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val)
1755 struct sd *sd = (struct sd *) gspca_dev;
1760 static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val)
1762 struct sd *sd = (struct sd *) gspca_dev;
1765 if (gspca_dev->streaming)
1766 return set_gamma(gspca_dev);
1770 static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val)
1772 struct sd *sd = (struct sd *) gspca_dev;
1777 static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val)
1779 struct sd *sd = (struct sd *) gspca_dev;
1782 if (gspca_dev->streaming)
1783 return set_redblue(gspca_dev);
1787 static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val)
1789 struct sd *sd = (struct sd *) gspca_dev;
1794 static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val)
1796 struct sd *sd = (struct sd *) gspca_dev;
1799 if (gspca_dev->streaming)
1800 return set_redblue(gspca_dev);
1804 static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val)
1806 struct sd *sd = (struct sd *) gspca_dev;
1811 static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val)
1813 struct sd *sd = (struct sd *) gspca_dev;
1816 if (gspca_dev->streaming)
1817 return set_hvflip(gspca_dev);
1821 static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val)
1823 struct sd *sd = (struct sd *) gspca_dev;
1828 static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val)
1830 struct sd *sd = (struct sd *) gspca_dev;
1833 if (gspca_dev->streaming)
1834 return set_hvflip(gspca_dev);
1838 static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val)
1840 struct sd *sd = (struct sd *) gspca_dev;
1845 static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val)
1847 struct sd *sd = (struct sd *) gspca_dev;
1850 if (gspca_dev->streaming)
1851 return set_exposure(gspca_dev);
1855 static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val)
1857 struct sd *sd = (struct sd *) gspca_dev;
1858 *val = sd->exposure;
1862 static int sd_setgain(struct gspca_dev *gspca_dev, s32 val)
1864 struct sd *sd = (struct sd *) gspca_dev;
1867 if (gspca_dev->streaming)
1868 return set_gain(gspca_dev);
1872 static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val)
1874 struct sd *sd = (struct sd *) gspca_dev;
1879 static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val)
1881 struct sd *sd = (struct sd *) gspca_dev;
1882 sd->auto_exposure = val;
1886 static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val)
1888 struct sd *sd = (struct sd *) gspca_dev;
1889 *val = sd->auto_exposure;
1893 #ifdef CONFIG_VIDEO_ADV_DEBUG
1894 static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1895 struct v4l2_dbg_register *reg)
1897 struct sd *sd = (struct sd *) gspca_dev;
1898 switch (reg->match.type) {
1899 case V4L2_CHIP_MATCH_HOST:
1900 if (reg->match.addr != 0)
1902 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1904 if (reg_r(gspca_dev, reg->reg, 1) < 0)
1906 reg->val = gspca_dev->usb_buf[0];
1908 case V4L2_CHIP_MATCH_I2C_ADDR:
1909 if (reg->match.addr != sd->i2c_addr)
1911 if (sd->sensor >= SENSOR_MT9V011 &&
1912 sd->sensor <= SENSOR_MT9M112) {
1913 if (i2c_r2(gspca_dev, reg->reg, (u16 *)®->val) < 0)
1916 if (i2c_r1(gspca_dev, reg->reg, (u8 *)®->val) < 0)
1924 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1925 struct v4l2_dbg_register *reg)
1927 struct sd *sd = (struct sd *) gspca_dev;
1928 switch (reg->match.type) {
1929 case V4L2_CHIP_MATCH_HOST:
1930 if (reg->match.addr != 0)
1932 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1934 if (reg_w1(gspca_dev, reg->reg, reg->val) < 0)
1937 case V4L2_CHIP_MATCH_I2C_ADDR:
1938 if (reg->match.addr != sd->i2c_addr)
1940 if (sd->sensor >= SENSOR_MT9V011 &&
1941 sd->sensor <= SENSOR_MT9M112) {
1942 if (i2c_w2(gspca_dev, reg->reg, reg->val) < 0)
1945 if (i2c_w1(gspca_dev, reg->reg, reg->val) < 0)
1954 static int sd_chip_ident(struct gspca_dev *gspca_dev,
1955 struct v4l2_dbg_chip_ident *chip)
1957 struct sd *sd = (struct sd *) gspca_dev;
1959 switch (chip->match.type) {
1960 case V4L2_CHIP_MATCH_HOST:
1961 if (chip->match.addr != 0)
1964 chip->ident = V4L2_IDENT_SN9C20X;
1966 case V4L2_CHIP_MATCH_I2C_ADDR:
1967 if (chip->match.addr != sd->i2c_addr)
1970 chip->ident = i2c_ident[sd->sensor];
1976 static int sd_config(struct gspca_dev *gspca_dev,
1977 const struct usb_device_id *id)
1979 struct sd *sd = (struct sd *) gspca_dev;
1982 cam = &gspca_dev->cam;
1984 sd->sensor = (id->driver_info >> 8) & 0xff;
1985 sd->i2c_addr = id->driver_info & 0xff;
1986 sd->flags = (id->driver_info >> 16) & 0xff;
1988 switch (sd->sensor) {
1989 case SENSOR_MT9M112:
1990 case SENSOR_MT9M111:
1993 cam->cam_mode = sxga_mode;
1994 cam->nmodes = ARRAY_SIZE(sxga_mode);
1997 cam->cam_mode = vga_mode;
1998 cam->nmodes = ARRAY_SIZE(vga_mode);
2004 sd->exposure_step = 16;
2006 sd->brightness = BRIGHTNESS_DEFAULT;
2007 sd->contrast = CONTRAST_DEFAULT;
2008 sd->saturation = SATURATION_DEFAULT;
2009 sd->hue = HUE_DEFAULT;
2010 sd->gamma = GAMMA_DEFAULT;
2011 sd->red = RED_DEFAULT;
2012 sd->blue = BLUE_DEFAULT;
2014 sd->hflip = HFLIP_DEFAULT;
2015 sd->vflip = VFLIP_DEFAULT;
2016 sd->exposure = EXPOSURE_DEFAULT;
2017 sd->gain = GAIN_DEFAULT;
2018 sd->auto_exposure = AUTO_EXPOSURE_DEFAULT;
2025 static int sd_init(struct gspca_dev *gspca_dev)
2027 struct sd *sd = (struct sd *) gspca_dev;
2031 {0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
2033 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
2034 value = bridge_init[i][1];
2035 if (reg_w(gspca_dev, bridge_init[i][0], &value, 1) < 0) {
2036 err("Device initialization failed");
2041 if (sd->flags & LED_REVERSE)
2042 reg_w1(gspca_dev, 0x1006, 0x00);
2044 reg_w1(gspca_dev, 0x1006, 0x20);
2046 if (reg_w(gspca_dev, 0x10c0, i2c_init, 9) < 0) {
2047 err("Device initialization failed");
2051 switch (sd->sensor) {
2053 if (ov9650_init_sensor(gspca_dev) < 0)
2055 info("OV9650 sensor detected");
2058 if (ov9655_init_sensor(gspca_dev) < 0)
2060 info("OV9655 sensor detected");
2063 if (soi968_init_sensor(gspca_dev) < 0)
2065 info("SOI968 sensor detected");
2068 if (ov7660_init_sensor(gspca_dev) < 0)
2070 info("OV7660 sensor detected");
2073 if (ov7670_init_sensor(gspca_dev) < 0)
2075 info("OV7670 sensor detected");
2077 case SENSOR_MT9VPRB:
2078 if (mt9v_init_sensor(gspca_dev) < 0)
2081 case SENSOR_MT9M111:
2082 if (mt9m111_init_sensor(gspca_dev) < 0)
2084 info("MT9M111 sensor detected");
2086 case SENSOR_MT9M112:
2087 if (mt9m112_init_sensor(gspca_dev) < 0)
2089 info("MT9M112 sensor detected");
2091 case SENSOR_MT9M001:
2092 if (mt9m001_init_sensor(gspca_dev) < 0)
2094 info("MT9M001 sensor detected");
2096 case SENSOR_HV7131R:
2097 if (hv7131r_init_sensor(gspca_dev) < 0)
2099 info("HV7131R sensor detected");
2102 info("Unsupported Sensor");
2109 static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
2111 struct sd *sd = (struct sd *) gspca_dev;
2113 switch (sd->sensor) {
2115 if (mode & MODE_SXGA) {
2116 i2c_w1(gspca_dev, 0x17, 0x1d);
2117 i2c_w1(gspca_dev, 0x18, 0xbd);
2118 i2c_w1(gspca_dev, 0x19, 0x01);
2119 i2c_w1(gspca_dev, 0x1a, 0x81);
2120 i2c_w1(gspca_dev, 0x12, 0x00);
2124 i2c_w1(gspca_dev, 0x17, 0x13);
2125 i2c_w1(gspca_dev, 0x18, 0x63);
2126 i2c_w1(gspca_dev, 0x19, 0x01);
2127 i2c_w1(gspca_dev, 0x1a, 0x79);
2128 i2c_w1(gspca_dev, 0x12, 0x40);
2134 if (mode & MODE_SXGA) {
2135 i2c_w1(gspca_dev, 0x17, 0x1b);
2136 i2c_w1(gspca_dev, 0x18, 0xbc);
2137 i2c_w1(gspca_dev, 0x19, 0x01);
2138 i2c_w1(gspca_dev, 0x1a, 0x82);
2139 i2c_r1(gspca_dev, 0x12, &value);
2140 i2c_w1(gspca_dev, 0x12, value & 0x07);
2142 i2c_w1(gspca_dev, 0x17, 0x24);
2143 i2c_w1(gspca_dev, 0x18, 0xc5);
2144 i2c_w1(gspca_dev, 0x19, 0x00);
2145 i2c_w1(gspca_dev, 0x1a, 0x3c);
2146 i2c_r1(gspca_dev, 0x12, &value);
2147 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
2150 case SENSOR_MT9M112:
2151 case SENSOR_MT9M111:
2152 if (mode & MODE_SXGA) {
2153 i2c_w2(gspca_dev, 0xf0, 0x0002);
2154 i2c_w2(gspca_dev, 0xc8, 0x970b);
2155 i2c_w2(gspca_dev, 0xf0, 0x0000);
2157 i2c_w2(gspca_dev, 0xf0, 0x0002);
2158 i2c_w2(gspca_dev, 0xc8, 0x8000);
2159 i2c_w2(gspca_dev, 0xf0, 0x0000);
2165 #define HW_WIN(mode, hstart, vstart) \
2166 ((const u8 []){hstart, 0, vstart, 0, \
2167 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
2168 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
2170 #define CLR_WIN(width, height) \
2172 {0, width >> 2, 0, height >> 1,\
2173 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
2175 static int sd_start(struct gspca_dev *gspca_dev)
2177 struct sd *sd = (struct sd *) gspca_dev;
2178 int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
2179 int width = gspca_dev->width;
2180 int height = gspca_dev->height;
2183 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
2184 if (sd->jpeg_hdr == NULL)
2187 jpeg_define(sd->jpeg_hdr, height, width,
2189 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2191 if (mode & MODE_RAW)
2193 else if (mode & MODE_JPEG)
2198 switch (mode & 0x0f) {
2201 info("Set 1280x1024");
2205 info("Set 640x480");
2209 info("Set 320x240");
2213 info("Set 160x120");
2217 configure_sensor_output(gspca_dev, mode);
2218 reg_w(gspca_dev, 0x1100, sd->jpeg_hdr + JPEG_QT0_OFFSET, 64);
2219 reg_w(gspca_dev, 0x1140, sd->jpeg_hdr + JPEG_QT1_OFFSET, 64);
2220 reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2221 reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2222 reg_w1(gspca_dev, 0x1189, scale);
2223 reg_w1(gspca_dev, 0x10e0, fmt);
2225 set_cmatrix(gspca_dev);
2226 set_gamma(gspca_dev);
2227 set_redblue(gspca_dev);
2228 set_gain(gspca_dev);
2229 set_exposure(gspca_dev);
2230 set_hvflip(gspca_dev);
2232 reg_w1(gspca_dev, 0x1007, 0x20);
2234 reg_r(gspca_dev, 0x1061, 1);
2235 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] | 0x02);
2239 static void sd_stopN(struct gspca_dev *gspca_dev)
2241 reg_w1(gspca_dev, 0x1007, 0x00);
2243 reg_r(gspca_dev, 0x1061, 1);
2244 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] & ~0x02);
2247 static void sd_stop0(struct gspca_dev *gspca_dev)
2249 struct sd *sd = (struct sd *) gspca_dev;
2250 kfree(sd->jpeg_hdr);
2253 static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2255 struct sd *sd = (struct sd *) gspca_dev;
2259 * some hardcoded values are present
2260 * like those for maximal/minimal exposure
2261 * and exposure steps
2263 if (avg_lum < MIN_AVG_LUM) {
2264 if (sd->exposure > 0x1770)
2267 new_exp = sd->exposure + sd->exposure_step;
2268 if (new_exp > 0x1770)
2272 sd->exposure = new_exp;
2273 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;
2283 if (avg_lum > MAX_AVG_LUM) {
2284 if (sd->exposure < 0x10)
2286 new_exp = sd->exposure - sd->exposure_step;
2287 if (new_exp > 0x1700)
2291 sd->exposure = new_exp;
2292 set_exposure(gspca_dev);
2293 sd->older_step = sd->old_step;
2296 if (sd->old_step ^ sd->older_step)
2297 sd->exposure_step /= 2;
2299 sd->exposure_step += 2;
2303 static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2305 struct sd *sd = (struct sd *) gspca_dev;
2307 if (avg_lum < MIN_AVG_LUM) {
2308 if (sd->gain + 1 <= 28) {
2310 set_gain(gspca_dev);
2313 if (avg_lum > MAX_AVG_LUM) {
2316 set_gain(gspca_dev);
2321 static void sd_dqcallback(struct gspca_dev *gspca_dev)
2323 struct sd *sd = (struct sd *) gspca_dev;
2326 if (!sd->auto_exposure)
2329 avg_lum = atomic_read(&sd->avg_lum);
2330 if (sd->sensor == SENSOR_SOI968)
2331 do_autogain(gspca_dev, avg_lum);
2333 do_autoexposure(gspca_dev, avg_lum);
2337 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2338 u8 *data, /* interrupt packet */
2339 int len) /* interrupt packet length */
2341 struct sd *sd = (struct sd *) gspca_dev;
2343 if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
2344 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2345 input_sync(gspca_dev->input_dev);
2346 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2347 input_sync(gspca_dev->input_dev);
2354 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2355 u8 *data, /* isoc packet */
2356 int len) /* iso packet length */
2358 struct sd *sd = (struct sd *) gspca_dev;
2360 static u8 frame_header[] =
2361 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2362 if (len == 64 && memcmp(data, frame_header, 6) == 0) {
2363 avg_lum = ((data[35] >> 2) & 3) |
2366 avg_lum += ((data[35] >> 4) & 3) |
2369 avg_lum += ((data[35] >> 6) & 3) |
2372 avg_lum += (data[36] & 3) |
2375 avg_lum += ((data[36] >> 2) & 3) |
2378 avg_lum += ((data[36] >> 4) & 3) |
2381 avg_lum += ((data[36] >> 6) & 3) |
2384 avg_lum += ((data[44] >> 4) & 3) |
2388 atomic_set(&sd->avg_lum, avg_lum);
2389 gspca_frame_add(gspca_dev, LAST_PACKET,
2393 if (gspca_dev->last_packet_type == LAST_PACKET) {
2394 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv
2396 gspca_frame_add(gspca_dev, FIRST_PACKET,
2397 sd->jpeg_hdr, JPEG_HDR_SZ);
2398 gspca_frame_add(gspca_dev, INTER_PACKET,
2401 gspca_frame_add(gspca_dev, FIRST_PACKET,
2405 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2409 /* sub-driver description */
2410 static const struct sd_desc sd_desc = {
2411 .name = MODULE_NAME,
2413 .nctrls = ARRAY_SIZE(sd_ctrls),
2414 .config = sd_config,
2419 .pkt_scan = sd_pkt_scan,
2421 .int_pkt_scan = sd_int_pkt_scan,
2423 .dq_callback = sd_dqcallback,
2424 #ifdef CONFIG_VIDEO_ADV_DEBUG
2425 .set_register = sd_dbg_s_register,
2426 .get_register = sd_dbg_g_register,
2428 .get_chip_ident = sd_chip_ident,
2431 #define SN9C20X(sensor, i2c_addr, flags) \
2432 .driver_info = ((flags & 0xff) << 16) \
2433 | (SENSOR_ ## sensor << 8) \
2436 static const __devinitdata struct usb_device_id device_table[] = {
2437 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2438 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
2439 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2440 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
2441 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
2442 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
2443 (FLIP_DETECT | HAS_NO_BUTTON))},
2444 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2445 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2446 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2447 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2448 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, 0)},
2449 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2450 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2451 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2452 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2453 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
2454 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
2455 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2456 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2457 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2458 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2459 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, 0)},
2460 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, 0)},
2461 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2462 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2463 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2464 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2465 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
2466 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
2467 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2468 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2469 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2470 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2471 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
2472 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2473 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2476 MODULE_DEVICE_TABLE(usb, device_table);
2478 /* -- device connect -- */
2479 static int sd_probe(struct usb_interface *intf,
2480 const struct usb_device_id *id)
2482 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2486 static struct usb_driver sd_driver = {
2487 .name = MODULE_NAME,
2488 .id_table = device_table,
2490 .disconnect = gspca_disconnect,
2492 .suspend = gspca_suspend,
2493 .resume = gspca_resume,
2494 .reset_resume = gspca_resume,
2498 /* -- module insert / remove -- */
2499 static int __init sd_mod_init(void)
2502 ret = usb_register(&sd_driver);
2508 static void __exit sd_mod_exit(void)
2510 usb_deregister(&sd_driver);
2511 info("deregistered");
2514 module_init(sd_mod_init);
2515 module_exit(sd_mod_exit);