2 * Sonix sn9c201 sn9c202 library
3 * Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com>
4 * Copyright (C) 2009 Brian Johnson <brijohn@gmail.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <linux/input.h>
26 #include <media/v4l2-chip-ident.h>
27 #include <linux/dmi.h>
29 MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, "
30 "microdia project <microdia@googlegroups.com>");
31 MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
32 MODULE_LICENSE("GPL");
34 #define MODULE_NAME "sn9c20x"
37 #define MODE_JPEG 0x20
38 #define MODE_SXGA 0x80
40 #define SENSOR_OV9650 0
41 #define SENSOR_OV9655 1
42 #define SENSOR_SOI968 2
43 #define SENSOR_OV7660 3
44 #define SENSOR_OV7670 4
45 #define SENSOR_MT9V011 5
46 #define SENSOR_MT9V111 6
47 #define SENSOR_MT9V112 7
48 #define SENSOR_MT9M001 8
49 #define SENSOR_MT9M111 9
50 #define SENSOR_MT9M112 10
51 #define SENSOR_HV7131R 11
52 #define SENSOR_MT9VPRB 20
55 #define HAS_NO_BUTTON 0x1
56 #define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
57 #define FLIP_DETECT 0x4
59 /* specific webcam descriptor */
61 struct gspca_dev gspca_dev
;
63 #define MIN_AVG_LUM 80
64 #define MAX_AVG_LUM 130
89 u8 jpeg_hdr
[JPEG_HDR_SZ
];
105 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, s32 val
);
106 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, s32
*val
);
107 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, s32 val
);
108 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, s32
*val
);
109 static int sd_setsaturation(struct gspca_dev
*gspca_dev
, s32 val
);
110 static int sd_getsaturation(struct gspca_dev
*gspca_dev
, s32
*val
);
111 static int sd_sethue(struct gspca_dev
*gspca_dev
, s32 val
);
112 static int sd_gethue(struct gspca_dev
*gspca_dev
, s32
*val
);
113 static int sd_setgamma(struct gspca_dev
*gspca_dev
, s32 val
);
114 static int sd_getgamma(struct gspca_dev
*gspca_dev
, s32
*val
);
115 static int sd_setredbalance(struct gspca_dev
*gspca_dev
, s32 val
);
116 static int sd_getredbalance(struct gspca_dev
*gspca_dev
, s32
*val
);
117 static int sd_setbluebalance(struct gspca_dev
*gspca_dev
, s32 val
);
118 static int sd_getbluebalance(struct gspca_dev
*gspca_dev
, s32
*val
);
119 static int sd_setvflip(struct gspca_dev
*gspca_dev
, s32 val
);
120 static int sd_getvflip(struct gspca_dev
*gspca_dev
, s32
*val
);
121 static int sd_sethflip(struct gspca_dev
*gspca_dev
, s32 val
);
122 static int sd_gethflip(struct gspca_dev
*gspca_dev
, s32
*val
);
123 static int sd_setgain(struct gspca_dev
*gspca_dev
, s32 val
);
124 static int sd_getgain(struct gspca_dev
*gspca_dev
, s32
*val
);
125 static int sd_setexposure(struct gspca_dev
*gspca_dev
, s32 val
);
126 static int sd_getexposure(struct gspca_dev
*gspca_dev
, s32
*val
);
127 static int sd_setautoexposure(struct gspca_dev
*gspca_dev
, s32 val
);
128 static int sd_getautoexposure(struct gspca_dev
*gspca_dev
, s32
*val
);
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-1635X",
149 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
150 DMI_MATCH(DMI_BOARD_NAME
, "MS-1635X")
154 .ident
= "ASUSTeK W7J",
156 DMI_MATCH(DMI_BOARD_VENDOR
, "ASUSTeK Computer Inc."),
157 DMI_MATCH(DMI_BOARD_NAME
, "W7J ")
163 static const struct ctrl sd_ctrls
[] = {
165 #define BRIGHTNESS_IDX 0
167 .id
= V4L2_CID_BRIGHTNESS
,
168 .type
= V4L2_CTRL_TYPE_INTEGER
,
169 .name
= "Brightness",
173 #define BRIGHTNESS_DEFAULT 0x7f
174 .default_value
= BRIGHTNESS_DEFAULT
,
176 .set
= sd_setbrightness
,
177 .get
= sd_getbrightness
,
180 #define CONTRAST_IDX 1
182 .id
= V4L2_CID_CONTRAST
,
183 .type
= V4L2_CTRL_TYPE_INTEGER
,
188 #define CONTRAST_DEFAULT 0x7f
189 .default_value
= CONTRAST_DEFAULT
,
191 .set
= sd_setcontrast
,
192 .get
= sd_getcontrast
,
195 #define SATURATION_IDX 2
197 .id
= V4L2_CID_SATURATION
,
198 .type
= V4L2_CTRL_TYPE_INTEGER
,
199 .name
= "Saturation",
203 #define SATURATION_DEFAULT 0x7f
204 .default_value
= SATURATION_DEFAULT
,
206 .set
= sd_setsaturation
,
207 .get
= sd_getsaturation
,
213 .type
= V4L2_CTRL_TYPE_INTEGER
,
218 #define HUE_DEFAULT 0
219 .default_value
= HUE_DEFAULT
,
227 .id
= V4L2_CID_GAMMA
,
228 .type
= V4L2_CTRL_TYPE_INTEGER
,
233 #define GAMMA_DEFAULT 0x10
234 .default_value
= GAMMA_DEFAULT
,
242 .id
= V4L2_CID_BLUE_BALANCE
,
243 .type
= V4L2_CTRL_TYPE_INTEGER
,
244 .name
= "Blue Balance",
248 #define BLUE_DEFAULT 0x28
249 .default_value
= BLUE_DEFAULT
,
251 .set
= sd_setbluebalance
,
252 .get
= sd_getbluebalance
,
257 .id
= V4L2_CID_RED_BALANCE
,
258 .type
= V4L2_CTRL_TYPE_INTEGER
,
259 .name
= "Red Balance",
263 #define RED_DEFAULT 0x28
264 .default_value
= RED_DEFAULT
,
266 .set
= sd_setredbalance
,
267 .get
= sd_getredbalance
,
272 .id
= V4L2_CID_HFLIP
,
273 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
274 .name
= "Horizontal Flip",
278 #define HFLIP_DEFAULT 0
279 .default_value
= HFLIP_DEFAULT
,
287 .id
= V4L2_CID_VFLIP
,
288 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
289 .name
= "Vertical Flip",
293 #define VFLIP_DEFAULT 0
294 .default_value
= VFLIP_DEFAULT
,
300 #define EXPOSURE_IDX 9
302 .id
= V4L2_CID_EXPOSURE
,
303 .type
= V4L2_CTRL_TYPE_INTEGER
,
308 #define EXPOSURE_DEFAULT 0x33
309 .default_value
= EXPOSURE_DEFAULT
,
311 .set
= sd_setexposure
,
312 .get
= sd_getexposure
,
318 .type
= V4L2_CTRL_TYPE_INTEGER
,
323 #define GAIN_DEFAULT 0x00
324 .default_value
= GAIN_DEFAULT
,
330 #define AUTOGAIN_IDX 11
332 .id
= V4L2_CID_AUTOGAIN
,
333 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
334 .name
= "Auto Exposure",
338 #define AUTO_EXPOSURE_DEFAULT 1
339 .default_value
= AUTO_EXPOSURE_DEFAULT
,
341 .set
= sd_setautoexposure
,
342 .get
= sd_getautoexposure
,
346 static const struct v4l2_pix_format vga_mode
[] = {
347 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
349 .sizeimage
= 160 * 120 * 4 / 8 + 590,
350 .colorspace
= V4L2_COLORSPACE_JPEG
,
351 .priv
= 0 | MODE_JPEG
},
352 {160, 120, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
354 .sizeimage
= 160 * 120,
355 .colorspace
= V4L2_COLORSPACE_SRGB
,
356 .priv
= 0 | MODE_RAW
},
357 {160, 120, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
359 .sizeimage
= 240 * 120,
360 .colorspace
= V4L2_COLORSPACE_SRGB
,
362 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
364 .sizeimage
= 320 * 240 * 3 / 8 + 590,
365 .colorspace
= V4L2_COLORSPACE_JPEG
,
366 .priv
= 1 | MODE_JPEG
},
367 {320, 240, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
369 .sizeimage
= 320 * 240 ,
370 .colorspace
= V4L2_COLORSPACE_SRGB
,
371 .priv
= 1 | MODE_RAW
},
372 {320, 240, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
374 .sizeimage
= 480 * 240 ,
375 .colorspace
= V4L2_COLORSPACE_SRGB
,
377 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
379 .sizeimage
= 640 * 480 * 3 / 8 + 590,
380 .colorspace
= V4L2_COLORSPACE_JPEG
,
381 .priv
= 2 | MODE_JPEG
},
382 {640, 480, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
384 .sizeimage
= 640 * 480,
385 .colorspace
= V4L2_COLORSPACE_SRGB
,
386 .priv
= 2 | MODE_RAW
},
387 {640, 480, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
389 .sizeimage
= 960 * 480,
390 .colorspace
= V4L2_COLORSPACE_SRGB
,
394 static const struct v4l2_pix_format sxga_mode
[] = {
395 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
397 .sizeimage
= 160 * 120 * 4 / 8 + 590,
398 .colorspace
= V4L2_COLORSPACE_JPEG
,
399 .priv
= 0 | MODE_JPEG
},
400 {160, 120, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
402 .sizeimage
= 160 * 120,
403 .colorspace
= V4L2_COLORSPACE_SRGB
,
404 .priv
= 0 | MODE_RAW
},
405 {160, 120, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
407 .sizeimage
= 240 * 120,
408 .colorspace
= V4L2_COLORSPACE_SRGB
,
410 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
412 .sizeimage
= 320 * 240 * 3 / 8 + 590,
413 .colorspace
= V4L2_COLORSPACE_JPEG
,
414 .priv
= 1 | MODE_JPEG
},
415 {320, 240, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
417 .sizeimage
= 320 * 240 ,
418 .colorspace
= V4L2_COLORSPACE_SRGB
,
419 .priv
= 1 | MODE_RAW
},
420 {320, 240, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
422 .sizeimage
= 480 * 240 ,
423 .colorspace
= V4L2_COLORSPACE_SRGB
,
425 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
427 .sizeimage
= 640 * 480 * 3 / 8 + 590,
428 .colorspace
= V4L2_COLORSPACE_JPEG
,
429 .priv
= 2 | MODE_JPEG
},
430 {640, 480, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
432 .sizeimage
= 640 * 480,
433 .colorspace
= V4L2_COLORSPACE_SRGB
,
434 .priv
= 2 | MODE_RAW
},
435 {640, 480, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
437 .sizeimage
= 960 * 480,
438 .colorspace
= V4L2_COLORSPACE_SRGB
,
440 {1280, 1024, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
441 .bytesperline
= 1280,
442 .sizeimage
= 1280 * 1024,
443 .colorspace
= V4L2_COLORSPACE_SRGB
,
444 .priv
= 3 | MODE_RAW
| MODE_SXGA
},
447 static const s16 hsv_red_x
[] = {
448 41, 44, 46, 48, 50, 52, 54, 56,
449 58, 60, 62, 64, 66, 68, 70, 72,
450 74, 76, 78, 80, 81, 83, 85, 87,
451 88, 90, 92, 93, 95, 97, 98, 100,
452 101, 102, 104, 105, 107, 108, 109, 110,
453 112, 113, 114, 115, 116, 117, 118, 119,
454 120, 121, 122, 123, 123, 124, 125, 125,
455 126, 127, 127, 128, 128, 129, 129, 129,
456 130, 130, 130, 130, 131, 131, 131, 131,
457 131, 131, 131, 131, 130, 130, 130, 130,
458 129, 129, 129, 128, 128, 127, 127, 126,
459 125, 125, 124, 123, 122, 122, 121, 120,
460 119, 118, 117, 116, 115, 114, 112, 111,
461 110, 109, 107, 106, 105, 103, 102, 101,
462 99, 98, 96, 94, 93, 91, 90, 88,
463 86, 84, 83, 81, 79, 77, 75, 74,
464 72, 70, 68, 66, 64, 62, 60, 58,
465 56, 54, 52, 49, 47, 45, 43, 41,
466 39, 36, 34, 32, 30, 28, 25, 23,
467 21, 19, 16, 14, 12, 9, 7, 5,
468 3, 0, -1, -3, -6, -8, -10, -12,
469 -15, -17, -19, -22, -24, -26, -28, -30,
470 -33, -35, -37, -39, -41, -44, -46, -48,
471 -50, -52, -54, -56, -58, -60, -62, -64,
472 -66, -68, -70, -72, -74, -76, -78, -80,
473 -81, -83, -85, -87, -88, -90, -92, -93,
474 -95, -97, -98, -100, -101, -102, -104, -105,
475 -107, -108, -109, -110, -112, -113, -114, -115,
476 -116, -117, -118, -119, -120, -121, -122, -123,
477 -123, -124, -125, -125, -126, -127, -127, -128,
478 -128, -128, -128, -128, -128, -128, -128, -128,
479 -128, -128, -128, -128, -128, -128, -128, -128,
480 -128, -128, -128, -128, -128, -128, -128, -128,
481 -128, -127, -127, -126, -125, -125, -124, -123,
482 -122, -122, -121, -120, -119, -118, -117, -116,
483 -115, -114, -112, -111, -110, -109, -107, -106,
484 -105, -103, -102, -101, -99, -98, -96, -94,
485 -93, -91, -90, -88, -86, -84, -83, -81,
486 -79, -77, -75, -74, -72, -70, -68, -66,
487 -64, -62, -60, -58, -56, -54, -52, -49,
488 -47, -45, -43, -41, -39, -36, -34, -32,
489 -30, -28, -25, -23, -21, -19, -16, -14,
490 -12, -9, -7, -5, -3, 0, 1, 3,
491 6, 8, 10, 12, 15, 17, 19, 22,
492 24, 26, 28, 30, 33, 35, 37, 39, 41
495 static const s16 hsv_red_y
[] = {
496 82, 80, 78, 76, 74, 73, 71, 69,
497 67, 65, 63, 61, 58, 56, 54, 52,
498 50, 48, 46, 44, 41, 39, 37, 35,
499 32, 30, 28, 26, 23, 21, 19, 16,
500 14, 12, 10, 7, 5, 3, 0, -1,
501 -3, -6, -8, -10, -13, -15, -17, -19,
502 -22, -24, -26, -29, -31, -33, -35, -38,
503 -40, -42, -44, -46, -48, -51, -53, -55,
504 -57, -59, -61, -63, -65, -67, -69, -71,
505 -73, -75, -77, -79, -81, -82, -84, -86,
506 -88, -89, -91, -93, -94, -96, -98, -99,
507 -101, -102, -104, -105, -106, -108, -109, -110,
508 -112, -113, -114, -115, -116, -117, -119, -120,
509 -120, -121, -122, -123, -124, -125, -126, -126,
510 -127, -128, -128, -128, -128, -128, -128, -128,
511 -128, -128, -128, -128, -128, -128, -128, -128,
512 -128, -128, -128, -128, -128, -128, -128, -128,
513 -128, -128, -128, -128, -128, -128, -128, -128,
514 -127, -127, -126, -125, -125, -124, -123, -122,
515 -121, -120, -119, -118, -117, -116, -115, -114,
516 -113, -111, -110, -109, -107, -106, -105, -103,
517 -102, -100, -99, -97, -96, -94, -92, -91,
518 -89, -87, -85, -84, -82, -80, -78, -76,
519 -74, -73, -71, -69, -67, -65, -63, -61,
520 -58, -56, -54, -52, -50, -48, -46, -44,
521 -41, -39, -37, -35, -32, -30, -28, -26,
522 -23, -21, -19, -16, -14, -12, -10, -7,
523 -5, -3, 0, 1, 3, 6, 8, 10,
524 13, 15, 17, 19, 22, 24, 26, 29,
525 31, 33, 35, 38, 40, 42, 44, 46,
526 48, 51, 53, 55, 57, 59, 61, 63,
527 65, 67, 69, 71, 73, 75, 77, 79,
528 81, 82, 84, 86, 88, 89, 91, 93,
529 94, 96, 98, 99, 101, 102, 104, 105,
530 106, 108, 109, 110, 112, 113, 114, 115,
531 116, 117, 119, 120, 120, 121, 122, 123,
532 124, 125, 126, 126, 127, 128, 128, 129,
533 129, 130, 130, 131, 131, 131, 131, 132,
534 132, 132, 132, 132, 132, 132, 132, 132,
535 132, 132, 132, 131, 131, 131, 130, 130,
536 130, 129, 129, 128, 127, 127, 126, 125,
537 125, 124, 123, 122, 121, 120, 119, 118,
538 117, 116, 115, 114, 113, 111, 110, 109,
539 107, 106, 105, 103, 102, 100, 99, 97,
540 96, 94, 92, 91, 89, 87, 85, 84, 82
543 static const s16 hsv_green_x
[] = {
544 -124, -124, -125, -125, -125, -125, -125, -125,
545 -125, -126, -126, -125, -125, -125, -125, -125,
546 -125, -124, -124, -124, -123, -123, -122, -122,
547 -121, -121, -120, -120, -119, -118, -117, -117,
548 -116, -115, -114, -113, -112, -111, -110, -109,
549 -108, -107, -105, -104, -103, -102, -100, -99,
550 -98, -96, -95, -93, -92, -91, -89, -87,
551 -86, -84, -83, -81, -79, -77, -76, -74,
552 -72, -70, -69, -67, -65, -63, -61, -59,
553 -57, -55, -53, -51, -49, -47, -45, -43,
554 -41, -39, -37, -35, -33, -30, -28, -26,
555 -24, -22, -20, -18, -15, -13, -11, -9,
556 -7, -4, -2, 0, 1, 3, 6, 8,
557 10, 12, 14, 17, 19, 21, 23, 25,
558 27, 29, 32, 34, 36, 38, 40, 42,
559 44, 46, 48, 50, 52, 54, 56, 58,
560 60, 62, 64, 66, 68, 70, 71, 73,
561 75, 77, 78, 80, 82, 83, 85, 87,
562 88, 90, 91, 93, 94, 96, 97, 98,
563 100, 101, 102, 104, 105, 106, 107, 108,
564 109, 111, 112, 113, 113, 114, 115, 116,
565 117, 118, 118, 119, 120, 120, 121, 122,
566 122, 123, 123, 124, 124, 124, 125, 125,
567 125, 125, 125, 125, 125, 126, 126, 125,
568 125, 125, 125, 125, 125, 124, 124, 124,
569 123, 123, 122, 122, 121, 121, 120, 120,
570 119, 118, 117, 117, 116, 115, 114, 113,
571 112, 111, 110, 109, 108, 107, 105, 104,
572 103, 102, 100, 99, 98, 96, 95, 93,
573 92, 91, 89, 87, 86, 84, 83, 81,
574 79, 77, 76, 74, 72, 70, 69, 67,
575 65, 63, 61, 59, 57, 55, 53, 51,
576 49, 47, 45, 43, 41, 39, 37, 35,
577 33, 30, 28, 26, 24, 22, 20, 18,
578 15, 13, 11, 9, 7, 4, 2, 0,
579 -1, -3, -6, -8, -10, -12, -14, -17,
580 -19, -21, -23, -25, -27, -29, -32, -34,
581 -36, -38, -40, -42, -44, -46, -48, -50,
582 -52, -54, -56, -58, -60, -62, -64, -66,
583 -68, -70, -71, -73, -75, -77, -78, -80,
584 -82, -83, -85, -87, -88, -90, -91, -93,
585 -94, -96, -97, -98, -100, -101, -102, -104,
586 -105, -106, -107, -108, -109, -111, -112, -113,
587 -113, -114, -115, -116, -117, -118, -118, -119,
588 -120, -120, -121, -122, -122, -123, -123, -124, -124
591 static const s16 hsv_green_y
[] = {
592 -100, -99, -98, -97, -95, -94, -93, -91,
593 -90, -89, -87, -86, -84, -83, -81, -80,
594 -78, -76, -75, -73, -71, -70, -68, -66,
595 -64, -63, -61, -59, -57, -55, -53, -51,
596 -49, -48, -46, -44, -42, -40, -38, -36,
597 -34, -32, -30, -27, -25, -23, -21, -19,
598 -17, -15, -13, -11, -9, -7, -4, -2,
599 0, 1, 3, 5, 7, 9, 11, 14,
600 16, 18, 20, 22, 24, 26, 28, 30,
601 32, 34, 36, 38, 40, 42, 44, 46,
602 48, 50, 52, 54, 56, 58, 59, 61,
603 63, 65, 67, 68, 70, 72, 74, 75,
604 77, 78, 80, 82, 83, 85, 86, 88,
605 89, 90, 92, 93, 95, 96, 97, 98,
606 100, 101, 102, 103, 104, 105, 106, 107,
607 108, 109, 110, 111, 112, 112, 113, 114,
608 115, 115, 116, 116, 117, 117, 118, 118,
609 119, 119, 119, 120, 120, 120, 120, 120,
610 121, 121, 121, 121, 121, 121, 120, 120,
611 120, 120, 120, 119, 119, 119, 118, 118,
612 117, 117, 116, 116, 115, 114, 114, 113,
613 112, 111, 111, 110, 109, 108, 107, 106,
614 105, 104, 103, 102, 100, 99, 98, 97,
615 95, 94, 93, 91, 90, 89, 87, 86,
616 84, 83, 81, 80, 78, 76, 75, 73,
617 71, 70, 68, 66, 64, 63, 61, 59,
618 57, 55, 53, 51, 49, 48, 46, 44,
619 42, 40, 38, 36, 34, 32, 30, 27,
620 25, 23, 21, 19, 17, 15, 13, 11,
621 9, 7, 4, 2, 0, -1, -3, -5,
622 -7, -9, -11, -14, -16, -18, -20, -22,
623 -24, -26, -28, -30, -32, -34, -36, -38,
624 -40, -42, -44, -46, -48, -50, -52, -54,
625 -56, -58, -59, -61, -63, -65, -67, -68,
626 -70, -72, -74, -75, -77, -78, -80, -82,
627 -83, -85, -86, -88, -89, -90, -92, -93,
628 -95, -96, -97, -98, -100, -101, -102, -103,
629 -104, -105, -106, -107, -108, -109, -110, -111,
630 -112, -112, -113, -114, -115, -115, -116, -116,
631 -117, -117, -118, -118, -119, -119, -119, -120,
632 -120, -120, -120, -120, -121, -121, -121, -121,
633 -121, -121, -120, -120, -120, -120, -120, -119,
634 -119, -119, -118, -118, -117, -117, -116, -116,
635 -115, -114, -114, -113, -112, -111, -111, -110,
636 -109, -108, -107, -106, -105, -104, -103, -102, -100
639 static const s16 hsv_blue_x
[] = {
640 112, 113, 114, 114, 115, 116, 117, 117,
641 118, 118, 119, 119, 120, 120, 120, 121,
642 121, 121, 122, 122, 122, 122, 122, 122,
643 122, 122, 122, 122, 122, 122, 121, 121,
644 121, 120, 120, 120, 119, 119, 118, 118,
645 117, 116, 116, 115, 114, 113, 113, 112,
646 111, 110, 109, 108, 107, 106, 105, 104,
647 103, 102, 100, 99, 98, 97, 95, 94,
648 93, 91, 90, 88, 87, 85, 84, 82,
649 80, 79, 77, 76, 74, 72, 70, 69,
650 67, 65, 63, 61, 60, 58, 56, 54,
651 52, 50, 48, 46, 44, 42, 40, 38,
652 36, 34, 32, 30, 28, 26, 24, 22,
653 19, 17, 15, 13, 11, 9, 7, 5,
654 2, 0, -1, -3, -5, -7, -9, -12,
655 -14, -16, -18, -20, -22, -24, -26, -28,
656 -31, -33, -35, -37, -39, -41, -43, -45,
657 -47, -49, -51, -53, -54, -56, -58, -60,
658 -62, -64, -66, -67, -69, -71, -73, -74,
659 -76, -78, -79, -81, -83, -84, -86, -87,
660 -89, -90, -92, -93, -94, -96, -97, -98,
661 -99, -101, -102, -103, -104, -105, -106, -107,
662 -108, -109, -110, -111, -112, -113, -114, -114,
663 -115, -116, -117, -117, -118, -118, -119, -119,
664 -120, -120, -120, -121, -121, -121, -122, -122,
665 -122, -122, -122, -122, -122, -122, -122, -122,
666 -122, -122, -121, -121, -121, -120, -120, -120,
667 -119, -119, -118, -118, -117, -116, -116, -115,
668 -114, -113, -113, -112, -111, -110, -109, -108,
669 -107, -106, -105, -104, -103, -102, -100, -99,
670 -98, -97, -95, -94, -93, -91, -90, -88,
671 -87, -85, -84, -82, -80, -79, -77, -76,
672 -74, -72, -70, -69, -67, -65, -63, -61,
673 -60, -58, -56, -54, -52, -50, -48, -46,
674 -44, -42, -40, -38, -36, -34, -32, -30,
675 -28, -26, -24, -22, -19, -17, -15, -13,
676 -11, -9, -7, -5, -2, 0, 1, 3,
677 5, 7, 9, 12, 14, 16, 18, 20,
678 22, 24, 26, 28, 31, 33, 35, 37,
679 39, 41, 43, 45, 47, 49, 51, 53,
680 54, 56, 58, 60, 62, 64, 66, 67,
681 69, 71, 73, 74, 76, 78, 79, 81,
682 83, 84, 86, 87, 89, 90, 92, 93,
683 94, 96, 97, 98, 99, 101, 102, 103,
684 104, 105, 106, 107, 108, 109, 110, 111, 112
687 static const s16 hsv_blue_y
[] = {
688 -11, -13, -15, -17, -19, -21, -23, -25,
689 -27, -29, -31, -33, -35, -37, -39, -41,
690 -43, -45, -46, -48, -50, -52, -54, -55,
691 -57, -59, -61, -62, -64, -66, -67, -69,
692 -71, -72, -74, -75, -77, -78, -80, -81,
693 -83, -84, -86, -87, -88, -90, -91, -92,
694 -93, -95, -96, -97, -98, -99, -100, -101,
695 -102, -103, -104, -105, -106, -106, -107, -108,
696 -109, -109, -110, -111, -111, -112, -112, -113,
697 -113, -114, -114, -114, -115, -115, -115, -115,
698 -116, -116, -116, -116, -116, -116, -116, -116,
699 -116, -115, -115, -115, -115, -114, -114, -114,
700 -113, -113, -112, -112, -111, -111, -110, -110,
701 -109, -108, -108, -107, -106, -105, -104, -103,
702 -102, -101, -100, -99, -98, -97, -96, -95,
703 -94, -93, -91, -90, -89, -88, -86, -85,
704 -84, -82, -81, -79, -78, -76, -75, -73,
705 -71, -70, -68, -67, -65, -63, -62, -60,
706 -58, -56, -55, -53, -51, -49, -47, -45,
707 -44, -42, -40, -38, -36, -34, -32, -30,
708 -28, -26, -24, -22, -20, -18, -16, -14,
709 -12, -10, -8, -6, -4, -2, 0, 1,
710 3, 5, 7, 9, 11, 13, 15, 17,
711 19, 21, 23, 25, 27, 29, 31, 33,
712 35, 37, 39, 41, 43, 45, 46, 48,
713 50, 52, 54, 55, 57, 59, 61, 62,
714 64, 66, 67, 69, 71, 72, 74, 75,
715 77, 78, 80, 81, 83, 84, 86, 87,
716 88, 90, 91, 92, 93, 95, 96, 97,
717 98, 99, 100, 101, 102, 103, 104, 105,
718 106, 106, 107, 108, 109, 109, 110, 111,
719 111, 112, 112, 113, 113, 114, 114, 114,
720 115, 115, 115, 115, 116, 116, 116, 116,
721 116, 116, 116, 116, 116, 115, 115, 115,
722 115, 114, 114, 114, 113, 113, 112, 112,
723 111, 111, 110, 110, 109, 108, 108, 107,
724 106, 105, 104, 103, 102, 101, 100, 99,
725 98, 97, 96, 95, 94, 93, 91, 90,
726 89, 88, 86, 85, 84, 82, 81, 79,
727 78, 76, 75, 73, 71, 70, 68, 67,
728 65, 63, 62, 60, 58, 56, 55, 53,
729 51, 49, 47, 45, 44, 42, 40, 38,
730 36, 34, 32, 30, 28, 26, 24, 22,
731 20, 18, 16, 14, 12, 10, 8, 6,
732 4, 2, 0, -1, -3, -5, -7, -9, -11
735 static u16 i2c_ident
[] = {
744 V4L2_IDENT_MT9M001C12ST
,
750 static u16 bridge_init
[][2] = {
751 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
752 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
753 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
754 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
755 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
756 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
757 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
758 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
759 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
760 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
761 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
762 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
763 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
764 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
765 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
766 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
767 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
768 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
769 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
773 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
774 static u8 ov_gain
[] = {
775 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
776 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
777 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
778 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
779 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
780 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
781 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
785 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
786 static u16 micron1_gain
[] = {
787 /* 1x 1.25x 1.5x 1.75x */
788 0x0020, 0x0028, 0x0030, 0x0038,
789 /* 2x 2.25x 2.5x 2.75x */
790 0x00a0, 0x00a4, 0x00a8, 0x00ac,
791 /* 3x 3.25x 3.5x 3.75x */
792 0x00b0, 0x00b4, 0x00b8, 0x00bc,
793 /* 4x 4.25x 4.5x 4.75x */
794 0x00c0, 0x00c4, 0x00c8, 0x00cc,
795 /* 5x 5.25x 5.5x 5.75x */
796 0x00d0, 0x00d4, 0x00d8, 0x00dc,
797 /* 6x 6.25x 6.5x 6.75x */
798 0x00e0, 0x00e4, 0x00e8, 0x00ec,
799 /* 7x 7.25x 7.5x 7.75x */
800 0x00f0, 0x00f4, 0x00f8, 0x00fc,
805 /* mt9m001 sensor uses a different gain formula then other micron sensors */
806 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
807 static u16 micron2_gain
[] = {
808 /* 1x 1.25x 1.5x 1.75x */
809 0x0008, 0x000a, 0x000c, 0x000e,
810 /* 2x 2.25x 2.5x 2.75x */
811 0x0010, 0x0012, 0x0014, 0x0016,
812 /* 3x 3.25x 3.5x 3.75x */
813 0x0018, 0x001a, 0x001c, 0x001e,
814 /* 4x 4.25x 4.5x 4.75x */
815 0x0020, 0x0051, 0x0052, 0x0053,
816 /* 5x 5.25x 5.5x 5.75x */
817 0x0054, 0x0055, 0x0056, 0x0057,
818 /* 6x 6.25x 6.5x 6.75x */
819 0x0058, 0x0059, 0x005a, 0x005b,
820 /* 7x 7.25x 7.5x 7.75x */
821 0x005c, 0x005d, 0x005e, 0x005f,
826 /* Gain = .5 + bit[7:0] / 16 */
827 static u8 hv7131r_gain
[] = {
828 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
829 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
830 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
831 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
832 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
833 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
834 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
838 static struct i2c_reg_u8 soi968_init
[] = {
839 {0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f},
840 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
841 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
842 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
843 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
844 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
845 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
846 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
847 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
848 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
849 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
852 static struct i2c_reg_u8 ov7660_init
[] = {
853 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
854 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
855 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
856 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
857 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6},
858 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
861 static struct i2c_reg_u8 ov7670_init
[] = {
862 {0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
863 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
864 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
865 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
866 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
867 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
868 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
869 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
870 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
871 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
872 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
873 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
874 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
875 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
876 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
877 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
878 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
879 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
880 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
881 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
882 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
883 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
884 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
885 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
886 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
887 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
888 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
889 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
890 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
891 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
892 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
893 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
894 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
895 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
896 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
897 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
898 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
899 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
900 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
901 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
902 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
903 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
904 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
905 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
906 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
907 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
908 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
909 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
910 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
911 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
912 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
913 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
914 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
918 static struct i2c_reg_u8 ov9650_init
[] = {
919 {0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78},
920 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
921 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
922 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
923 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
924 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
925 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
926 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
927 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
928 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
929 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
930 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
931 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
932 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
933 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
934 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
935 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
936 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
937 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
938 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
939 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
940 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
941 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
942 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
943 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
944 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
945 {0xaa, 0x92}, {0xab, 0x0a},
948 static struct i2c_reg_u8 ov9655_init
[] = {
949 {0x12, 0x80}, {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
950 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
951 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
952 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
953 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
954 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
955 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
956 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
957 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
958 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
959 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
960 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
961 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
962 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
963 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
964 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
965 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
966 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
967 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
968 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
969 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
970 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
971 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
972 {0x04, 0x03}, {0x00, 0x13},
975 static struct i2c_reg_u16 mt9v112_init
[] = {
976 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
977 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
978 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
979 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
980 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
981 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
982 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
983 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
984 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
985 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
986 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
987 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
988 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
989 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
990 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
991 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
994 static struct i2c_reg_u16 mt9v111_init
[] = {
995 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
996 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
997 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
998 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
999 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
1000 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
1001 {0x0e, 0x0008}, {0x20, 0x0000}
1004 static struct i2c_reg_u16 mt9v011_init
[] = {
1005 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
1006 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
1007 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
1008 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
1009 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
1010 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
1011 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
1012 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
1013 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
1014 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
1015 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
1016 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
1017 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
1018 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
1019 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
1020 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
1021 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
1022 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
1023 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
1024 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
1025 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
1026 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1027 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
1028 {0x06, 0x0029}, {0x05, 0x0009},
1031 static struct i2c_reg_u16 mt9m001_init
[] = {
1032 {0x0d, 0x0001}, {0x0d, 0x0000}, {0x01, 0x000e},
1033 {0x02, 0x0014}, {0x03, 0x03c1}, {0x04, 0x0501},
1034 {0x05, 0x0083}, {0x06, 0x0006}, {0x0d, 0x0002},
1035 {0x0a, 0x0000}, {0x0c, 0x0000}, {0x11, 0x0000},
1036 {0x1e, 0x8000}, {0x5f, 0x8904}, {0x60, 0x0000},
1037 {0x61, 0x0000}, {0x62, 0x0498}, {0x63, 0x0000},
1038 {0x64, 0x0000}, {0x20, 0x111d}, {0x06, 0x00f2},
1039 {0x05, 0x0013}, {0x09, 0x10f2}, {0x07, 0x0003},
1040 {0x2b, 0x002a}, {0x2d, 0x002a}, {0x2c, 0x002a},
1041 {0x2e, 0x0029}, {0x07, 0x0002},
1044 static struct i2c_reg_u16 mt9m111_init
[] = {
1045 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1046 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1047 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1051 static struct i2c_reg_u16 mt9m112_init
[] = {
1052 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1053 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1054 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1058 static struct i2c_reg_u8 hv7131r_init
[] = {
1059 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
1060 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
1061 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
1062 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
1063 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
1064 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
1065 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
1066 {0x23, 0x09}, {0x01, 0x08},
1069 static int reg_r(struct gspca_dev
*gspca_dev
, u16 reg
, u16 length
)
1071 struct usb_device
*dev
= gspca_dev
->dev
;
1073 result
= usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
1075 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
1081 if (unlikely(result
< 0 || result
!= length
)) {
1082 err("Read register failed 0x%02X", reg
);
1088 static int reg_w(struct gspca_dev
*gspca_dev
, u16 reg
,
1089 const u8
*buffer
, int length
)
1091 struct usb_device
*dev
= gspca_dev
->dev
;
1093 memcpy(gspca_dev
->usb_buf
, buffer
, length
);
1094 result
= usb_control_msg(dev
, usb_sndctrlpipe(dev
, 0),
1096 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
1102 if (unlikely(result
< 0 || result
!= length
)) {
1103 err("Write register failed index 0x%02X", reg
);
1109 static int reg_w1(struct gspca_dev
*gspca_dev
, u16 reg
, const u8 value
)
1111 u8 data
[1] = {value
};
1112 return reg_w(gspca_dev
, reg
, data
, 1);
1115 static int i2c_w(struct gspca_dev
*gspca_dev
, const u8
*buffer
)
1118 reg_w(gspca_dev
, 0x10c0, buffer
, 8);
1119 for (i
= 0; i
< 5; i
++) {
1120 reg_r(gspca_dev
, 0x10c0, 1);
1121 if (gspca_dev
->usb_buf
[0] & 0x04) {
1122 if (gspca_dev
->usb_buf
[0] & 0x08)
1131 static int i2c_w1(struct gspca_dev
*gspca_dev
, u8 reg
, u8 val
)
1133 struct sd
*sd
= (struct sd
*) gspca_dev
;
1138 * from the point of view of the bridge, the length
1139 * includes the address
1141 row
[0] = 0x81 | (2 << 4);
1142 row
[1] = sd
->i2c_addr
;
1150 return i2c_w(gspca_dev
, row
);
1153 static int i2c_w2(struct gspca_dev
*gspca_dev
, u8 reg
, u16 val
)
1155 struct sd
*sd
= (struct sd
*) gspca_dev
;
1159 * from the point of view of the bridge, the length
1160 * includes the address
1162 row
[0] = 0x81 | (3 << 4);
1163 row
[1] = sd
->i2c_addr
;
1165 row
[3] = (val
>> 8) & 0xff;
1166 row
[4] = val
& 0xff;
1171 return i2c_w(gspca_dev
, row
);
1174 static int i2c_r1(struct gspca_dev
*gspca_dev
, u8 reg
, u8
*val
)
1176 struct sd
*sd
= (struct sd
*) gspca_dev
;
1179 row
[0] = 0x81 | (1 << 4);
1180 row
[1] = sd
->i2c_addr
;
1187 if (i2c_w(gspca_dev
, row
) < 0)
1189 row
[0] = 0x81 | (1 << 4) | 0x02;
1191 if (i2c_w(gspca_dev
, row
) < 0)
1193 if (reg_r(gspca_dev
, 0x10c2, 5) < 0)
1195 *val
= gspca_dev
->usb_buf
[4];
1199 static int i2c_r2(struct gspca_dev
*gspca_dev
, u8 reg
, u16
*val
)
1201 struct sd
*sd
= (struct sd
*) gspca_dev
;
1204 row
[0] = 0x81 | (1 << 4);
1205 row
[1] = sd
->i2c_addr
;
1212 if (i2c_w(gspca_dev
, row
) < 0)
1214 row
[0] = 0x81 | (2 << 4) | 0x02;
1216 if (i2c_w(gspca_dev
, row
) < 0)
1218 if (reg_r(gspca_dev
, 0x10c2, 5) < 0)
1220 *val
= (gspca_dev
->usb_buf
[3] << 8) | gspca_dev
->usb_buf
[4];
1224 static int ov9650_init_sensor(struct gspca_dev
*gspca_dev
)
1227 struct sd
*sd
= (struct sd
*) gspca_dev
;
1229 for (i
= 0; i
< ARRAY_SIZE(ov9650_init
); i
++) {
1230 if (i2c_w1(gspca_dev
, ov9650_init
[i
].reg
,
1231 ov9650_init
[i
].val
) < 0) {
1232 err("OV9650 sensor initialization failed");
1241 static int ov9655_init_sensor(struct gspca_dev
*gspca_dev
)
1244 struct sd
*sd
= (struct sd
*) gspca_dev
;
1246 for (i
= 0; i
< ARRAY_SIZE(ov9655_init
); i
++) {
1247 if (i2c_w1(gspca_dev
, ov9655_init
[i
].reg
,
1248 ov9655_init
[i
].val
) < 0) {
1249 err("OV9655 sensor initialization failed");
1253 /* disable hflip and vflip */
1254 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1260 static int soi968_init_sensor(struct gspca_dev
*gspca_dev
)
1263 struct sd
*sd
= (struct sd
*) gspca_dev
;
1265 for (i
= 0; i
< ARRAY_SIZE(soi968_init
); i
++) {
1266 if (i2c_w1(gspca_dev
, soi968_init
[i
].reg
,
1267 soi968_init
[i
].val
) < 0) {
1268 err("SOI968 sensor initialization failed");
1272 /* disable hflip and vflip */
1273 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
) | (1 << EXPOSURE_IDX
);
1279 static int ov7660_init_sensor(struct gspca_dev
*gspca_dev
)
1282 struct sd
*sd
= (struct sd
*) gspca_dev
;
1284 for (i
= 0; i
< ARRAY_SIZE(ov7660_init
); i
++) {
1285 if (i2c_w1(gspca_dev
, ov7660_init
[i
].reg
,
1286 ov7660_init
[i
].val
) < 0) {
1287 err("OV7660 sensor initialization failed");
1291 /* disable hflip and vflip */
1292 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1298 static int ov7670_init_sensor(struct gspca_dev
*gspca_dev
)
1301 struct sd
*sd
= (struct sd
*) gspca_dev
;
1303 for (i
= 0; i
< ARRAY_SIZE(ov7670_init
); i
++) {
1304 if (i2c_w1(gspca_dev
, ov7670_init
[i
].reg
,
1305 ov7670_init
[i
].val
) < 0) {
1306 err("OV7670 sensor initialization failed");
1310 /* disable hflip and vflip */
1311 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1317 static int mt9v_init_sensor(struct gspca_dev
*gspca_dev
)
1319 struct sd
*sd
= (struct sd
*) gspca_dev
;
1324 sd
->i2c_addr
= 0x5d;
1325 ret
= i2c_r2(gspca_dev
, 0xff, &value
);
1326 if ((ret
== 0) && (value
== 0x8243)) {
1327 for (i
= 0; i
< ARRAY_SIZE(mt9v011_init
); i
++) {
1328 if (i2c_w2(gspca_dev
, mt9v011_init
[i
].reg
,
1329 mt9v011_init
[i
].val
) < 0) {
1330 err("MT9V011 sensor initialization failed");
1336 sd
->sensor
= SENSOR_MT9V011
;
1337 info("MT9V011 sensor detected");
1341 sd
->i2c_addr
= 0x5c;
1342 i2c_w2(gspca_dev
, 0x01, 0x0004);
1343 ret
= i2c_r2(gspca_dev
, 0xff, &value
);
1344 if ((ret
== 0) && (value
== 0x823a)) {
1345 for (i
= 0; i
< ARRAY_SIZE(mt9v111_init
); i
++) {
1346 if (i2c_w2(gspca_dev
, mt9v111_init
[i
].reg
,
1347 mt9v111_init
[i
].val
) < 0) {
1348 err("MT9V111 sensor initialization failed");
1352 gspca_dev
->ctrl_dis
= (1 << EXPOSURE_IDX
) | (1 << AUTOGAIN_IDX
) | (1 << GAIN_IDX
);
1355 sd
->sensor
= SENSOR_MT9V111
;
1356 info("MT9V111 sensor detected");
1360 sd
->i2c_addr
= 0x5d;
1361 ret
= i2c_w2(gspca_dev
, 0xf0, 0x0000);
1363 sd
->i2c_addr
= 0x48;
1364 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1366 ret
= i2c_r2(gspca_dev
, 0x00, &value
);
1367 if ((ret
== 0) && (value
== 0x1229)) {
1368 for (i
= 0; i
< ARRAY_SIZE(mt9v112_init
); i
++) {
1369 if (i2c_w2(gspca_dev
, mt9v112_init
[i
].reg
,
1370 mt9v112_init
[i
].val
) < 0) {
1371 err("MT9V112 sensor initialization failed");
1377 sd
->sensor
= SENSOR_MT9V112
;
1378 info("MT9V112 sensor detected");
1385 static int mt9m112_init_sensor(struct gspca_dev
*gspca_dev
)
1387 struct sd
*sd
= (struct sd
*) gspca_dev
;
1389 for (i
= 0; i
< ARRAY_SIZE(mt9m112_init
); i
++) {
1390 if (i2c_w2(gspca_dev
, mt9m112_init
[i
].reg
,
1391 mt9m112_init
[i
].val
) < 0) {
1392 err("MT9M112 sensor initialization failed");
1396 gspca_dev
->ctrl_dis
= (1 << EXPOSURE_IDX
) | (1 << AUTOGAIN_IDX
) | (1 << GAIN_IDX
);
1402 static int mt9m111_init_sensor(struct gspca_dev
*gspca_dev
)
1404 struct sd
*sd
= (struct sd
*) gspca_dev
;
1406 for (i
= 0; i
< ARRAY_SIZE(mt9m111_init
); i
++) {
1407 if (i2c_w2(gspca_dev
, mt9m111_init
[i
].reg
,
1408 mt9m111_init
[i
].val
) < 0) {
1409 err("MT9M111 sensor initialization failed");
1413 gspca_dev
->ctrl_dis
= (1 << EXPOSURE_IDX
) | (1 << AUTOGAIN_IDX
) | (1 << GAIN_IDX
);
1419 static int mt9m001_init_sensor(struct gspca_dev
*gspca_dev
)
1421 struct sd
*sd
= (struct sd
*) gspca_dev
;
1423 for (i
= 0; i
< ARRAY_SIZE(mt9m001_init
); i
++) {
1424 if (i2c_w2(gspca_dev
, mt9m001_init
[i
].reg
,
1425 mt9m001_init
[i
].val
) < 0) {
1426 err("MT9M001 sensor initialization failed");
1430 /* disable hflip and vflip */
1431 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1437 static int hv7131r_init_sensor(struct gspca_dev
*gspca_dev
)
1440 struct sd
*sd
= (struct sd
*) gspca_dev
;
1442 for (i
= 0; i
< ARRAY_SIZE(hv7131r_init
); i
++) {
1443 if (i2c_w1(gspca_dev
, hv7131r_init
[i
].reg
,
1444 hv7131r_init
[i
].val
) < 0) {
1445 err("HV7131R Sensor initialization failed");
1454 static int set_cmatrix(struct gspca_dev
*gspca_dev
)
1456 struct sd
*sd
= (struct sd
*) gspca_dev
;
1457 s32 hue_coord
, hue_index
= 180 + sd
->hue
;
1460 memset(cmatrix
, 0, sizeof cmatrix
);
1461 cmatrix
[2] = (sd
->contrast
* 0x25 / 0x100) + 0x26;
1462 cmatrix
[0] = 0x13 + (cmatrix
[2] - 0x26) * 0x13 / 0x25;
1463 cmatrix
[4] = 0x07 + (cmatrix
[2] - 0x26) * 0x07 / 0x25;
1464 cmatrix
[18] = sd
->brightness
- 0x80;
1466 hue_coord
= (hsv_red_x
[hue_index
] * sd
->saturation
) >> 8;
1467 cmatrix
[6] = hue_coord
;
1468 cmatrix
[7] = (hue_coord
>> 8) & 0x0f;
1470 hue_coord
= (hsv_red_y
[hue_index
] * sd
->saturation
) >> 8;
1471 cmatrix
[8] = hue_coord
;
1472 cmatrix
[9] = (hue_coord
>> 8) & 0x0f;
1474 hue_coord
= (hsv_green_x
[hue_index
] * sd
->saturation
) >> 8;
1475 cmatrix
[10] = hue_coord
;
1476 cmatrix
[11] = (hue_coord
>> 8) & 0x0f;
1478 hue_coord
= (hsv_green_y
[hue_index
] * sd
->saturation
) >> 8;
1479 cmatrix
[12] = hue_coord
;
1480 cmatrix
[13] = (hue_coord
>> 8) & 0x0f;
1482 hue_coord
= (hsv_blue_x
[hue_index
] * sd
->saturation
) >> 8;
1483 cmatrix
[14] = hue_coord
;
1484 cmatrix
[15] = (hue_coord
>> 8) & 0x0f;
1486 hue_coord
= (hsv_blue_y
[hue_index
] * sd
->saturation
) >> 8;
1487 cmatrix
[16] = hue_coord
;
1488 cmatrix
[17] = (hue_coord
>> 8) & 0x0f;
1490 return reg_w(gspca_dev
, 0x10e1, cmatrix
, 21);
1493 static int set_gamma(struct gspca_dev
*gspca_dev
)
1495 struct sd
*sd
= (struct sd
*) gspca_dev
;
1497 u8 gval
= sd
->gamma
* 0xb8 / 0x100;
1501 gamma
[1] = 0x13 + (gval
* (0xcb - 0x13) / 0xb8);
1502 gamma
[2] = 0x25 + (gval
* (0xee - 0x25) / 0xb8);
1503 gamma
[3] = 0x37 + (gval
* (0xfa - 0x37) / 0xb8);
1504 gamma
[4] = 0x45 + (gval
* (0xfc - 0x45) / 0xb8);
1505 gamma
[5] = 0x55 + (gval
* (0xfb - 0x55) / 0xb8);
1506 gamma
[6] = 0x65 + (gval
* (0xfc - 0x65) / 0xb8);
1507 gamma
[7] = 0x74 + (gval
* (0xfd - 0x74) / 0xb8);
1508 gamma
[8] = 0x83 + (gval
* (0xfe - 0x83) / 0xb8);
1509 gamma
[9] = 0x92 + (gval
* (0xfc - 0x92) / 0xb8);
1510 gamma
[10] = 0xa1 + (gval
* (0xfc - 0xa1) / 0xb8);
1511 gamma
[11] = 0xb0 + (gval
* (0xfc - 0xb0) / 0xb8);
1512 gamma
[12] = 0xbf + (gval
* (0xfb - 0xbf) / 0xb8);
1513 gamma
[13] = 0xce + (gval
* (0xfb - 0xce) / 0xb8);
1514 gamma
[14] = 0xdf + (gval
* (0xfd - 0xdf) / 0xb8);
1515 gamma
[15] = 0xea + (gval
* (0xf9 - 0xea) / 0xb8);
1518 return reg_w(gspca_dev
, 0x1190, gamma
, 17);
1521 static int set_redblue(struct gspca_dev
*gspca_dev
)
1523 struct sd
*sd
= (struct sd
*) gspca_dev
;
1524 reg_w1(gspca_dev
, 0x118c, sd
->red
);
1525 reg_w1(gspca_dev
, 0x118f, sd
->blue
);
1529 static int set_hvflip(struct gspca_dev
*gspca_dev
)
1531 u8 value
, tslb
, hflip
, vflip
;
1533 struct sd
*sd
= (struct sd
*) gspca_dev
;
1535 if ((sd
->flags
& FLIP_DETECT
) && dmi_check_system(flip_dmi_table
)) {
1543 switch (sd
->sensor
) {
1545 i2c_r1(gspca_dev
, 0x1e, &value
);
1554 i2c_w1(gspca_dev
, 0x1e, value
);
1555 i2c_w1(gspca_dev
, 0x3a, tslb
);
1557 case SENSOR_MT9V111
:
1558 case SENSOR_MT9V011
:
1559 i2c_r2(gspca_dev
, 0x20, &value2
);
1565 i2c_w2(gspca_dev
, 0x20, value2
);
1567 case SENSOR_MT9M112
:
1568 case SENSOR_MT9M111
:
1569 case SENSOR_MT9V112
:
1570 i2c_r2(gspca_dev
, 0x20, &value2
);
1576 i2c_w2(gspca_dev
, 0x20, value2
);
1578 case SENSOR_HV7131R
:
1579 i2c_r1(gspca_dev
, 0x01, &value
);
1585 i2c_w1(gspca_dev
, 0x01, value
);
1591 static int set_exposure(struct gspca_dev
*gspca_dev
)
1593 struct sd
*sd
= (struct sd
*) gspca_dev
;
1594 u8 exp
[8] = {0x81, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1595 switch (sd
->sensor
) {
1602 exp
[3] = sd
->exposure
& 0xff;
1603 exp
[4] = sd
->exposure
>> 8;
1605 case SENSOR_MT9M001
:
1606 case SENSOR_MT9V112
:
1607 case SENSOR_MT9V011
:
1610 exp
[3] = sd
->exposure
>> 8;
1611 exp
[4] = sd
->exposure
& 0xff;
1613 case SENSOR_HV7131R
:
1616 exp
[3] = (sd
->exposure
>> 5) & 0xff;
1617 exp
[4] = (sd
->exposure
<< 3) & 0xff;
1623 i2c_w(gspca_dev
, exp
);
1627 static int set_gain(struct gspca_dev
*gspca_dev
)
1629 struct sd
*sd
= (struct sd
*) gspca_dev
;
1630 u8 gain
[8] = {0x81, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1631 switch (sd
->sensor
) {
1637 gain
[0] |= (2 << 4);
1638 gain
[3] = ov_gain
[sd
->gain
];
1640 case SENSOR_MT9V011
:
1641 gain
[0] |= (3 << 4);
1643 gain
[3] = micron1_gain
[sd
->gain
] >> 8;
1644 gain
[4] = micron1_gain
[sd
->gain
] & 0xff;
1646 case SENSOR_MT9V112
:
1647 gain
[0] |= (3 << 4);
1649 gain
[3] = micron1_gain
[sd
->gain
] >> 8;
1650 gain
[4] = micron1_gain
[sd
->gain
] & 0xff;
1652 case SENSOR_MT9M001
:
1653 gain
[0] |= (3 << 4);
1655 gain
[3] = micron2_gain
[sd
->gain
] >> 8;
1656 gain
[4] = micron2_gain
[sd
->gain
] & 0xff;
1658 case SENSOR_HV7131R
:
1659 gain
[0] |= (2 << 4);
1661 gain
[3] = hv7131r_gain
[sd
->gain
];
1666 i2c_w(gspca_dev
, gain
);
1670 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, s32 val
)
1672 struct sd
*sd
= (struct sd
*) gspca_dev
;
1674 sd
->brightness
= val
;
1675 if (gspca_dev
->streaming
)
1676 return set_cmatrix(gspca_dev
);
1680 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, s32
*val
)
1682 struct sd
*sd
= (struct sd
*) gspca_dev
;
1683 *val
= sd
->brightness
;
1688 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, s32 val
)
1690 struct sd
*sd
= (struct sd
*) gspca_dev
;
1693 if (gspca_dev
->streaming
)
1694 return set_cmatrix(gspca_dev
);
1698 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, s32
*val
)
1700 struct sd
*sd
= (struct sd
*) gspca_dev
;
1701 *val
= sd
->contrast
;
1705 static int sd_setsaturation(struct gspca_dev
*gspca_dev
, s32 val
)
1707 struct sd
*sd
= (struct sd
*) gspca_dev
;
1709 sd
->saturation
= val
;
1710 if (gspca_dev
->streaming
)
1711 return set_cmatrix(gspca_dev
);
1715 static int sd_getsaturation(struct gspca_dev
*gspca_dev
, s32
*val
)
1717 struct sd
*sd
= (struct sd
*) gspca_dev
;
1718 *val
= sd
->saturation
;
1722 static int sd_sethue(struct gspca_dev
*gspca_dev
, s32 val
)
1724 struct sd
*sd
= (struct sd
*) gspca_dev
;
1727 if (gspca_dev
->streaming
)
1728 return set_cmatrix(gspca_dev
);
1732 static int sd_gethue(struct gspca_dev
*gspca_dev
, s32
*val
)
1734 struct sd
*sd
= (struct sd
*) gspca_dev
;
1739 static int sd_setgamma(struct gspca_dev
*gspca_dev
, s32 val
)
1741 struct sd
*sd
= (struct sd
*) gspca_dev
;
1744 if (gspca_dev
->streaming
)
1745 return set_gamma(gspca_dev
);
1749 static int sd_getgamma(struct gspca_dev
*gspca_dev
, s32
*val
)
1751 struct sd
*sd
= (struct sd
*) gspca_dev
;
1756 static int sd_setredbalance(struct gspca_dev
*gspca_dev
, s32 val
)
1758 struct sd
*sd
= (struct sd
*) gspca_dev
;
1761 if (gspca_dev
->streaming
)
1762 return set_redblue(gspca_dev
);
1766 static int sd_getredbalance(struct gspca_dev
*gspca_dev
, s32
*val
)
1768 struct sd
*sd
= (struct sd
*) gspca_dev
;
1773 static int sd_setbluebalance(struct gspca_dev
*gspca_dev
, s32 val
)
1775 struct sd
*sd
= (struct sd
*) gspca_dev
;
1778 if (gspca_dev
->streaming
)
1779 return set_redblue(gspca_dev
);
1783 static int sd_getbluebalance(struct gspca_dev
*gspca_dev
, s32
*val
)
1785 struct sd
*sd
= (struct sd
*) gspca_dev
;
1790 static int sd_sethflip(struct gspca_dev
*gspca_dev
, s32 val
)
1792 struct sd
*sd
= (struct sd
*) gspca_dev
;
1795 if (gspca_dev
->streaming
)
1796 return set_hvflip(gspca_dev
);
1800 static int sd_gethflip(struct gspca_dev
*gspca_dev
, s32
*val
)
1802 struct sd
*sd
= (struct sd
*) gspca_dev
;
1807 static int sd_setvflip(struct gspca_dev
*gspca_dev
, s32 val
)
1809 struct sd
*sd
= (struct sd
*) gspca_dev
;
1812 if (gspca_dev
->streaming
)
1813 return set_hvflip(gspca_dev
);
1817 static int sd_getvflip(struct gspca_dev
*gspca_dev
, s32
*val
)
1819 struct sd
*sd
= (struct sd
*) gspca_dev
;
1824 static int sd_setexposure(struct gspca_dev
*gspca_dev
, s32 val
)
1826 struct sd
*sd
= (struct sd
*) gspca_dev
;
1829 if (gspca_dev
->streaming
)
1830 return set_exposure(gspca_dev
);
1834 static int sd_getexposure(struct gspca_dev
*gspca_dev
, s32
*val
)
1836 struct sd
*sd
= (struct sd
*) gspca_dev
;
1837 *val
= sd
->exposure
;
1841 static int sd_setgain(struct gspca_dev
*gspca_dev
, s32 val
)
1843 struct sd
*sd
= (struct sd
*) gspca_dev
;
1846 if (gspca_dev
->streaming
)
1847 return set_gain(gspca_dev
);
1851 static int sd_getgain(struct gspca_dev
*gspca_dev
, s32
*val
)
1853 struct sd
*sd
= (struct sd
*) gspca_dev
;
1858 static int sd_setautoexposure(struct gspca_dev
*gspca_dev
, s32 val
)
1860 struct sd
*sd
= (struct sd
*) gspca_dev
;
1861 sd
->auto_exposure
= val
;
1865 static int sd_getautoexposure(struct gspca_dev
*gspca_dev
, s32
*val
)
1867 struct sd
*sd
= (struct sd
*) gspca_dev
;
1868 *val
= sd
->auto_exposure
;
1872 #ifdef CONFIG_VIDEO_ADV_DEBUG
1873 static int sd_dbg_g_register(struct gspca_dev
*gspca_dev
,
1874 struct v4l2_dbg_register
*reg
)
1876 struct sd
*sd
= (struct sd
*) gspca_dev
;
1877 switch (reg
->match
.type
) {
1878 case V4L2_CHIP_MATCH_HOST
:
1879 if (reg
->match
.addr
!= 0)
1881 if (reg
->reg
< 0x1000 || reg
->reg
> 0x11ff)
1883 if (reg_r(gspca_dev
, reg
->reg
, 1) < 0)
1885 reg
->val
= gspca_dev
->usb_buf
[0];
1887 case V4L2_CHIP_MATCH_I2C_ADDR
:
1888 if (reg
->match
.addr
!= sd
->i2c_addr
)
1890 if (sd
->sensor
>= SENSOR_MT9V011
&&
1891 sd
->sensor
<= SENSOR_MT9M112
) {
1892 if (i2c_r2(gspca_dev
, reg
->reg
, (u16
*)®
->val
) < 0)
1895 if (i2c_r1(gspca_dev
, reg
->reg
, (u8
*)®
->val
) < 0)
1903 static int sd_dbg_s_register(struct gspca_dev
*gspca_dev
,
1904 struct v4l2_dbg_register
*reg
)
1906 struct sd
*sd
= (struct sd
*) gspca_dev
;
1907 switch (reg
->match
.type
) {
1908 case V4L2_CHIP_MATCH_HOST
:
1909 if (reg
->match
.addr
!= 0)
1911 if (reg
->reg
< 0x1000 || reg
->reg
> 0x11ff)
1913 if (reg_w1(gspca_dev
, reg
->reg
, reg
->val
) < 0)
1916 case V4L2_CHIP_MATCH_I2C_ADDR
:
1917 if (reg
->match
.addr
!= sd
->i2c_addr
)
1919 if (sd
->sensor
>= SENSOR_MT9V011
&&
1920 sd
->sensor
<= SENSOR_MT9M112
) {
1921 if (i2c_w2(gspca_dev
, reg
->reg
, reg
->val
) < 0)
1924 if (i2c_w1(gspca_dev
, reg
->reg
, reg
->val
) < 0)
1933 static int sd_chip_ident(struct gspca_dev
*gspca_dev
,
1934 struct v4l2_dbg_chip_ident
*chip
)
1936 struct sd
*sd
= (struct sd
*) gspca_dev
;
1938 switch (chip
->match
.type
) {
1939 case V4L2_CHIP_MATCH_HOST
:
1940 if (chip
->match
.addr
!= 0)
1943 chip
->ident
= V4L2_IDENT_SN9C20X
;
1945 case V4L2_CHIP_MATCH_I2C_ADDR
:
1946 if (chip
->match
.addr
!= sd
->i2c_addr
)
1949 chip
->ident
= i2c_ident
[sd
->sensor
];
1955 static int sd_config(struct gspca_dev
*gspca_dev
,
1956 const struct usb_device_id
*id
)
1958 struct sd
*sd
= (struct sd
*) gspca_dev
;
1961 cam
= &gspca_dev
->cam
;
1963 sd
->sensor
= (id
->driver_info
>> 8) & 0xff;
1964 sd
->i2c_addr
= id
->driver_info
& 0xff;
1965 sd
->flags
= (id
->driver_info
>> 16) & 0xff;
1967 switch (sd
->sensor
) {
1968 case SENSOR_MT9M112
:
1969 case SENSOR_MT9M111
:
1972 cam
->cam_mode
= sxga_mode
;
1973 cam
->nmodes
= ARRAY_SIZE(sxga_mode
);
1976 cam
->cam_mode
= vga_mode
;
1977 cam
->nmodes
= ARRAY_SIZE(vga_mode
);
1983 sd
->exposure_step
= 16;
1985 sd
->brightness
= BRIGHTNESS_DEFAULT
;
1986 sd
->contrast
= CONTRAST_DEFAULT
;
1987 sd
->saturation
= SATURATION_DEFAULT
;
1988 sd
->hue
= HUE_DEFAULT
;
1989 sd
->gamma
= GAMMA_DEFAULT
;
1990 sd
->red
= RED_DEFAULT
;
1991 sd
->blue
= BLUE_DEFAULT
;
1993 sd
->hflip
= HFLIP_DEFAULT
;
1994 sd
->vflip
= VFLIP_DEFAULT
;
1995 sd
->exposure
= EXPOSURE_DEFAULT
;
1996 sd
->gain
= GAIN_DEFAULT
;
1997 sd
->auto_exposure
= AUTO_EXPOSURE_DEFAULT
;
2004 static int sd_init(struct gspca_dev
*gspca_dev
)
2006 struct sd
*sd
= (struct sd
*) gspca_dev
;
2010 {0x80, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
2012 for (i
= 0; i
< ARRAY_SIZE(bridge_init
); i
++) {
2013 value
= bridge_init
[i
][1];
2014 if (reg_w(gspca_dev
, bridge_init
[i
][0], &value
, 1) < 0) {
2015 err("Device initialization failed");
2020 if (sd
->flags
& LED_REVERSE
)
2021 reg_w1(gspca_dev
, 0x1006, 0x00);
2023 reg_w1(gspca_dev
, 0x1006, 0x20);
2025 if (reg_w(gspca_dev
, 0x10c0, i2c_init
, 9) < 0) {
2026 err("Device initialization failed");
2030 switch (sd
->sensor
) {
2032 if (ov9650_init_sensor(gspca_dev
) < 0)
2034 info("OV9650 sensor detected");
2037 if (ov9655_init_sensor(gspca_dev
) < 0)
2039 info("OV9655 sensor detected");
2042 if (soi968_init_sensor(gspca_dev
) < 0)
2044 info("SOI968 sensor detected");
2047 if (ov7660_init_sensor(gspca_dev
) < 0)
2049 info("OV7660 sensor detected");
2052 if (ov7670_init_sensor(gspca_dev
) < 0)
2054 info("OV7670 sensor detected");
2056 case SENSOR_MT9VPRB
:
2057 if (mt9v_init_sensor(gspca_dev
) < 0)
2060 case SENSOR_MT9M111
:
2061 if (mt9m111_init_sensor(gspca_dev
) < 0)
2063 info("MT9M111 sensor detected");
2065 case SENSOR_MT9M112
:
2066 if (mt9m112_init_sensor(gspca_dev
) < 0)
2068 info("MT9M112 sensor detected");
2070 case SENSOR_MT9M001
:
2071 if (mt9m001_init_sensor(gspca_dev
) < 0)
2073 info("MT9M001 sensor detected");
2075 case SENSOR_HV7131R
:
2076 if (hv7131r_init_sensor(gspca_dev
) < 0)
2078 info("HV7131R sensor detected");
2081 info("Unsupported Sensor");
2088 static void configure_sensor_output(struct gspca_dev
*gspca_dev
, int mode
)
2090 struct sd
*sd
= (struct sd
*) gspca_dev
;
2092 switch (sd
->sensor
) {
2094 if (mode
& MODE_SXGA
) {
2095 i2c_w1(gspca_dev
, 0x17, 0x1d);
2096 i2c_w1(gspca_dev
, 0x18, 0xbd);
2097 i2c_w1(gspca_dev
, 0x19, 0x01);
2098 i2c_w1(gspca_dev
, 0x1a, 0x81);
2099 i2c_w1(gspca_dev
, 0x12, 0x00);
2103 i2c_w1(gspca_dev
, 0x17, 0x13);
2104 i2c_w1(gspca_dev
, 0x18, 0x63);
2105 i2c_w1(gspca_dev
, 0x19, 0x01);
2106 i2c_w1(gspca_dev
, 0x1a, 0x79);
2107 i2c_w1(gspca_dev
, 0x12, 0x40);
2113 if (mode
& MODE_SXGA
) {
2114 i2c_w1(gspca_dev
, 0x17, 0x1b);
2115 i2c_w1(gspca_dev
, 0x18, 0xbc);
2116 i2c_w1(gspca_dev
, 0x19, 0x01);
2117 i2c_w1(gspca_dev
, 0x1a, 0x82);
2118 i2c_r1(gspca_dev
, 0x12, &value
);
2119 i2c_w1(gspca_dev
, 0x12, value
& 0x07);
2121 i2c_w1(gspca_dev
, 0x17, 0x24);
2122 i2c_w1(gspca_dev
, 0x18, 0xc5);
2123 i2c_w1(gspca_dev
, 0x19, 0x00);
2124 i2c_w1(gspca_dev
, 0x1a, 0x3c);
2125 i2c_r1(gspca_dev
, 0x12, &value
);
2126 i2c_w1(gspca_dev
, 0x12, (value
& 0x7) | 0x40);
2129 case SENSOR_MT9M112
:
2130 case SENSOR_MT9M111
:
2131 if (mode
& MODE_SXGA
) {
2132 i2c_w2(gspca_dev
, 0xf0, 0x0002);
2133 i2c_w2(gspca_dev
, 0xc8, 0x970b);
2134 i2c_w2(gspca_dev
, 0xf0, 0x0000);
2136 i2c_w2(gspca_dev
, 0xf0, 0x0002);
2137 i2c_w2(gspca_dev
, 0xc8, 0x8000);
2138 i2c_w2(gspca_dev
, 0xf0, 0x0000);
2144 #define HW_WIN(mode, hstart, vstart) \
2145 ((const u8 []){hstart, 0, vstart, 0, \
2146 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
2147 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
2149 #define CLR_WIN(width, height) \
2151 {0, width >> 2, 0, height >> 1,\
2152 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
2154 static int sd_start(struct gspca_dev
*gspca_dev
)
2156 struct sd
*sd
= (struct sd
*) gspca_dev
;
2157 int mode
= gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
;
2158 int width
= gspca_dev
->width
;
2159 int height
= gspca_dev
->height
;
2162 jpeg_define(sd
->jpeg_hdr
, height
, width
,
2164 jpeg_set_qual(sd
->jpeg_hdr
, sd
->quality
);
2166 if (mode
& MODE_RAW
)
2168 else if (mode
& MODE_JPEG
)
2173 switch (mode
& 0x0f) {
2176 info("Set 1280x1024");
2180 info("Set 640x480");
2184 info("Set 320x240");
2188 info("Set 160x120");
2192 configure_sensor_output(gspca_dev
, mode
);
2193 reg_w(gspca_dev
, 0x1100, &sd
->jpeg_hdr
[JPEG_QT0_OFFSET
], 64);
2194 reg_w(gspca_dev
, 0x1140, &sd
->jpeg_hdr
[JPEG_QT1_OFFSET
], 64);
2195 reg_w(gspca_dev
, 0x10fb, CLR_WIN(width
, height
), 5);
2196 reg_w(gspca_dev
, 0x1180, HW_WIN(mode
, sd
->hstart
, sd
->vstart
), 6);
2197 reg_w1(gspca_dev
, 0x1189, scale
);
2198 reg_w1(gspca_dev
, 0x10e0, fmt
);
2200 set_cmatrix(gspca_dev
);
2201 set_gamma(gspca_dev
);
2202 set_redblue(gspca_dev
);
2203 set_gain(gspca_dev
);
2204 set_exposure(gspca_dev
);
2205 set_hvflip(gspca_dev
);
2207 reg_w1(gspca_dev
, 0x1007, 0x20);
2209 reg_r(gspca_dev
, 0x1061, 1);
2210 reg_w1(gspca_dev
, 0x1061, gspca_dev
->usb_buf
[0] | 0x02);
2214 static void sd_stopN(struct gspca_dev
*gspca_dev
)
2216 reg_w1(gspca_dev
, 0x1007, 0x00);
2218 reg_r(gspca_dev
, 0x1061, 1);
2219 reg_w1(gspca_dev
, 0x1061, gspca_dev
->usb_buf
[0] & ~0x02);
2222 static void do_autoexposure(struct gspca_dev
*gspca_dev
, u16 avg_lum
)
2224 struct sd
*sd
= (struct sd
*) gspca_dev
;
2228 * some hardcoded values are present
2229 * like those for maximal/minimal exposure
2230 * and exposure steps
2232 if (avg_lum
< MIN_AVG_LUM
) {
2233 if (sd
->exposure
> 0x1770)
2236 new_exp
= sd
->exposure
+ sd
->exposure_step
;
2237 if (new_exp
> 0x1770)
2241 sd
->exposure
= new_exp
;
2242 set_exposure(gspca_dev
);
2244 sd
->older_step
= sd
->old_step
;
2247 if (sd
->old_step
^ sd
->older_step
)
2248 sd
->exposure_step
/= 2;
2250 sd
->exposure_step
+= 2;
2252 if (avg_lum
> MAX_AVG_LUM
) {
2253 if (sd
->exposure
< 0x10)
2255 new_exp
= sd
->exposure
- sd
->exposure_step
;
2256 if (new_exp
> 0x1700)
2260 sd
->exposure
= new_exp
;
2261 set_exposure(gspca_dev
);
2262 sd
->older_step
= sd
->old_step
;
2265 if (sd
->old_step
^ sd
->older_step
)
2266 sd
->exposure_step
/= 2;
2268 sd
->exposure_step
+= 2;
2272 static void do_autogain(struct gspca_dev
*gspca_dev
, u16 avg_lum
)
2274 struct sd
*sd
= (struct sd
*) gspca_dev
;
2276 if (avg_lum
< MIN_AVG_LUM
) {
2277 if (sd
->gain
+ 1 <= 28) {
2279 set_gain(gspca_dev
);
2282 if (avg_lum
> MAX_AVG_LUM
) {
2285 set_gain(gspca_dev
);
2290 static void sd_dqcallback(struct gspca_dev
*gspca_dev
)
2292 struct sd
*sd
= (struct sd
*) gspca_dev
;
2295 if (!sd
->auto_exposure
)
2298 avg_lum
= atomic_read(&sd
->avg_lum
);
2299 if (sd
->sensor
== SENSOR_SOI968
)
2300 do_autogain(gspca_dev
, avg_lum
);
2302 do_autoexposure(gspca_dev
, avg_lum
);
2305 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2306 static int sd_int_pkt_scan(struct gspca_dev
*gspca_dev
,
2307 u8
*data
, /* interrupt packet */
2308 int len
) /* interrupt packet length */
2310 struct sd
*sd
= (struct sd
*) gspca_dev
;
2312 if (!(sd
->flags
& HAS_NO_BUTTON
) && len
== 1) {
2313 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 1);
2314 input_sync(gspca_dev
->input_dev
);
2315 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 0);
2316 input_sync(gspca_dev
->input_dev
);
2323 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
2324 u8
*data
, /* isoc packet */
2325 int len
) /* iso packet length */
2327 struct sd
*sd
= (struct sd
*) gspca_dev
;
2329 static u8 frame_header
[] =
2330 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2331 if (len
== 64 && memcmp(data
, frame_header
, 6) == 0) {
2332 avg_lum
= ((data
[35] >> 2) & 3) |
2335 avg_lum
+= ((data
[35] >> 4) & 3) |
2338 avg_lum
+= ((data
[35] >> 6) & 3) |
2341 avg_lum
+= (data
[36] & 3) |
2344 avg_lum
+= ((data
[36] >> 2) & 3) |
2347 avg_lum
+= ((data
[36] >> 4) & 3) |
2350 avg_lum
+= ((data
[36] >> 6) & 3) |
2353 avg_lum
+= ((data
[44] >> 4) & 3) |
2357 atomic_set(&sd
->avg_lum
, avg_lum
);
2358 gspca_frame_add(gspca_dev
, LAST_PACKET
, NULL
, 0);
2361 if (gspca_dev
->last_packet_type
== LAST_PACKET
) {
2362 if (gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
2364 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
2365 sd
->jpeg_hdr
, JPEG_HDR_SZ
);
2366 gspca_frame_add(gspca_dev
, INTER_PACKET
,
2369 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
2373 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, len
);
2377 /* sub-driver description */
2378 static const struct sd_desc sd_desc
= {
2379 .name
= MODULE_NAME
,
2381 .nctrls
= ARRAY_SIZE(sd_ctrls
),
2382 .config
= sd_config
,
2386 .pkt_scan
= sd_pkt_scan
,
2387 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2388 .int_pkt_scan
= sd_int_pkt_scan
,
2390 .dq_callback
= sd_dqcallback
,
2391 #ifdef CONFIG_VIDEO_ADV_DEBUG
2392 .set_register
= sd_dbg_s_register
,
2393 .get_register
= sd_dbg_g_register
,
2395 .get_chip_ident
= sd_chip_ident
,
2398 #define SN9C20X(sensor, i2c_addr, flags) \
2399 .driver_info = ((flags & 0xff) << 16) \
2400 | (SENSOR_ ## sensor << 8) \
2403 static const __devinitdata
struct usb_device_id device_table
[] = {
2404 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001
, 0x5d, 0)},
2405 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111
, 0x5d, 0)},
2406 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655
, 0x30, 0)},
2407 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112
, 0x5d, 0)},
2408 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968
, 0x30, LED_REVERSE
)},
2409 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650
, 0x30,
2410 (FLIP_DETECT
| HAS_NO_BUTTON
))},
2411 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650
, 0x30, 0)},
2412 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650
, 0x30, 0)},
2413 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670
, 0x21, 0)},
2414 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB
, 0x00, 0)},
2415 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660
, 0x21, 0)},
2416 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R
, 0x11, 0)},
2417 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650
, 0x30, 0)},
2418 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001
, 0x5d, 0)},
2419 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111
, 0x5d, 0)},
2420 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655
, 0x30, 0)},
2421 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112
, 0x5d, 0)},
2422 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968
, 0x30, 0)},
2423 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650
, 0x30, 0)},
2424 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670
, 0x21, 0)},
2425 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB
, 0x00, 0)},
2426 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655
, 0x30, 0)},
2427 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660
, 0x21, 0)},
2428 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R
, 0x11, 0)},
2429 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650
, 0x30, 0)},
2430 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660
, 0x21, 0)},
2431 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R
, 0x11, 0)},
2432 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112
, 0x5d, 0)},
2433 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112
, 0x5d, 0)},
2434 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R
, 0x11, 0)},
2435 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R
, 0x11, 0)},
2436 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R
, 0x11, 0)},
2437 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R
, 0x11, 0)},
2438 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111
, 0x5d, 0)},
2439 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111
, 0x5d, 0)},
2440 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111
, 0x5d, 0)},
2443 MODULE_DEVICE_TABLE(usb
, device_table
);
2445 /* -- device connect -- */
2446 static int sd_probe(struct usb_interface
*intf
,
2447 const struct usb_device_id
*id
)
2449 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
2453 static struct usb_driver sd_driver
= {
2454 .name
= MODULE_NAME
,
2455 .id_table
= device_table
,
2457 .disconnect
= gspca_disconnect
,
2459 .suspend
= gspca_suspend
,
2460 .resume
= gspca_resume
,
2461 .reset_resume
= gspca_resume
,
2465 /* -- module insert / remove -- */
2466 static int __init
sd_mod_init(void)
2468 return usb_register(&sd_driver
);
2470 static void __exit
sd_mod_exit(void)
2472 usb_deregister(&sd_driver
);
2475 module_init(sd_mod_init
);
2476 module_exit(sd_mod_exit
);