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
113 u8 jpeg_hdr[JPEG_HDR_SZ];
118 static void qual_upd(struct work_struct *work);
130 static const struct dmi_system_id flip_dmi_table[] = {
132 .ident = "MSI MS-1034",
134 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
135 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1034"),
136 DMI_MATCH(DMI_PRODUCT_VERSION, "0341")
140 .ident = "MSI MS-1632",
142 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
143 DMI_MATCH(DMI_BOARD_NAME, "MS-1632")
147 .ident = "MSI MS-1633X",
149 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
150 DMI_MATCH(DMI_BOARD_NAME, "MS-1633X")
154 .ident = "MSI MS-1635X",
156 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
157 DMI_MATCH(DMI_BOARD_NAME, "MS-1635X")
161 .ident = "ASUSTeK W7J",
163 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
164 DMI_MATCH(DMI_BOARD_NAME, "W7J ")
170 static void set_cmatrix(struct gspca_dev *gspca_dev);
171 static void set_gamma(struct gspca_dev *gspca_dev);
172 static void set_redblue(struct gspca_dev *gspca_dev);
173 static void set_hvflip(struct gspca_dev *gspca_dev);
174 static void set_exposure(struct gspca_dev *gspca_dev);
175 static void set_gain(struct gspca_dev *gspca_dev);
176 static void set_quality(struct gspca_dev *gspca_dev);
178 static const struct ctrl sd_ctrls[NCTRLS] = {
181 .id = V4L2_CID_BRIGHTNESS,
182 .type = V4L2_CTRL_TYPE_INTEGER,
183 .name = "Brightness",
187 .default_value = 0x7f
189 .set_control = set_cmatrix
193 .id = V4L2_CID_CONTRAST,
194 .type = V4L2_CTRL_TYPE_INTEGER,
199 .default_value = 0x7f
201 .set_control = set_cmatrix
205 .id = V4L2_CID_SATURATION,
206 .type = V4L2_CTRL_TYPE_INTEGER,
207 .name = "Saturation",
211 .default_value = 0x7f
213 .set_control = set_cmatrix
218 .type = V4L2_CTRL_TYPE_INTEGER,
225 .set_control = set_cmatrix
229 .id = V4L2_CID_GAMMA,
230 .type = V4L2_CTRL_TYPE_INTEGER,
235 .default_value = 0x10
237 .set_control = set_gamma
241 .id = V4L2_CID_BLUE_BALANCE,
242 .type = V4L2_CTRL_TYPE_INTEGER,
243 .name = "Blue Balance",
247 .default_value = 0x28
249 .set_control = set_redblue
253 .id = V4L2_CID_RED_BALANCE,
254 .type = V4L2_CTRL_TYPE_INTEGER,
255 .name = "Red Balance",
259 .default_value = 0x28
261 .set_control = set_redblue
265 .id = V4L2_CID_HFLIP,
266 .type = V4L2_CTRL_TYPE_BOOLEAN,
267 .name = "Horizontal Flip",
273 .set_control = set_hvflip
277 .id = V4L2_CID_VFLIP,
278 .type = V4L2_CTRL_TYPE_BOOLEAN,
279 .name = "Vertical Flip",
285 .set_control = set_hvflip
289 .id = V4L2_CID_EXPOSURE,
290 .type = V4L2_CTRL_TYPE_INTEGER,
295 .default_value = 0x33,
297 .set_control = set_exposure
302 .type = V4L2_CTRL_TYPE_INTEGER,
309 .set_control = set_gain
313 .id = V4L2_CID_AUTOGAIN,
314 .type = V4L2_CTRL_TYPE_BOOLEAN,
315 .name = "Auto Exposure",
324 .id = V4L2_CID_JPEG_COMPRESSION_QUALITY,
325 .type = V4L2_CTRL_TYPE_INTEGER,
326 .name = "Compression Quality",
327 #define QUALITY_MIN 50
328 #define QUALITY_MAX 90
329 #define QUALITY_DEF 80
330 .minimum = QUALITY_MIN,
331 .maximum = QUALITY_MAX,
333 .default_value = QUALITY_DEF,
335 .set_control = set_quality
339 static const struct v4l2_pix_format vga_mode[] = {
340 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
342 .sizeimage = 160 * 120 * 4 / 8 + 590,
343 .colorspace = V4L2_COLORSPACE_JPEG,
344 .priv = SCALE_160x120 | MODE_JPEG},
345 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
347 .sizeimage = 160 * 120,
348 .colorspace = V4L2_COLORSPACE_SRGB,
349 .priv = SCALE_160x120 | MODE_RAW},
350 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
352 .sizeimage = 240 * 120,
353 .colorspace = V4L2_COLORSPACE_SRGB,
354 .priv = SCALE_160x120},
355 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
357 .sizeimage = 320 * 240 * 4 / 8 + 590,
358 .colorspace = V4L2_COLORSPACE_JPEG,
359 .priv = SCALE_320x240 | MODE_JPEG},
360 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
362 .sizeimage = 320 * 240 ,
363 .colorspace = V4L2_COLORSPACE_SRGB,
364 .priv = SCALE_320x240 | MODE_RAW},
365 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
367 .sizeimage = 480 * 240 ,
368 .colorspace = V4L2_COLORSPACE_SRGB,
369 .priv = SCALE_320x240},
370 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
372 .sizeimage = 640 * 480 * 4 / 8 + 590,
373 .colorspace = V4L2_COLORSPACE_JPEG,
374 .priv = SCALE_640x480 | MODE_JPEG},
375 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
377 .sizeimage = 640 * 480,
378 .colorspace = V4L2_COLORSPACE_SRGB,
379 .priv = SCALE_640x480 | MODE_RAW},
380 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
382 .sizeimage = 960 * 480,
383 .colorspace = V4L2_COLORSPACE_SRGB,
384 .priv = SCALE_640x480},
387 static const struct v4l2_pix_format sxga_mode[] = {
388 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
390 .sizeimage = 160 * 120 * 4 / 8 + 590,
391 .colorspace = V4L2_COLORSPACE_JPEG,
392 .priv = SCALE_160x120 | MODE_JPEG},
393 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
395 .sizeimage = 160 * 120,
396 .colorspace = V4L2_COLORSPACE_SRGB,
397 .priv = SCALE_160x120 | MODE_RAW},
398 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
400 .sizeimage = 240 * 120,
401 .colorspace = V4L2_COLORSPACE_SRGB,
402 .priv = SCALE_160x120},
403 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
405 .sizeimage = 320 * 240 * 4 / 8 + 590,
406 .colorspace = V4L2_COLORSPACE_JPEG,
407 .priv = SCALE_320x240 | MODE_JPEG},
408 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
410 .sizeimage = 320 * 240 ,
411 .colorspace = V4L2_COLORSPACE_SRGB,
412 .priv = SCALE_320x240 | MODE_RAW},
413 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
415 .sizeimage = 480 * 240 ,
416 .colorspace = V4L2_COLORSPACE_SRGB,
417 .priv = SCALE_320x240},
418 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
420 .sizeimage = 640 * 480 * 4 / 8 + 590,
421 .colorspace = V4L2_COLORSPACE_JPEG,
422 .priv = SCALE_640x480 | MODE_JPEG},
423 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
425 .sizeimage = 640 * 480,
426 .colorspace = V4L2_COLORSPACE_SRGB,
427 .priv = SCALE_640x480 | MODE_RAW},
428 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
430 .sizeimage = 960 * 480,
431 .colorspace = V4L2_COLORSPACE_SRGB,
432 .priv = SCALE_640x480},
433 {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
434 .bytesperline = 1280,
435 .sizeimage = 1280 * 1024,
436 .colorspace = V4L2_COLORSPACE_SRGB,
437 .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
440 static const struct v4l2_pix_format mono_mode[] = {
441 {160, 120, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
443 .sizeimage = 160 * 120,
444 .colorspace = V4L2_COLORSPACE_SRGB,
445 .priv = SCALE_160x120 | MODE_RAW},
446 {320, 240, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
448 .sizeimage = 320 * 240 ,
449 .colorspace = V4L2_COLORSPACE_SRGB,
450 .priv = SCALE_320x240 | MODE_RAW},
451 {640, 480, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
453 .sizeimage = 640 * 480,
454 .colorspace = V4L2_COLORSPACE_SRGB,
455 .priv = SCALE_640x480 | MODE_RAW},
456 {1280, 1024, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
457 .bytesperline = 1280,
458 .sizeimage = 1280 * 1024,
459 .colorspace = V4L2_COLORSPACE_SRGB,
460 .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
463 static const s16 hsv_red_x[] = {
464 41, 44, 46, 48, 50, 52, 54, 56,
465 58, 60, 62, 64, 66, 68, 70, 72,
466 74, 76, 78, 80, 81, 83, 85, 87,
467 88, 90, 92, 93, 95, 97, 98, 100,
468 101, 102, 104, 105, 107, 108, 109, 110,
469 112, 113, 114, 115, 116, 117, 118, 119,
470 120, 121, 122, 123, 123, 124, 125, 125,
471 126, 127, 127, 128, 128, 129, 129, 129,
472 130, 130, 130, 130, 131, 131, 131, 131,
473 131, 131, 131, 131, 130, 130, 130, 130,
474 129, 129, 129, 128, 128, 127, 127, 126,
475 125, 125, 124, 123, 122, 122, 121, 120,
476 119, 118, 117, 116, 115, 114, 112, 111,
477 110, 109, 107, 106, 105, 103, 102, 101,
478 99, 98, 96, 94, 93, 91, 90, 88,
479 86, 84, 83, 81, 79, 77, 75, 74,
480 72, 70, 68, 66, 64, 62, 60, 58,
481 56, 54, 52, 49, 47, 45, 43, 41,
482 39, 36, 34, 32, 30, 28, 25, 23,
483 21, 19, 16, 14, 12, 9, 7, 5,
484 3, 0, -1, -3, -6, -8, -10, -12,
485 -15, -17, -19, -22, -24, -26, -28, -30,
486 -33, -35, -37, -39, -41, -44, -46, -48,
487 -50, -52, -54, -56, -58, -60, -62, -64,
488 -66, -68, -70, -72, -74, -76, -78, -80,
489 -81, -83, -85, -87, -88, -90, -92, -93,
490 -95, -97, -98, -100, -101, -102, -104, -105,
491 -107, -108, -109, -110, -112, -113, -114, -115,
492 -116, -117, -118, -119, -120, -121, -122, -123,
493 -123, -124, -125, -125, -126, -127, -127, -128,
494 -128, -128, -128, -128, -128, -128, -128, -128,
495 -128, -128, -128, -128, -128, -128, -128, -128,
496 -128, -128, -128, -128, -128, -128, -128, -128,
497 -128, -127, -127, -126, -125, -125, -124, -123,
498 -122, -122, -121, -120, -119, -118, -117, -116,
499 -115, -114, -112, -111, -110, -109, -107, -106,
500 -105, -103, -102, -101, -99, -98, -96, -94,
501 -93, -91, -90, -88, -86, -84, -83, -81,
502 -79, -77, -75, -74, -72, -70, -68, -66,
503 -64, -62, -60, -58, -56, -54, -52, -49,
504 -47, -45, -43, -41, -39, -36, -34, -32,
505 -30, -28, -25, -23, -21, -19, -16, -14,
506 -12, -9, -7, -5, -3, 0, 1, 3,
507 6, 8, 10, 12, 15, 17, 19, 22,
508 24, 26, 28, 30, 33, 35, 37, 39, 41
511 static const s16 hsv_red_y[] = {
512 82, 80, 78, 76, 74, 73, 71, 69,
513 67, 65, 63, 61, 58, 56, 54, 52,
514 50, 48, 46, 44, 41, 39, 37, 35,
515 32, 30, 28, 26, 23, 21, 19, 16,
516 14, 12, 10, 7, 5, 3, 0, -1,
517 -3, -6, -8, -10, -13, -15, -17, -19,
518 -22, -24, -26, -29, -31, -33, -35, -38,
519 -40, -42, -44, -46, -48, -51, -53, -55,
520 -57, -59, -61, -63, -65, -67, -69, -71,
521 -73, -75, -77, -79, -81, -82, -84, -86,
522 -88, -89, -91, -93, -94, -96, -98, -99,
523 -101, -102, -104, -105, -106, -108, -109, -110,
524 -112, -113, -114, -115, -116, -117, -119, -120,
525 -120, -121, -122, -123, -124, -125, -126, -126,
526 -127, -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 -128, -128, -128, -128, -128, -128, -128, -128,
530 -127, -127, -126, -125, -125, -124, -123, -122,
531 -121, -120, -119, -118, -117, -116, -115, -114,
532 -113, -111, -110, -109, -107, -106, -105, -103,
533 -102, -100, -99, -97, -96, -94, -92, -91,
534 -89, -87, -85, -84, -82, -80, -78, -76,
535 -74, -73, -71, -69, -67, -65, -63, -61,
536 -58, -56, -54, -52, -50, -48, -46, -44,
537 -41, -39, -37, -35, -32, -30, -28, -26,
538 -23, -21, -19, -16, -14, -12, -10, -7,
539 -5, -3, 0, 1, 3, 6, 8, 10,
540 13, 15, 17, 19, 22, 24, 26, 29,
541 31, 33, 35, 38, 40, 42, 44, 46,
542 48, 51, 53, 55, 57, 59, 61, 63,
543 65, 67, 69, 71, 73, 75, 77, 79,
544 81, 82, 84, 86, 88, 89, 91, 93,
545 94, 96, 98, 99, 101, 102, 104, 105,
546 106, 108, 109, 110, 112, 113, 114, 115,
547 116, 117, 119, 120, 120, 121, 122, 123,
548 124, 125, 126, 126, 127, 128, 128, 129,
549 129, 130, 130, 131, 131, 131, 131, 132,
550 132, 132, 132, 132, 132, 132, 132, 132,
551 132, 132, 132, 131, 131, 131, 130, 130,
552 130, 129, 129, 128, 127, 127, 126, 125,
553 125, 124, 123, 122, 121, 120, 119, 118,
554 117, 116, 115, 114, 113, 111, 110, 109,
555 107, 106, 105, 103, 102, 100, 99, 97,
556 96, 94, 92, 91, 89, 87, 85, 84, 82
559 static const s16 hsv_green_x[] = {
560 -124, -124, -125, -125, -125, -125, -125, -125,
561 -125, -126, -126, -125, -125, -125, -125, -125,
562 -125, -124, -124, -124, -123, -123, -122, -122,
563 -121, -121, -120, -120, -119, -118, -117, -117,
564 -116, -115, -114, -113, -112, -111, -110, -109,
565 -108, -107, -105, -104, -103, -102, -100, -99,
566 -98, -96, -95, -93, -92, -91, -89, -87,
567 -86, -84, -83, -81, -79, -77, -76, -74,
568 -72, -70, -69, -67, -65, -63, -61, -59,
569 -57, -55, -53, -51, -49, -47, -45, -43,
570 -41, -39, -37, -35, -33, -30, -28, -26,
571 -24, -22, -20, -18, -15, -13, -11, -9,
572 -7, -4, -2, 0, 1, 3, 6, 8,
573 10, 12, 14, 17, 19, 21, 23, 25,
574 27, 29, 32, 34, 36, 38, 40, 42,
575 44, 46, 48, 50, 52, 54, 56, 58,
576 60, 62, 64, 66, 68, 70, 71, 73,
577 75, 77, 78, 80, 82, 83, 85, 87,
578 88, 90, 91, 93, 94, 96, 97, 98,
579 100, 101, 102, 104, 105, 106, 107, 108,
580 109, 111, 112, 113, 113, 114, 115, 116,
581 117, 118, 118, 119, 120, 120, 121, 122,
582 122, 123, 123, 124, 124, 124, 125, 125,
583 125, 125, 125, 125, 125, 126, 126, 125,
584 125, 125, 125, 125, 125, 124, 124, 124,
585 123, 123, 122, 122, 121, 121, 120, 120,
586 119, 118, 117, 117, 116, 115, 114, 113,
587 112, 111, 110, 109, 108, 107, 105, 104,
588 103, 102, 100, 99, 98, 96, 95, 93,
589 92, 91, 89, 87, 86, 84, 83, 81,
590 79, 77, 76, 74, 72, 70, 69, 67,
591 65, 63, 61, 59, 57, 55, 53, 51,
592 49, 47, 45, 43, 41, 39, 37, 35,
593 33, 30, 28, 26, 24, 22, 20, 18,
594 15, 13, 11, 9, 7, 4, 2, 0,
595 -1, -3, -6, -8, -10, -12, -14, -17,
596 -19, -21, -23, -25, -27, -29, -32, -34,
597 -36, -38, -40, -42, -44, -46, -48, -50,
598 -52, -54, -56, -58, -60, -62, -64, -66,
599 -68, -70, -71, -73, -75, -77, -78, -80,
600 -82, -83, -85, -87, -88, -90, -91, -93,
601 -94, -96, -97, -98, -100, -101, -102, -104,
602 -105, -106, -107, -108, -109, -111, -112, -113,
603 -113, -114, -115, -116, -117, -118, -118, -119,
604 -120, -120, -121, -122, -122, -123, -123, -124, -124
607 static const s16 hsv_green_y[] = {
608 -100, -99, -98, -97, -95, -94, -93, -91,
609 -90, -89, -87, -86, -84, -83, -81, -80,
610 -78, -76, -75, -73, -71, -70, -68, -66,
611 -64, -63, -61, -59, -57, -55, -53, -51,
612 -49, -48, -46, -44, -42, -40, -38, -36,
613 -34, -32, -30, -27, -25, -23, -21, -19,
614 -17, -15, -13, -11, -9, -7, -4, -2,
615 0, 1, 3, 5, 7, 9, 11, 14,
616 16, 18, 20, 22, 24, 26, 28, 30,
617 32, 34, 36, 38, 40, 42, 44, 46,
618 48, 50, 52, 54, 56, 58, 59, 61,
619 63, 65, 67, 68, 70, 72, 74, 75,
620 77, 78, 80, 82, 83, 85, 86, 88,
621 89, 90, 92, 93, 95, 96, 97, 98,
622 100, 101, 102, 103, 104, 105, 106, 107,
623 108, 109, 110, 111, 112, 112, 113, 114,
624 115, 115, 116, 116, 117, 117, 118, 118,
625 119, 119, 119, 120, 120, 120, 120, 120,
626 121, 121, 121, 121, 121, 121, 120, 120,
627 120, 120, 120, 119, 119, 119, 118, 118,
628 117, 117, 116, 116, 115, 114, 114, 113,
629 112, 111, 111, 110, 109, 108, 107, 106,
630 105, 104, 103, 102, 100, 99, 98, 97,
631 95, 94, 93, 91, 90, 89, 87, 86,
632 84, 83, 81, 80, 78, 76, 75, 73,
633 71, 70, 68, 66, 64, 63, 61, 59,
634 57, 55, 53, 51, 49, 48, 46, 44,
635 42, 40, 38, 36, 34, 32, 30, 27,
636 25, 23, 21, 19, 17, 15, 13, 11,
637 9, 7, 4, 2, 0, -1, -3, -5,
638 -7, -9, -11, -14, -16, -18, -20, -22,
639 -24, -26, -28, -30, -32, -34, -36, -38,
640 -40, -42, -44, -46, -48, -50, -52, -54,
641 -56, -58, -59, -61, -63, -65, -67, -68,
642 -70, -72, -74, -75, -77, -78, -80, -82,
643 -83, -85, -86, -88, -89, -90, -92, -93,
644 -95, -96, -97, -98, -100, -101, -102, -103,
645 -104, -105, -106, -107, -108, -109, -110, -111,
646 -112, -112, -113, -114, -115, -115, -116, -116,
647 -117, -117, -118, -118, -119, -119, -119, -120,
648 -120, -120, -120, -120, -121, -121, -121, -121,
649 -121, -121, -120, -120, -120, -120, -120, -119,
650 -119, -119, -118, -118, -117, -117, -116, -116,
651 -115, -114, -114, -113, -112, -111, -111, -110,
652 -109, -108, -107, -106, -105, -104, -103, -102, -100
655 static const s16 hsv_blue_x[] = {
656 112, 113, 114, 114, 115, 116, 117, 117,
657 118, 118, 119, 119, 120, 120, 120, 121,
658 121, 121, 122, 122, 122, 122, 122, 122,
659 122, 122, 122, 122, 122, 122, 121, 121,
660 121, 120, 120, 120, 119, 119, 118, 118,
661 117, 116, 116, 115, 114, 113, 113, 112,
662 111, 110, 109, 108, 107, 106, 105, 104,
663 103, 102, 100, 99, 98, 97, 95, 94,
664 93, 91, 90, 88, 87, 85, 84, 82,
665 80, 79, 77, 76, 74, 72, 70, 69,
666 67, 65, 63, 61, 60, 58, 56, 54,
667 52, 50, 48, 46, 44, 42, 40, 38,
668 36, 34, 32, 30, 28, 26, 24, 22,
669 19, 17, 15, 13, 11, 9, 7, 5,
670 2, 0, -1, -3, -5, -7, -9, -12,
671 -14, -16, -18, -20, -22, -24, -26, -28,
672 -31, -33, -35, -37, -39, -41, -43, -45,
673 -47, -49, -51, -53, -54, -56, -58, -60,
674 -62, -64, -66, -67, -69, -71, -73, -74,
675 -76, -78, -79, -81, -83, -84, -86, -87,
676 -89, -90, -92, -93, -94, -96, -97, -98,
677 -99, -101, -102, -103, -104, -105, -106, -107,
678 -108, -109, -110, -111, -112, -113, -114, -114,
679 -115, -116, -117, -117, -118, -118, -119, -119,
680 -120, -120, -120, -121, -121, -121, -122, -122,
681 -122, -122, -122, -122, -122, -122, -122, -122,
682 -122, -122, -121, -121, -121, -120, -120, -120,
683 -119, -119, -118, -118, -117, -116, -116, -115,
684 -114, -113, -113, -112, -111, -110, -109, -108,
685 -107, -106, -105, -104, -103, -102, -100, -99,
686 -98, -97, -95, -94, -93, -91, -90, -88,
687 -87, -85, -84, -82, -80, -79, -77, -76,
688 -74, -72, -70, -69, -67, -65, -63, -61,
689 -60, -58, -56, -54, -52, -50, -48, -46,
690 -44, -42, -40, -38, -36, -34, -32, -30,
691 -28, -26, -24, -22, -19, -17, -15, -13,
692 -11, -9, -7, -5, -2, 0, 1, 3,
693 5, 7, 9, 12, 14, 16, 18, 20,
694 22, 24, 26, 28, 31, 33, 35, 37,
695 39, 41, 43, 45, 47, 49, 51, 53,
696 54, 56, 58, 60, 62, 64, 66, 67,
697 69, 71, 73, 74, 76, 78, 79, 81,
698 83, 84, 86, 87, 89, 90, 92, 93,
699 94, 96, 97, 98, 99, 101, 102, 103,
700 104, 105, 106, 107, 108, 109, 110, 111, 112
703 static const s16 hsv_blue_y[] = {
704 -11, -13, -15, -17, -19, -21, -23, -25,
705 -27, -29, -31, -33, -35, -37, -39, -41,
706 -43, -45, -46, -48, -50, -52, -54, -55,
707 -57, -59, -61, -62, -64, -66, -67, -69,
708 -71, -72, -74, -75, -77, -78, -80, -81,
709 -83, -84, -86, -87, -88, -90, -91, -92,
710 -93, -95, -96, -97, -98, -99, -100, -101,
711 -102, -103, -104, -105, -106, -106, -107, -108,
712 -109, -109, -110, -111, -111, -112, -112, -113,
713 -113, -114, -114, -114, -115, -115, -115, -115,
714 -116, -116, -116, -116, -116, -116, -116, -116,
715 -116, -115, -115, -115, -115, -114, -114, -114,
716 -113, -113, -112, -112, -111, -111, -110, -110,
717 -109, -108, -108, -107, -106, -105, -104, -103,
718 -102, -101, -100, -99, -98, -97, -96, -95,
719 -94, -93, -91, -90, -89, -88, -86, -85,
720 -84, -82, -81, -79, -78, -76, -75, -73,
721 -71, -70, -68, -67, -65, -63, -62, -60,
722 -58, -56, -55, -53, -51, -49, -47, -45,
723 -44, -42, -40, -38, -36, -34, -32, -30,
724 -28, -26, -24, -22, -20, -18, -16, -14,
725 -12, -10, -8, -6, -4, -2, 0, 1,
726 3, 5, 7, 9, 11, 13, 15, 17,
727 19, 21, 23, 25, 27, 29, 31, 33,
728 35, 37, 39, 41, 43, 45, 46, 48,
729 50, 52, 54, 55, 57, 59, 61, 62,
730 64, 66, 67, 69, 71, 72, 74, 75,
731 77, 78, 80, 81, 83, 84, 86, 87,
732 88, 90, 91, 92, 93, 95, 96, 97,
733 98, 99, 100, 101, 102, 103, 104, 105,
734 106, 106, 107, 108, 109, 109, 110, 111,
735 111, 112, 112, 113, 113, 114, 114, 114,
736 115, 115, 115, 115, 116, 116, 116, 116,
737 116, 116, 116, 116, 116, 115, 115, 115,
738 115, 114, 114, 114, 113, 113, 112, 112,
739 111, 111, 110, 110, 109, 108, 108, 107,
740 106, 105, 104, 103, 102, 101, 100, 99,
741 98, 97, 96, 95, 94, 93, 91, 90,
742 89, 88, 86, 85, 84, 82, 81, 79,
743 78, 76, 75, 73, 71, 70, 68, 67,
744 65, 63, 62, 60, 58, 56, 55, 53,
745 51, 49, 47, 45, 44, 42, 40, 38,
746 36, 34, 32, 30, 28, 26, 24, 22,
747 20, 18, 16, 14, 12, 10, 8, 6,
748 4, 2, 0, -1, -3, -5, -7, -9, -11
751 static const u16 i2c_ident[] = {
760 V4L2_IDENT_MT9M001C12ST,
764 [SENSOR_MT9VPRB] = V4L2_IDENT_UNKNOWN,
767 static const u16 bridge_init[][2] = {
768 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
769 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
770 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
771 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
772 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
773 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
774 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
775 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
776 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
777 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
778 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
779 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
780 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
781 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
782 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
783 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
784 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
785 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
786 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
790 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
791 static const u8 ov_gain[] = {
792 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
793 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
794 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
795 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
796 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
797 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
798 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
802 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
803 static const u16 micron1_gain[] = {
804 /* 1x 1.25x 1.5x 1.75x */
805 0x0020, 0x0028, 0x0030, 0x0038,
806 /* 2x 2.25x 2.5x 2.75x */
807 0x00a0, 0x00a4, 0x00a8, 0x00ac,
808 /* 3x 3.25x 3.5x 3.75x */
809 0x00b0, 0x00b4, 0x00b8, 0x00bc,
810 /* 4x 4.25x 4.5x 4.75x */
811 0x00c0, 0x00c4, 0x00c8, 0x00cc,
812 /* 5x 5.25x 5.5x 5.75x */
813 0x00d0, 0x00d4, 0x00d8, 0x00dc,
814 /* 6x 6.25x 6.5x 6.75x */
815 0x00e0, 0x00e4, 0x00e8, 0x00ec,
816 /* 7x 7.25x 7.5x 7.75x */
817 0x00f0, 0x00f4, 0x00f8, 0x00fc,
822 /* mt9m001 sensor uses a different gain formula then other micron sensors */
823 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
824 static const u16 micron2_gain[] = {
825 /* 1x 1.25x 1.5x 1.75x */
826 0x0008, 0x000a, 0x000c, 0x000e,
827 /* 2x 2.25x 2.5x 2.75x */
828 0x0010, 0x0012, 0x0014, 0x0016,
829 /* 3x 3.25x 3.5x 3.75x */
830 0x0018, 0x001a, 0x001c, 0x001e,
831 /* 4x 4.25x 4.5x 4.75x */
832 0x0020, 0x0051, 0x0052, 0x0053,
833 /* 5x 5.25x 5.5x 5.75x */
834 0x0054, 0x0055, 0x0056, 0x0057,
835 /* 6x 6.25x 6.5x 6.75x */
836 0x0058, 0x0059, 0x005a, 0x005b,
837 /* 7x 7.25x 7.5x 7.75x */
838 0x005c, 0x005d, 0x005e, 0x005f,
843 /* Gain = .5 + bit[7:0] / 16 */
844 static const u8 hv7131r_gain[] = {
845 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
846 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
847 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
848 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
849 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
850 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
851 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
855 static const struct i2c_reg_u8 soi968_init[] = {
856 {0x0c, 0x00}, {0x0f, 0x1f},
857 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
858 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
859 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
860 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
861 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
862 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
863 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
864 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
865 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
866 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
869 static const struct i2c_reg_u8 ov7660_init[] = {
870 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
871 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
872 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
873 /* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using
874 0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
875 {0x17, 0x10}, {0x18, 0x61},
876 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
877 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0x00},
878 {0x2e, 0x00}, {0x01, 0x78}, {0x02, 0x50},
881 static const struct i2c_reg_u8 ov7670_init[] = {
882 {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
883 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
884 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
885 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
886 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
887 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
888 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
889 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
890 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
891 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
892 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
893 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
894 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
895 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
896 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
897 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
898 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
899 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
900 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
901 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
902 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
903 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
904 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
905 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
906 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
907 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
908 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
909 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
910 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
911 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
912 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
913 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
914 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
915 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
916 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
917 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
918 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
919 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
920 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
921 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
922 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
923 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
924 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
925 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
926 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
927 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
928 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
929 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
930 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
931 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
932 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
933 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
934 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
938 static const struct i2c_reg_u8 ov9650_init[] = {
939 {0x00, 0x00}, {0x01, 0x78},
940 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
941 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
942 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
943 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
944 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
945 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
946 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
947 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
948 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
949 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
950 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
951 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
952 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
953 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
954 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
955 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
956 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
957 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
958 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
959 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
960 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
961 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
962 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
963 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
964 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
965 {0xaa, 0x92}, {0xab, 0x0a},
968 static const struct i2c_reg_u8 ov9655_init[] = {
969 {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
970 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
971 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
972 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
973 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
974 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
975 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
976 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
977 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
978 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
979 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
980 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
981 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
982 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
983 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
984 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
985 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
986 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
987 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
988 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
989 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
990 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
991 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
992 {0x04, 0x03}, {0x00, 0x13},
995 static const struct i2c_reg_u16 mt9v112_init[] = {
996 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
997 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
998 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
999 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
1000 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
1001 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
1002 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
1003 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
1004 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
1005 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
1006 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
1007 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1008 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
1009 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
1010 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
1011 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
1014 static const struct i2c_reg_u16 mt9v111_init[] = {
1015 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
1016 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
1017 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
1018 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
1019 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
1020 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
1021 {0x0e, 0x0008}, {0x20, 0x0000}
1024 static const struct i2c_reg_u16 mt9v011_init[] = {
1025 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
1026 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
1027 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
1028 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
1029 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
1030 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
1031 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
1032 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
1033 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
1034 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
1035 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
1036 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
1037 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
1038 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
1039 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
1040 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
1041 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
1042 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
1043 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
1044 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
1045 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
1046 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1047 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
1048 {0x06, 0x0029}, {0x05, 0x0009},
1051 static const struct i2c_reg_u16 mt9m001_init[] = {
1054 {0x04, 0x0500}, /* hres = 1280 */
1055 {0x03, 0x0400}, /* vres = 1024 */
1067 static const struct i2c_reg_u16 mt9m111_init[] = {
1068 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1069 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1070 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1074 static const struct i2c_reg_u16 mt9m112_init[] = {
1075 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1076 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1077 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1081 static const struct i2c_reg_u8 hv7131r_init[] = {
1082 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
1083 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
1084 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
1085 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
1086 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
1087 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
1088 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
1089 {0x23, 0x09}, {0x01, 0x08},
1092 static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
1094 struct usb_device *dev = gspca_dev->dev;
1097 if (gspca_dev->usb_err < 0)
1099 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
1101 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1107 if (unlikely(result < 0 || result != length)) {
1108 pr_err("Read register %02x failed %d\n", reg, result);
1109 gspca_dev->usb_err = result;
1113 static void reg_w(struct gspca_dev *gspca_dev, u16 reg,
1114 const u8 *buffer, int length)
1116 struct usb_device *dev = gspca_dev->dev;
1119 if (gspca_dev->usb_err < 0)
1121 memcpy(gspca_dev->usb_buf, buffer, length);
1122 result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1124 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1130 if (unlikely(result < 0 || result != length)) {
1131 pr_err("Write register %02x failed %d\n", reg, result);
1132 gspca_dev->usb_err = result;
1136 static void reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
1138 reg_w(gspca_dev, reg, &value, 1);
1141 static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
1145 reg_w(gspca_dev, 0x10c0, buffer, 8);
1146 for (i = 0; i < 5; i++) {
1147 reg_r(gspca_dev, 0x10c0, 1);
1148 if (gspca_dev->usb_err < 0)
1150 if (gspca_dev->usb_buf[0] & 0x04) {
1151 if (gspca_dev->usb_buf[0] & 0x08) {
1152 pr_err("i2c_w error\n");
1153 gspca_dev->usb_err = -EIO;
1159 pr_err("i2c_w reg %02x no response\n", buffer[2]);
1160 /* gspca_dev->usb_err = -EIO; fixme: may occur */
1163 static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1165 struct sd *sd = (struct sd *) gspca_dev;
1169 * from the point of view of the bridge, the length
1170 * includes the address
1172 row[0] = sd->i2c_intf | (2 << 4);
1173 row[1] = sd->i2c_addr;
1181 i2c_w(gspca_dev, row);
1184 static void i2c_w1_buf(struct gspca_dev *gspca_dev,
1185 const struct i2c_reg_u8 *buf, int sz)
1188 i2c_w1(gspca_dev, buf->reg, buf->val);
1193 static void i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1195 struct sd *sd = (struct sd *) gspca_dev;
1199 * from the point of view of the bridge, the length
1200 * includes the address
1202 row[0] = sd->i2c_intf | (3 << 4);
1203 row[1] = sd->i2c_addr;
1211 i2c_w(gspca_dev, row);
1214 static void i2c_w2_buf(struct gspca_dev *gspca_dev,
1215 const struct i2c_reg_u16 *buf, int sz)
1218 i2c_w2(gspca_dev, buf->reg, buf->val);
1223 static void i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1225 struct sd *sd = (struct sd *) gspca_dev;
1228 row[0] = sd->i2c_intf | (1 << 4);
1229 row[1] = sd->i2c_addr;
1236 i2c_w(gspca_dev, row);
1237 row[0] = sd->i2c_intf | (1 << 4) | 0x02;
1239 i2c_w(gspca_dev, row);
1240 reg_r(gspca_dev, 0x10c2, 5);
1241 *val = gspca_dev->usb_buf[4];
1244 static void i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1246 struct sd *sd = (struct sd *) gspca_dev;
1249 row[0] = sd->i2c_intf | (1 << 4);
1250 row[1] = sd->i2c_addr;
1257 i2c_w(gspca_dev, row);
1258 row[0] = sd->i2c_intf | (2 << 4) | 0x02;
1260 i2c_w(gspca_dev, row);
1261 reg_r(gspca_dev, 0x10c2, 5);
1262 *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1265 static void ov9650_init_sensor(struct gspca_dev *gspca_dev)
1268 struct sd *sd = (struct sd *) gspca_dev;
1270 i2c_r2(gspca_dev, 0x1c, &id);
1271 if (gspca_dev->usb_err < 0)
1275 pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id);
1276 gspca_dev->usb_err = -ENODEV;
1280 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1282 i2c_w1_buf(gspca_dev, ov9650_init, ARRAY_SIZE(ov9650_init));
1283 if (gspca_dev->usb_err < 0)
1284 pr_err("OV9650 sensor initialization failed\n");
1289 static void ov9655_init_sensor(struct gspca_dev *gspca_dev)
1291 struct sd *sd = (struct sd *) gspca_dev;
1293 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1295 i2c_w1_buf(gspca_dev, ov9655_init, ARRAY_SIZE(ov9655_init));
1296 if (gspca_dev->usb_err < 0)
1297 pr_err("OV9655 sensor initialization failed\n");
1299 /* disable hflip and vflip */
1300 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
1305 static void soi968_init_sensor(struct gspca_dev *gspca_dev)
1307 struct sd *sd = (struct sd *) gspca_dev;
1309 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1311 i2c_w1_buf(gspca_dev, soi968_init, ARRAY_SIZE(soi968_init));
1312 if (gspca_dev->usb_err < 0)
1313 pr_err("SOI968 sensor initialization failed\n");
1315 /* disable hflip and vflip */
1316 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP)
1322 static void ov7660_init_sensor(struct gspca_dev *gspca_dev)
1324 struct sd *sd = (struct sd *) gspca_dev;
1326 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1328 i2c_w1_buf(gspca_dev, ov7660_init, ARRAY_SIZE(ov7660_init));
1329 if (gspca_dev->usb_err < 0)
1330 pr_err("OV7660 sensor initialization failed\n");
1335 static void ov7670_init_sensor(struct gspca_dev *gspca_dev)
1337 struct sd *sd = (struct sd *) gspca_dev;
1339 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1341 i2c_w1_buf(gspca_dev, ov7670_init, ARRAY_SIZE(ov7670_init));
1342 if (gspca_dev->usb_err < 0)
1343 pr_err("OV7670 sensor initialization failed\n");
1345 /* disable hflip and vflip */
1346 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
1351 static void mt9v_init_sensor(struct gspca_dev *gspca_dev)
1353 struct sd *sd = (struct sd *) gspca_dev;
1356 sd->i2c_addr = 0x5d;
1357 i2c_r2(gspca_dev, 0xff, &value);
1358 if (gspca_dev->usb_err >= 0
1359 && value == 0x8243) {
1360 i2c_w2_buf(gspca_dev, mt9v011_init, ARRAY_SIZE(mt9v011_init));
1361 if (gspca_dev->usb_err < 0) {
1362 pr_err("MT9V011 sensor initialization failed\n");
1367 sd->sensor = SENSOR_MT9V011;
1368 pr_info("MT9V011 sensor detected\n");
1372 gspca_dev->usb_err = 0;
1373 sd->i2c_addr = 0x5c;
1374 i2c_w2(gspca_dev, 0x01, 0x0004);
1375 i2c_r2(gspca_dev, 0xff, &value);
1376 if (gspca_dev->usb_err >= 0
1377 && value == 0x823a) {
1378 i2c_w2_buf(gspca_dev, mt9v111_init, ARRAY_SIZE(mt9v111_init));
1379 if (gspca_dev->usb_err < 0) {
1380 pr_err("MT9V111 sensor initialization failed\n");
1383 gspca_dev->ctrl_dis = (1 << EXPOSURE)
1388 sd->sensor = SENSOR_MT9V111;
1389 pr_info("MT9V111 sensor detected\n");
1393 gspca_dev->usb_err = 0;
1394 sd->i2c_addr = 0x5d;
1395 i2c_w2(gspca_dev, 0xf0, 0x0000);
1396 if (gspca_dev->usb_err < 0) {
1397 gspca_dev->usb_err = 0;
1398 sd->i2c_addr = 0x48;
1399 i2c_w2(gspca_dev, 0xf0, 0x0000);
1401 i2c_r2(gspca_dev, 0x00, &value);
1402 if (gspca_dev->usb_err >= 0
1403 && value == 0x1229) {
1404 i2c_w2_buf(gspca_dev, mt9v112_init, ARRAY_SIZE(mt9v112_init));
1405 if (gspca_dev->usb_err < 0) {
1406 pr_err("MT9V112 sensor initialization failed\n");
1411 sd->sensor = SENSOR_MT9V112;
1412 pr_info("MT9V112 sensor detected\n");
1416 gspca_dev->usb_err = -ENODEV;
1419 static void mt9m112_init_sensor(struct gspca_dev *gspca_dev)
1421 struct sd *sd = (struct sd *) gspca_dev;
1423 i2c_w2_buf(gspca_dev, mt9m112_init, ARRAY_SIZE(mt9m112_init));
1424 if (gspca_dev->usb_err < 0)
1425 pr_err("MT9M112 sensor initialization failed\n");
1427 gspca_dev->ctrl_dis = (1 << EXPOSURE) | (1 << AUTOGAIN)
1433 static void mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1435 struct sd *sd = (struct sd *) gspca_dev;
1437 i2c_w2_buf(gspca_dev, mt9m111_init, ARRAY_SIZE(mt9m111_init));
1438 if (gspca_dev->usb_err < 0)
1439 pr_err("MT9M111 sensor initialization failed\n");
1441 gspca_dev->ctrl_dis = (1 << EXPOSURE) | (1 << AUTOGAIN)
1447 static void mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1449 struct sd *sd = (struct sd *) gspca_dev;
1452 i2c_r2(gspca_dev, 0x00, &id);
1453 if (gspca_dev->usb_err < 0)
1456 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
1460 pr_info("MT9M001 color sensor detected\n");
1463 pr_info("MT9M001 mono sensor detected\n");
1466 pr_err("No MT9M001 chip detected, ID = %x\n\n", id);
1467 gspca_dev->usb_err = -ENODEV;
1471 i2c_w2_buf(gspca_dev, mt9m001_init, ARRAY_SIZE(mt9m001_init));
1472 if (gspca_dev->usb_err < 0)
1473 pr_err("MT9M001 sensor initialization failed\n");
1475 /* disable hflip and vflip */
1476 gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
1481 static void hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1483 struct sd *sd = (struct sd *) gspca_dev;
1485 i2c_w1_buf(gspca_dev, hv7131r_init, ARRAY_SIZE(hv7131r_init));
1486 if (gspca_dev->usb_err < 0)
1487 pr_err("HV7131R Sensor initialization failed\n");
1493 static void set_cmatrix(struct gspca_dev *gspca_dev)
1495 struct sd *sd = (struct sd *) gspca_dev;
1497 s32 hue_coord, hue_index = 180 + sd->ctrls[HUE].val;
1500 memset(cmatrix, 0, sizeof cmatrix);
1501 cmatrix[2] = (sd->ctrls[CONTRAST].val * 0x25 / 0x100) + 0x26;
1502 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1503 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1504 cmatrix[18] = sd->ctrls[BRIGHTNESS].val - 0x80;
1506 satur = sd->ctrls[SATURATION].val;
1507 hue_coord = (hsv_red_x[hue_index] * satur) >> 8;
1508 cmatrix[6] = hue_coord;
1509 cmatrix[7] = (hue_coord >> 8) & 0x0f;
1511 hue_coord = (hsv_red_y[hue_index] * satur) >> 8;
1512 cmatrix[8] = hue_coord;
1513 cmatrix[9] = (hue_coord >> 8) & 0x0f;
1515 hue_coord = (hsv_green_x[hue_index] * satur) >> 8;
1516 cmatrix[10] = hue_coord;
1517 cmatrix[11] = (hue_coord >> 8) & 0x0f;
1519 hue_coord = (hsv_green_y[hue_index] * satur) >> 8;
1520 cmatrix[12] = hue_coord;
1521 cmatrix[13] = (hue_coord >> 8) & 0x0f;
1523 hue_coord = (hsv_blue_x[hue_index] * satur) >> 8;
1524 cmatrix[14] = hue_coord;
1525 cmatrix[15] = (hue_coord >> 8) & 0x0f;
1527 hue_coord = (hsv_blue_y[hue_index] * satur) >> 8;
1528 cmatrix[16] = hue_coord;
1529 cmatrix[17] = (hue_coord >> 8) & 0x0f;
1531 reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1534 static void set_gamma(struct gspca_dev *gspca_dev)
1536 struct sd *sd = (struct sd *) gspca_dev;
1538 u8 gval = sd->ctrls[GAMMA].val * 0xb8 / 0x100;
1541 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
1542 gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8);
1543 gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8);
1544 gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8);
1545 gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8);
1546 gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8);
1547 gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8);
1548 gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8);
1549 gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8);
1550 gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8);
1551 gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8);
1552 gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8);
1553 gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8);
1554 gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8);
1555 gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
1558 reg_w(gspca_dev, 0x1190, gamma, 17);
1561 static void set_redblue(struct gspca_dev *gspca_dev)
1563 struct sd *sd = (struct sd *) gspca_dev;
1565 reg_w1(gspca_dev, 0x118c, sd->ctrls[RED].val);
1566 reg_w1(gspca_dev, 0x118f, sd->ctrls[BLUE].val);
1569 static void set_hvflip(struct gspca_dev *gspca_dev)
1571 u8 value, tslb, hflip, vflip;
1573 struct sd *sd = (struct sd *) gspca_dev;
1575 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1576 hflip = !sd->ctrls[HFLIP].val;
1577 vflip = !sd->ctrls[VFLIP].val;
1579 hflip = sd->ctrls[HFLIP].val;
1580 vflip = sd->ctrls[VFLIP].val;
1583 switch (sd->sensor) {
1594 reg_w1(gspca_dev, 0x1182, sd->vstart);
1595 i2c_w1(gspca_dev, 0x1e, value);
1598 i2c_r1(gspca_dev, 0x1e, &value);
1607 i2c_w1(gspca_dev, 0x1e, value);
1608 i2c_w1(gspca_dev, 0x3a, tslb);
1610 case SENSOR_MT9V111:
1611 case SENSOR_MT9V011:
1612 i2c_r2(gspca_dev, 0x20, &value2);
1618 i2c_w2(gspca_dev, 0x20, value2);
1620 case SENSOR_MT9M112:
1621 case SENSOR_MT9M111:
1622 case SENSOR_MT9V112:
1623 i2c_r2(gspca_dev, 0x20, &value2);
1629 i2c_w2(gspca_dev, 0x20, value2);
1631 case SENSOR_HV7131R:
1632 i2c_r1(gspca_dev, 0x01, &value);
1638 i2c_w1(gspca_dev, 0x01, value);
1643 static void set_exposure(struct gspca_dev *gspca_dev)
1645 struct sd *sd = (struct sd *) gspca_dev;
1646 u8 exp[8] = {sd->i2c_intf, sd->i2c_addr,
1647 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1650 if (gspca_dev->streaming)
1653 expo = sd->ctrls[EXPOSURE].val;
1654 switch (sd->sensor) {
1664 exp[2] = 0x10; /* AECH */
1665 exp[3] = expo2 >> 2;
1667 i2c_w(gspca_dev, exp);
1668 exp[2] = 0x04; /* COM1 */
1669 exp[3] = expo2 & 0x0003;
1671 i2c_w(gspca_dev, exp);
1675 exp[2] = 0x2d; /* ADVFL & ADVFH */
1679 case SENSOR_MT9M001:
1680 case SENSOR_MT9V112:
1681 case SENSOR_MT9V011:
1687 case SENSOR_HV7131R:
1697 i2c_w(gspca_dev, exp);
1700 static void set_gain(struct gspca_dev *gspca_dev)
1702 struct sd *sd = (struct sd *) gspca_dev;
1703 u8 gain[8] = {sd->i2c_intf, sd->i2c_addr,
1704 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1707 if (gspca_dev->streaming)
1708 gain[7] = 0x15; /* or 1d ? */
1710 g = sd->ctrls[GAIN].val;
1711 switch (sd->sensor) {
1717 gain[0] |= (2 << 4);
1718 gain[3] = ov_gain[g];
1720 case SENSOR_MT9V011:
1721 gain[0] |= (3 << 4);
1723 gain[3] = micron1_gain[g] >> 8;
1724 gain[4] = micron1_gain[g];
1726 case SENSOR_MT9V112:
1727 gain[0] |= (3 << 4);
1729 gain[3] = micron1_gain[g] >> 8;
1730 gain[4] = micron1_gain[g];
1732 case SENSOR_MT9M001:
1733 gain[0] |= (3 << 4);
1735 gain[3] = micron2_gain[g] >> 8;
1736 gain[4] = micron2_gain[g];
1738 case SENSOR_HV7131R:
1739 gain[0] |= (2 << 4);
1741 gain[3] = hv7131r_gain[g];
1746 i2c_w(gspca_dev, gain);
1749 static void set_quality(struct gspca_dev *gspca_dev)
1751 struct sd *sd = (struct sd *) gspca_dev;
1753 jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val);
1754 reg_w1(gspca_dev, 0x1061, 0x01); /* stop transfer */
1755 reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20); /* write QTAB */
1756 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
1757 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
1758 reg_w1(gspca_dev, 0x1061, 0x03); /* restart transfer */
1759 reg_w1(gspca_dev, 0x10e0, sd->fmt);
1760 sd->fmt ^= 0x0c; /* invert QTAB use + write */
1761 reg_w1(gspca_dev, 0x10e0, sd->fmt);
1764 #ifdef CONFIG_VIDEO_ADV_DEBUG
1765 static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1766 struct v4l2_dbg_register *reg)
1768 struct sd *sd = (struct sd *) gspca_dev;
1770 switch (reg->match.type) {
1771 case V4L2_CHIP_MATCH_HOST:
1772 if (reg->match.addr != 0)
1774 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1776 reg_r(gspca_dev, reg->reg, 1);
1777 reg->val = gspca_dev->usb_buf[0];
1778 return gspca_dev->usb_err;
1779 case V4L2_CHIP_MATCH_I2C_ADDR:
1780 if (reg->match.addr != sd->i2c_addr)
1782 if (sd->sensor >= SENSOR_MT9V011 &&
1783 sd->sensor <= SENSOR_MT9M112) {
1784 i2c_r2(gspca_dev, reg->reg, (u16 *) ®->val);
1786 i2c_r1(gspca_dev, reg->reg, (u8 *) ®->val);
1788 return gspca_dev->usb_err;
1793 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1794 struct v4l2_dbg_register *reg)
1796 struct sd *sd = (struct sd *) gspca_dev;
1798 switch (reg->match.type) {
1799 case V4L2_CHIP_MATCH_HOST:
1800 if (reg->match.addr != 0)
1802 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1804 reg_w1(gspca_dev, reg->reg, reg->val);
1805 return gspca_dev->usb_err;
1806 case V4L2_CHIP_MATCH_I2C_ADDR:
1807 if (reg->match.addr != sd->i2c_addr)
1809 if (sd->sensor >= SENSOR_MT9V011 &&
1810 sd->sensor <= SENSOR_MT9M112) {
1811 i2c_w2(gspca_dev, reg->reg, reg->val);
1813 i2c_w1(gspca_dev, reg->reg, reg->val);
1815 return gspca_dev->usb_err;
1821 static int sd_chip_ident(struct gspca_dev *gspca_dev,
1822 struct v4l2_dbg_chip_ident *chip)
1824 struct sd *sd = (struct sd *) gspca_dev;
1826 switch (chip->match.type) {
1827 case V4L2_CHIP_MATCH_HOST:
1828 if (chip->match.addr != 0)
1831 chip->ident = V4L2_IDENT_SN9C20X;
1833 case V4L2_CHIP_MATCH_I2C_ADDR:
1834 if (chip->match.addr != sd->i2c_addr)
1837 chip->ident = i2c_ident[sd->sensor];
1843 static int sd_config(struct gspca_dev *gspca_dev,
1844 const struct usb_device_id *id)
1846 struct sd *sd = (struct sd *) gspca_dev;
1849 cam = &gspca_dev->cam;
1850 cam->needs_full_bandwidth = 1;
1852 sd->sensor = id->driver_info >> 8;
1853 sd->i2c_addr = id->driver_info;
1854 sd->flags = id->driver_info >> 16;
1855 sd->i2c_intf = 0x80; /* i2c 100 Kb/s */
1857 switch (sd->sensor) {
1858 case SENSOR_MT9M112:
1859 case SENSOR_MT9M111:
1862 cam->cam_mode = sxga_mode;
1863 cam->nmodes = ARRAY_SIZE(sxga_mode);
1865 case SENSOR_MT9M001:
1866 cam->cam_mode = mono_mode;
1867 cam->nmodes = ARRAY_SIZE(mono_mode);
1869 case SENSOR_HV7131R:
1870 sd->i2c_intf = 0x81; /* i2c 400 Kb/s */
1873 cam->cam_mode = vga_mode;
1874 cam->nmodes = ARRAY_SIZE(vga_mode);
1880 sd->exposure_step = 16;
1882 gspca_dev->cam.ctrls = sd->ctrls;
1884 INIT_WORK(&sd->work, qual_upd);
1889 static int sd_init(struct gspca_dev *gspca_dev)
1891 struct sd *sd = (struct sd *) gspca_dev;
1895 {0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
1897 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
1898 value = bridge_init[i][1];
1899 reg_w(gspca_dev, bridge_init[i][0], &value, 1);
1900 if (gspca_dev->usb_err < 0) {
1901 pr_err("Device initialization failed\n");
1902 return gspca_dev->usb_err;
1906 if (sd->flags & LED_REVERSE)
1907 reg_w1(gspca_dev, 0x1006, 0x00);
1909 reg_w1(gspca_dev, 0x1006, 0x20);
1911 reg_w(gspca_dev, 0x10c0, i2c_init, 9);
1912 if (gspca_dev->usb_err < 0) {
1913 pr_err("Device initialization failed\n");
1914 return gspca_dev->usb_err;
1917 switch (sd->sensor) {
1919 ov9650_init_sensor(gspca_dev);
1920 if (gspca_dev->usb_err < 0)
1922 pr_info("OV9650 sensor detected\n");
1925 ov9655_init_sensor(gspca_dev);
1926 if (gspca_dev->usb_err < 0)
1928 pr_info("OV9655 sensor detected\n");
1931 soi968_init_sensor(gspca_dev);
1932 if (gspca_dev->usb_err < 0)
1934 pr_info("SOI968 sensor detected\n");
1937 ov7660_init_sensor(gspca_dev);
1938 if (gspca_dev->usb_err < 0)
1940 pr_info("OV7660 sensor detected\n");
1943 ov7670_init_sensor(gspca_dev);
1944 if (gspca_dev->usb_err < 0)
1946 pr_info("OV7670 sensor detected\n");
1948 case SENSOR_MT9VPRB:
1949 mt9v_init_sensor(gspca_dev);
1950 if (gspca_dev->usb_err < 0)
1952 pr_info("MT9VPRB sensor detected\n");
1954 case SENSOR_MT9M111:
1955 mt9m111_init_sensor(gspca_dev);
1956 if (gspca_dev->usb_err < 0)
1958 pr_info("MT9M111 sensor detected\n");
1960 case SENSOR_MT9M112:
1961 mt9m112_init_sensor(gspca_dev);
1962 if (gspca_dev->usb_err < 0)
1964 pr_info("MT9M112 sensor detected\n");
1966 case SENSOR_MT9M001:
1967 mt9m001_init_sensor(gspca_dev);
1968 if (gspca_dev->usb_err < 0)
1971 case SENSOR_HV7131R:
1972 hv7131r_init_sensor(gspca_dev);
1973 if (gspca_dev->usb_err < 0)
1975 pr_info("HV7131R sensor detected\n");
1978 pr_err("Unsupported sensor\n");
1979 gspca_dev->usb_err = -ENODEV;
1982 return gspca_dev->usb_err;
1985 static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
1987 struct sd *sd = (struct sd *) gspca_dev;
1990 switch (sd->sensor) {
1992 if (mode & MODE_SXGA) {
1993 i2c_w1(gspca_dev, 0x17, 0x1d);
1994 i2c_w1(gspca_dev, 0x18, 0xbd);
1995 i2c_w1(gspca_dev, 0x19, 0x01);
1996 i2c_w1(gspca_dev, 0x1a, 0x81);
1997 i2c_w1(gspca_dev, 0x12, 0x00);
2001 i2c_w1(gspca_dev, 0x17, 0x13);
2002 i2c_w1(gspca_dev, 0x18, 0x63);
2003 i2c_w1(gspca_dev, 0x19, 0x01);
2004 i2c_w1(gspca_dev, 0x1a, 0x79);
2005 i2c_w1(gspca_dev, 0x12, 0x40);
2011 if (mode & MODE_SXGA) {
2012 i2c_w1(gspca_dev, 0x17, 0x1b);
2013 i2c_w1(gspca_dev, 0x18, 0xbc);
2014 i2c_w1(gspca_dev, 0x19, 0x01);
2015 i2c_w1(gspca_dev, 0x1a, 0x82);
2016 i2c_r1(gspca_dev, 0x12, &value);
2017 i2c_w1(gspca_dev, 0x12, value & 0x07);
2019 i2c_w1(gspca_dev, 0x17, 0x24);
2020 i2c_w1(gspca_dev, 0x18, 0xc5);
2021 i2c_w1(gspca_dev, 0x19, 0x00);
2022 i2c_w1(gspca_dev, 0x1a, 0x3c);
2023 i2c_r1(gspca_dev, 0x12, &value);
2024 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
2027 case SENSOR_MT9M112:
2028 case SENSOR_MT9M111:
2029 if (mode & MODE_SXGA) {
2030 i2c_w2(gspca_dev, 0xf0, 0x0002);
2031 i2c_w2(gspca_dev, 0xc8, 0x970b);
2032 i2c_w2(gspca_dev, 0xf0, 0x0000);
2034 i2c_w2(gspca_dev, 0xf0, 0x0002);
2035 i2c_w2(gspca_dev, 0xc8, 0x8000);
2036 i2c_w2(gspca_dev, 0xf0, 0x0000);
2042 static int sd_isoc_init(struct gspca_dev *gspca_dev)
2044 struct usb_interface *intf;
2045 u32 flags = gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv;
2048 * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth
2049 * than our regular bandwidth calculations reserve, so we force the
2050 * use of a specific altsetting when using the SN9C20X_I420 fmt.
2052 if (!(flags & (MODE_RAW | MODE_JPEG))) {
2053 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
2055 if (intf->num_altsetting != 9) {
2056 pr_warn("sn9c20x camera with unknown number of alt "
2057 "settings (%d), please report!\n",
2058 intf->num_altsetting);
2059 gspca_dev->alt = intf->num_altsetting;
2063 switch (gspca_dev->width) {
2064 case 160: /* 160x120 */
2067 case 320: /* 320x240 */
2070 default: /* >= 640x480 */
2079 #define HW_WIN(mode, hstart, vstart) \
2080 ((const u8 []){hstart, 0, vstart, 0, \
2081 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
2082 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
2084 #define CLR_WIN(width, height) \
2086 {0, width >> 2, 0, height >> 1,\
2087 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
2089 static int sd_start(struct gspca_dev *gspca_dev)
2091 struct sd *sd = (struct sd *) gspca_dev;
2092 int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
2093 int width = gspca_dev->width;
2094 int height = gspca_dev->height;
2097 jpeg_define(sd->jpeg_hdr, height, width,
2099 jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val);
2101 if (mode & MODE_RAW)
2103 else if (mode & MODE_JPEG)
2106 fmt = 0x2f; /* YUV 420 */
2109 switch (mode & SCALE_MASK) {
2110 case SCALE_1280x1024:
2112 pr_info("Set 1280x1024\n");
2116 pr_info("Set 640x480\n");
2120 pr_info("Set 320x240\n");
2124 pr_info("Set 160x120\n");
2128 configure_sensor_output(gspca_dev, mode);
2129 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2130 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2131 reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2132 reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2133 reg_w1(gspca_dev, 0x1189, scale);
2134 reg_w1(gspca_dev, 0x10e0, fmt);
2136 set_cmatrix(gspca_dev);
2137 set_gamma(gspca_dev);
2138 set_redblue(gspca_dev);
2139 set_gain(gspca_dev);
2140 set_exposure(gspca_dev);
2141 set_hvflip(gspca_dev);
2143 reg_w1(gspca_dev, 0x1007, 0x20);
2144 reg_w1(gspca_dev, 0x1061, 0x03);
2146 /* if JPEG, prepare the compression quality update */
2147 if (mode & MODE_JPEG) {
2148 sd->pktsz = sd->npkt = 0;
2151 create_singlethread_workqueue(KBUILD_MODNAME);
2154 return gspca_dev->usb_err;
2157 static void sd_stopN(struct gspca_dev *gspca_dev)
2159 reg_w1(gspca_dev, 0x1007, 0x00);
2160 reg_w1(gspca_dev, 0x1061, 0x01);
2163 /* called on streamoff with alt==0 and on disconnect */
2164 /* the usb_lock is held at entry - restore on exit */
2165 static void sd_stop0(struct gspca_dev *gspca_dev)
2167 struct sd *sd = (struct sd *) gspca_dev;
2169 if (sd->work_thread != NULL) {
2170 mutex_unlock(&gspca_dev->usb_lock);
2171 destroy_workqueue(sd->work_thread);
2172 mutex_lock(&gspca_dev->usb_lock);
2173 sd->work_thread = NULL;
2177 static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2179 struct sd *sd = (struct sd *) gspca_dev;
2183 * some hardcoded values are present
2184 * like those for maximal/minimal exposure
2185 * and exposure steps
2187 if (avg_lum < MIN_AVG_LUM) {
2188 if (sd->ctrls[EXPOSURE].val > 0x1770)
2191 new_exp = sd->ctrls[EXPOSURE].val + sd->exposure_step;
2192 if (new_exp > 0x1770)
2196 sd->ctrls[EXPOSURE].val = new_exp;
2197 set_exposure(gspca_dev);
2199 sd->older_step = sd->old_step;
2202 if (sd->old_step ^ sd->older_step)
2203 sd->exposure_step /= 2;
2205 sd->exposure_step += 2;
2207 if (avg_lum > MAX_AVG_LUM) {
2208 if (sd->ctrls[EXPOSURE].val < 0x10)
2210 new_exp = sd->ctrls[EXPOSURE].val - sd->exposure_step;
2211 if (new_exp > 0x1700)
2215 sd->ctrls[EXPOSURE].val = new_exp;
2216 set_exposure(gspca_dev);
2217 sd->older_step = sd->old_step;
2220 if (sd->old_step ^ sd->older_step)
2221 sd->exposure_step /= 2;
2223 sd->exposure_step += 2;
2227 static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2229 struct sd *sd = (struct sd *) gspca_dev;
2231 if (avg_lum < MIN_AVG_LUM) {
2232 if (sd->ctrls[GAIN].val + 1 <= 28) {
2233 sd->ctrls[GAIN].val++;
2234 set_gain(gspca_dev);
2237 if (avg_lum > MAX_AVG_LUM) {
2238 if (sd->ctrls[GAIN].val > 0) {
2239 sd->ctrls[GAIN].val--;
2240 set_gain(gspca_dev);
2245 static void sd_dqcallback(struct gspca_dev *gspca_dev)
2247 struct sd *sd = (struct sd *) gspca_dev;
2250 if (!sd->ctrls[AUTOGAIN].val)
2253 avg_lum = atomic_read(&sd->avg_lum);
2254 if (sd->sensor == SENSOR_SOI968)
2255 do_autogain(gspca_dev, avg_lum);
2257 do_autoexposure(gspca_dev, avg_lum);
2260 /* JPEG quality update */
2261 /* This function is executed from a work queue. */
2262 static void qual_upd(struct work_struct *work)
2264 struct sd *sd = container_of(work, struct sd, work);
2265 struct gspca_dev *gspca_dev = &sd->gspca_dev;
2267 mutex_lock(&gspca_dev->usb_lock);
2268 PDEBUG(D_STREAM, "qual_upd %d%%", sd->ctrls[QUALITY].val);
2269 set_quality(gspca_dev);
2270 mutex_unlock(&gspca_dev->usb_lock);
2273 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2274 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2275 u8 *data, /* interrupt packet */
2276 int len) /* interrupt packet length */
2278 struct sd *sd = (struct sd *) gspca_dev;
2280 if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
2281 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2282 input_sync(gspca_dev->input_dev);
2283 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2284 input_sync(gspca_dev->input_dev);
2291 /* check the JPEG compression */
2292 static void transfer_check(struct gspca_dev *gspca_dev,
2295 struct sd *sd = (struct sd *) gspca_dev;
2300 /* if USB error, discard the frame and decrease the quality */
2301 if (data[6] & 0x08) { /* USB FIFO full */
2302 gspca_dev->last_packet_type = DISCARD_PACKET;
2306 /* else, compute the filling rate and a new JPEG quality */
2307 r = (sd->pktsz * 100) /
2309 gspca_dev->urb[0]->iso_frame_desc[0].length);
2315 if (new_qual != 0) {
2316 sd->nchg += new_qual;
2317 if (sd->nchg < -6 || sd->nchg >= 12) {
2319 new_qual += sd->ctrls[QUALITY].val;
2320 if (new_qual < QUALITY_MIN)
2321 new_qual = QUALITY_MIN;
2322 else if (new_qual > QUALITY_MAX)
2323 new_qual = QUALITY_MAX;
2324 if (new_qual != sd->ctrls[QUALITY].val) {
2325 sd->ctrls[QUALITY].val = new_qual;
2326 queue_work(sd->work_thread, &sd->work);
2332 sd->pktsz = sd->npkt = 0;
2335 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2336 u8 *data, /* isoc packet */
2337 int len) /* iso packet length */
2339 struct sd *sd = (struct sd *) gspca_dev;
2340 int avg_lum, is_jpeg;
2341 static const u8 frame_header[] =
2342 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2344 is_jpeg = (sd->fmt & 0x03) == 0;
2345 if (len >= 64 && memcmp(data, frame_header, 6) == 0) {
2346 avg_lum = ((data[35] >> 2) & 3) |
2349 avg_lum += ((data[35] >> 4) & 3) |
2352 avg_lum += ((data[35] >> 6) & 3) |
2355 avg_lum += (data[36] & 3) |
2358 avg_lum += ((data[36] >> 2) & 3) |
2361 avg_lum += ((data[36] >> 4) & 3) |
2364 avg_lum += ((data[36] >> 6) & 3) |
2367 avg_lum += ((data[44] >> 4) & 3) |
2371 atomic_set(&sd->avg_lum, avg_lum);
2374 transfer_check(gspca_dev, data);
2376 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2382 if (gspca_dev->last_packet_type == LAST_PACKET) {
2384 gspca_frame_add(gspca_dev, FIRST_PACKET,
2385 sd->jpeg_hdr, JPEG_HDR_SZ);
2386 gspca_frame_add(gspca_dev, INTER_PACKET,
2389 gspca_frame_add(gspca_dev, FIRST_PACKET,
2393 /* if JPEG, count the packets and their size */
2398 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2402 /* sub-driver description */
2403 static const struct sd_desc sd_desc = {
2404 .name = KBUILD_MODNAME,
2406 .nctrls = ARRAY_SIZE(sd_ctrls),
2407 .config = sd_config,
2409 .isoc_init = sd_isoc_init,
2413 .pkt_scan = sd_pkt_scan,
2414 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2415 .int_pkt_scan = sd_int_pkt_scan,
2417 .dq_callback = sd_dqcallback,
2418 #ifdef CONFIG_VIDEO_ADV_DEBUG
2419 .set_register = sd_dbg_s_register,
2420 .get_register = sd_dbg_g_register,
2422 .get_chip_ident = sd_chip_ident,
2425 #define SN9C20X(sensor, i2c_addr, flags) \
2426 .driver_info = ((flags & 0xff) << 16) \
2427 | (SENSOR_ ## sensor << 8) \
2430 static const struct usb_device_id device_table[] = {
2431 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2432 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
2433 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2434 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
2435 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
2436 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
2437 (FLIP_DETECT | HAS_NO_BUTTON))},
2438 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2439 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2440 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2441 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2442 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, FLIP_DETECT)},
2443 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2444 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2445 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2446 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2447 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
2448 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
2449 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2450 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2451 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2452 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2453 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, LED_REVERSE)},
2454 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, LED_REVERSE)},
2455 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2456 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2457 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2458 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2459 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
2460 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
2461 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2462 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2463 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2464 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2465 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
2466 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2467 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2470 MODULE_DEVICE_TABLE(usb, device_table);
2472 /* -- device connect -- */
2473 static int sd_probe(struct usb_interface *intf,
2474 const struct usb_device_id *id)
2476 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2480 static struct usb_driver sd_driver = {
2481 .name = KBUILD_MODNAME,
2482 .id_table = device_table,
2484 .disconnect = gspca_disconnect,
2486 .suspend = gspca_suspend,
2487 .resume = gspca_resume,
2488 .reset_resume = gspca_resume,
2492 module_usb_driver(sd_driver);