2 * Sonix sn9c201 sn9c202 library
4 * Copyright (C) 2012 Jean-Francois Moine <http://moinejf.free.fr>
5 * Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com>
6 * Copyright (C) 2009 Brian Johnson <brijohn@gmail.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25 #include <linux/input.h>
30 #include <media/v4l2-chip-ident.h>
31 #include <linux/dmi.h>
33 MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, "
34 "microdia project <microdia@googlegroups.com>");
35 MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
36 MODULE_LICENSE("GPL");
39 * Pixel format private data
41 #define SCALE_MASK 0x0f
42 #define SCALE_160x120 0
43 #define SCALE_320x240 1
44 #define SCALE_640x480 2
45 #define SCALE_1280x1024 3
47 #define MODE_JPEG 0x20
48 #define MODE_SXGA 0x80
50 #define SENSOR_OV9650 0
51 #define SENSOR_OV9655 1
52 #define SENSOR_SOI968 2
53 #define SENSOR_OV7660 3
54 #define SENSOR_OV7670 4
55 #define SENSOR_MT9V011 5
56 #define SENSOR_MT9V111 6
57 #define SENSOR_MT9V112 7
58 #define SENSOR_MT9M001 8
59 #define SENSOR_MT9M111 9
60 #define SENSOR_MT9M112 10
61 #define SENSOR_HV7131R 11
62 #define SENSOR_MT9VPRB 12
65 #define HAS_NO_BUTTON 0x1
66 #define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
67 #define FLIP_DETECT 0x4
83 NCTRLS /* number of controls */
86 /* specific webcam descriptor */
88 struct gspca_dev gspca_dev;
90 struct gspca_ctrl ctrls[NCTRLS];
92 struct work_struct work;
93 struct workqueue_struct *work_thread;
95 u32 pktsz; /* (used by pkt_scan) */
98 u8 fmt; /* (used for JPEG QTAB update */
100 #define MIN_AVG_LUM 80
101 #define MAX_AVG_LUM 130
112 u8 jpeg_hdr[JPEG_HDR_SZ];
117 static void qual_upd(struct work_struct *work);
129 static const struct dmi_system_id flip_dmi_table[] = {
131 .ident = "MSI MS-1034",
133 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
134 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1034"),
135 DMI_MATCH(DMI_PRODUCT_VERSION, "0341")
139 .ident = "MSI MS-1632",
141 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
142 DMI_MATCH(DMI_BOARD_NAME, "MS-1632")
146 .ident = "MSI MS-1633X",
148 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
149 DMI_MATCH(DMI_BOARD_NAME, "MS-1633X")
153 .ident = "MSI MS-1635X",
155 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
156 DMI_MATCH(DMI_BOARD_NAME, "MS-1635X")
160 .ident = "ASUSTeK W7J",
162 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
163 DMI_MATCH(DMI_BOARD_NAME, "W7J ")
169 static void set_cmatrix(struct gspca_dev *gspca_dev);
170 static void set_gamma(struct gspca_dev *gspca_dev);
171 static void set_redblue(struct gspca_dev *gspca_dev);
172 static void set_hvflip(struct gspca_dev *gspca_dev);
173 static void set_exposure(struct gspca_dev *gspca_dev);
174 static void set_gain(struct gspca_dev *gspca_dev);
175 static void set_quality(struct gspca_dev *gspca_dev);
177 static const struct ctrl sd_ctrls[NCTRLS] = {
180 .id = V4L2_CID_BRIGHTNESS,
181 .type = V4L2_CTRL_TYPE_INTEGER,
182 .name = "Brightness",
186 .default_value = 0x7f
188 .set_control = set_cmatrix
192 .id = V4L2_CID_CONTRAST,
193 .type = V4L2_CTRL_TYPE_INTEGER,
198 .default_value = 0x7f
200 .set_control = set_cmatrix
204 .id = V4L2_CID_SATURATION,
205 .type = V4L2_CTRL_TYPE_INTEGER,
206 .name = "Saturation",
210 .default_value = 0x7f
212 .set_control = set_cmatrix
217 .type = V4L2_CTRL_TYPE_INTEGER,
224 .set_control = set_cmatrix
228 .id = V4L2_CID_GAMMA,
229 .type = V4L2_CTRL_TYPE_INTEGER,
234 .default_value = 0x10
236 .set_control = set_gamma
240 .id = V4L2_CID_BLUE_BALANCE,
241 .type = V4L2_CTRL_TYPE_INTEGER,
242 .name = "Blue Balance",
246 .default_value = 0x28
248 .set_control = set_redblue
252 .id = V4L2_CID_RED_BALANCE,
253 .type = V4L2_CTRL_TYPE_INTEGER,
254 .name = "Red Balance",
258 .default_value = 0x28
260 .set_control = set_redblue
264 .id = V4L2_CID_HFLIP,
265 .type = V4L2_CTRL_TYPE_BOOLEAN,
266 .name = "Horizontal Flip",
272 .set_control = set_hvflip
276 .id = V4L2_CID_VFLIP,
277 .type = V4L2_CTRL_TYPE_BOOLEAN,
278 .name = "Vertical Flip",
284 .set_control = set_hvflip
288 .id = V4L2_CID_EXPOSURE,
289 .type = V4L2_CTRL_TYPE_INTEGER,
294 .default_value = 0x33,
296 .set_control = set_exposure
301 .type = V4L2_CTRL_TYPE_INTEGER,
308 .set_control = set_gain
312 .id = V4L2_CID_AUTOGAIN,
313 .type = V4L2_CTRL_TYPE_BOOLEAN,
314 .name = "Auto Exposure",
323 .id = V4L2_CID_JPEG_COMPRESSION_QUALITY,
324 .type = V4L2_CTRL_TYPE_INTEGER,
325 .name = "Compression Quality",
326 #define QUALITY_MIN 50
327 #define QUALITY_MAX 90
328 #define QUALITY_DEF 80
329 .minimum = QUALITY_MIN,
330 .maximum = QUALITY_MAX,
332 .default_value = QUALITY_DEF,
334 .set_control = set_quality
338 static const struct v4l2_pix_format vga_mode[] = {
339 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
341 .sizeimage = 160 * 120 * 4 / 8 + 590,
342 .colorspace = V4L2_COLORSPACE_JPEG,
343 .priv = SCALE_160x120 | MODE_JPEG},
344 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
346 .sizeimage = 160 * 120,
347 .colorspace = V4L2_COLORSPACE_SRGB,
348 .priv = SCALE_160x120 | MODE_RAW},
349 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
351 .sizeimage = 240 * 120,
352 .colorspace = V4L2_COLORSPACE_SRGB,
353 .priv = SCALE_160x120},
354 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
356 .sizeimage = 320 * 240 * 4 / 8 + 590,
357 .colorspace = V4L2_COLORSPACE_JPEG,
358 .priv = SCALE_320x240 | MODE_JPEG},
359 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
361 .sizeimage = 320 * 240 ,
362 .colorspace = V4L2_COLORSPACE_SRGB,
363 .priv = SCALE_320x240 | MODE_RAW},
364 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
366 .sizeimage = 480 * 240 ,
367 .colorspace = V4L2_COLORSPACE_SRGB,
368 .priv = SCALE_320x240},
369 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
371 .sizeimage = 640 * 480 * 4 / 8 + 590,
372 .colorspace = V4L2_COLORSPACE_JPEG,
373 .priv = SCALE_640x480 | MODE_JPEG},
374 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
376 .sizeimage = 640 * 480,
377 .colorspace = V4L2_COLORSPACE_SRGB,
378 .priv = SCALE_640x480 | MODE_RAW},
379 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
381 .sizeimage = 960 * 480,
382 .colorspace = V4L2_COLORSPACE_SRGB,
383 .priv = SCALE_640x480},
386 static const struct v4l2_pix_format sxga_mode[] = {
387 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
389 .sizeimage = 160 * 120 * 4 / 8 + 590,
390 .colorspace = V4L2_COLORSPACE_JPEG,
391 .priv = SCALE_160x120 | MODE_JPEG},
392 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
394 .sizeimage = 160 * 120,
395 .colorspace = V4L2_COLORSPACE_SRGB,
396 .priv = SCALE_160x120 | MODE_RAW},
397 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
399 .sizeimage = 240 * 120,
400 .colorspace = V4L2_COLORSPACE_SRGB,
401 .priv = SCALE_160x120},
402 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
404 .sizeimage = 320 * 240 * 4 / 8 + 590,
405 .colorspace = V4L2_COLORSPACE_JPEG,
406 .priv = SCALE_320x240 | MODE_JPEG},
407 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
409 .sizeimage = 320 * 240 ,
410 .colorspace = V4L2_COLORSPACE_SRGB,
411 .priv = SCALE_320x240 | MODE_RAW},
412 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
414 .sizeimage = 480 * 240 ,
415 .colorspace = V4L2_COLORSPACE_SRGB,
416 .priv = SCALE_320x240},
417 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
419 .sizeimage = 640 * 480 * 4 / 8 + 590,
420 .colorspace = V4L2_COLORSPACE_JPEG,
421 .priv = SCALE_640x480 | MODE_JPEG},
422 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
424 .sizeimage = 640 * 480,
425 .colorspace = V4L2_COLORSPACE_SRGB,
426 .priv = SCALE_640x480 | MODE_RAW},
427 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
429 .sizeimage = 960 * 480,
430 .colorspace = V4L2_COLORSPACE_SRGB,
431 .priv = SCALE_640x480},
432 {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
433 .bytesperline = 1280,
434 .sizeimage = 1280 * 1024,
435 .colorspace = V4L2_COLORSPACE_SRGB,
436 .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
439 static const struct v4l2_pix_format mono_mode[] = {
440 {160, 120, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
442 .sizeimage = 160 * 120,
443 .colorspace = V4L2_COLORSPACE_SRGB,
444 .priv = SCALE_160x120 | MODE_RAW},
445 {320, 240, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
447 .sizeimage = 320 * 240 ,
448 .colorspace = V4L2_COLORSPACE_SRGB,
449 .priv = SCALE_320x240 | MODE_RAW},
450 {640, 480, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
452 .sizeimage = 640 * 480,
453 .colorspace = V4L2_COLORSPACE_SRGB,
454 .priv = SCALE_640x480 | MODE_RAW},
455 {1280, 1024, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
456 .bytesperline = 1280,
457 .sizeimage = 1280 * 1024,
458 .colorspace = V4L2_COLORSPACE_SRGB,
459 .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
462 static const s16 hsv_red_x[] = {
463 41, 44, 46, 48, 50, 52, 54, 56,
464 58, 60, 62, 64, 66, 68, 70, 72,
465 74, 76, 78, 80, 81, 83, 85, 87,
466 88, 90, 92, 93, 95, 97, 98, 100,
467 101, 102, 104, 105, 107, 108, 109, 110,
468 112, 113, 114, 115, 116, 117, 118, 119,
469 120, 121, 122, 123, 123, 124, 125, 125,
470 126, 127, 127, 128, 128, 129, 129, 129,
471 130, 130, 130, 130, 131, 131, 131, 131,
472 131, 131, 131, 131, 130, 130, 130, 130,
473 129, 129, 129, 128, 128, 127, 127, 126,
474 125, 125, 124, 123, 122, 122, 121, 120,
475 119, 118, 117, 116, 115, 114, 112, 111,
476 110, 109, 107, 106, 105, 103, 102, 101,
477 99, 98, 96, 94, 93, 91, 90, 88,
478 86, 84, 83, 81, 79, 77, 75, 74,
479 72, 70, 68, 66, 64, 62, 60, 58,
480 56, 54, 52, 49, 47, 45, 43, 41,
481 39, 36, 34, 32, 30, 28, 25, 23,
482 21, 19, 16, 14, 12, 9, 7, 5,
483 3, 0, -1, -3, -6, -8, -10, -12,
484 -15, -17, -19, -22, -24, -26, -28, -30,
485 -33, -35, -37, -39, -41, -44, -46, -48,
486 -50, -52, -54, -56, -58, -60, -62, -64,
487 -66, -68, -70, -72, -74, -76, -78, -80,
488 -81, -83, -85, -87, -88, -90, -92, -93,
489 -95, -97, -98, -100, -101, -102, -104, -105,
490 -107, -108, -109, -110, -112, -113, -114, -115,
491 -116, -117, -118, -119, -120, -121, -122, -123,
492 -123, -124, -125, -125, -126, -127, -127, -128,
493 -128, -128, -128, -128, -128, -128, -128, -128,
494 -128, -128, -128, -128, -128, -128, -128, -128,
495 -128, -128, -128, -128, -128, -128, -128, -128,
496 -128, -127, -127, -126, -125, -125, -124, -123,
497 -122, -122, -121, -120, -119, -118, -117, -116,
498 -115, -114, -112, -111, -110, -109, -107, -106,
499 -105, -103, -102, -101, -99, -98, -96, -94,
500 -93, -91, -90, -88, -86, -84, -83, -81,
501 -79, -77, -75, -74, -72, -70, -68, -66,
502 -64, -62, -60, -58, -56, -54, -52, -49,
503 -47, -45, -43, -41, -39, -36, -34, -32,
504 -30, -28, -25, -23, -21, -19, -16, -14,
505 -12, -9, -7, -5, -3, 0, 1, 3,
506 6, 8, 10, 12, 15, 17, 19, 22,
507 24, 26, 28, 30, 33, 35, 37, 39, 41
510 static const s16 hsv_red_y[] = {
511 82, 80, 78, 76, 74, 73, 71, 69,
512 67, 65, 63, 61, 58, 56, 54, 52,
513 50, 48, 46, 44, 41, 39, 37, 35,
514 32, 30, 28, 26, 23, 21, 19, 16,
515 14, 12, 10, 7, 5, 3, 0, -1,
516 -3, -6, -8, -10, -13, -15, -17, -19,
517 -22, -24, -26, -29, -31, -33, -35, -38,
518 -40, -42, -44, -46, -48, -51, -53, -55,
519 -57, -59, -61, -63, -65, -67, -69, -71,
520 -73, -75, -77, -79, -81, -82, -84, -86,
521 -88, -89, -91, -93, -94, -96, -98, -99,
522 -101, -102, -104, -105, -106, -108, -109, -110,
523 -112, -113, -114, -115, -116, -117, -119, -120,
524 -120, -121, -122, -123, -124, -125, -126, -126,
525 -127, -128, -128, -128, -128, -128, -128, -128,
526 -128, -128, -128, -128, -128, -128, -128, -128,
527 -128, -128, -128, -128, -128, -128, -128, -128,
528 -128, -128, -128, -128, -128, -128, -128, -128,
529 -127, -127, -126, -125, -125, -124, -123, -122,
530 -121, -120, -119, -118, -117, -116, -115, -114,
531 -113, -111, -110, -109, -107, -106, -105, -103,
532 -102, -100, -99, -97, -96, -94, -92, -91,
533 -89, -87, -85, -84, -82, -80, -78, -76,
534 -74, -73, -71, -69, -67, -65, -63, -61,
535 -58, -56, -54, -52, -50, -48, -46, -44,
536 -41, -39, -37, -35, -32, -30, -28, -26,
537 -23, -21, -19, -16, -14, -12, -10, -7,
538 -5, -3, 0, 1, 3, 6, 8, 10,
539 13, 15, 17, 19, 22, 24, 26, 29,
540 31, 33, 35, 38, 40, 42, 44, 46,
541 48, 51, 53, 55, 57, 59, 61, 63,
542 65, 67, 69, 71, 73, 75, 77, 79,
543 81, 82, 84, 86, 88, 89, 91, 93,
544 94, 96, 98, 99, 101, 102, 104, 105,
545 106, 108, 109, 110, 112, 113, 114, 115,
546 116, 117, 119, 120, 120, 121, 122, 123,
547 124, 125, 126, 126, 127, 128, 128, 129,
548 129, 130, 130, 131, 131, 131, 131, 132,
549 132, 132, 132, 132, 132, 132, 132, 132,
550 132, 132, 132, 131, 131, 131, 130, 130,
551 130, 129, 129, 128, 127, 127, 126, 125,
552 125, 124, 123, 122, 121, 120, 119, 118,
553 117, 116, 115, 114, 113, 111, 110, 109,
554 107, 106, 105, 103, 102, 100, 99, 97,
555 96, 94, 92, 91, 89, 87, 85, 84, 82
558 static const s16 hsv_green_x[] = {
559 -124, -124, -125, -125, -125, -125, -125, -125,
560 -125, -126, -126, -125, -125, -125, -125, -125,
561 -125, -124, -124, -124, -123, -123, -122, -122,
562 -121, -121, -120, -120, -119, -118, -117, -117,
563 -116, -115, -114, -113, -112, -111, -110, -109,
564 -108, -107, -105, -104, -103, -102, -100, -99,
565 -98, -96, -95, -93, -92, -91, -89, -87,
566 -86, -84, -83, -81, -79, -77, -76, -74,
567 -72, -70, -69, -67, -65, -63, -61, -59,
568 -57, -55, -53, -51, -49, -47, -45, -43,
569 -41, -39, -37, -35, -33, -30, -28, -26,
570 -24, -22, -20, -18, -15, -13, -11, -9,
571 -7, -4, -2, 0, 1, 3, 6, 8,
572 10, 12, 14, 17, 19, 21, 23, 25,
573 27, 29, 32, 34, 36, 38, 40, 42,
574 44, 46, 48, 50, 52, 54, 56, 58,
575 60, 62, 64, 66, 68, 70, 71, 73,
576 75, 77, 78, 80, 82, 83, 85, 87,
577 88, 90, 91, 93, 94, 96, 97, 98,
578 100, 101, 102, 104, 105, 106, 107, 108,
579 109, 111, 112, 113, 113, 114, 115, 116,
580 117, 118, 118, 119, 120, 120, 121, 122,
581 122, 123, 123, 124, 124, 124, 125, 125,
582 125, 125, 125, 125, 125, 126, 126, 125,
583 125, 125, 125, 125, 125, 124, 124, 124,
584 123, 123, 122, 122, 121, 121, 120, 120,
585 119, 118, 117, 117, 116, 115, 114, 113,
586 112, 111, 110, 109, 108, 107, 105, 104,
587 103, 102, 100, 99, 98, 96, 95, 93,
588 92, 91, 89, 87, 86, 84, 83, 81,
589 79, 77, 76, 74, 72, 70, 69, 67,
590 65, 63, 61, 59, 57, 55, 53, 51,
591 49, 47, 45, 43, 41, 39, 37, 35,
592 33, 30, 28, 26, 24, 22, 20, 18,
593 15, 13, 11, 9, 7, 4, 2, 0,
594 -1, -3, -6, -8, -10, -12, -14, -17,
595 -19, -21, -23, -25, -27, -29, -32, -34,
596 -36, -38, -40, -42, -44, -46, -48, -50,
597 -52, -54, -56, -58, -60, -62, -64, -66,
598 -68, -70, -71, -73, -75, -77, -78, -80,
599 -82, -83, -85, -87, -88, -90, -91, -93,
600 -94, -96, -97, -98, -100, -101, -102, -104,
601 -105, -106, -107, -108, -109, -111, -112, -113,
602 -113, -114, -115, -116, -117, -118, -118, -119,
603 -120, -120, -121, -122, -122, -123, -123, -124, -124
606 static const s16 hsv_green_y[] = {
607 -100, -99, -98, -97, -95, -94, -93, -91,
608 -90, -89, -87, -86, -84, -83, -81, -80,
609 -78, -76, -75, -73, -71, -70, -68, -66,
610 -64, -63, -61, -59, -57, -55, -53, -51,
611 -49, -48, -46, -44, -42, -40, -38, -36,
612 -34, -32, -30, -27, -25, -23, -21, -19,
613 -17, -15, -13, -11, -9, -7, -4, -2,
614 0, 1, 3, 5, 7, 9, 11, 14,
615 16, 18, 20, 22, 24, 26, 28, 30,
616 32, 34, 36, 38, 40, 42, 44, 46,
617 48, 50, 52, 54, 56, 58, 59, 61,
618 63, 65, 67, 68, 70, 72, 74, 75,
619 77, 78, 80, 82, 83, 85, 86, 88,
620 89, 90, 92, 93, 95, 96, 97, 98,
621 100, 101, 102, 103, 104, 105, 106, 107,
622 108, 109, 110, 111, 112, 112, 113, 114,
623 115, 115, 116, 116, 117, 117, 118, 118,
624 119, 119, 119, 120, 120, 120, 120, 120,
625 121, 121, 121, 121, 121, 121, 120, 120,
626 120, 120, 120, 119, 119, 119, 118, 118,
627 117, 117, 116, 116, 115, 114, 114, 113,
628 112, 111, 111, 110, 109, 108, 107, 106,
629 105, 104, 103, 102, 100, 99, 98, 97,
630 95, 94, 93, 91, 90, 89, 87, 86,
631 84, 83, 81, 80, 78, 76, 75, 73,
632 71, 70, 68, 66, 64, 63, 61, 59,
633 57, 55, 53, 51, 49, 48, 46, 44,
634 42, 40, 38, 36, 34, 32, 30, 27,
635 25, 23, 21, 19, 17, 15, 13, 11,
636 9, 7, 4, 2, 0, -1, -3, -5,
637 -7, -9, -11, -14, -16, -18, -20, -22,
638 -24, -26, -28, -30, -32, -34, -36, -38,
639 -40, -42, -44, -46, -48, -50, -52, -54,
640 -56, -58, -59, -61, -63, -65, -67, -68,
641 -70, -72, -74, -75, -77, -78, -80, -82,
642 -83, -85, -86, -88, -89, -90, -92, -93,
643 -95, -96, -97, -98, -100, -101, -102, -103,
644 -104, -105, -106, -107, -108, -109, -110, -111,
645 -112, -112, -113, -114, -115, -115, -116, -116,
646 -117, -117, -118, -118, -119, -119, -119, -120,
647 -120, -120, -120, -120, -121, -121, -121, -121,
648 -121, -121, -120, -120, -120, -120, -120, -119,
649 -119, -119, -118, -118, -117, -117, -116, -116,
650 -115, -114, -114, -113, -112, -111, -111, -110,
651 -109, -108, -107, -106, -105, -104, -103, -102, -100
654 static const s16 hsv_blue_x[] = {
655 112, 113, 114, 114, 115, 116, 117, 117,
656 118, 118, 119, 119, 120, 120, 120, 121,
657 121, 121, 122, 122, 122, 122, 122, 122,
658 122, 122, 122, 122, 122, 122, 121, 121,
659 121, 120, 120, 120, 119, 119, 118, 118,
660 117, 116, 116, 115, 114, 113, 113, 112,
661 111, 110, 109, 108, 107, 106, 105, 104,
662 103, 102, 100, 99, 98, 97, 95, 94,
663 93, 91, 90, 88, 87, 85, 84, 82,
664 80, 79, 77, 76, 74, 72, 70, 69,
665 67, 65, 63, 61, 60, 58, 56, 54,
666 52, 50, 48, 46, 44, 42, 40, 38,
667 36, 34, 32, 30, 28, 26, 24, 22,
668 19, 17, 15, 13, 11, 9, 7, 5,
669 2, 0, -1, -3, -5, -7, -9, -12,
670 -14, -16, -18, -20, -22, -24, -26, -28,
671 -31, -33, -35, -37, -39, -41, -43, -45,
672 -47, -49, -51, -53, -54, -56, -58, -60,
673 -62, -64, -66, -67, -69, -71, -73, -74,
674 -76, -78, -79, -81, -83, -84, -86, -87,
675 -89, -90, -92, -93, -94, -96, -97, -98,
676 -99, -101, -102, -103, -104, -105, -106, -107,
677 -108, -109, -110, -111, -112, -113, -114, -114,
678 -115, -116, -117, -117, -118, -118, -119, -119,
679 -120, -120, -120, -121, -121, -121, -122, -122,
680 -122, -122, -122, -122, -122, -122, -122, -122,
681 -122, -122, -121, -121, -121, -120, -120, -120,
682 -119, -119, -118, -118, -117, -116, -116, -115,
683 -114, -113, -113, -112, -111, -110, -109, -108,
684 -107, -106, -105, -104, -103, -102, -100, -99,
685 -98, -97, -95, -94, -93, -91, -90, -88,
686 -87, -85, -84, -82, -80, -79, -77, -76,
687 -74, -72, -70, -69, -67, -65, -63, -61,
688 -60, -58, -56, -54, -52, -50, -48, -46,
689 -44, -42, -40, -38, -36, -34, -32, -30,
690 -28, -26, -24, -22, -19, -17, -15, -13,
691 -11, -9, -7, -5, -2, 0, 1, 3,
692 5, 7, 9, 12, 14, 16, 18, 20,
693 22, 24, 26, 28, 31, 33, 35, 37,
694 39, 41, 43, 45, 47, 49, 51, 53,
695 54, 56, 58, 60, 62, 64, 66, 67,
696 69, 71, 73, 74, 76, 78, 79, 81,
697 83, 84, 86, 87, 89, 90, 92, 93,
698 94, 96, 97, 98, 99, 101, 102, 103,
699 104, 105, 106, 107, 108, 109, 110, 111, 112
702 static const s16 hsv_blue_y[] = {
703 -11, -13, -15, -17, -19, -21, -23, -25,
704 -27, -29, -31, -33, -35, -37, -39, -41,
705 -43, -45, -46, -48, -50, -52, -54, -55,
706 -57, -59, -61, -62, -64, -66, -67, -69,
707 -71, -72, -74, -75, -77, -78, -80, -81,
708 -83, -84, -86, -87, -88, -90, -91, -92,
709 -93, -95, -96, -97, -98, -99, -100, -101,
710 -102, -103, -104, -105, -106, -106, -107, -108,
711 -109, -109, -110, -111, -111, -112, -112, -113,
712 -113, -114, -114, -114, -115, -115, -115, -115,
713 -116, -116, -116, -116, -116, -116, -116, -116,
714 -116, -115, -115, -115, -115, -114, -114, -114,
715 -113, -113, -112, -112, -111, -111, -110, -110,
716 -109, -108, -108, -107, -106, -105, -104, -103,
717 -102, -101, -100, -99, -98, -97, -96, -95,
718 -94, -93, -91, -90, -89, -88, -86, -85,
719 -84, -82, -81, -79, -78, -76, -75, -73,
720 -71, -70, -68, -67, -65, -63, -62, -60,
721 -58, -56, -55, -53, -51, -49, -47, -45,
722 -44, -42, -40, -38, -36, -34, -32, -30,
723 -28, -26, -24, -22, -20, -18, -16, -14,
724 -12, -10, -8, -6, -4, -2, 0, 1,
725 3, 5, 7, 9, 11, 13, 15, 17,
726 19, 21, 23, 25, 27, 29, 31, 33,
727 35, 37, 39, 41, 43, 45, 46, 48,
728 50, 52, 54, 55, 57, 59, 61, 62,
729 64, 66, 67, 69, 71, 72, 74, 75,
730 77, 78, 80, 81, 83, 84, 86, 87,
731 88, 90, 91, 92, 93, 95, 96, 97,
732 98, 99, 100, 101, 102, 103, 104, 105,
733 106, 106, 107, 108, 109, 109, 110, 111,
734 111, 112, 112, 113, 113, 114, 114, 114,
735 115, 115, 115, 115, 116, 116, 116, 116,
736 116, 116, 116, 116, 116, 115, 115, 115,
737 115, 114, 114, 114, 113, 113, 112, 112,
738 111, 111, 110, 110, 109, 108, 108, 107,
739 106, 105, 104, 103, 102, 101, 100, 99,
740 98, 97, 96, 95, 94, 93, 91, 90,
741 89, 88, 86, 85, 84, 82, 81, 79,
742 78, 76, 75, 73, 71, 70, 68, 67,
743 65, 63, 62, 60, 58, 56, 55, 53,
744 51, 49, 47, 45, 44, 42, 40, 38,
745 36, 34, 32, 30, 28, 26, 24, 22,
746 20, 18, 16, 14, 12, 10, 8, 6,
747 4, 2, 0, -1, -3, -5, -7, -9, -11
750 static const u16 i2c_ident[] = {
759 V4L2_IDENT_MT9M001C12ST,
763 [SENSOR_MT9VPRB] = V4L2_IDENT_UNKNOWN,
766 static const u16 bridge_init[][2] = {
767 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
768 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
769 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
770 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
771 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
772 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
773 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
774 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
775 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
776 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
777 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
778 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
779 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
780 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
781 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
782 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
783 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
784 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
785 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
789 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
790 static const u8 ov_gain[] = {
791 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
792 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
793 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
794 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
795 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
796 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
797 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
801 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
802 static const u16 micron1_gain[] = {
803 /* 1x 1.25x 1.5x 1.75x */
804 0x0020, 0x0028, 0x0030, 0x0038,
805 /* 2x 2.25x 2.5x 2.75x */
806 0x00a0, 0x00a4, 0x00a8, 0x00ac,
807 /* 3x 3.25x 3.5x 3.75x */
808 0x00b0, 0x00b4, 0x00b8, 0x00bc,
809 /* 4x 4.25x 4.5x 4.75x */
810 0x00c0, 0x00c4, 0x00c8, 0x00cc,
811 /* 5x 5.25x 5.5x 5.75x */
812 0x00d0, 0x00d4, 0x00d8, 0x00dc,
813 /* 6x 6.25x 6.5x 6.75x */
814 0x00e0, 0x00e4, 0x00e8, 0x00ec,
815 /* 7x 7.25x 7.5x 7.75x */
816 0x00f0, 0x00f4, 0x00f8, 0x00fc,
821 /* mt9m001 sensor uses a different gain formula then other micron sensors */
822 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
823 static const u16 micron2_gain[] = {
824 /* 1x 1.25x 1.5x 1.75x */
825 0x0008, 0x000a, 0x000c, 0x000e,
826 /* 2x 2.25x 2.5x 2.75x */
827 0x0010, 0x0012, 0x0014, 0x0016,
828 /* 3x 3.25x 3.5x 3.75x */
829 0x0018, 0x001a, 0x001c, 0x001e,
830 /* 4x 4.25x 4.5x 4.75x */
831 0x0020, 0x0051, 0x0052, 0x0053,
832 /* 5x 5.25x 5.5x 5.75x */
833 0x0054, 0x0055, 0x0056, 0x0057,
834 /* 6x 6.25x 6.5x 6.75x */
835 0x0058, 0x0059, 0x005a, 0x005b,
836 /* 7x 7.25x 7.5x 7.75x */
837 0x005c, 0x005d, 0x005e, 0x005f,
842 /* Gain = .5 + bit[7:0] / 16 */
843 static const u8 hv7131r_gain[] = {
844 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
845 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
846 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
847 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
848 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
849 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
850 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
854 static const struct i2c_reg_u8 soi968_init[] = {
855 {0x0c, 0x00}, {0x0f, 0x1f},
856 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
857 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
858 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
859 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
860 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
861 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
862 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
863 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
864 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
865 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
868 static const struct i2c_reg_u8 ov7660_init[] = {
869 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
870 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
871 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
872 /* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using
873 0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
874 {0x17, 0x10}, {0x18, 0x61},
875 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
876 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6},
877 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
880 static const struct i2c_reg_u8 ov7670_init[] = {
881 {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
882 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
883 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
884 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
885 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
886 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
887 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
888 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
889 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
890 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
891 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
892 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
893 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
894 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
895 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
896 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
897 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
898 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
899 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
900 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
901 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
902 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
903 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
904 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
905 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
906 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
907 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
908 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
909 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
910 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
911 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
912 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
913 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
914 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
915 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
916 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
917 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
918 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
919 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
920 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
921 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
922 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
923 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
924 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
925 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
926 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
927 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
928 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
929 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
930 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
931 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
932 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
933 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
937 static const struct i2c_reg_u8 ov9650_init[] = {
938 {0x00, 0x00}, {0x01, 0x78},
939 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
940 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
941 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
942 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
943 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
944 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
945 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
946 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
947 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
948 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
949 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
950 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
951 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
952 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
953 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
954 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
955 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
956 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
957 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
958 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
959 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
960 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
961 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
962 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
963 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
964 {0xaa, 0x92}, {0xab, 0x0a},
967 static const struct i2c_reg_u8 ov9655_init[] = {
968 {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
969 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
970 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
971 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
972 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
973 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
974 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
975 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
976 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
977 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
978 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
979 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
980 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
981 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
982 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
983 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
984 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
985 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
986 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
987 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
988 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
989 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
990 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
991 {0x04, 0x03}, {0x00, 0x13},
994 static const struct i2c_reg_u16 mt9v112_init[] = {
995 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
996 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
997 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
998 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
999 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
1000 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
1001 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
1002 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
1003 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
1004 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
1005 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
1006 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1007 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
1008 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
1009 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
1010 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
1013 static const struct i2c_reg_u16 mt9v111_init[] = {
1014 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
1015 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
1016 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
1017 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
1018 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
1019 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
1020 {0x0e, 0x0008}, {0x20, 0x0000}
1023 static const struct i2c_reg_u16 mt9v011_init[] = {
1024 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
1025 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
1026 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
1027 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
1028 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
1029 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
1030 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
1031 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
1032 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
1033 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
1034 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
1035 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
1036 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
1037 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
1038 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
1039 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
1040 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
1041 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
1042 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
1043 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
1044 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
1045 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1046 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
1047 {0x06, 0x0029}, {0x05, 0x0009},
1050 static const struct i2c_reg_u16 mt9m001_init[] = {
1053 {0x04, 0x0500}, /* hres = 1280 */
1054 {0x03, 0x0400}, /* vres = 1024 */
1066 static const struct i2c_reg_u16 mt9m111_init[] = {
1067 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1068 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1069 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1073 static const struct i2c_reg_u16 mt9m112_init[] = {
1074 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1075 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1076 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1080 static const struct i2c_reg_u8 hv7131r_init[] = {
1081 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
1082 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
1083 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
1084 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
1085 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
1086 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
1087 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
1088 {0x23, 0x09}, {0x01, 0x08},
1091 static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
1093 struct usb_device *dev = gspca_dev->dev;
1096 if (gspca_dev->usb_err < 0)
1098 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
1100 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1106 if (unlikely(result < 0 || result != length)) {
1107 pr_err("Read register %02x failed %d\n", reg, result);
1108 gspca_dev->usb_err = result;
1112 static void reg_w(struct gspca_dev *gspca_dev, u16 reg,
1113 const u8 *buffer, int length)
1115 struct usb_device *dev = gspca_dev->dev;
1118 if (gspca_dev->usb_err < 0)
1120 memcpy(gspca_dev->usb_buf, buffer, length);
1121 result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1123 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1129 if (unlikely(result < 0 || result != length)) {
1130 pr_err("Write register %02x failed %d\n", reg, result);
1131 gspca_dev->usb_err = result;
1135 static void reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
1137 reg_w(gspca_dev, reg, &value, 1);
1140 static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
1144 reg_w(gspca_dev, 0x10c0, buffer, 8);
1145 for (i = 0; i < 5; i++) {
1146 reg_r(gspca_dev, 0x10c0, 1);
1147 if (gspca_dev->usb_err < 0)
1149 if (gspca_dev->usb_buf[0] & 0x04) {
1150 if (gspca_dev->usb_buf[0] & 0x08) {
1151 pr_err("i2c_w error\n");
1152 gspca_dev->usb_err = -EIO;
1158 pr_err("i2c_w reg %02x no response\n", buffer[2]);
1159 /* gspca_dev->usb_err = -EIO; fixme: may occur */
1162 static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1164 struct sd *sd = (struct sd *) gspca_dev;
1168 * from the point of view of the bridge, the length
1169 * includes the address
1171 row[0] = 0x81 | (2 << 4);
1172 row[1] = sd->i2c_addr;
1180 i2c_w(gspca_dev, row);
1183 static void i2c_w1_buf(struct gspca_dev *gspca_dev,
1184 const struct i2c_reg_u8 *buf, int sz)
1187 i2c_w1(gspca_dev, buf->reg, buf->val);
1192 static void i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1194 struct sd *sd = (struct sd *) gspca_dev;
1198 * from the point of view of the bridge, the length
1199 * includes the address
1201 row[0] = 0x81 | (3 << 4);
1202 row[1] = sd->i2c_addr;
1210 i2c_w(gspca_dev, row);
1213 static void i2c_w2_buf(struct gspca_dev *gspca_dev,
1214 const struct i2c_reg_u16 *buf, int sz)
1217 i2c_w2(gspca_dev, buf->reg, buf->val);
1222 static void i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1224 struct sd *sd = (struct sd *) gspca_dev;
1227 row[0] = 0x81 | (1 << 4);
1228 row[1] = sd->i2c_addr;
1235 i2c_w(gspca_dev, row);
1236 row[0] = 0x81 | (1 << 4) | 0x02;
1238 i2c_w(gspca_dev, row);
1239 reg_r(gspca_dev, 0x10c2, 5);
1240 *val = gspca_dev->usb_buf[4];
1243 static void i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1245 struct sd *sd = (struct sd *) gspca_dev;
1248 row[0] = 0x81 | (1 << 4);
1249 row[1] = sd->i2c_addr;
1256 i2c_w(gspca_dev, row);
1257 row[0] = 0x81 | (2 << 4) | 0x02;
1259 i2c_w(gspca_dev, row);
1260 reg_r(gspca_dev, 0x10c2, 5);
1261 *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1264 static void ov9650_init_sensor(struct gspca_dev *gspca_dev)
1267 struct sd *sd = (struct sd *) gspca_dev;
1269 i2c_r2(gspca_dev, 0x1c, &id);
1270 if (gspca_dev->usb_err < 0)
1274 pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id);
1275 gspca_dev->usb_err = -ENODEV;
1279 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1281 i2c_w1_buf(gspca_dev, ov9650_init, ARRAY_SIZE(ov9650_init));
1282 if (gspca_dev->usb_err < 0)
1283 pr_err("OV9650 sensor initialization failed\n");
1288 static void ov9655_init_sensor(struct gspca_dev *gspca_dev)
1290 struct sd *sd = (struct sd *) gspca_dev;
1292 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1294 i2c_w1_buf(gspca_dev, ov9655_init, ARRAY_SIZE(ov9655_init));
1295 if (gspca_dev->usb_err < 0)
1296 pr_err("OV9655 sensor initialization failed\n");
1298 /* disable hflip and vflip */
1299 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
1304 static void soi968_init_sensor(struct gspca_dev *gspca_dev)
1306 struct sd *sd = (struct sd *) gspca_dev;
1308 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1310 i2c_w1_buf(gspca_dev, soi968_init, ARRAY_SIZE(soi968_init));
1311 if (gspca_dev->usb_err < 0)
1312 pr_err("SOI968 sensor initialization failed\n");
1314 /* disable hflip and vflip */
1315 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP)
1321 static void ov7660_init_sensor(struct gspca_dev *gspca_dev)
1323 struct sd *sd = (struct sd *) gspca_dev;
1325 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1327 i2c_w1_buf(gspca_dev, ov7660_init, ARRAY_SIZE(ov7660_init));
1328 if (gspca_dev->usb_err < 0)
1329 pr_err("OV7660 sensor initialization failed\n");
1334 static void ov7670_init_sensor(struct gspca_dev *gspca_dev)
1336 struct sd *sd = (struct sd *) gspca_dev;
1338 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1340 i2c_w1_buf(gspca_dev, ov7670_init, ARRAY_SIZE(ov7670_init));
1341 if (gspca_dev->usb_err < 0)
1342 pr_err("OV7670 sensor initialization failed\n");
1344 /* disable hflip and vflip */
1345 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
1350 static void mt9v_init_sensor(struct gspca_dev *gspca_dev)
1352 struct sd *sd = (struct sd *) gspca_dev;
1355 sd->i2c_addr = 0x5d;
1356 i2c_r2(gspca_dev, 0xff, &value);
1357 if (gspca_dev->usb_err >= 0
1358 && value == 0x8243) {
1359 i2c_w2_buf(gspca_dev, mt9v011_init, ARRAY_SIZE(mt9v011_init));
1360 if (gspca_dev->usb_err < 0) {
1361 pr_err("MT9V011 sensor initialization failed\n");
1366 sd->sensor = SENSOR_MT9V011;
1367 pr_info("MT9V011 sensor detected\n");
1371 gspca_dev->usb_err = 0;
1372 sd->i2c_addr = 0x5c;
1373 i2c_w2(gspca_dev, 0x01, 0x0004);
1374 i2c_r2(gspca_dev, 0xff, &value);
1375 if (gspca_dev->usb_err >= 0
1376 && value == 0x823a) {
1377 i2c_w2_buf(gspca_dev, mt9v111_init, ARRAY_SIZE(mt9v111_init));
1378 if (gspca_dev->usb_err < 0) {
1379 pr_err("MT9V111 sensor initialization failed\n");
1382 gspca_dev->ctrl_dis = (1 << EXPOSURE)
1387 sd->sensor = SENSOR_MT9V111;
1388 pr_info("MT9V111 sensor detected\n");
1392 gspca_dev->usb_err = 0;
1393 sd->i2c_addr = 0x5d;
1394 i2c_w2(gspca_dev, 0xf0, 0x0000);
1395 if (gspca_dev->usb_err < 0) {
1396 gspca_dev->usb_err = 0;
1397 sd->i2c_addr = 0x48;
1398 i2c_w2(gspca_dev, 0xf0, 0x0000);
1400 i2c_r2(gspca_dev, 0x00, &value);
1401 if (gspca_dev->usb_err >= 0
1402 && value == 0x1229) {
1403 i2c_w2_buf(gspca_dev, mt9v112_init, ARRAY_SIZE(mt9v112_init));
1404 if (gspca_dev->usb_err < 0) {
1405 pr_err("MT9V112 sensor initialization failed\n");
1410 sd->sensor = SENSOR_MT9V112;
1411 pr_info("MT9V112 sensor detected\n");
1415 gspca_dev->usb_err = -ENODEV;
1418 static void mt9m112_init_sensor(struct gspca_dev *gspca_dev)
1420 struct sd *sd = (struct sd *) gspca_dev;
1422 i2c_w2_buf(gspca_dev, mt9m112_init, ARRAY_SIZE(mt9m112_init));
1423 if (gspca_dev->usb_err < 0)
1424 pr_err("MT9M112 sensor initialization failed\n");
1426 gspca_dev->ctrl_dis = (1 << EXPOSURE) | (1 << AUTOGAIN)
1432 static void mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1434 struct sd *sd = (struct sd *) gspca_dev;
1436 i2c_w2_buf(gspca_dev, mt9m111_init, ARRAY_SIZE(mt9m111_init));
1437 if (gspca_dev->usb_err < 0)
1438 pr_err("MT9M111 sensor initialization failed\n");
1440 gspca_dev->ctrl_dis = (1 << EXPOSURE) | (1 << AUTOGAIN)
1446 static void mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1448 struct sd *sd = (struct sd *) gspca_dev;
1451 i2c_r2(gspca_dev, 0x00, &id);
1452 if (gspca_dev->usb_err < 0)
1455 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
1459 pr_info("MT9M001 color sensor detected\n");
1462 pr_info("MT9M001 mono sensor detected\n");
1465 pr_err("No MT9M001 chip detected, ID = %x\n\n", id);
1466 gspca_dev->usb_err = -ENODEV;
1470 i2c_w2_buf(gspca_dev, mt9m001_init, ARRAY_SIZE(mt9m001_init));
1471 if (gspca_dev->usb_err < 0)
1472 pr_err("MT9M001 sensor initialization failed\n");
1474 /* disable hflip and vflip */
1475 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
1480 static void hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1482 struct sd *sd = (struct sd *) gspca_dev;
1484 i2c_w1_buf(gspca_dev, hv7131r_init, ARRAY_SIZE(hv7131r_init));
1485 if (gspca_dev->usb_err < 0)
1486 pr_err("HV7131R Sensor initialization failed\n");
1492 static void set_cmatrix(struct gspca_dev *gspca_dev)
1494 struct sd *sd = (struct sd *) gspca_dev;
1496 s32 hue_coord, hue_index = 180 + sd->ctrls[HUE].val;
1499 memset(cmatrix, 0, sizeof cmatrix);
1500 cmatrix[2] = (sd->ctrls[CONTRAST].val * 0x25 / 0x100) + 0x26;
1501 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1502 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1503 cmatrix[18] = sd->ctrls[BRIGHTNESS].val - 0x80;
1505 satur = sd->ctrls[SATURATION].val;
1506 hue_coord = (hsv_red_x[hue_index] * satur) >> 8;
1507 cmatrix[6] = hue_coord;
1508 cmatrix[7] = (hue_coord >> 8) & 0x0f;
1510 hue_coord = (hsv_red_y[hue_index] * satur) >> 8;
1511 cmatrix[8] = hue_coord;
1512 cmatrix[9] = (hue_coord >> 8) & 0x0f;
1514 hue_coord = (hsv_green_x[hue_index] * satur) >> 8;
1515 cmatrix[10] = hue_coord;
1516 cmatrix[11] = (hue_coord >> 8) & 0x0f;
1518 hue_coord = (hsv_green_y[hue_index] * satur) >> 8;
1519 cmatrix[12] = hue_coord;
1520 cmatrix[13] = (hue_coord >> 8) & 0x0f;
1522 hue_coord = (hsv_blue_x[hue_index] * satur) >> 8;
1523 cmatrix[14] = hue_coord;
1524 cmatrix[15] = (hue_coord >> 8) & 0x0f;
1526 hue_coord = (hsv_blue_y[hue_index] * satur) >> 8;
1527 cmatrix[16] = hue_coord;
1528 cmatrix[17] = (hue_coord >> 8) & 0x0f;
1530 reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1533 static void set_gamma(struct gspca_dev *gspca_dev)
1535 struct sd *sd = (struct sd *) gspca_dev;
1537 u8 gval = sd->ctrls[GAMMA].val * 0xb8 / 0x100;
1540 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
1541 gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8);
1542 gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8);
1543 gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8);
1544 gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8);
1545 gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8);
1546 gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8);
1547 gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8);
1548 gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8);
1549 gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8);
1550 gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8);
1551 gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8);
1552 gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8);
1553 gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8);
1554 gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
1557 reg_w(gspca_dev, 0x1190, gamma, 17);
1560 static void set_redblue(struct gspca_dev *gspca_dev)
1562 struct sd *sd = (struct sd *) gspca_dev;
1564 reg_w1(gspca_dev, 0x118c, sd->ctrls[RED].val);
1565 reg_w1(gspca_dev, 0x118f, sd->ctrls[BLUE].val);
1568 static void set_hvflip(struct gspca_dev *gspca_dev)
1570 u8 value, tslb, hflip, vflip;
1572 struct sd *sd = (struct sd *) gspca_dev;
1574 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1575 hflip = !sd->ctrls[HFLIP].val;
1576 vflip = !sd->ctrls[VFLIP].val;
1578 hflip = sd->ctrls[HFLIP].val;
1579 vflip = sd->ctrls[VFLIP].val;
1582 switch (sd->sensor) {
1593 reg_w1(gspca_dev, 0x1182, sd->vstart);
1594 i2c_w1(gspca_dev, 0x1e, value);
1597 i2c_r1(gspca_dev, 0x1e, &value);
1606 i2c_w1(gspca_dev, 0x1e, value);
1607 i2c_w1(gspca_dev, 0x3a, tslb);
1609 case SENSOR_MT9V111:
1610 case SENSOR_MT9V011:
1611 i2c_r2(gspca_dev, 0x20, &value2);
1617 i2c_w2(gspca_dev, 0x20, value2);
1619 case SENSOR_MT9M112:
1620 case SENSOR_MT9M111:
1621 case SENSOR_MT9V112:
1622 i2c_r2(gspca_dev, 0x20, &value2);
1628 i2c_w2(gspca_dev, 0x20, value2);
1630 case SENSOR_HV7131R:
1631 i2c_r1(gspca_dev, 0x01, &value);
1637 i2c_w1(gspca_dev, 0x01, value);
1642 static void set_exposure(struct gspca_dev *gspca_dev)
1644 struct sd *sd = (struct sd *) gspca_dev;
1645 u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1648 expo = sd->ctrls[EXPOSURE].val;
1649 switch (sd->sensor) {
1659 case SENSOR_MT9M001:
1660 case SENSOR_MT9V112:
1661 case SENSOR_MT9V011:
1667 case SENSOR_HV7131R:
1677 i2c_w(gspca_dev, exp);
1680 static void set_gain(struct gspca_dev *gspca_dev)
1682 struct sd *sd = (struct sd *) gspca_dev;
1683 u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1686 g = sd->ctrls[GAIN].val;
1687 switch (sd->sensor) {
1693 gain[0] |= (2 << 4);
1694 gain[3] = ov_gain[g];
1696 case SENSOR_MT9V011:
1697 gain[0] |= (3 << 4);
1699 gain[3] = micron1_gain[g] >> 8;
1700 gain[4] = micron1_gain[g];
1702 case SENSOR_MT9V112:
1703 gain[0] |= (3 << 4);
1705 gain[3] = micron1_gain[g] >> 8;
1706 gain[4] = micron1_gain[g];
1708 case SENSOR_MT9M001:
1709 gain[0] |= (3 << 4);
1711 gain[3] = micron2_gain[g] >> 8;
1712 gain[4] = micron2_gain[g];
1714 case SENSOR_HV7131R:
1715 gain[0] |= (2 << 4);
1717 gain[3] = hv7131r_gain[g];
1722 i2c_w(gspca_dev, gain);
1725 static void set_quality(struct gspca_dev *gspca_dev)
1727 struct sd *sd = (struct sd *) gspca_dev;
1729 jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val);
1730 reg_w1(gspca_dev, 0x1061, 0x01); /* stop transfer */
1731 reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20); /* write QTAB */
1732 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
1733 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
1734 reg_w1(gspca_dev, 0x1061, 0x03); /* restart transfer */
1735 reg_w1(gspca_dev, 0x10e0, sd->fmt);
1736 sd->fmt ^= 0x0c; /* invert QTAB use + write */
1737 reg_w1(gspca_dev, 0x10e0, sd->fmt);
1740 #ifdef CONFIG_VIDEO_ADV_DEBUG
1741 static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1742 struct v4l2_dbg_register *reg)
1744 struct sd *sd = (struct sd *) gspca_dev;
1746 switch (reg->match.type) {
1747 case V4L2_CHIP_MATCH_HOST:
1748 if (reg->match.addr != 0)
1750 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1752 reg_r(gspca_dev, reg->reg, 1);
1753 reg->val = gspca_dev->usb_buf[0];
1754 return gspca_dev->usb_err;
1755 case V4L2_CHIP_MATCH_I2C_ADDR:
1756 if (reg->match.addr != sd->i2c_addr)
1758 if (sd->sensor >= SENSOR_MT9V011 &&
1759 sd->sensor <= SENSOR_MT9M112) {
1760 i2c_r2(gspca_dev, reg->reg, (u16 *) ®->val);
1762 i2c_r1(gspca_dev, reg->reg, (u8 *) ®->val);
1764 return gspca_dev->usb_err;
1769 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1770 struct v4l2_dbg_register *reg)
1772 struct sd *sd = (struct sd *) gspca_dev;
1774 switch (reg->match.type) {
1775 case V4L2_CHIP_MATCH_HOST:
1776 if (reg->match.addr != 0)
1778 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1780 reg_w1(gspca_dev, reg->reg, reg->val);
1781 return gspca_dev->usb_err;
1782 case V4L2_CHIP_MATCH_I2C_ADDR:
1783 if (reg->match.addr != sd->i2c_addr)
1785 if (sd->sensor >= SENSOR_MT9V011 &&
1786 sd->sensor <= SENSOR_MT9M112) {
1787 i2c_w2(gspca_dev, reg->reg, reg->val);
1789 i2c_w1(gspca_dev, reg->reg, reg->val);
1791 return gspca_dev->usb_err;
1797 static int sd_chip_ident(struct gspca_dev *gspca_dev,
1798 struct v4l2_dbg_chip_ident *chip)
1800 struct sd *sd = (struct sd *) gspca_dev;
1802 switch (chip->match.type) {
1803 case V4L2_CHIP_MATCH_HOST:
1804 if (chip->match.addr != 0)
1807 chip->ident = V4L2_IDENT_SN9C20X;
1809 case V4L2_CHIP_MATCH_I2C_ADDR:
1810 if (chip->match.addr != sd->i2c_addr)
1813 chip->ident = i2c_ident[sd->sensor];
1819 static int sd_config(struct gspca_dev *gspca_dev,
1820 const struct usb_device_id *id)
1822 struct sd *sd = (struct sd *) gspca_dev;
1825 cam = &gspca_dev->cam;
1826 cam->needs_full_bandwidth = 1;
1828 sd->sensor = id->driver_info >> 8;
1829 sd->i2c_addr = id->driver_info;
1830 sd->flags = id->driver_info >> 16;
1832 switch (sd->sensor) {
1833 case SENSOR_MT9M112:
1834 case SENSOR_MT9M111:
1837 cam->cam_mode = sxga_mode;
1838 cam->nmodes = ARRAY_SIZE(sxga_mode);
1840 case SENSOR_MT9M001:
1841 cam->cam_mode = mono_mode;
1842 cam->nmodes = ARRAY_SIZE(mono_mode);
1845 cam->cam_mode = vga_mode;
1846 cam->nmodes = ARRAY_SIZE(vga_mode);
1852 sd->exposure_step = 16;
1854 gspca_dev->cam.ctrls = sd->ctrls;
1856 INIT_WORK(&sd->work, qual_upd);
1861 static int sd_init(struct gspca_dev *gspca_dev)
1863 struct sd *sd = (struct sd *) gspca_dev;
1867 {0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
1869 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
1870 value = bridge_init[i][1];
1871 reg_w(gspca_dev, bridge_init[i][0], &value, 1);
1872 if (gspca_dev->usb_err < 0) {
1873 pr_err("Device initialization failed\n");
1874 return gspca_dev->usb_err;
1878 if (sd->flags & LED_REVERSE)
1879 reg_w1(gspca_dev, 0x1006, 0x00);
1881 reg_w1(gspca_dev, 0x1006, 0x20);
1883 reg_w(gspca_dev, 0x10c0, i2c_init, 9);
1884 if (gspca_dev->usb_err < 0) {
1885 pr_err("Device initialization failed\n");
1886 return gspca_dev->usb_err;
1889 switch (sd->sensor) {
1891 ov9650_init_sensor(gspca_dev);
1892 if (gspca_dev->usb_err < 0)
1894 pr_info("OV9650 sensor detected\n");
1897 ov9655_init_sensor(gspca_dev);
1898 if (gspca_dev->usb_err < 0)
1900 pr_info("OV9655 sensor detected\n");
1903 soi968_init_sensor(gspca_dev);
1904 if (gspca_dev->usb_err < 0)
1906 pr_info("SOI968 sensor detected\n");
1909 ov7660_init_sensor(gspca_dev);
1910 if (gspca_dev->usb_err < 0)
1912 pr_info("OV7660 sensor detected\n");
1915 ov7670_init_sensor(gspca_dev);
1916 if (gspca_dev->usb_err < 0)
1918 pr_info("OV7670 sensor detected\n");
1920 case SENSOR_MT9VPRB:
1921 mt9v_init_sensor(gspca_dev);
1922 if (gspca_dev->usb_err < 0)
1924 pr_info("MT9VPRB sensor detected\n");
1926 case SENSOR_MT9M111:
1927 mt9m111_init_sensor(gspca_dev);
1928 if (gspca_dev->usb_err < 0)
1930 pr_info("MT9M111 sensor detected\n");
1932 case SENSOR_MT9M112:
1933 mt9m112_init_sensor(gspca_dev);
1934 if (gspca_dev->usb_err < 0)
1936 pr_info("MT9M112 sensor detected\n");
1938 case SENSOR_MT9M001:
1939 mt9m001_init_sensor(gspca_dev);
1940 if (gspca_dev->usb_err < 0)
1943 case SENSOR_HV7131R:
1944 hv7131r_init_sensor(gspca_dev);
1945 if (gspca_dev->usb_err < 0)
1947 pr_info("HV7131R sensor detected\n");
1950 pr_err("Unsupported sensor\n");
1951 gspca_dev->usb_err = -ENODEV;
1954 return gspca_dev->usb_err;
1957 static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
1959 struct sd *sd = (struct sd *) gspca_dev;
1962 switch (sd->sensor) {
1964 if (mode & MODE_SXGA) {
1965 i2c_w1(gspca_dev, 0x17, 0x1d);
1966 i2c_w1(gspca_dev, 0x18, 0xbd);
1967 i2c_w1(gspca_dev, 0x19, 0x01);
1968 i2c_w1(gspca_dev, 0x1a, 0x81);
1969 i2c_w1(gspca_dev, 0x12, 0x00);
1973 i2c_w1(gspca_dev, 0x17, 0x13);
1974 i2c_w1(gspca_dev, 0x18, 0x63);
1975 i2c_w1(gspca_dev, 0x19, 0x01);
1976 i2c_w1(gspca_dev, 0x1a, 0x79);
1977 i2c_w1(gspca_dev, 0x12, 0x40);
1983 if (mode & MODE_SXGA) {
1984 i2c_w1(gspca_dev, 0x17, 0x1b);
1985 i2c_w1(gspca_dev, 0x18, 0xbc);
1986 i2c_w1(gspca_dev, 0x19, 0x01);
1987 i2c_w1(gspca_dev, 0x1a, 0x82);
1988 i2c_r1(gspca_dev, 0x12, &value);
1989 i2c_w1(gspca_dev, 0x12, value & 0x07);
1991 i2c_w1(gspca_dev, 0x17, 0x24);
1992 i2c_w1(gspca_dev, 0x18, 0xc5);
1993 i2c_w1(gspca_dev, 0x19, 0x00);
1994 i2c_w1(gspca_dev, 0x1a, 0x3c);
1995 i2c_r1(gspca_dev, 0x12, &value);
1996 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
1999 case SENSOR_MT9M112:
2000 case SENSOR_MT9M111:
2001 if (mode & MODE_SXGA) {
2002 i2c_w2(gspca_dev, 0xf0, 0x0002);
2003 i2c_w2(gspca_dev, 0xc8, 0x970b);
2004 i2c_w2(gspca_dev, 0xf0, 0x0000);
2006 i2c_w2(gspca_dev, 0xf0, 0x0002);
2007 i2c_w2(gspca_dev, 0xc8, 0x8000);
2008 i2c_w2(gspca_dev, 0xf0, 0x0000);
2014 static int sd_isoc_init(struct gspca_dev *gspca_dev)
2016 struct usb_interface *intf;
2017 u32 flags = gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv;
2020 * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth
2021 * than our regular bandwidth calculations reserve, so we force the
2022 * use of a specific altsetting when using the SN9C20X_I420 fmt.
2024 if (!(flags & (MODE_RAW | MODE_JPEG))) {
2025 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
2027 if (intf->num_altsetting != 9) {
2028 pr_warn("sn9c20x camera with unknown number of alt "
2029 "settings (%d), please report!\n",
2030 intf->num_altsetting);
2031 gspca_dev->alt = intf->num_altsetting;
2035 switch (gspca_dev->width) {
2036 case 160: /* 160x120 */
2039 case 320: /* 320x240 */
2042 default: /* >= 640x480 */
2051 #define HW_WIN(mode, hstart, vstart) \
2052 ((const u8 []){hstart, 0, vstart, 0, \
2053 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
2054 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
2056 #define CLR_WIN(width, height) \
2058 {0, width >> 2, 0, height >> 1,\
2059 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
2061 static int sd_start(struct gspca_dev *gspca_dev)
2063 struct sd *sd = (struct sd *) gspca_dev;
2064 int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
2065 int width = gspca_dev->width;
2066 int height = gspca_dev->height;
2069 jpeg_define(sd->jpeg_hdr, height, width,
2071 jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val);
2073 if (mode & MODE_RAW)
2075 else if (mode & MODE_JPEG)
2078 fmt = 0x2f; /* YUV 420 */
2081 switch (mode & SCALE_MASK) {
2082 case SCALE_1280x1024:
2084 pr_info("Set 1280x1024\n");
2088 pr_info("Set 640x480\n");
2092 pr_info("Set 320x240\n");
2096 pr_info("Set 160x120\n");
2100 configure_sensor_output(gspca_dev, mode);
2101 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2102 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2103 reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2104 reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2105 reg_w1(gspca_dev, 0x1189, scale);
2106 reg_w1(gspca_dev, 0x10e0, fmt);
2108 set_cmatrix(gspca_dev);
2109 set_gamma(gspca_dev);
2110 set_redblue(gspca_dev);
2111 set_gain(gspca_dev);
2112 set_exposure(gspca_dev);
2113 set_hvflip(gspca_dev);
2115 reg_w1(gspca_dev, 0x1007, 0x20);
2116 reg_w1(gspca_dev, 0x1061, 0x03);
2118 /* if JPEG, prepare the compression quality update */
2119 if (mode & MODE_JPEG) {
2120 sd->pktsz = sd->npkt = 0;
2123 create_singlethread_workqueue(KBUILD_MODNAME);
2126 return gspca_dev->usb_err;
2129 static void sd_stopN(struct gspca_dev *gspca_dev)
2131 reg_w1(gspca_dev, 0x1007, 0x00);
2132 reg_w1(gspca_dev, 0x1061, 0x01);
2135 /* called on streamoff with alt==0 and on disconnect */
2136 /* the usb_lock is held at entry - restore on exit */
2137 static void sd_stop0(struct gspca_dev *gspca_dev)
2139 struct sd *sd = (struct sd *) gspca_dev;
2141 if (sd->work_thread != NULL) {
2142 mutex_unlock(&gspca_dev->usb_lock);
2143 destroy_workqueue(sd->work_thread);
2144 mutex_lock(&gspca_dev->usb_lock);
2145 sd->work_thread = NULL;
2149 static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2151 struct sd *sd = (struct sd *) gspca_dev;
2155 * some hardcoded values are present
2156 * like those for maximal/minimal exposure
2157 * and exposure steps
2159 if (avg_lum < MIN_AVG_LUM) {
2160 if (sd->ctrls[EXPOSURE].val > 0x1770)
2163 new_exp = sd->ctrls[EXPOSURE].val + sd->exposure_step;
2164 if (new_exp > 0x1770)
2168 sd->ctrls[EXPOSURE].val = new_exp;
2169 set_exposure(gspca_dev);
2171 sd->older_step = sd->old_step;
2174 if (sd->old_step ^ sd->older_step)
2175 sd->exposure_step /= 2;
2177 sd->exposure_step += 2;
2179 if (avg_lum > MAX_AVG_LUM) {
2180 if (sd->ctrls[EXPOSURE].val < 0x10)
2182 new_exp = sd->ctrls[EXPOSURE].val - sd->exposure_step;
2183 if (new_exp > 0x1700)
2187 sd->ctrls[EXPOSURE].val = new_exp;
2188 set_exposure(gspca_dev);
2189 sd->older_step = sd->old_step;
2192 if (sd->old_step ^ sd->older_step)
2193 sd->exposure_step /= 2;
2195 sd->exposure_step += 2;
2199 static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2201 struct sd *sd = (struct sd *) gspca_dev;
2203 if (avg_lum < MIN_AVG_LUM) {
2204 if (sd->ctrls[GAIN].val + 1 <= 28) {
2205 sd->ctrls[GAIN].val++;
2206 set_gain(gspca_dev);
2209 if (avg_lum > MAX_AVG_LUM) {
2210 if (sd->ctrls[GAIN].val > 0) {
2211 sd->ctrls[GAIN].val--;
2212 set_gain(gspca_dev);
2217 static void sd_dqcallback(struct gspca_dev *gspca_dev)
2219 struct sd *sd = (struct sd *) gspca_dev;
2222 if (!sd->ctrls[AUTOGAIN].val)
2225 avg_lum = atomic_read(&sd->avg_lum);
2226 if (sd->sensor == SENSOR_SOI968)
2227 do_autogain(gspca_dev, avg_lum);
2229 do_autoexposure(gspca_dev, avg_lum);
2232 /* JPEG quality update */
2233 /* This function is executed from a work queue. */
2234 static void qual_upd(struct work_struct *work)
2236 struct sd *sd = container_of(work, struct sd, work);
2237 struct gspca_dev *gspca_dev = &sd->gspca_dev;
2239 mutex_lock(&gspca_dev->usb_lock);
2240 PDEBUG(D_STREAM, "qual_upd %d%%", sd->ctrls[QUALITY].val);
2241 set_quality(gspca_dev);
2242 mutex_unlock(&gspca_dev->usb_lock);
2245 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2246 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2247 u8 *data, /* interrupt packet */
2248 int len) /* interrupt packet length */
2250 struct sd *sd = (struct sd *) gspca_dev;
2252 if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
2253 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2254 input_sync(gspca_dev->input_dev);
2255 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2256 input_sync(gspca_dev->input_dev);
2263 /* check the JPEG compression */
2264 static void transfer_check(struct gspca_dev *gspca_dev,
2267 struct sd *sd = (struct sd *) gspca_dev;
2272 /* if USB error, discard the frame and decrease the quality */
2273 if (data[6] & 0x08) { /* USB FIFO full */
2274 gspca_dev->last_packet_type = DISCARD_PACKET;
2278 /* else, compute the filling rate and a new JPEG quality */
2279 r = (sd->pktsz * 100) /
2281 gspca_dev->urb[0]->iso_frame_desc[0].length);
2287 if (new_qual != 0) {
2288 sd->nchg += new_qual;
2289 if (sd->nchg < -6 || sd->nchg >= 12) {
2291 new_qual += sd->ctrls[QUALITY].val;
2292 if (new_qual < QUALITY_MIN)
2293 new_qual = QUALITY_MIN;
2294 else if (new_qual > QUALITY_MAX)
2295 new_qual = QUALITY_MAX;
2296 if (new_qual != sd->ctrls[QUALITY].val) {
2297 sd->ctrls[QUALITY].val = new_qual;
2298 queue_work(sd->work_thread, &sd->work);
2304 sd->pktsz = sd->npkt = 0;
2307 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2308 u8 *data, /* isoc packet */
2309 int len) /* iso packet length */
2311 struct sd *sd = (struct sd *) gspca_dev;
2312 int avg_lum, is_jpeg;
2313 static const u8 frame_header[] =
2314 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2316 is_jpeg = (sd->fmt & 0x03) == 0;
2317 if (len >= 64 && memcmp(data, frame_header, 6) == 0) {
2318 avg_lum = ((data[35] >> 2) & 3) |
2321 avg_lum += ((data[35] >> 4) & 3) |
2324 avg_lum += ((data[35] >> 6) & 3) |
2327 avg_lum += (data[36] & 3) |
2330 avg_lum += ((data[36] >> 2) & 3) |
2333 avg_lum += ((data[36] >> 4) & 3) |
2336 avg_lum += ((data[36] >> 6) & 3) |
2339 avg_lum += ((data[44] >> 4) & 3) |
2343 atomic_set(&sd->avg_lum, avg_lum);
2346 transfer_check(gspca_dev, data);
2348 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2354 if (gspca_dev->last_packet_type == LAST_PACKET) {
2356 gspca_frame_add(gspca_dev, FIRST_PACKET,
2357 sd->jpeg_hdr, JPEG_HDR_SZ);
2358 gspca_frame_add(gspca_dev, INTER_PACKET,
2361 gspca_frame_add(gspca_dev, FIRST_PACKET,
2365 /* if JPEG, count the packets and their size */
2370 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2374 /* sub-driver description */
2375 static const struct sd_desc sd_desc = {
2376 .name = KBUILD_MODNAME,
2378 .nctrls = ARRAY_SIZE(sd_ctrls),
2379 .config = sd_config,
2381 .isoc_init = sd_isoc_init,
2385 .pkt_scan = sd_pkt_scan,
2386 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2387 .int_pkt_scan = sd_int_pkt_scan,
2389 .dq_callback = sd_dqcallback,
2390 #ifdef CONFIG_VIDEO_ADV_DEBUG
2391 .set_register = sd_dbg_s_register,
2392 .get_register = sd_dbg_g_register,
2394 .get_chip_ident = sd_chip_ident,
2397 #define SN9C20X(sensor, i2c_addr, flags) \
2398 .driver_info = ((flags & 0xff) << 16) \
2399 | (SENSOR_ ## sensor << 8) \
2402 static const struct usb_device_id device_table[] = {
2403 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2404 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
2405 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2406 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
2407 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
2408 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
2409 (FLIP_DETECT | HAS_NO_BUTTON))},
2410 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2411 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2412 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2413 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2414 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, FLIP_DETECT)},
2415 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2416 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2417 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2418 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2419 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
2420 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
2421 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2422 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2423 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2424 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2425 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, LED_REVERSE)},
2426 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, LED_REVERSE)},
2427 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2428 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2429 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2430 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2431 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
2432 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
2433 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2434 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2435 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2436 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2437 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
2438 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2439 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2442 MODULE_DEVICE_TABLE(usb, device_table);
2444 /* -- device connect -- */
2445 static int sd_probe(struct usb_interface *intf,
2446 const struct usb_device_id *id)
2448 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2452 static struct usb_driver sd_driver = {
2453 .name = KBUILD_MODNAME,
2454 .id_table = device_table,
2456 .disconnect = gspca_disconnect,
2458 .suspend = gspca_suspend,
2459 .resume = gspca_resume,
2460 .reset_resume = gspca_resume,
2464 module_usb_driver(sd_driver);