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 20
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 u16 i2c_ident[] = {
759 V4L2_IDENT_MT9M001C12ST,
765 static u16 bridge_init[][2] = {
766 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
767 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
768 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
769 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
770 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
771 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
772 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
773 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
774 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
775 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
776 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
777 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
778 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
779 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
780 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
781 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
782 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
783 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
784 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
788 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
789 static u8 ov_gain[] = {
790 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
791 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
792 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
793 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
794 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
795 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
796 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
800 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
801 static u16 micron1_gain[] = {
802 /* 1x 1.25x 1.5x 1.75x */
803 0x0020, 0x0028, 0x0030, 0x0038,
804 /* 2x 2.25x 2.5x 2.75x */
805 0x00a0, 0x00a4, 0x00a8, 0x00ac,
806 /* 3x 3.25x 3.5x 3.75x */
807 0x00b0, 0x00b4, 0x00b8, 0x00bc,
808 /* 4x 4.25x 4.5x 4.75x */
809 0x00c0, 0x00c4, 0x00c8, 0x00cc,
810 /* 5x 5.25x 5.5x 5.75x */
811 0x00d0, 0x00d4, 0x00d8, 0x00dc,
812 /* 6x 6.25x 6.5x 6.75x */
813 0x00e0, 0x00e4, 0x00e8, 0x00ec,
814 /* 7x 7.25x 7.5x 7.75x */
815 0x00f0, 0x00f4, 0x00f8, 0x00fc,
820 /* mt9m001 sensor uses a different gain formula then other micron sensors */
821 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
822 static u16 micron2_gain[] = {
823 /* 1x 1.25x 1.5x 1.75x */
824 0x0008, 0x000a, 0x000c, 0x000e,
825 /* 2x 2.25x 2.5x 2.75x */
826 0x0010, 0x0012, 0x0014, 0x0016,
827 /* 3x 3.25x 3.5x 3.75x */
828 0x0018, 0x001a, 0x001c, 0x001e,
829 /* 4x 4.25x 4.5x 4.75x */
830 0x0020, 0x0051, 0x0052, 0x0053,
831 /* 5x 5.25x 5.5x 5.75x */
832 0x0054, 0x0055, 0x0056, 0x0057,
833 /* 6x 6.25x 6.5x 6.75x */
834 0x0058, 0x0059, 0x005a, 0x005b,
835 /* 7x 7.25x 7.5x 7.75x */
836 0x005c, 0x005d, 0x005e, 0x005f,
841 /* Gain = .5 + bit[7:0] / 16 */
842 static u8 hv7131r_gain[] = {
843 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
844 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
845 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
846 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
847 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
848 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
849 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
853 static struct i2c_reg_u8 soi968_init[] = {
854 {0x0c, 0x00}, {0x0f, 0x1f},
855 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
856 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
857 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
858 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
859 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
860 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
861 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
862 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
863 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
864 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
867 static struct i2c_reg_u8 ov7660_init[] = {
868 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
869 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
870 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
871 /* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using
872 0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
873 {0x17, 0x10}, {0x18, 0x61},
874 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
875 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6},
876 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
879 static struct i2c_reg_u8 ov7670_init[] = {
880 {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
881 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
882 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
883 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
884 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
885 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
886 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
887 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
888 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
889 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
890 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
891 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
892 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
893 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
894 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
895 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
896 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
897 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
898 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
899 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
900 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
901 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
902 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
903 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
904 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
905 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
906 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
907 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
908 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
909 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
910 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
911 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
912 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
913 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
914 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
915 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
916 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
917 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
918 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
919 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
920 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
921 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
922 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
923 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
924 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
925 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
926 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
927 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
928 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
929 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
930 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
931 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
932 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
936 static struct i2c_reg_u8 ov9650_init[] = {
937 {0x00, 0x00}, {0x01, 0x78},
938 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
939 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
940 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
941 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
942 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
943 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
944 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
945 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
946 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
947 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
948 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
949 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
950 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
951 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
952 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
953 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
954 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
955 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
956 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
957 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
958 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
959 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
960 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
961 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
962 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
963 {0xaa, 0x92}, {0xab, 0x0a},
966 static struct i2c_reg_u8 ov9655_init[] = {
967 {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
968 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
969 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
970 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
971 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
972 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
973 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
974 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
975 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
976 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
977 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
978 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
979 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
980 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
981 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
982 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
983 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
984 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
985 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
986 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
987 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
988 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
989 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
990 {0x04, 0x03}, {0x00, 0x13},
993 static struct i2c_reg_u16 mt9v112_init[] = {
994 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
995 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
996 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
997 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
998 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
999 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
1000 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
1001 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
1002 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
1003 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
1004 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
1005 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1006 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
1007 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
1008 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
1009 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
1012 static struct i2c_reg_u16 mt9v111_init[] = {
1013 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
1014 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
1015 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
1016 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
1017 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
1018 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
1019 {0x0e, 0x0008}, {0x20, 0x0000}
1022 static struct i2c_reg_u16 mt9v011_init[] = {
1023 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
1024 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
1025 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
1026 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
1027 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
1028 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
1029 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
1030 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
1031 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
1032 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
1033 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
1034 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
1035 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
1036 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
1037 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
1038 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
1039 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
1040 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
1041 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
1042 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
1043 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
1044 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1045 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
1046 {0x06, 0x0029}, {0x05, 0x0009},
1049 static struct i2c_reg_u16 mt9m001_init[] = {
1052 {0x04, 0x0500}, /* hres = 1280 */
1053 {0x03, 0x0400}, /* vres = 1024 */
1065 static struct i2c_reg_u16 mt9m111_init[] = {
1066 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1067 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1068 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1072 static struct i2c_reg_u16 mt9m112_init[] = {
1073 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1074 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1075 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1079 static struct i2c_reg_u8 hv7131r_init[] = {
1080 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
1081 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
1082 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
1083 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
1084 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
1085 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
1086 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
1087 {0x23, 0x09}, {0x01, 0x08},
1090 static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
1092 struct usb_device *dev = gspca_dev->dev;
1095 if (gspca_dev->usb_err < 0)
1097 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
1099 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1105 if (unlikely(result < 0 || result != length)) {
1106 pr_err("Read register %02x failed %d\n", reg, result);
1107 gspca_dev->usb_err = result;
1111 static void reg_w(struct gspca_dev *gspca_dev, u16 reg,
1112 const u8 *buffer, int length)
1114 struct usb_device *dev = gspca_dev->dev;
1117 if (gspca_dev->usb_err < 0)
1119 memcpy(gspca_dev->usb_buf, buffer, length);
1120 result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1122 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1128 if (unlikely(result < 0 || result != length)) {
1129 pr_err("Write register %02x failed %d\n", reg, result);
1130 gspca_dev->usb_err = result;
1134 static void reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
1136 reg_w(gspca_dev, reg, &value, 1);
1139 static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
1143 reg_w(gspca_dev, 0x10c0, buffer, 8);
1144 for (i = 0; i < 5; i++) {
1145 reg_r(gspca_dev, 0x10c0, 1);
1146 if (gspca_dev->usb_err < 0)
1148 if (gspca_dev->usb_buf[0] & 0x04) {
1149 if (gspca_dev->usb_buf[0] & 0x08) {
1150 pr_err("i2c_w error\n");
1151 gspca_dev->usb_err = -EIO;
1157 pr_err("i2c_w reg %02x no response\n", buffer[2]);
1158 /* gspca_dev->usb_err = -EIO; fixme: may occur */
1161 static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1163 struct sd *sd = (struct sd *) gspca_dev;
1167 * from the point of view of the bridge, the length
1168 * includes the address
1170 row[0] = 0x81 | (2 << 4);
1171 row[1] = sd->i2c_addr;
1179 i2c_w(gspca_dev, row);
1182 static void i2c_w1_buf(struct gspca_dev *gspca_dev,
1183 struct i2c_reg_u8 *buf, int sz)
1186 i2c_w1(gspca_dev, buf->reg, buf->val);
1191 static void i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1193 struct sd *sd = (struct sd *) gspca_dev;
1197 * from the point of view of the bridge, the length
1198 * includes the address
1200 row[0] = 0x81 | (3 << 4);
1201 row[1] = sd->i2c_addr;
1209 i2c_w(gspca_dev, row);
1212 static void i2c_w2_buf(struct gspca_dev *gspca_dev,
1213 struct i2c_reg_u16 *buf, int sz)
1216 i2c_w2(gspca_dev, buf->reg, buf->val);
1221 static void i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1223 struct sd *sd = (struct sd *) gspca_dev;
1226 row[0] = 0x81 | (1 << 4);
1227 row[1] = sd->i2c_addr;
1234 i2c_w(gspca_dev, row);
1235 row[0] = 0x81 | (1 << 4) | 0x02;
1237 i2c_w(gspca_dev, row);
1238 reg_r(gspca_dev, 0x10c2, 5);
1239 *val = gspca_dev->usb_buf[4];
1242 static void i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1244 struct sd *sd = (struct sd *) gspca_dev;
1247 row[0] = 0x81 | (1 << 4);
1248 row[1] = sd->i2c_addr;
1255 i2c_w(gspca_dev, row);
1256 row[0] = 0x81 | (2 << 4) | 0x02;
1258 i2c_w(gspca_dev, row);
1259 reg_r(gspca_dev, 0x10c2, 5);
1260 *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1263 static void ov9650_init_sensor(struct gspca_dev *gspca_dev)
1266 struct sd *sd = (struct sd *) gspca_dev;
1268 i2c_r2(gspca_dev, 0x1c, &id);
1269 if (gspca_dev->usb_err < 0)
1273 pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id);
1274 gspca_dev->usb_err = -ENODEV;
1278 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1280 i2c_w1_buf(gspca_dev, ov9650_init, ARRAY_SIZE(ov9650_init));
1281 if (gspca_dev->usb_err < 0)
1282 pr_err("OV9650 sensor initialization failed\n");
1287 static void ov9655_init_sensor(struct gspca_dev *gspca_dev)
1289 struct sd *sd = (struct sd *) gspca_dev;
1291 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1293 i2c_w1_buf(gspca_dev, ov9655_init, ARRAY_SIZE(ov9655_init));
1294 if (gspca_dev->usb_err < 0)
1295 pr_err("OV9655 sensor initialization failed\n");
1297 /* disable hflip and vflip */
1298 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
1303 static void soi968_init_sensor(struct gspca_dev *gspca_dev)
1305 struct sd *sd = (struct sd *) gspca_dev;
1307 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1309 i2c_w1_buf(gspca_dev, soi968_init, ARRAY_SIZE(soi968_init));
1310 if (gspca_dev->usb_err < 0)
1311 pr_err("SOI968 sensor initialization failed\n");
1313 /* disable hflip and vflip */
1314 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP)
1320 static void ov7660_init_sensor(struct gspca_dev *gspca_dev)
1322 struct sd *sd = (struct sd *) gspca_dev;
1324 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1326 i2c_w1_buf(gspca_dev, ov7660_init, ARRAY_SIZE(ov7660_init));
1327 if (gspca_dev->usb_err < 0)
1328 pr_err("OV7660 sensor initialization failed\n");
1333 static void ov7670_init_sensor(struct gspca_dev *gspca_dev)
1335 struct sd *sd = (struct sd *) gspca_dev;
1337 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1339 i2c_w1_buf(gspca_dev, ov7670_init, ARRAY_SIZE(ov7670_init));
1340 if (gspca_dev->usb_err < 0)
1341 pr_err("OV7670 sensor initialization failed\n");
1343 /* disable hflip and vflip */
1344 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
1349 static void mt9v_init_sensor(struct gspca_dev *gspca_dev)
1351 struct sd *sd = (struct sd *) gspca_dev;
1354 sd->i2c_addr = 0x5d;
1355 i2c_r2(gspca_dev, 0xff, &value);
1356 if (gspca_dev->usb_err >= 0
1357 && value == 0x8243) {
1358 i2c_w2_buf(gspca_dev, mt9v011_init, ARRAY_SIZE(mt9v011_init));
1359 if (gspca_dev->usb_err < 0) {
1360 pr_err("MT9V011 sensor initialization failed\n");
1365 sd->sensor = SENSOR_MT9V011;
1366 pr_info("MT9V011 sensor detected\n");
1370 gspca_dev->usb_err = 0;
1371 sd->i2c_addr = 0x5c;
1372 i2c_w2(gspca_dev, 0x01, 0x0004);
1373 i2c_r2(gspca_dev, 0xff, &value);
1374 if (gspca_dev->usb_err >= 0
1375 && value == 0x823a) {
1376 i2c_w2_buf(gspca_dev, mt9v111_init, ARRAY_SIZE(mt9v111_init));
1377 if (gspca_dev->usb_err < 0) {
1378 pr_err("MT9V111 sensor initialization failed\n");
1381 gspca_dev->ctrl_dis = (1 << EXPOSURE)
1386 sd->sensor = SENSOR_MT9V111;
1387 pr_info("MT9V111 sensor detected\n");
1391 gspca_dev->usb_err = 0;
1392 sd->i2c_addr = 0x5d;
1393 i2c_w2(gspca_dev, 0xf0, 0x0000);
1394 if (gspca_dev->usb_err < 0) {
1395 gspca_dev->usb_err = 0;
1396 sd->i2c_addr = 0x48;
1397 i2c_w2(gspca_dev, 0xf0, 0x0000);
1399 i2c_r2(gspca_dev, 0x00, &value);
1400 if (gspca_dev->usb_err >= 0
1401 && value == 0x1229) {
1402 i2c_w2_buf(gspca_dev, mt9v112_init, ARRAY_SIZE(mt9v112_init));
1403 if (gspca_dev->usb_err < 0) {
1404 pr_err("MT9V112 sensor initialization failed\n");
1409 sd->sensor = SENSOR_MT9V112;
1410 pr_info("MT9V112 sensor detected\n");
1414 gspca_dev->usb_err = -ENODEV;
1417 static void mt9m112_init_sensor(struct gspca_dev *gspca_dev)
1419 struct sd *sd = (struct sd *) gspca_dev;
1421 i2c_w2_buf(gspca_dev, mt9m112_init, ARRAY_SIZE(mt9m112_init));
1422 if (gspca_dev->usb_err < 0)
1423 pr_err("MT9M112 sensor initialization failed\n");
1425 gspca_dev->ctrl_dis = (1 << EXPOSURE) | (1 << AUTOGAIN)
1431 static void mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1433 struct sd *sd = (struct sd *) gspca_dev;
1435 i2c_w2_buf(gspca_dev, mt9m111_init, ARRAY_SIZE(mt9m111_init));
1436 if (gspca_dev->usb_err < 0)
1437 pr_err("MT9M111 sensor initialization failed\n");
1439 gspca_dev->ctrl_dis = (1 << EXPOSURE) | (1 << AUTOGAIN)
1445 static void mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1447 struct sd *sd = (struct sd *) gspca_dev;
1450 i2c_r2(gspca_dev, 0x00, &id);
1451 if (gspca_dev->usb_err < 0)
1454 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
1458 pr_info("MT9M001 color sensor detected\n");
1461 pr_info("MT9M001 mono sensor detected\n");
1464 pr_err("No MT9M001 chip detected, ID = %x\n\n", id);
1465 gspca_dev->usb_err = -ENODEV;
1469 i2c_w2_buf(gspca_dev, mt9m001_init, ARRAY_SIZE(mt9m001_init));
1470 if (gspca_dev->usb_err < 0)
1471 pr_err("MT9M001 sensor initialization failed\n");
1473 /* disable hflip and vflip */
1474 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
1479 static void hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1481 struct sd *sd = (struct sd *) gspca_dev;
1483 i2c_w1_buf(gspca_dev, hv7131r_init, ARRAY_SIZE(hv7131r_init));
1484 if (gspca_dev->usb_err < 0)
1485 pr_err("HV7131R Sensor initialization failed\n");
1491 static void set_cmatrix(struct gspca_dev *gspca_dev)
1493 struct sd *sd = (struct sd *) gspca_dev;
1495 s32 hue_coord, hue_index = 180 + sd->ctrls[HUE].val;
1498 memset(cmatrix, 0, sizeof cmatrix);
1499 cmatrix[2] = (sd->ctrls[CONTRAST].val * 0x25 / 0x100) + 0x26;
1500 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1501 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1502 cmatrix[18] = sd->ctrls[BRIGHTNESS].val - 0x80;
1504 satur = sd->ctrls[SATURATION].val;
1505 hue_coord = (hsv_red_x[hue_index] * satur) >> 8;
1506 cmatrix[6] = hue_coord;
1507 cmatrix[7] = (hue_coord >> 8) & 0x0f;
1509 hue_coord = (hsv_red_y[hue_index] * satur) >> 8;
1510 cmatrix[8] = hue_coord;
1511 cmatrix[9] = (hue_coord >> 8) & 0x0f;
1513 hue_coord = (hsv_green_x[hue_index] * satur) >> 8;
1514 cmatrix[10] = hue_coord;
1515 cmatrix[11] = (hue_coord >> 8) & 0x0f;
1517 hue_coord = (hsv_green_y[hue_index] * satur) >> 8;
1518 cmatrix[12] = hue_coord;
1519 cmatrix[13] = (hue_coord >> 8) & 0x0f;
1521 hue_coord = (hsv_blue_x[hue_index] * satur) >> 8;
1522 cmatrix[14] = hue_coord;
1523 cmatrix[15] = (hue_coord >> 8) & 0x0f;
1525 hue_coord = (hsv_blue_y[hue_index] * satur) >> 8;
1526 cmatrix[16] = hue_coord;
1527 cmatrix[17] = (hue_coord >> 8) & 0x0f;
1529 reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1532 static void set_gamma(struct gspca_dev *gspca_dev)
1534 struct sd *sd = (struct sd *) gspca_dev;
1536 u8 gval = sd->ctrls[GAMMA].val * 0xb8 / 0x100;
1539 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
1540 gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8);
1541 gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8);
1542 gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8);
1543 gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8);
1544 gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8);
1545 gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8);
1546 gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8);
1547 gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8);
1548 gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8);
1549 gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8);
1550 gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8);
1551 gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8);
1552 gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8);
1553 gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
1556 reg_w(gspca_dev, 0x1190, gamma, 17);
1559 static void set_redblue(struct gspca_dev *gspca_dev)
1561 struct sd *sd = (struct sd *) gspca_dev;
1563 reg_w1(gspca_dev, 0x118c, sd->ctrls[RED].val);
1564 reg_w1(gspca_dev, 0x118f, sd->ctrls[BLUE].val);
1567 static void set_hvflip(struct gspca_dev *gspca_dev)
1569 u8 value, tslb, hflip, vflip;
1571 struct sd *sd = (struct sd *) gspca_dev;
1573 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1574 hflip = !sd->ctrls[HFLIP].val;
1575 vflip = !sd->ctrls[VFLIP].val;
1577 hflip = sd->ctrls[HFLIP].val;
1578 vflip = sd->ctrls[VFLIP].val;
1581 switch (sd->sensor) {
1592 reg_w1(gspca_dev, 0x1182, sd->vstart);
1593 i2c_w1(gspca_dev, 0x1e, value);
1596 i2c_r1(gspca_dev, 0x1e, &value);
1605 i2c_w1(gspca_dev, 0x1e, value);
1606 i2c_w1(gspca_dev, 0x3a, tslb);
1608 case SENSOR_MT9V111:
1609 case SENSOR_MT9V011:
1610 i2c_r2(gspca_dev, 0x20, &value2);
1616 i2c_w2(gspca_dev, 0x20, value2);
1618 case SENSOR_MT9M112:
1619 case SENSOR_MT9M111:
1620 case SENSOR_MT9V112:
1621 i2c_r2(gspca_dev, 0x20, &value2);
1627 i2c_w2(gspca_dev, 0x20, value2);
1629 case SENSOR_HV7131R:
1630 i2c_r1(gspca_dev, 0x01, &value);
1636 i2c_w1(gspca_dev, 0x01, value);
1641 static void set_exposure(struct gspca_dev *gspca_dev)
1643 struct sd *sd = (struct sd *) gspca_dev;
1644 u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1647 expo = sd->ctrls[EXPOSURE].val;
1648 switch (sd->sensor) {
1658 case SENSOR_MT9M001:
1659 case SENSOR_MT9V112:
1660 case SENSOR_MT9V011:
1666 case SENSOR_HV7131R:
1676 i2c_w(gspca_dev, exp);
1679 static void set_gain(struct gspca_dev *gspca_dev)
1681 struct sd *sd = (struct sd *) gspca_dev;
1682 u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1685 g = sd->ctrls[GAIN].val;
1686 switch (sd->sensor) {
1692 gain[0] |= (2 << 4);
1693 gain[3] = ov_gain[g];
1695 case SENSOR_MT9V011:
1696 gain[0] |= (3 << 4);
1698 gain[3] = micron1_gain[g] >> 8;
1699 gain[4] = micron1_gain[g];
1701 case SENSOR_MT9V112:
1702 gain[0] |= (3 << 4);
1704 gain[3] = micron1_gain[g] >> 8;
1705 gain[4] = micron1_gain[g];
1707 case SENSOR_MT9M001:
1708 gain[0] |= (3 << 4);
1710 gain[3] = micron2_gain[g] >> 8;
1711 gain[4] = micron2_gain[g];
1713 case SENSOR_HV7131R:
1714 gain[0] |= (2 << 4);
1716 gain[3] = hv7131r_gain[g];
1721 i2c_w(gspca_dev, gain);
1724 static void set_quality(struct gspca_dev *gspca_dev)
1726 struct sd *sd = (struct sd *) gspca_dev;
1728 jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val);
1729 reg_w1(gspca_dev, 0x1061, 0x01); /* stop transfer */
1730 reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20); /* write QTAB */
1731 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
1732 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
1733 reg_w1(gspca_dev, 0x1061, 0x03); /* restart transfer */
1734 reg_w1(gspca_dev, 0x10e0, sd->fmt);
1735 sd->fmt ^= 0x0c; /* invert QTAB use + write */
1736 reg_w1(gspca_dev, 0x10e0, sd->fmt);
1739 #ifdef CONFIG_VIDEO_ADV_DEBUG
1740 static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1741 struct v4l2_dbg_register *reg)
1743 struct sd *sd = (struct sd *) gspca_dev;
1745 switch (reg->match.type) {
1746 case V4L2_CHIP_MATCH_HOST:
1747 if (reg->match.addr != 0)
1749 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1751 reg_r(gspca_dev, reg->reg, 1);
1752 reg->val = gspca_dev->usb_buf[0];
1753 return gspca_dev->usb_err;
1754 case V4L2_CHIP_MATCH_I2C_ADDR:
1755 if (reg->match.addr != sd->i2c_addr)
1757 if (sd->sensor >= SENSOR_MT9V011 &&
1758 sd->sensor <= SENSOR_MT9M112) {
1759 i2c_r2(gspca_dev, reg->reg, (u16 *) ®->val);
1761 i2c_r1(gspca_dev, reg->reg, (u8 *) ®->val);
1763 return gspca_dev->usb_err;
1768 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1769 struct v4l2_dbg_register *reg)
1771 struct sd *sd = (struct sd *) gspca_dev;
1773 switch (reg->match.type) {
1774 case V4L2_CHIP_MATCH_HOST:
1775 if (reg->match.addr != 0)
1777 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1779 reg_w1(gspca_dev, reg->reg, reg->val);
1780 return gspca_dev->usb_err;
1781 case V4L2_CHIP_MATCH_I2C_ADDR:
1782 if (reg->match.addr != sd->i2c_addr)
1784 if (sd->sensor >= SENSOR_MT9V011 &&
1785 sd->sensor <= SENSOR_MT9M112) {
1786 i2c_w2(gspca_dev, reg->reg, reg->val);
1788 i2c_w1(gspca_dev, reg->reg, reg->val);
1790 return gspca_dev->usb_err;
1796 static int sd_chip_ident(struct gspca_dev *gspca_dev,
1797 struct v4l2_dbg_chip_ident *chip)
1799 struct sd *sd = (struct sd *) gspca_dev;
1801 switch (chip->match.type) {
1802 case V4L2_CHIP_MATCH_HOST:
1803 if (chip->match.addr != 0)
1806 chip->ident = V4L2_IDENT_SN9C20X;
1808 case V4L2_CHIP_MATCH_I2C_ADDR:
1809 if (chip->match.addr != sd->i2c_addr)
1812 chip->ident = i2c_ident[sd->sensor];
1818 static int sd_config(struct gspca_dev *gspca_dev,
1819 const struct usb_device_id *id)
1821 struct sd *sd = (struct sd *) gspca_dev;
1824 cam = &gspca_dev->cam;
1825 cam->needs_full_bandwidth = 1;
1827 sd->sensor = id->driver_info >> 8;
1828 sd->i2c_addr = id->driver_info;
1829 sd->flags = id->driver_info >> 16;
1831 switch (sd->sensor) {
1832 case SENSOR_MT9M112:
1833 case SENSOR_MT9M111:
1836 cam->cam_mode = sxga_mode;
1837 cam->nmodes = ARRAY_SIZE(sxga_mode);
1839 case SENSOR_MT9M001:
1840 cam->cam_mode = mono_mode;
1841 cam->nmodes = ARRAY_SIZE(mono_mode);
1844 cam->cam_mode = vga_mode;
1845 cam->nmodes = ARRAY_SIZE(vga_mode);
1851 sd->exposure_step = 16;
1853 gspca_dev->cam.ctrls = sd->ctrls;
1855 INIT_WORK(&sd->work, qual_upd);
1860 static int sd_init(struct gspca_dev *gspca_dev)
1862 struct sd *sd = (struct sd *) gspca_dev;
1866 {0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
1868 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
1869 value = bridge_init[i][1];
1870 reg_w(gspca_dev, bridge_init[i][0], &value, 1);
1871 if (gspca_dev->usb_err < 0) {
1872 pr_err("Device initialization failed\n");
1873 return gspca_dev->usb_err;
1877 if (sd->flags & LED_REVERSE)
1878 reg_w1(gspca_dev, 0x1006, 0x00);
1880 reg_w1(gspca_dev, 0x1006, 0x20);
1882 reg_w(gspca_dev, 0x10c0, i2c_init, 9);
1883 if (gspca_dev->usb_err < 0) {
1884 pr_err("Device initialization failed\n");
1885 return gspca_dev->usb_err;
1888 switch (sd->sensor) {
1890 ov9650_init_sensor(gspca_dev);
1891 if (gspca_dev->usb_err < 0)
1893 pr_info("OV9650 sensor detected\n");
1896 ov9655_init_sensor(gspca_dev);
1897 if (gspca_dev->usb_err < 0)
1899 pr_info("OV9655 sensor detected\n");
1902 soi968_init_sensor(gspca_dev);
1903 if (gspca_dev->usb_err < 0)
1905 pr_info("SOI968 sensor detected\n");
1908 ov7660_init_sensor(gspca_dev);
1909 if (gspca_dev->usb_err < 0)
1911 pr_info("OV7660 sensor detected\n");
1914 ov7670_init_sensor(gspca_dev);
1915 if (gspca_dev->usb_err < 0)
1917 pr_info("OV7670 sensor detected\n");
1919 case SENSOR_MT9VPRB:
1920 mt9v_init_sensor(gspca_dev);
1921 if (gspca_dev->usb_err < 0)
1923 pr_info("MT9VPRB sensor detected\n");
1925 case SENSOR_MT9M111:
1926 mt9m111_init_sensor(gspca_dev);
1927 if (gspca_dev->usb_err < 0)
1929 pr_info("MT9M111 sensor detected\n");
1931 case SENSOR_MT9M112:
1932 mt9m112_init_sensor(gspca_dev);
1933 if (gspca_dev->usb_err < 0)
1935 pr_info("MT9M112 sensor detected\n");
1937 case SENSOR_MT9M001:
1938 mt9m001_init_sensor(gspca_dev);
1939 if (gspca_dev->usb_err < 0)
1942 case SENSOR_HV7131R:
1943 hv7131r_init_sensor(gspca_dev);
1944 if (gspca_dev->usb_err < 0)
1946 pr_info("HV7131R sensor detected\n");
1949 pr_err("Unsupported sensor\n");
1950 gspca_dev->usb_err = -ENODEV;
1953 return gspca_dev->usb_err;
1956 static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
1958 struct sd *sd = (struct sd *) gspca_dev;
1961 switch (sd->sensor) {
1963 if (mode & MODE_SXGA) {
1964 i2c_w1(gspca_dev, 0x17, 0x1d);
1965 i2c_w1(gspca_dev, 0x18, 0xbd);
1966 i2c_w1(gspca_dev, 0x19, 0x01);
1967 i2c_w1(gspca_dev, 0x1a, 0x81);
1968 i2c_w1(gspca_dev, 0x12, 0x00);
1972 i2c_w1(gspca_dev, 0x17, 0x13);
1973 i2c_w1(gspca_dev, 0x18, 0x63);
1974 i2c_w1(gspca_dev, 0x19, 0x01);
1975 i2c_w1(gspca_dev, 0x1a, 0x79);
1976 i2c_w1(gspca_dev, 0x12, 0x40);
1982 if (mode & MODE_SXGA) {
1983 i2c_w1(gspca_dev, 0x17, 0x1b);
1984 i2c_w1(gspca_dev, 0x18, 0xbc);
1985 i2c_w1(gspca_dev, 0x19, 0x01);
1986 i2c_w1(gspca_dev, 0x1a, 0x82);
1987 i2c_r1(gspca_dev, 0x12, &value);
1988 i2c_w1(gspca_dev, 0x12, value & 0x07);
1990 i2c_w1(gspca_dev, 0x17, 0x24);
1991 i2c_w1(gspca_dev, 0x18, 0xc5);
1992 i2c_w1(gspca_dev, 0x19, 0x00);
1993 i2c_w1(gspca_dev, 0x1a, 0x3c);
1994 i2c_r1(gspca_dev, 0x12, &value);
1995 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
1998 case SENSOR_MT9M112:
1999 case SENSOR_MT9M111:
2000 if (mode & MODE_SXGA) {
2001 i2c_w2(gspca_dev, 0xf0, 0x0002);
2002 i2c_w2(gspca_dev, 0xc8, 0x970b);
2003 i2c_w2(gspca_dev, 0xf0, 0x0000);
2005 i2c_w2(gspca_dev, 0xf0, 0x0002);
2006 i2c_w2(gspca_dev, 0xc8, 0x8000);
2007 i2c_w2(gspca_dev, 0xf0, 0x0000);
2013 static int sd_isoc_init(struct gspca_dev *gspca_dev)
2015 struct usb_interface *intf;
2016 u32 flags = gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv;
2019 * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth
2020 * than our regular bandwidth calculations reserve, so we force the
2021 * use of a specific altsetting when using the SN9C20X_I420 fmt.
2023 if (!(flags & (MODE_RAW | MODE_JPEG))) {
2024 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
2026 if (intf->num_altsetting != 9) {
2027 pr_warn("sn9c20x camera with unknown number of alt "
2028 "settings (%d), please report!\n",
2029 intf->num_altsetting);
2030 gspca_dev->alt = intf->num_altsetting;
2034 switch (gspca_dev->width) {
2035 case 160: /* 160x120 */
2038 case 320: /* 320x240 */
2041 default: /* >= 640x480 */
2050 #define HW_WIN(mode, hstart, vstart) \
2051 ((const u8 []){hstart, 0, vstart, 0, \
2052 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
2053 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
2055 #define CLR_WIN(width, height) \
2057 {0, width >> 2, 0, height >> 1,\
2058 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
2060 static int sd_start(struct gspca_dev *gspca_dev)
2062 struct sd *sd = (struct sd *) gspca_dev;
2063 int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
2064 int width = gspca_dev->width;
2065 int height = gspca_dev->height;
2068 jpeg_define(sd->jpeg_hdr, height, width,
2070 jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val);
2072 if (mode & MODE_RAW)
2074 else if (mode & MODE_JPEG)
2077 fmt = 0x2f; /* YUV 420 */
2080 switch (mode & SCALE_MASK) {
2081 case SCALE_1280x1024:
2083 pr_info("Set 1280x1024\n");
2087 pr_info("Set 640x480\n");
2091 pr_info("Set 320x240\n");
2095 pr_info("Set 160x120\n");
2099 configure_sensor_output(gspca_dev, mode);
2100 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2101 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2102 reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2103 reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2104 reg_w1(gspca_dev, 0x1189, scale);
2105 reg_w1(gspca_dev, 0x10e0, fmt);
2107 set_cmatrix(gspca_dev);
2108 set_gamma(gspca_dev);
2109 set_redblue(gspca_dev);
2110 set_gain(gspca_dev);
2111 set_exposure(gspca_dev);
2112 set_hvflip(gspca_dev);
2114 reg_w1(gspca_dev, 0x1007, 0x20);
2115 reg_w1(gspca_dev, 0x1061, 0x03);
2117 /* if JPEG, prepare the compression quality update */
2118 if (mode & MODE_JPEG) {
2119 sd->pktsz = sd->npkt = 0;
2122 create_singlethread_workqueue(KBUILD_MODNAME);
2125 return gspca_dev->usb_err;
2128 static void sd_stopN(struct gspca_dev *gspca_dev)
2130 reg_w1(gspca_dev, 0x1007, 0x00);
2131 reg_w1(gspca_dev, 0x1061, 0x01);
2134 /* called on streamoff with alt==0 and on disconnect */
2135 /* the usb_lock is held at entry - restore on exit */
2136 static void sd_stop0(struct gspca_dev *gspca_dev)
2138 struct sd *sd = (struct sd *) gspca_dev;
2140 if (sd->work_thread != NULL) {
2141 mutex_unlock(&gspca_dev->usb_lock);
2142 destroy_workqueue(sd->work_thread);
2143 mutex_lock(&gspca_dev->usb_lock);
2144 sd->work_thread = NULL;
2148 static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2150 struct sd *sd = (struct sd *) gspca_dev;
2154 * some hardcoded values are present
2155 * like those for maximal/minimal exposure
2156 * and exposure steps
2158 if (avg_lum < MIN_AVG_LUM) {
2159 if (sd->ctrls[EXPOSURE].val > 0x1770)
2162 new_exp = sd->ctrls[EXPOSURE].val + sd->exposure_step;
2163 if (new_exp > 0x1770)
2167 sd->ctrls[EXPOSURE].val = new_exp;
2168 set_exposure(gspca_dev);
2170 sd->older_step = sd->old_step;
2173 if (sd->old_step ^ sd->older_step)
2174 sd->exposure_step /= 2;
2176 sd->exposure_step += 2;
2178 if (avg_lum > MAX_AVG_LUM) {
2179 if (sd->ctrls[EXPOSURE].val < 0x10)
2181 new_exp = sd->ctrls[EXPOSURE].val - sd->exposure_step;
2182 if (new_exp > 0x1700)
2186 sd->ctrls[EXPOSURE].val = new_exp;
2187 set_exposure(gspca_dev);
2188 sd->older_step = sd->old_step;
2191 if (sd->old_step ^ sd->older_step)
2192 sd->exposure_step /= 2;
2194 sd->exposure_step += 2;
2198 static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2200 struct sd *sd = (struct sd *) gspca_dev;
2202 if (avg_lum < MIN_AVG_LUM) {
2203 if (sd->ctrls[GAIN].val + 1 <= 28) {
2204 sd->ctrls[GAIN].val++;
2205 set_gain(gspca_dev);
2208 if (avg_lum > MAX_AVG_LUM) {
2209 if (sd->ctrls[GAIN].val > 0) {
2210 sd->ctrls[GAIN].val--;
2211 set_gain(gspca_dev);
2216 static void sd_dqcallback(struct gspca_dev *gspca_dev)
2218 struct sd *sd = (struct sd *) gspca_dev;
2221 if (!sd->ctrls[AUTOGAIN].val)
2224 avg_lum = atomic_read(&sd->avg_lum);
2225 if (sd->sensor == SENSOR_SOI968)
2226 do_autogain(gspca_dev, avg_lum);
2228 do_autoexposure(gspca_dev, avg_lum);
2231 /* JPEG quality update */
2232 /* This function is executed from a work queue. */
2233 static void qual_upd(struct work_struct *work)
2235 struct sd *sd = container_of(work, struct sd, work);
2236 struct gspca_dev *gspca_dev = &sd->gspca_dev;
2238 mutex_lock(&gspca_dev->usb_lock);
2239 PDEBUG(D_STREAM, "qual_upd %d%%", sd->ctrls[QUALITY].val);
2240 set_quality(gspca_dev);
2241 mutex_unlock(&gspca_dev->usb_lock);
2244 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2245 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2246 u8 *data, /* interrupt packet */
2247 int len) /* interrupt packet length */
2249 struct sd *sd = (struct sd *) gspca_dev;
2251 if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
2252 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2253 input_sync(gspca_dev->input_dev);
2254 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2255 input_sync(gspca_dev->input_dev);
2262 /* check the JPEG compression */
2263 static void transfer_check(struct gspca_dev *gspca_dev,
2266 struct sd *sd = (struct sd *) gspca_dev;
2271 /* if USB error, discard the frame and decrease the quality */
2272 if (data[6] & 0x08) { /* USB FIFO full */
2273 gspca_dev->last_packet_type = DISCARD_PACKET;
2277 /* else, compute the filling rate and a new JPEG quality */
2278 r = (sd->pktsz * 100) /
2280 gspca_dev->urb[0]->iso_frame_desc[0].length);
2286 if (new_qual != 0) {
2287 sd->nchg += new_qual;
2288 if (sd->nchg < -6 || sd->nchg >= 12) {
2290 new_qual += sd->ctrls[QUALITY].val;
2291 if (new_qual < QUALITY_MIN)
2292 new_qual = QUALITY_MIN;
2293 else if (new_qual > QUALITY_MAX)
2294 new_qual = QUALITY_MAX;
2295 if (new_qual != sd->ctrls[QUALITY].val) {
2296 sd->ctrls[QUALITY].val = new_qual;
2297 queue_work(sd->work_thread, &sd->work);
2303 sd->pktsz = sd->npkt = 0;
2306 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2307 u8 *data, /* isoc packet */
2308 int len) /* iso packet length */
2310 struct sd *sd = (struct sd *) gspca_dev;
2311 int avg_lum, is_jpeg;
2312 static u8 frame_header[] =
2313 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2315 is_jpeg = (sd->fmt & 0x03) == 0;
2316 if (len >= 64 && memcmp(data, frame_header, 6) == 0) {
2317 avg_lum = ((data[35] >> 2) & 3) |
2320 avg_lum += ((data[35] >> 4) & 3) |
2323 avg_lum += ((data[35] >> 6) & 3) |
2326 avg_lum += (data[36] & 3) |
2329 avg_lum += ((data[36] >> 2) & 3) |
2332 avg_lum += ((data[36] >> 4) & 3) |
2335 avg_lum += ((data[36] >> 6) & 3) |
2338 avg_lum += ((data[44] >> 4) & 3) |
2342 atomic_set(&sd->avg_lum, avg_lum);
2345 transfer_check(gspca_dev, data);
2347 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2353 if (gspca_dev->last_packet_type == LAST_PACKET) {
2355 gspca_frame_add(gspca_dev, FIRST_PACKET,
2356 sd->jpeg_hdr, JPEG_HDR_SZ);
2357 gspca_frame_add(gspca_dev, INTER_PACKET,
2360 gspca_frame_add(gspca_dev, FIRST_PACKET,
2364 /* if JPEG, count the packets and their size */
2369 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2373 /* sub-driver description */
2374 static const struct sd_desc sd_desc = {
2375 .name = KBUILD_MODNAME,
2377 .nctrls = ARRAY_SIZE(sd_ctrls),
2378 .config = sd_config,
2380 .isoc_init = sd_isoc_init,
2384 .pkt_scan = sd_pkt_scan,
2385 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2386 .int_pkt_scan = sd_int_pkt_scan,
2388 .dq_callback = sd_dqcallback,
2389 #ifdef CONFIG_VIDEO_ADV_DEBUG
2390 .set_register = sd_dbg_s_register,
2391 .get_register = sd_dbg_g_register,
2393 .get_chip_ident = sd_chip_ident,
2396 #define SN9C20X(sensor, i2c_addr, flags) \
2397 .driver_info = ((flags & 0xff) << 16) \
2398 | (SENSOR_ ## sensor << 8) \
2401 static const struct usb_device_id device_table[] = {
2402 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2403 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
2404 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2405 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
2406 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
2407 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
2408 (FLIP_DETECT | HAS_NO_BUTTON))},
2409 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2410 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2411 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2412 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2413 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, FLIP_DETECT)},
2414 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2415 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2416 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2417 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2418 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
2419 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
2420 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2421 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2422 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2423 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2424 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, LED_REVERSE)},
2425 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, LED_REVERSE)},
2426 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2427 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2428 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2429 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2430 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
2431 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
2432 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2433 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2434 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2435 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2436 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
2437 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2438 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2441 MODULE_DEVICE_TABLE(usb, device_table);
2443 /* -- device connect -- */
2444 static int sd_probe(struct usb_interface *intf,
2445 const struct usb_device_id *id)
2447 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2451 static struct usb_driver sd_driver = {
2452 .name = KBUILD_MODNAME,
2453 .id_table = device_table,
2455 .disconnect = gspca_disconnect,
2457 .suspend = gspca_suspend,
2458 .resume = gspca_resume,
2459 .reset_resume = gspca_resume,
2463 module_usb_driver(sd_driver);