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_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 = "ASUSTeK W7J",
152 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
153 DMI_MATCH(DMI_BOARD_NAME, "W7J ")
159 static const struct ctrl sd_ctrls[] = {
161 #define BRIGHTNESS_IDX 0
163 .id = V4L2_CID_BRIGHTNESS,
164 .type = V4L2_CTRL_TYPE_INTEGER,
165 .name = "Brightness",
169 #define BRIGHTNESS_DEFAULT 0x7f
170 .default_value = BRIGHTNESS_DEFAULT,
172 .set = sd_setbrightness,
173 .get = sd_getbrightness,
176 #define CONTRAST_IDX 1
178 .id = V4L2_CID_CONTRAST,
179 .type = V4L2_CTRL_TYPE_INTEGER,
184 #define CONTRAST_DEFAULT 0x7f
185 .default_value = CONTRAST_DEFAULT,
187 .set = sd_setcontrast,
188 .get = sd_getcontrast,
191 #define SATURATION_IDX 2
193 .id = V4L2_CID_SATURATION,
194 .type = V4L2_CTRL_TYPE_INTEGER,
195 .name = "Saturation",
199 #define SATURATION_DEFAULT 0x7f
200 .default_value = SATURATION_DEFAULT,
202 .set = sd_setsaturation,
203 .get = sd_getsaturation,
209 .type = V4L2_CTRL_TYPE_INTEGER,
214 #define HUE_DEFAULT 0
215 .default_value = HUE_DEFAULT,
223 .id = V4L2_CID_GAMMA,
224 .type = V4L2_CTRL_TYPE_INTEGER,
229 #define GAMMA_DEFAULT 0x10
230 .default_value = GAMMA_DEFAULT,
238 .id = V4L2_CID_BLUE_BALANCE,
239 .type = V4L2_CTRL_TYPE_INTEGER,
240 .name = "Blue Balance",
244 #define BLUE_DEFAULT 0x28
245 .default_value = BLUE_DEFAULT,
247 .set = sd_setbluebalance,
248 .get = sd_getbluebalance,
253 .id = V4L2_CID_RED_BALANCE,
254 .type = V4L2_CTRL_TYPE_INTEGER,
255 .name = "Red Balance",
259 #define RED_DEFAULT 0x28
260 .default_value = RED_DEFAULT,
262 .set = sd_setredbalance,
263 .get = sd_getredbalance,
268 .id = V4L2_CID_HFLIP,
269 .type = V4L2_CTRL_TYPE_BOOLEAN,
270 .name = "Horizontal Flip",
274 #define HFLIP_DEFAULT 0
275 .default_value = HFLIP_DEFAULT,
283 .id = V4L2_CID_VFLIP,
284 .type = V4L2_CTRL_TYPE_BOOLEAN,
285 .name = "Vertical Flip",
289 #define VFLIP_DEFAULT 0
290 .default_value = VFLIP_DEFAULT,
296 #define EXPOSURE_IDX 9
298 .id = V4L2_CID_EXPOSURE,
299 .type = V4L2_CTRL_TYPE_INTEGER,
304 #define EXPOSURE_DEFAULT 0x33
305 .default_value = EXPOSURE_DEFAULT,
307 .set = sd_setexposure,
308 .get = sd_getexposure,
314 .type = V4L2_CTRL_TYPE_INTEGER,
319 #define GAIN_DEFAULT 0x00
320 .default_value = GAIN_DEFAULT,
326 #define AUTOGAIN_IDX 11
328 .id = V4L2_CID_AUTOGAIN,
329 .type = V4L2_CTRL_TYPE_BOOLEAN,
330 .name = "Auto Exposure",
334 #define AUTO_EXPOSURE_DEFAULT 1
335 .default_value = AUTO_EXPOSURE_DEFAULT,
337 .set = sd_setautoexposure,
338 .get = sd_getautoexposure,
342 static const struct v4l2_pix_format vga_mode[] = {
343 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
345 .sizeimage = 240 * 120,
346 .colorspace = V4L2_COLORSPACE_JPEG,
347 .priv = 0 | MODE_JPEG},
348 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
350 .sizeimage = 160 * 120,
351 .colorspace = V4L2_COLORSPACE_SRGB,
352 .priv = 0 | MODE_RAW},
353 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
355 .sizeimage = 240 * 120,
356 .colorspace = V4L2_COLORSPACE_SRGB,
358 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
360 .sizeimage = 480 * 240 ,
361 .colorspace = V4L2_COLORSPACE_JPEG,
362 .priv = 1 | MODE_JPEG},
363 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
365 .sizeimage = 320 * 240 ,
366 .colorspace = V4L2_COLORSPACE_SRGB,
367 .priv = 1 | MODE_RAW},
368 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
370 .sizeimage = 480 * 240 ,
371 .colorspace = V4L2_COLORSPACE_SRGB,
373 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
375 .sizeimage = 960 * 480,
376 .colorspace = V4L2_COLORSPACE_JPEG,
377 .priv = 2 | MODE_JPEG},
378 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
380 .sizeimage = 640 * 480,
381 .colorspace = V4L2_COLORSPACE_SRGB,
382 .priv = 2 | MODE_RAW},
383 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
385 .sizeimage = 960 * 480,
386 .colorspace = V4L2_COLORSPACE_SRGB,
390 static const struct v4l2_pix_format sxga_mode[] = {
391 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
393 .sizeimage = 240 * 120,
394 .colorspace = V4L2_COLORSPACE_JPEG,
395 .priv = 0 | MODE_JPEG},
396 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
398 .sizeimage = 160 * 120,
399 .colorspace = V4L2_COLORSPACE_SRGB,
400 .priv = 0 | MODE_RAW},
401 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
403 .sizeimage = 240 * 120,
404 .colorspace = V4L2_COLORSPACE_SRGB,
406 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
408 .sizeimage = 480 * 240 ,
409 .colorspace = V4L2_COLORSPACE_JPEG,
410 .priv = 1 | MODE_JPEG},
411 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
413 .sizeimage = 320 * 240 ,
414 .colorspace = V4L2_COLORSPACE_SRGB,
415 .priv = 1 | MODE_RAW},
416 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
418 .sizeimage = 480 * 240 ,
419 .colorspace = V4L2_COLORSPACE_SRGB,
421 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
423 .sizeimage = 960 * 480,
424 .colorspace = V4L2_COLORSPACE_JPEG,
425 .priv = 2 | MODE_JPEG},
426 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
428 .sizeimage = 640 * 480,
429 .colorspace = V4L2_COLORSPACE_SRGB,
430 .priv = 2 | MODE_RAW},
431 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
433 .sizeimage = 960 * 480,
434 .colorspace = V4L2_COLORSPACE_SRGB,
436 {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
437 .bytesperline = 1280,
438 .sizeimage = (1280 * 1024) + 64,
439 .colorspace = V4L2_COLORSPACE_SRGB,
440 .priv = 3 | MODE_RAW | MODE_SXGA},
443 static const s16 hsv_red_x[] = {
444 41, 44, 46, 48, 50, 52, 54, 56,
445 58, 60, 62, 64, 66, 68, 70, 72,
446 74, 76, 78, 80, 81, 83, 85, 87,
447 88, 90, 92, 93, 95, 97, 98, 100,
448 101, 102, 104, 105, 107, 108, 109, 110,
449 112, 113, 114, 115, 116, 117, 118, 119,
450 120, 121, 122, 123, 123, 124, 125, 125,
451 126, 127, 127, 128, 128, 129, 129, 129,
452 130, 130, 130, 130, 131, 131, 131, 131,
453 131, 131, 131, 131, 130, 130, 130, 130,
454 129, 129, 129, 128, 128, 127, 127, 126,
455 125, 125, 124, 123, 122, 122, 121, 120,
456 119, 118, 117, 116, 115, 114, 112, 111,
457 110, 109, 107, 106, 105, 103, 102, 101,
458 99, 98, 96, 94, 93, 91, 90, 88,
459 86, 84, 83, 81, 79, 77, 75, 74,
460 72, 70, 68, 66, 64, 62, 60, 58,
461 56, 54, 52, 49, 47, 45, 43, 41,
462 39, 36, 34, 32, 30, 28, 25, 23,
463 21, 19, 16, 14, 12, 9, 7, 5,
464 3, 0, -1, -3, -6, -8, -10, -12,
465 -15, -17, -19, -22, -24, -26, -28, -30,
466 -33, -35, -37, -39, -41, -44, -46, -48,
467 -50, -52, -54, -56, -58, -60, -62, -64,
468 -66, -68, -70, -72, -74, -76, -78, -80,
469 -81, -83, -85, -87, -88, -90, -92, -93,
470 -95, -97, -98, -100, -101, -102, -104, -105,
471 -107, -108, -109, -110, -112, -113, -114, -115,
472 -116, -117, -118, -119, -120, -121, -122, -123,
473 -123, -124, -125, -125, -126, -127, -127, -128,
474 -128, -128, -128, -128, -128, -128, -128, -128,
475 -128, -128, -128, -128, -128, -128, -128, -128,
476 -128, -128, -128, -128, -128, -128, -128, -128,
477 -128, -127, -127, -126, -125, -125, -124, -123,
478 -122, -122, -121, -120, -119, -118, -117, -116,
479 -115, -114, -112, -111, -110, -109, -107, -106,
480 -105, -103, -102, -101, -99, -98, -96, -94,
481 -93, -91, -90, -88, -86, -84, -83, -81,
482 -79, -77, -75, -74, -72, -70, -68, -66,
483 -64, -62, -60, -58, -56, -54, -52, -49,
484 -47, -45, -43, -41, -39, -36, -34, -32,
485 -30, -28, -25, -23, -21, -19, -16, -14,
486 -12, -9, -7, -5, -3, 0, 1, 3,
487 6, 8, 10, 12, 15, 17, 19, 22,
488 24, 26, 28, 30, 33, 35, 37, 39, 41
491 static const s16 hsv_red_y[] = {
492 82, 80, 78, 76, 74, 73, 71, 69,
493 67, 65, 63, 61, 58, 56, 54, 52,
494 50, 48, 46, 44, 41, 39, 37, 35,
495 32, 30, 28, 26, 23, 21, 19, 16,
496 14, 12, 10, 7, 5, 3, 0, -1,
497 -3, -6, -8, -10, -13, -15, -17, -19,
498 -22, -24, -26, -29, -31, -33, -35, -38,
499 -40, -42, -44, -46, -48, -51, -53, -55,
500 -57, -59, -61, -63, -65, -67, -69, -71,
501 -73, -75, -77, -79, -81, -82, -84, -86,
502 -88, -89, -91, -93, -94, -96, -98, -99,
503 -101, -102, -104, -105, -106, -108, -109, -110,
504 -112, -113, -114, -115, -116, -117, -119, -120,
505 -120, -121, -122, -123, -124, -125, -126, -126,
506 -127, -128, -128, -128, -128, -128, -128, -128,
507 -128, -128, -128, -128, -128, -128, -128, -128,
508 -128, -128, -128, -128, -128, -128, -128, -128,
509 -128, -128, -128, -128, -128, -128, -128, -128,
510 -127, -127, -126, -125, -125, -124, -123, -122,
511 -121, -120, -119, -118, -117, -116, -115, -114,
512 -113, -111, -110, -109, -107, -106, -105, -103,
513 -102, -100, -99, -97, -96, -94, -92, -91,
514 -89, -87, -85, -84, -82, -80, -78, -76,
515 -74, -73, -71, -69, -67, -65, -63, -61,
516 -58, -56, -54, -52, -50, -48, -46, -44,
517 -41, -39, -37, -35, -32, -30, -28, -26,
518 -23, -21, -19, -16, -14, -12, -10, -7,
519 -5, -3, 0, 1, 3, 6, 8, 10,
520 13, 15, 17, 19, 22, 24, 26, 29,
521 31, 33, 35, 38, 40, 42, 44, 46,
522 48, 51, 53, 55, 57, 59, 61, 63,
523 65, 67, 69, 71, 73, 75, 77, 79,
524 81, 82, 84, 86, 88, 89, 91, 93,
525 94, 96, 98, 99, 101, 102, 104, 105,
526 106, 108, 109, 110, 112, 113, 114, 115,
527 116, 117, 119, 120, 120, 121, 122, 123,
528 124, 125, 126, 126, 127, 128, 128, 129,
529 129, 130, 130, 131, 131, 131, 131, 132,
530 132, 132, 132, 132, 132, 132, 132, 132,
531 132, 132, 132, 131, 131, 131, 130, 130,
532 130, 129, 129, 128, 127, 127, 126, 125,
533 125, 124, 123, 122, 121, 120, 119, 118,
534 117, 116, 115, 114, 113, 111, 110, 109,
535 107, 106, 105, 103, 102, 100, 99, 97,
536 96, 94, 92, 91, 89, 87, 85, 84, 82
539 static const s16 hsv_green_x[] = {
540 -124, -124, -125, -125, -125, -125, -125, -125,
541 -125, -126, -126, -125, -125, -125, -125, -125,
542 -125, -124, -124, -124, -123, -123, -122, -122,
543 -121, -121, -120, -120, -119, -118, -117, -117,
544 -116, -115, -114, -113, -112, -111, -110, -109,
545 -108, -107, -105, -104, -103, -102, -100, -99,
546 -98, -96, -95, -93, -92, -91, -89, -87,
547 -86, -84, -83, -81, -79, -77, -76, -74,
548 -72, -70, -69, -67, -65, -63, -61, -59,
549 -57, -55, -53, -51, -49, -47, -45, -43,
550 -41, -39, -37, -35, -33, -30, -28, -26,
551 -24, -22, -20, -18, -15, -13, -11, -9,
552 -7, -4, -2, 0, 1, 3, 6, 8,
553 10, 12, 14, 17, 19, 21, 23, 25,
554 27, 29, 32, 34, 36, 38, 40, 42,
555 44, 46, 48, 50, 52, 54, 56, 58,
556 60, 62, 64, 66, 68, 70, 71, 73,
557 75, 77, 78, 80, 82, 83, 85, 87,
558 88, 90, 91, 93, 94, 96, 97, 98,
559 100, 101, 102, 104, 105, 106, 107, 108,
560 109, 111, 112, 113, 113, 114, 115, 116,
561 117, 118, 118, 119, 120, 120, 121, 122,
562 122, 123, 123, 124, 124, 124, 125, 125,
563 125, 125, 125, 125, 125, 126, 126, 125,
564 125, 125, 125, 125, 125, 124, 124, 124,
565 123, 123, 122, 122, 121, 121, 120, 120,
566 119, 118, 117, 117, 116, 115, 114, 113,
567 112, 111, 110, 109, 108, 107, 105, 104,
568 103, 102, 100, 99, 98, 96, 95, 93,
569 92, 91, 89, 87, 86, 84, 83, 81,
570 79, 77, 76, 74, 72, 70, 69, 67,
571 65, 63, 61, 59, 57, 55, 53, 51,
572 49, 47, 45, 43, 41, 39, 37, 35,
573 33, 30, 28, 26, 24, 22, 20, 18,
574 15, 13, 11, 9, 7, 4, 2, 0,
575 -1, -3, -6, -8, -10, -12, -14, -17,
576 -19, -21, -23, -25, -27, -29, -32, -34,
577 -36, -38, -40, -42, -44, -46, -48, -50,
578 -52, -54, -56, -58, -60, -62, -64, -66,
579 -68, -70, -71, -73, -75, -77, -78, -80,
580 -82, -83, -85, -87, -88, -90, -91, -93,
581 -94, -96, -97, -98, -100, -101, -102, -104,
582 -105, -106, -107, -108, -109, -111, -112, -113,
583 -113, -114, -115, -116, -117, -118, -118, -119,
584 -120, -120, -121, -122, -122, -123, -123, -124, -124
587 static const s16 hsv_green_y[] = {
588 -100, -99, -98, -97, -95, -94, -93, -91,
589 -90, -89, -87, -86, -84, -83, -81, -80,
590 -78, -76, -75, -73, -71, -70, -68, -66,
591 -64, -63, -61, -59, -57, -55, -53, -51,
592 -49, -48, -46, -44, -42, -40, -38, -36,
593 -34, -32, -30, -27, -25, -23, -21, -19,
594 -17, -15, -13, -11, -9, -7, -4, -2,
595 0, 1, 3, 5, 7, 9, 11, 14,
596 16, 18, 20, 22, 24, 26, 28, 30,
597 32, 34, 36, 38, 40, 42, 44, 46,
598 48, 50, 52, 54, 56, 58, 59, 61,
599 63, 65, 67, 68, 70, 72, 74, 75,
600 77, 78, 80, 82, 83, 85, 86, 88,
601 89, 90, 92, 93, 95, 96, 97, 98,
602 100, 101, 102, 103, 104, 105, 106, 107,
603 108, 109, 110, 111, 112, 112, 113, 114,
604 115, 115, 116, 116, 117, 117, 118, 118,
605 119, 119, 119, 120, 120, 120, 120, 120,
606 121, 121, 121, 121, 121, 121, 120, 120,
607 120, 120, 120, 119, 119, 119, 118, 118,
608 117, 117, 116, 116, 115, 114, 114, 113,
609 112, 111, 111, 110, 109, 108, 107, 106,
610 105, 104, 103, 102, 100, 99, 98, 97,
611 95, 94, 93, 91, 90, 89, 87, 86,
612 84, 83, 81, 80, 78, 76, 75, 73,
613 71, 70, 68, 66, 64, 63, 61, 59,
614 57, 55, 53, 51, 49, 48, 46, 44,
615 42, 40, 38, 36, 34, 32, 30, 27,
616 25, 23, 21, 19, 17, 15, 13, 11,
617 9, 7, 4, 2, 0, -1, -3, -5,
618 -7, -9, -11, -14, -16, -18, -20, -22,
619 -24, -26, -28, -30, -32, -34, -36, -38,
620 -40, -42, -44, -46, -48, -50, -52, -54,
621 -56, -58, -59, -61, -63, -65, -67, -68,
622 -70, -72, -74, -75, -77, -78, -80, -82,
623 -83, -85, -86, -88, -89, -90, -92, -93,
624 -95, -96, -97, -98, -100, -101, -102, -103,
625 -104, -105, -106, -107, -108, -109, -110, -111,
626 -112, -112, -113, -114, -115, -115, -116, -116,
627 -117, -117, -118, -118, -119, -119, -119, -120,
628 -120, -120, -120, -120, -121, -121, -121, -121,
629 -121, -121, -120, -120, -120, -120, -120, -119,
630 -119, -119, -118, -118, -117, -117, -116, -116,
631 -115, -114, -114, -113, -112, -111, -111, -110,
632 -109, -108, -107, -106, -105, -104, -103, -102, -100
635 static const s16 hsv_blue_x[] = {
636 112, 113, 114, 114, 115, 116, 117, 117,
637 118, 118, 119, 119, 120, 120, 120, 121,
638 121, 121, 122, 122, 122, 122, 122, 122,
639 122, 122, 122, 122, 122, 122, 121, 121,
640 121, 120, 120, 120, 119, 119, 118, 118,
641 117, 116, 116, 115, 114, 113, 113, 112,
642 111, 110, 109, 108, 107, 106, 105, 104,
643 103, 102, 100, 99, 98, 97, 95, 94,
644 93, 91, 90, 88, 87, 85, 84, 82,
645 80, 79, 77, 76, 74, 72, 70, 69,
646 67, 65, 63, 61, 60, 58, 56, 54,
647 52, 50, 48, 46, 44, 42, 40, 38,
648 36, 34, 32, 30, 28, 26, 24, 22,
649 19, 17, 15, 13, 11, 9, 7, 5,
650 2, 0, -1, -3, -5, -7, -9, -12,
651 -14, -16, -18, -20, -22, -24, -26, -28,
652 -31, -33, -35, -37, -39, -41, -43, -45,
653 -47, -49, -51, -53, -54, -56, -58, -60,
654 -62, -64, -66, -67, -69, -71, -73, -74,
655 -76, -78, -79, -81, -83, -84, -86, -87,
656 -89, -90, -92, -93, -94, -96, -97, -98,
657 -99, -101, -102, -103, -104, -105, -106, -107,
658 -108, -109, -110, -111, -112, -113, -114, -114,
659 -115, -116, -117, -117, -118, -118, -119, -119,
660 -120, -120, -120, -121, -121, -121, -122, -122,
661 -122, -122, -122, -122, -122, -122, -122, -122,
662 -122, -122, -121, -121, -121, -120, -120, -120,
663 -119, -119, -118, -118, -117, -116, -116, -115,
664 -114, -113, -113, -112, -111, -110, -109, -108,
665 -107, -106, -105, -104, -103, -102, -100, -99,
666 -98, -97, -95, -94, -93, -91, -90, -88,
667 -87, -85, -84, -82, -80, -79, -77, -76,
668 -74, -72, -70, -69, -67, -65, -63, -61,
669 -60, -58, -56, -54, -52, -50, -48, -46,
670 -44, -42, -40, -38, -36, -34, -32, -30,
671 -28, -26, -24, -22, -19, -17, -15, -13,
672 -11, -9, -7, -5, -2, 0, 1, 3,
673 5, 7, 9, 12, 14, 16, 18, 20,
674 22, 24, 26, 28, 31, 33, 35, 37,
675 39, 41, 43, 45, 47, 49, 51, 53,
676 54, 56, 58, 60, 62, 64, 66, 67,
677 69, 71, 73, 74, 76, 78, 79, 81,
678 83, 84, 86, 87, 89, 90, 92, 93,
679 94, 96, 97, 98, 99, 101, 102, 103,
680 104, 105, 106, 107, 108, 109, 110, 111, 112
683 static const s16 hsv_blue_y[] = {
684 -11, -13, -15, -17, -19, -21, -23, -25,
685 -27, -29, -31, -33, -35, -37, -39, -41,
686 -43, -45, -46, -48, -50, -52, -54, -55,
687 -57, -59, -61, -62, -64, -66, -67, -69,
688 -71, -72, -74, -75, -77, -78, -80, -81,
689 -83, -84, -86, -87, -88, -90, -91, -92,
690 -93, -95, -96, -97, -98, -99, -100, -101,
691 -102, -103, -104, -105, -106, -106, -107, -108,
692 -109, -109, -110, -111, -111, -112, -112, -113,
693 -113, -114, -114, -114, -115, -115, -115, -115,
694 -116, -116, -116, -116, -116, -116, -116, -116,
695 -116, -115, -115, -115, -115, -114, -114, -114,
696 -113, -113, -112, -112, -111, -111, -110, -110,
697 -109, -108, -108, -107, -106, -105, -104, -103,
698 -102, -101, -100, -99, -98, -97, -96, -95,
699 -94, -93, -91, -90, -89, -88, -86, -85,
700 -84, -82, -81, -79, -78, -76, -75, -73,
701 -71, -70, -68, -67, -65, -63, -62, -60,
702 -58, -56, -55, -53, -51, -49, -47, -45,
703 -44, -42, -40, -38, -36, -34, -32, -30,
704 -28, -26, -24, -22, -20, -18, -16, -14,
705 -12, -10, -8, -6, -4, -2, 0, 1,
706 3, 5, 7, 9, 11, 13, 15, 17,
707 19, 21, 23, 25, 27, 29, 31, 33,
708 35, 37, 39, 41, 43, 45, 46, 48,
709 50, 52, 54, 55, 57, 59, 61, 62,
710 64, 66, 67, 69, 71, 72, 74, 75,
711 77, 78, 80, 81, 83, 84, 86, 87,
712 88, 90, 91, 92, 93, 95, 96, 97,
713 98, 99, 100, 101, 102, 103, 104, 105,
714 106, 106, 107, 108, 109, 109, 110, 111,
715 111, 112, 112, 113, 113, 114, 114, 114,
716 115, 115, 115, 115, 116, 116, 116, 116,
717 116, 116, 116, 116, 116, 115, 115, 115,
718 115, 114, 114, 114, 113, 113, 112, 112,
719 111, 111, 110, 110, 109, 108, 108, 107,
720 106, 105, 104, 103, 102, 101, 100, 99,
721 98, 97, 96, 95, 94, 93, 91, 90,
722 89, 88, 86, 85, 84, 82, 81, 79,
723 78, 76, 75, 73, 71, 70, 68, 67,
724 65, 63, 62, 60, 58, 56, 55, 53,
725 51, 49, 47, 45, 44, 42, 40, 38,
726 36, 34, 32, 30, 28, 26, 24, 22,
727 20, 18, 16, 14, 12, 10, 8, 6,
728 4, 2, 0, -1, -3, -5, -7, -9, -11
731 static u16 i2c_ident[] = {
740 V4L2_IDENT_MT9M001C12ST,
746 static u16 bridge_init[][2] = {
747 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
748 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
749 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
750 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
751 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
752 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
753 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
754 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
755 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
756 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
757 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
758 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
759 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
760 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
761 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
762 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
763 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
764 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
765 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
769 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
770 static u8 ov_gain[] = {
771 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
772 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
773 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
774 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
775 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
776 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
777 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
781 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
782 static u16 micron1_gain[] = {
783 /* 1x 1.25x 1.5x 1.75x */
784 0x0020, 0x0028, 0x0030, 0x0038,
785 /* 2x 2.25x 2.5x 2.75x */
786 0x00a0, 0x00a4, 0x00a8, 0x00ac,
787 /* 3x 3.25x 3.5x 3.75x */
788 0x00b0, 0x00b4, 0x00b8, 0x00bc,
789 /* 4x 4.25x 4.5x 4.75x */
790 0x00c0, 0x00c4, 0x00c8, 0x00cc,
791 /* 5x 5.25x 5.5x 5.75x */
792 0x00d0, 0x00d4, 0x00d8, 0x00dc,
793 /* 6x 6.25x 6.5x 6.75x */
794 0x00e0, 0x00e4, 0x00e8, 0x00ec,
795 /* 7x 7.25x 7.5x 7.75x */
796 0x00f0, 0x00f4, 0x00f8, 0x00fc,
801 /* mt9m001 sensor uses a different gain formula then other micron sensors */
802 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
803 static u16 micron2_gain[] = {
804 /* 1x 1.25x 1.5x 1.75x */
805 0x0008, 0x000a, 0x000c, 0x000e,
806 /* 2x 2.25x 2.5x 2.75x */
807 0x0010, 0x0012, 0x0014, 0x0016,
808 /* 3x 3.25x 3.5x 3.75x */
809 0x0018, 0x001a, 0x001c, 0x001e,
810 /* 4x 4.25x 4.5x 4.75x */
811 0x0020, 0x0051, 0x0052, 0x0053,
812 /* 5x 5.25x 5.5x 5.75x */
813 0x0054, 0x0055, 0x0056, 0x0057,
814 /* 6x 6.25x 6.5x 6.75x */
815 0x0058, 0x0059, 0x005a, 0x005b,
816 /* 7x 7.25x 7.5x 7.75x */
817 0x005c, 0x005d, 0x005e, 0x005f,
822 /* Gain = .5 + bit[7:0] / 16 */
823 static u8 hv7131r_gain[] = {
824 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
825 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
826 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
827 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
828 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
829 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
830 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
834 static struct i2c_reg_u8 soi968_init[] = {
835 {0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f},
836 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
837 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
838 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
839 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
840 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
841 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
842 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
843 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
844 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
845 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
848 static struct i2c_reg_u8 ov7660_init[] = {
849 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
850 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
851 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
852 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
853 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6},
854 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
857 static struct i2c_reg_u8 ov7670_init[] = {
858 {0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
859 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
860 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
861 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
862 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
863 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
864 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
865 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
866 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
867 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
868 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
869 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
870 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
871 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
872 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
873 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
874 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
875 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
876 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
877 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
878 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
879 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
880 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
881 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
882 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
883 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
884 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
885 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
886 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
887 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
888 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
889 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
890 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
891 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
892 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
893 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
894 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
895 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
896 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
897 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
898 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
899 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
900 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
901 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
902 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
903 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
904 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
905 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
906 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
907 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
908 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
909 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
910 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
914 static struct i2c_reg_u8 ov9650_init[] = {
915 {0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78},
916 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
917 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
918 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
919 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
920 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
921 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
922 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
923 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
924 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
925 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
926 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
927 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
928 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
929 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
930 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
931 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
932 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
933 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
934 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
935 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
936 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
937 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
938 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
939 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
940 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
941 {0xaa, 0x92}, {0xab, 0x0a},
944 static struct i2c_reg_u8 ov9655_init[] = {
945 {0x12, 0x80}, {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
946 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
947 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
948 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
949 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
950 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
951 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
952 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
953 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
954 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
955 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
956 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
957 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
958 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
959 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
960 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
961 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
962 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
963 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
964 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
965 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
966 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
967 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
968 {0x04, 0x03}, {0x00, 0x13},
971 static struct i2c_reg_u16 mt9v112_init[] = {
972 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
973 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
974 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
975 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
976 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
977 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
978 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
979 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
980 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
981 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
982 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
983 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
984 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
985 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
986 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
987 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
990 static struct i2c_reg_u16 mt9v111_init[] = {
991 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
992 {0x01, 0x0001}, {0x02, 0x0016}, {0x03, 0x01e1},
993 {0x04, 0x0281}, {0x05, 0x0004}, {0x07, 0x3002},
994 {0x21, 0x0000}, {0x25, 0x4024}, {0x26, 0xff03},
995 {0x27, 0xff10}, {0x2b, 0x7828}, {0x2c, 0xb43c},
996 {0x2d, 0xf0a0}, {0x2e, 0x0c64}, {0x2f, 0x0064},
997 {0x67, 0x4010}, {0x06, 0x301e}, {0x08, 0x0480},
998 {0x01, 0x0004}, {0x02, 0x0016}, {0x03, 0x01e6},
999 {0x04, 0x0286}, {0x05, 0x0004}, {0x06, 0x0000},
1000 {0x07, 0x3002}, {0x08, 0x0008}, {0x0c, 0x0000},
1001 {0x0d, 0x0000}, {0x0e, 0x0000}, {0x0f, 0x0000},
1002 {0x10, 0x0000}, {0x11, 0x0000}, {0x12, 0x00b0},
1003 {0x13, 0x007c}, {0x14, 0x0000}, {0x15, 0x0000},
1004 {0x16, 0x0000}, {0x17, 0x0000}, {0x18, 0x0000},
1005 {0x19, 0x0000}, {0x1a, 0x0000}, {0x1b, 0x0000},
1006 {0x1c, 0x0000}, {0x1d, 0x0000}, {0x30, 0x0000},
1007 {0x30, 0x0005}, {0x31, 0x0000}, {0x02, 0x0016},
1008 {0x03, 0x01e1}, {0x04, 0x0281}, {0x05, 0x0004},
1009 {0x06, 0x0000}, {0x07, 0x3002}, {0x06, 0x002d},
1010 {0x05, 0x0004}, {0x09, 0x0064}, {0x2b, 0x00a0},
1011 {0x2c, 0x00a0}, {0x2d, 0x00a0}, {0x2e, 0x00a0},
1012 {0x02, 0x0016}, {0x03, 0x01e1}, {0x04, 0x0281},
1013 {0x05, 0x0004}, {0x06, 0x002d}, {0x07, 0x3002},
1014 {0x0e, 0x0008}, {0x06, 0x002d}, {0x05, 0x0004},
1017 static struct i2c_reg_u16 mt9v011_init[] = {
1018 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
1019 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
1020 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
1021 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
1022 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
1023 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
1024 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
1025 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
1026 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
1027 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
1028 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
1029 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
1030 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
1031 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
1032 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
1033 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
1034 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
1035 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
1036 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
1037 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
1038 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
1039 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1040 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
1041 {0x06, 0x0029}, {0x05, 0x0009},
1044 static struct i2c_reg_u16 mt9m001_init[] = {
1045 {0x0d, 0x0001}, {0x0d, 0x0000}, {0x01, 0x000e},
1046 {0x02, 0x0014}, {0x03, 0x03c1}, {0x04, 0x0501},
1047 {0x05, 0x0083}, {0x06, 0x0006}, {0x0d, 0x0002},
1048 {0x0a, 0x0000}, {0x0c, 0x0000}, {0x11, 0x0000},
1049 {0x1e, 0x8000}, {0x5f, 0x8904}, {0x60, 0x0000},
1050 {0x61, 0x0000}, {0x62, 0x0498}, {0x63, 0x0000},
1051 {0x64, 0x0000}, {0x20, 0x111d}, {0x06, 0x00f2},
1052 {0x05, 0x0013}, {0x09, 0x10f2}, {0x07, 0x0003},
1053 {0x2b, 0x002a}, {0x2d, 0x002a}, {0x2c, 0x002a},
1054 {0x2e, 0x0029}, {0x07, 0x0002},
1057 static struct i2c_reg_u16 mt9m111_init[] = {
1058 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1059 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1060 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1064 static struct i2c_reg_u16 mt9m112_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_u8 hv7131r_init[] = {
1072 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
1073 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
1074 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
1075 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
1076 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
1077 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
1078 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
1079 {0x23, 0x09}, {0x01, 0x08},
1082 static int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
1084 struct usb_device *dev = gspca_dev->dev;
1086 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
1088 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1094 if (unlikely(result < 0 || result != length)) {
1095 err("Read register failed 0x%02X", reg);
1101 static int reg_w(struct gspca_dev *gspca_dev, u16 reg,
1102 const u8 *buffer, int length)
1104 struct usb_device *dev = gspca_dev->dev;
1106 memcpy(gspca_dev->usb_buf, buffer, length);
1107 result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1109 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1115 if (unlikely(result < 0 || result != length)) {
1116 err("Write register failed index 0x%02X", reg);
1122 static int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
1124 u8 data[1] = {value};
1125 return reg_w(gspca_dev, reg, data, 1);
1128 static int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
1131 reg_w(gspca_dev, 0x10c0, buffer, 8);
1132 for (i = 0; i < 5; i++) {
1133 reg_r(gspca_dev, 0x10c0, 1);
1134 if (gspca_dev->usb_buf[0] & 0x04) {
1135 if (gspca_dev->usb_buf[0] & 0x08)
1144 static int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1146 struct sd *sd = (struct sd *) gspca_dev;
1151 * from the point of view of the bridge, the length
1152 * includes the address
1154 row[0] = 0x81 | (2 << 4);
1155 row[1] = sd->i2c_addr;
1163 return i2c_w(gspca_dev, row);
1166 static int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1168 struct sd *sd = (struct sd *) gspca_dev;
1172 * from the point of view of the bridge, the length
1173 * includes the address
1175 row[0] = 0x81 | (3 << 4);
1176 row[1] = sd->i2c_addr;
1178 row[3] = (val >> 8) & 0xff;
1179 row[4] = val & 0xff;
1184 return i2c_w(gspca_dev, row);
1187 static int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1189 struct sd *sd = (struct sd *) gspca_dev;
1192 row[0] = 0x81 | (1 << 4);
1193 row[1] = sd->i2c_addr;
1200 if (i2c_w(gspca_dev, row) < 0)
1202 row[0] = 0x81 | (1 << 4) | 0x02;
1204 if (i2c_w(gspca_dev, row) < 0)
1206 if (reg_r(gspca_dev, 0x10c2, 5) < 0)
1208 *val = gspca_dev->usb_buf[4];
1212 static int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1214 struct sd *sd = (struct sd *) gspca_dev;
1217 row[0] = 0x81 | (1 << 4);
1218 row[1] = sd->i2c_addr;
1225 if (i2c_w(gspca_dev, row) < 0)
1227 row[0] = 0x81 | (2 << 4) | 0x02;
1229 if (i2c_w(gspca_dev, row) < 0)
1231 if (reg_r(gspca_dev, 0x10c2, 5) < 0)
1233 *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1237 static int ov9650_init_sensor(struct gspca_dev *gspca_dev)
1240 struct sd *sd = (struct sd *) gspca_dev;
1242 for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) {
1243 if (i2c_w1(gspca_dev, ov9650_init[i].reg,
1244 ov9650_init[i].val) < 0) {
1245 err("OV9650 sensor initialization failed");
1254 static int ov9655_init_sensor(struct gspca_dev *gspca_dev)
1257 struct sd *sd = (struct sd *) gspca_dev;
1259 for (i = 0; i < ARRAY_SIZE(ov9655_init); i++) {
1260 if (i2c_w1(gspca_dev, ov9655_init[i].reg,
1261 ov9655_init[i].val) < 0) {
1262 err("OV9655 sensor initialization failed");
1266 /* disable hflip and vflip */
1267 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1273 static int soi968_init_sensor(struct gspca_dev *gspca_dev)
1276 struct sd *sd = (struct sd *) gspca_dev;
1278 for (i = 0; i < ARRAY_SIZE(soi968_init); i++) {
1279 if (i2c_w1(gspca_dev, soi968_init[i].reg,
1280 soi968_init[i].val) < 0) {
1281 err("SOI968 sensor initialization failed");
1285 /* disable hflip and vflip */
1286 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << EXPOSURE_IDX);
1292 static int ov7660_init_sensor(struct gspca_dev *gspca_dev)
1295 struct sd *sd = (struct sd *) gspca_dev;
1297 for (i = 0; i < ARRAY_SIZE(ov7660_init); i++) {
1298 if (i2c_w1(gspca_dev, ov7660_init[i].reg,
1299 ov7660_init[i].val) < 0) {
1300 err("OV7660 sensor initialization failed");
1304 /* disable hflip and vflip */
1305 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1311 static int ov7670_init_sensor(struct gspca_dev *gspca_dev)
1314 struct sd *sd = (struct sd *) gspca_dev;
1316 for (i = 0; i < ARRAY_SIZE(ov7670_init); i++) {
1317 if (i2c_w1(gspca_dev, ov7670_init[i].reg,
1318 ov7670_init[i].val) < 0) {
1319 err("OV7670 sensor initialization failed");
1323 /* disable hflip and vflip */
1324 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1330 static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
1332 struct sd *sd = (struct sd *) gspca_dev;
1337 sd->i2c_addr = 0x5d;
1338 ret = i2c_r2(gspca_dev, 0xff, &value);
1339 if ((ret == 0) && (value == 0x8243)) {
1340 for (i = 0; i < ARRAY_SIZE(mt9v011_init); i++) {
1341 if (i2c_w2(gspca_dev, mt9v011_init[i].reg,
1342 mt9v011_init[i].val) < 0) {
1343 err("MT9V011 sensor initialization failed");
1349 sd->sensor = SENSOR_MT9V011;
1350 info("MT9V011 sensor detected");
1354 sd->i2c_addr = 0x5c;
1355 i2c_w2(gspca_dev, 0x01, 0x0004);
1356 ret = i2c_r2(gspca_dev, 0xff, &value);
1357 if ((ret == 0) && (value == 0x823a)) {
1358 for (i = 0; i < ARRAY_SIZE(mt9v111_init); i++) {
1359 if (i2c_w2(gspca_dev, mt9v111_init[i].reg,
1360 mt9v111_init[i].val) < 0) {
1361 err("MT9V111 sensor initialization failed");
1367 sd->sensor = SENSOR_MT9V111;
1368 info("MT9V111 sensor detected");
1372 sd->i2c_addr = 0x5d;
1373 ret = i2c_w2(gspca_dev, 0xf0, 0x0000);
1375 sd->i2c_addr = 0x48;
1376 i2c_w2(gspca_dev, 0xf0, 0x0000);
1378 ret = i2c_r2(gspca_dev, 0x00, &value);
1379 if ((ret == 0) && (value == 0x1229)) {
1380 for (i = 0; i < ARRAY_SIZE(mt9v112_init); i++) {
1381 if (i2c_w2(gspca_dev, mt9v112_init[i].reg,
1382 mt9v112_init[i].val) < 0) {
1383 err("MT9V112 sensor initialization failed");
1389 sd->sensor = SENSOR_MT9V112;
1390 info("MT9V112 sensor detected");
1397 static int mt9m112_init_sensor(struct gspca_dev *gspca_dev)
1399 struct sd *sd = (struct sd *) gspca_dev;
1401 for (i = 0; i < ARRAY_SIZE(mt9m112_init); i++) {
1402 if (i2c_w2(gspca_dev, mt9m112_init[i].reg,
1403 mt9m112_init[i].val) < 0) {
1404 err("MT9M112 sensor initialization failed");
1408 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | (1 << GAIN_IDX);
1414 static int mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1416 struct sd *sd = (struct sd *) gspca_dev;
1418 for (i = 0; i < ARRAY_SIZE(mt9m111_init); i++) {
1419 if (i2c_w2(gspca_dev, mt9m111_init[i].reg,
1420 mt9m111_init[i].val) < 0) {
1421 err("MT9M111 sensor initialization failed");
1425 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | (1 << GAIN_IDX);
1431 static int mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1433 struct sd *sd = (struct sd *) gspca_dev;
1435 for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) {
1436 if (i2c_w2(gspca_dev, mt9m001_init[i].reg,
1437 mt9m001_init[i].val) < 0) {
1438 err("MT9M001 sensor initialization failed");
1442 /* disable hflip and vflip */
1443 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1449 static int hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1452 struct sd *sd = (struct sd *) gspca_dev;
1454 for (i = 0; i < ARRAY_SIZE(hv7131r_init); i++) {
1455 if (i2c_w1(gspca_dev, hv7131r_init[i].reg,
1456 hv7131r_init[i].val) < 0) {
1457 err("HV7131R Sensor initialization failed");
1466 static int set_cmatrix(struct gspca_dev *gspca_dev)
1468 struct sd *sd = (struct sd *) gspca_dev;
1469 s32 hue_coord, hue_index = 180 + sd->hue;
1472 memset(cmatrix, 0, sizeof cmatrix);
1473 cmatrix[2] = (sd->contrast * 0x25 / 0x100) + 0x26;
1474 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1475 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1476 cmatrix[18] = sd->brightness - 0x80;
1478 hue_coord = (hsv_red_x[hue_index] * sd->saturation) >> 8;
1479 cmatrix[6] = hue_coord;
1480 cmatrix[7] = (hue_coord >> 8) & 0x0f;
1482 hue_coord = (hsv_red_y[hue_index] * sd->saturation) >> 8;
1483 cmatrix[8] = hue_coord;
1484 cmatrix[9] = (hue_coord >> 8) & 0x0f;
1486 hue_coord = (hsv_green_x[hue_index] * sd->saturation) >> 8;
1487 cmatrix[10] = hue_coord;
1488 cmatrix[11] = (hue_coord >> 8) & 0x0f;
1490 hue_coord = (hsv_green_y[hue_index] * sd->saturation) >> 8;
1491 cmatrix[12] = hue_coord;
1492 cmatrix[13] = (hue_coord >> 8) & 0x0f;
1494 hue_coord = (hsv_blue_x[hue_index] * sd->saturation) >> 8;
1495 cmatrix[14] = hue_coord;
1496 cmatrix[15] = (hue_coord >> 8) & 0x0f;
1498 hue_coord = (hsv_blue_y[hue_index] * sd->saturation) >> 8;
1499 cmatrix[16] = hue_coord;
1500 cmatrix[17] = (hue_coord >> 8) & 0x0f;
1502 return reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1505 static int set_gamma(struct gspca_dev *gspca_dev)
1507 struct sd *sd = (struct sd *) gspca_dev;
1509 u8 gval = sd->gamma * 0xb8 / 0x100;
1513 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
1514 gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8);
1515 gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8);
1516 gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8);
1517 gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8);
1518 gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8);
1519 gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8);
1520 gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8);
1521 gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8);
1522 gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8);
1523 gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8);
1524 gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8);
1525 gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8);
1526 gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8);
1527 gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
1530 return reg_w(gspca_dev, 0x1190, gamma, 17);
1533 static int set_redblue(struct gspca_dev *gspca_dev)
1535 struct sd *sd = (struct sd *) gspca_dev;
1536 reg_w1(gspca_dev, 0x118c, sd->red);
1537 reg_w1(gspca_dev, 0x118f, sd->blue);
1541 static int set_hvflip(struct gspca_dev *gspca_dev)
1543 u8 value, tslb, hflip, vflip;
1545 struct sd *sd = (struct sd *) gspca_dev;
1547 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1555 switch (sd->sensor) {
1557 i2c_r1(gspca_dev, 0x1e, &value);
1566 i2c_w1(gspca_dev, 0x1e, value);
1567 i2c_w1(gspca_dev, 0x3a, tslb);
1569 case SENSOR_MT9V111:
1570 case SENSOR_MT9V011:
1571 i2c_r2(gspca_dev, 0x20, &value2);
1577 i2c_w2(gspca_dev, 0x20, value2);
1579 case SENSOR_MT9M112:
1580 case SENSOR_MT9M111:
1581 case SENSOR_MT9V112:
1582 i2c_r2(gspca_dev, 0x20, &value2);
1588 i2c_w2(gspca_dev, 0x20, value2);
1590 case SENSOR_HV7131R:
1591 i2c_r1(gspca_dev, 0x01, &value);
1597 i2c_w1(gspca_dev, 0x01, value);
1603 static int set_exposure(struct gspca_dev *gspca_dev)
1605 struct sd *sd = (struct sd *) gspca_dev;
1606 u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1607 switch (sd->sensor) {
1614 exp[3] = sd->exposure & 0xff;
1615 exp[4] = sd->exposure >> 8;
1617 case SENSOR_MT9M001:
1618 case SENSOR_MT9V112:
1619 case SENSOR_MT9V111:
1620 case SENSOR_MT9V011:
1623 exp[3] = sd->exposure >> 8;
1624 exp[4] = sd->exposure & 0xff;
1626 case SENSOR_HV7131R:
1629 exp[3] = (sd->exposure >> 5) & 0xff;
1630 exp[4] = (sd->exposure << 3) & 0xff;
1636 i2c_w(gspca_dev, exp);
1640 static int set_gain(struct gspca_dev *gspca_dev)
1642 struct sd *sd = (struct sd *) gspca_dev;
1643 u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1644 switch (sd->sensor) {
1650 gain[0] |= (2 << 4);
1651 gain[3] = ov_gain[sd->gain];
1653 case SENSOR_MT9V011:
1654 case SENSOR_MT9V111:
1655 gain[0] |= (3 << 4);
1657 gain[3] = micron1_gain[sd->gain] >> 8;
1658 gain[4] = micron1_gain[sd->gain] & 0xff;
1660 case SENSOR_MT9V112:
1661 gain[0] |= (3 << 4);
1663 gain[3] = micron1_gain[sd->gain] >> 8;
1664 gain[4] = micron1_gain[sd->gain] & 0xff;
1666 case SENSOR_MT9M001:
1667 gain[0] |= (3 << 4);
1669 gain[3] = micron2_gain[sd->gain] >> 8;
1670 gain[4] = micron2_gain[sd->gain] & 0xff;
1672 case SENSOR_HV7131R:
1673 gain[0] |= (2 << 4);
1675 gain[3] = hv7131r_gain[sd->gain];
1680 i2c_w(gspca_dev, gain);
1684 static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val)
1686 struct sd *sd = (struct sd *) gspca_dev;
1688 sd->brightness = val;
1689 if (gspca_dev->streaming)
1690 return set_cmatrix(gspca_dev);
1694 static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val)
1696 struct sd *sd = (struct sd *) gspca_dev;
1697 *val = sd->brightness;
1702 static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val)
1704 struct sd *sd = (struct sd *) gspca_dev;
1707 if (gspca_dev->streaming)
1708 return set_cmatrix(gspca_dev);
1712 static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val)
1714 struct sd *sd = (struct sd *) gspca_dev;
1715 *val = sd->contrast;
1719 static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val)
1721 struct sd *sd = (struct sd *) gspca_dev;
1723 sd->saturation = val;
1724 if (gspca_dev->streaming)
1725 return set_cmatrix(gspca_dev);
1729 static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val)
1731 struct sd *sd = (struct sd *) gspca_dev;
1732 *val = sd->saturation;
1736 static int sd_sethue(struct gspca_dev *gspca_dev, s32 val)
1738 struct sd *sd = (struct sd *) gspca_dev;
1741 if (gspca_dev->streaming)
1742 return set_cmatrix(gspca_dev);
1746 static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val)
1748 struct sd *sd = (struct sd *) gspca_dev;
1753 static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val)
1755 struct sd *sd = (struct sd *) gspca_dev;
1758 if (gspca_dev->streaming)
1759 return set_gamma(gspca_dev);
1763 static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val)
1765 struct sd *sd = (struct sd *) gspca_dev;
1770 static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val)
1772 struct sd *sd = (struct sd *) gspca_dev;
1775 if (gspca_dev->streaming)
1776 return set_redblue(gspca_dev);
1780 static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val)
1782 struct sd *sd = (struct sd *) gspca_dev;
1787 static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val)
1789 struct sd *sd = (struct sd *) gspca_dev;
1792 if (gspca_dev->streaming)
1793 return set_redblue(gspca_dev);
1797 static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val)
1799 struct sd *sd = (struct sd *) gspca_dev;
1804 static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val)
1806 struct sd *sd = (struct sd *) gspca_dev;
1809 if (gspca_dev->streaming)
1810 return set_hvflip(gspca_dev);
1814 static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val)
1816 struct sd *sd = (struct sd *) gspca_dev;
1821 static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val)
1823 struct sd *sd = (struct sd *) gspca_dev;
1826 if (gspca_dev->streaming)
1827 return set_hvflip(gspca_dev);
1831 static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val)
1833 struct sd *sd = (struct sd *) gspca_dev;
1838 static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val)
1840 struct sd *sd = (struct sd *) gspca_dev;
1843 if (gspca_dev->streaming)
1844 return set_exposure(gspca_dev);
1848 static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val)
1850 struct sd *sd = (struct sd *) gspca_dev;
1851 *val = sd->exposure;
1855 static int sd_setgain(struct gspca_dev *gspca_dev, s32 val)
1857 struct sd *sd = (struct sd *) gspca_dev;
1860 if (gspca_dev->streaming)
1861 return set_gain(gspca_dev);
1865 static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val)
1867 struct sd *sd = (struct sd *) gspca_dev;
1872 static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val)
1874 struct sd *sd = (struct sd *) gspca_dev;
1875 sd->auto_exposure = val;
1879 static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val)
1881 struct sd *sd = (struct sd *) gspca_dev;
1882 *val = sd->auto_exposure;
1886 #ifdef CONFIG_VIDEO_ADV_DEBUG
1887 static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1888 struct v4l2_dbg_register *reg)
1890 struct sd *sd = (struct sd *) gspca_dev;
1891 switch (reg->match.type) {
1892 case V4L2_CHIP_MATCH_HOST:
1893 if (reg->match.addr != 0)
1895 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1897 if (reg_r(gspca_dev, reg->reg, 1) < 0)
1899 reg->val = gspca_dev->usb_buf[0];
1901 case V4L2_CHIP_MATCH_I2C_ADDR:
1902 if (reg->match.addr != sd->i2c_addr)
1904 if (sd->sensor >= SENSOR_MT9V011 &&
1905 sd->sensor <= SENSOR_MT9M112) {
1906 if (i2c_r2(gspca_dev, reg->reg, (u16 *)®->val) < 0)
1909 if (i2c_r1(gspca_dev, reg->reg, (u8 *)®->val) < 0)
1917 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1918 struct v4l2_dbg_register *reg)
1920 struct sd *sd = (struct sd *) gspca_dev;
1921 switch (reg->match.type) {
1922 case V4L2_CHIP_MATCH_HOST:
1923 if (reg->match.addr != 0)
1925 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1927 if (reg_w1(gspca_dev, reg->reg, reg->val) < 0)
1930 case V4L2_CHIP_MATCH_I2C_ADDR:
1931 if (reg->match.addr != sd->i2c_addr)
1933 if (sd->sensor >= SENSOR_MT9V011 &&
1934 sd->sensor <= SENSOR_MT9M112) {
1935 if (i2c_w2(gspca_dev, reg->reg, reg->val) < 0)
1938 if (i2c_w1(gspca_dev, reg->reg, reg->val) < 0)
1947 static int sd_chip_ident(struct gspca_dev *gspca_dev,
1948 struct v4l2_dbg_chip_ident *chip)
1950 struct sd *sd = (struct sd *) gspca_dev;
1952 switch (chip->match.type) {
1953 case V4L2_CHIP_MATCH_HOST:
1954 if (chip->match.addr != 0)
1957 chip->ident = V4L2_IDENT_SN9C20X;
1959 case V4L2_CHIP_MATCH_I2C_ADDR:
1960 if (chip->match.addr != sd->i2c_addr)
1963 chip->ident = i2c_ident[sd->sensor];
1969 static int sd_config(struct gspca_dev *gspca_dev,
1970 const struct usb_device_id *id)
1972 struct sd *sd = (struct sd *) gspca_dev;
1975 cam = &gspca_dev->cam;
1977 sd->sensor = (id->driver_info >> 8) & 0xff;
1978 sd->i2c_addr = id->driver_info & 0xff;
1979 sd->flags = (id->driver_info >> 16) & 0xff;
1981 switch (sd->sensor) {
1982 case SENSOR_MT9M112:
1983 case SENSOR_MT9M111:
1986 cam->cam_mode = sxga_mode;
1987 cam->nmodes = ARRAY_SIZE(sxga_mode);
1990 cam->cam_mode = vga_mode;
1991 cam->nmodes = ARRAY_SIZE(vga_mode);
1997 sd->exposure_step = 16;
1999 sd->brightness = BRIGHTNESS_DEFAULT;
2000 sd->contrast = CONTRAST_DEFAULT;
2001 sd->saturation = SATURATION_DEFAULT;
2002 sd->hue = HUE_DEFAULT;
2003 sd->gamma = GAMMA_DEFAULT;
2004 sd->red = RED_DEFAULT;
2005 sd->blue = BLUE_DEFAULT;
2007 sd->hflip = HFLIP_DEFAULT;
2008 sd->vflip = VFLIP_DEFAULT;
2009 sd->exposure = EXPOSURE_DEFAULT;
2010 sd->gain = GAIN_DEFAULT;
2011 sd->auto_exposure = AUTO_EXPOSURE_DEFAULT;
2018 static int sd_init(struct gspca_dev *gspca_dev)
2020 struct sd *sd = (struct sd *) gspca_dev;
2024 {0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
2026 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
2027 value = bridge_init[i][1];
2028 if (reg_w(gspca_dev, bridge_init[i][0], &value, 1) < 0) {
2029 err("Device initialization failed");
2034 if (sd->flags & LED_REVERSE)
2035 reg_w1(gspca_dev, 0x1006, 0x00);
2037 reg_w1(gspca_dev, 0x1006, 0x20);
2039 if (reg_w(gspca_dev, 0x10c0, i2c_init, 9) < 0) {
2040 err("Device initialization failed");
2044 switch (sd->sensor) {
2046 if (ov9650_init_sensor(gspca_dev) < 0)
2048 info("OV9650 sensor detected");
2051 if (ov9655_init_sensor(gspca_dev) < 0)
2053 info("OV9655 sensor detected");
2056 if (soi968_init_sensor(gspca_dev) < 0)
2058 info("SOI968 sensor detected");
2061 if (ov7660_init_sensor(gspca_dev) < 0)
2063 info("OV7660 sensor detected");
2066 if (ov7670_init_sensor(gspca_dev) < 0)
2068 info("OV7670 sensor detected");
2070 case SENSOR_MT9VPRB:
2071 if (mt9v_init_sensor(gspca_dev) < 0)
2074 case SENSOR_MT9M111:
2075 if (mt9m111_init_sensor(gspca_dev) < 0)
2077 info("MT9M111 sensor detected");
2079 case SENSOR_MT9M112:
2080 if (mt9m112_init_sensor(gspca_dev) < 0)
2082 info("MT9M112 sensor detected");
2084 case SENSOR_MT9M001:
2085 if (mt9m001_init_sensor(gspca_dev) < 0)
2087 info("MT9M001 sensor detected");
2089 case SENSOR_HV7131R:
2090 if (hv7131r_init_sensor(gspca_dev) < 0)
2092 info("HV7131R sensor detected");
2095 info("Unsupported Sensor");
2102 static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
2104 struct sd *sd = (struct sd *) gspca_dev;
2106 switch (sd->sensor) {
2108 if (mode & MODE_SXGA) {
2109 i2c_w1(gspca_dev, 0x17, 0x1d);
2110 i2c_w1(gspca_dev, 0x18, 0xbd);
2111 i2c_w1(gspca_dev, 0x19, 0x01);
2112 i2c_w1(gspca_dev, 0x1a, 0x81);
2113 i2c_w1(gspca_dev, 0x12, 0x00);
2117 i2c_w1(gspca_dev, 0x17, 0x13);
2118 i2c_w1(gspca_dev, 0x18, 0x63);
2119 i2c_w1(gspca_dev, 0x19, 0x01);
2120 i2c_w1(gspca_dev, 0x1a, 0x79);
2121 i2c_w1(gspca_dev, 0x12, 0x40);
2127 if (mode & MODE_SXGA) {
2128 i2c_w1(gspca_dev, 0x17, 0x1b);
2129 i2c_w1(gspca_dev, 0x18, 0xbc);
2130 i2c_w1(gspca_dev, 0x19, 0x01);
2131 i2c_w1(gspca_dev, 0x1a, 0x82);
2132 i2c_r1(gspca_dev, 0x12, &value);
2133 i2c_w1(gspca_dev, 0x12, value & 0x07);
2135 i2c_w1(gspca_dev, 0x17, 0x24);
2136 i2c_w1(gspca_dev, 0x18, 0xc5);
2137 i2c_w1(gspca_dev, 0x19, 0x00);
2138 i2c_w1(gspca_dev, 0x1a, 0x3c);
2139 i2c_r1(gspca_dev, 0x12, &value);
2140 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
2143 case SENSOR_MT9M112:
2144 case SENSOR_MT9M111:
2145 if (mode & MODE_SXGA) {
2146 i2c_w2(gspca_dev, 0xf0, 0x0002);
2147 i2c_w2(gspca_dev, 0xc8, 0x970b);
2148 i2c_w2(gspca_dev, 0xf0, 0x0000);
2150 i2c_w2(gspca_dev, 0xf0, 0x0002);
2151 i2c_w2(gspca_dev, 0xc8, 0x8000);
2152 i2c_w2(gspca_dev, 0xf0, 0x0000);
2158 #define HW_WIN(mode, hstart, vstart) \
2159 ((const u8 []){hstart, 0, vstart, 0, \
2160 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
2161 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
2163 #define CLR_WIN(width, height) \
2165 {0, width >> 2, 0, height >> 1,\
2166 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
2168 static int sd_start(struct gspca_dev *gspca_dev)
2170 struct sd *sd = (struct sd *) gspca_dev;
2171 int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
2172 int width = gspca_dev->width;
2173 int height = gspca_dev->height;
2176 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
2177 if (sd->jpeg_hdr == NULL)
2180 jpeg_define(sd->jpeg_hdr, height, width,
2182 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2184 if (mode & MODE_RAW)
2186 else if (mode & MODE_JPEG)
2191 switch (mode & 0x0f) {
2194 info("Set 1280x1024");
2198 info("Set 640x480");
2202 info("Set 320x240");
2206 info("Set 160x120");
2210 configure_sensor_output(gspca_dev, mode);
2211 reg_w(gspca_dev, 0x1100, sd->jpeg_hdr + JPEG_QT0_OFFSET, 64);
2212 reg_w(gspca_dev, 0x1140, sd->jpeg_hdr + JPEG_QT1_OFFSET, 64);
2213 reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2214 reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2215 reg_w1(gspca_dev, 0x1189, scale);
2216 reg_w1(gspca_dev, 0x10e0, fmt);
2218 set_cmatrix(gspca_dev);
2219 set_gamma(gspca_dev);
2220 set_redblue(gspca_dev);
2221 set_gain(gspca_dev);
2222 set_exposure(gspca_dev);
2223 set_hvflip(gspca_dev);
2225 reg_w1(gspca_dev, 0x1007, 0x20);
2227 reg_r(gspca_dev, 0x1061, 1);
2228 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] | 0x02);
2232 static void sd_stopN(struct gspca_dev *gspca_dev)
2234 reg_w1(gspca_dev, 0x1007, 0x00);
2236 reg_r(gspca_dev, 0x1061, 1);
2237 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] & ~0x02);
2240 static void sd_stop0(struct gspca_dev *gspca_dev)
2242 struct sd *sd = (struct sd *) gspca_dev;
2243 kfree(sd->jpeg_hdr);
2246 static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2248 struct sd *sd = (struct sd *) gspca_dev;
2252 * some hardcoded values are present
2253 * like those for maximal/minimal exposure
2254 * and exposure steps
2256 if (avg_lum < MIN_AVG_LUM) {
2257 if (sd->exposure > 0x1770)
2260 new_exp = sd->exposure + sd->exposure_step;
2261 if (new_exp > 0x1770)
2265 sd->exposure = new_exp;
2266 set_exposure(gspca_dev);
2268 sd->older_step = sd->old_step;
2271 if (sd->old_step ^ sd->older_step)
2272 sd->exposure_step /= 2;
2274 sd->exposure_step += 2;
2276 if (avg_lum > MAX_AVG_LUM) {
2277 if (sd->exposure < 0x10)
2279 new_exp = sd->exposure - sd->exposure_step;
2280 if (new_exp > 0x1700)
2284 sd->exposure = new_exp;
2285 set_exposure(gspca_dev);
2286 sd->older_step = sd->old_step;
2289 if (sd->old_step ^ sd->older_step)
2290 sd->exposure_step /= 2;
2292 sd->exposure_step += 2;
2296 static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2298 struct sd *sd = (struct sd *) gspca_dev;
2300 if (avg_lum < MIN_AVG_LUM) {
2301 if (sd->gain + 1 <= 28) {
2303 set_gain(gspca_dev);
2306 if (avg_lum > MAX_AVG_LUM) {
2309 set_gain(gspca_dev);
2314 static void sd_dqcallback(struct gspca_dev *gspca_dev)
2316 struct sd *sd = (struct sd *) gspca_dev;
2319 if (!sd->auto_exposure)
2322 avg_lum = atomic_read(&sd->avg_lum);
2323 if (sd->sensor == SENSOR_SOI968)
2324 do_autogain(gspca_dev, avg_lum);
2326 do_autoexposure(gspca_dev, avg_lum);
2330 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2331 u8 *data, /* interrupt packet */
2332 int len) /* interrupt packet length */
2334 struct sd *sd = (struct sd *) gspca_dev;
2336 if (sd->flags & HAS_BUTTON && len == 1) {
2337 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2338 input_sync(gspca_dev->input_dev);
2339 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2340 input_sync(gspca_dev->input_dev);
2347 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2348 u8 *data, /* isoc packet */
2349 int len) /* iso packet length */
2351 struct sd *sd = (struct sd *) gspca_dev;
2353 static u8 frame_header[] =
2354 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2355 if (len == 64 && memcmp(data, frame_header, 6) == 0) {
2356 avg_lum = ((data[35] >> 2) & 3) |
2359 avg_lum += ((data[35] >> 4) & 3) |
2362 avg_lum += ((data[35] >> 6) & 3) |
2365 avg_lum += (data[36] & 3) |
2368 avg_lum += ((data[36] >> 2) & 3) |
2371 avg_lum += ((data[36] >> 4) & 3) |
2374 avg_lum += ((data[36] >> 6) & 3) |
2377 avg_lum += ((data[44] >> 4) & 3) |
2381 atomic_set(&sd->avg_lum, avg_lum);
2382 gspca_frame_add(gspca_dev, LAST_PACKET,
2386 if (gspca_dev->last_packet_type == LAST_PACKET) {
2387 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv
2389 gspca_frame_add(gspca_dev, FIRST_PACKET,
2390 sd->jpeg_hdr, JPEG_HDR_SZ);
2391 gspca_frame_add(gspca_dev, INTER_PACKET,
2394 gspca_frame_add(gspca_dev, FIRST_PACKET,
2398 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2402 /* sub-driver description */
2403 static const struct sd_desc sd_desc = {
2404 .name = MODULE_NAME,
2406 .nctrls = ARRAY_SIZE(sd_ctrls),
2407 .config = sd_config,
2412 .pkt_scan = sd_pkt_scan,
2414 .int_pkt_scan = sd_int_pkt_scan,
2416 .dq_callback = sd_dqcallback,
2417 #ifdef CONFIG_VIDEO_ADV_DEBUG
2418 .set_register = sd_dbg_s_register,
2419 .get_register = sd_dbg_g_register,
2421 .get_chip_ident = sd_chip_ident,
2424 #define SN9C20X(sensor, i2c_addr, flags) \
2425 .driver_info = ((flags & 0xff) << 16) \
2426 | (SENSOR_ ## sensor << 8) \
2429 static const __devinitdata struct usb_device_id device_table[] = {
2430 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2431 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
2432 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2433 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
2434 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30,
2435 (HAS_BUTTON | LED_REVERSE))},
2436 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30, FLIP_DETECT)},
2437 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2438 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2439 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2440 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2441 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, 0)},
2442 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2443 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2444 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2445 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2446 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, HAS_BUTTON)},
2447 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
2448 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2449 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2450 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2451 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2452 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, 0)},
2453 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, HAS_BUTTON)},
2454 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2455 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2456 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2457 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2458 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
2459 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
2460 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2461 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2462 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2463 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2464 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, HAS_BUTTON)},
2465 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2466 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2469 MODULE_DEVICE_TABLE(usb, device_table);
2471 /* -- device connect -- */
2472 static int sd_probe(struct usb_interface *intf,
2473 const struct usb_device_id *id)
2475 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2479 static struct usb_driver sd_driver = {
2480 .name = MODULE_NAME,
2481 .id_table = device_table,
2483 .disconnect = gspca_disconnect,
2485 .suspend = gspca_suspend,
2486 .resume = gspca_resume,
2487 .reset_resume = gspca_resume,
2491 /* -- module insert / remove -- */
2492 static int __init sd_mod_init(void)
2495 ret = usb_register(&sd_driver);
2501 static void __exit sd_mod_exit(void)
2503 usb_deregister(&sd_driver);
2504 info("deregistered");
2507 module_init(sd_mod_init);
2508 module_exit(sd_mod_exit);