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 * Pixel format private data
39 #define SCALE_MASK 0x0f
40 #define SCALE_160x120 0
41 #define SCALE_320x240 1
42 #define SCALE_640x480 2
43 #define SCALE_1280x1024 3
45 #define MODE_JPEG 0x20
46 #define MODE_SXGA 0x80
48 #define SENSOR_OV9650 0
49 #define SENSOR_OV9655 1
50 #define SENSOR_SOI968 2
51 #define SENSOR_OV7660 3
52 #define SENSOR_OV7670 4
53 #define SENSOR_MT9V011 5
54 #define SENSOR_MT9V111 6
55 #define SENSOR_MT9V112 7
56 #define SENSOR_MT9M001 8
57 #define SENSOR_MT9M111 9
58 #define SENSOR_MT9M112 10
59 #define SENSOR_HV7131R 11
60 #define SENSOR_MT9VPRB 20
63 #define HAS_NO_BUTTON 0x1
64 #define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
65 #define FLIP_DETECT 0x4
67 /* specific webcam descriptor */
69 struct gspca_dev gspca_dev
;
71 #define MIN_AVG_LUM 80
72 #define MAX_AVG_LUM 130
97 u8 jpeg_hdr
[JPEG_HDR_SZ
];
113 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, s32 val
);
114 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, s32
*val
);
115 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, s32 val
);
116 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, s32
*val
);
117 static int sd_setsaturation(struct gspca_dev
*gspca_dev
, s32 val
);
118 static int sd_getsaturation(struct gspca_dev
*gspca_dev
, s32
*val
);
119 static int sd_sethue(struct gspca_dev
*gspca_dev
, s32 val
);
120 static int sd_gethue(struct gspca_dev
*gspca_dev
, s32
*val
);
121 static int sd_setgamma(struct gspca_dev
*gspca_dev
, s32 val
);
122 static int sd_getgamma(struct gspca_dev
*gspca_dev
, s32
*val
);
123 static int sd_setredbalance(struct gspca_dev
*gspca_dev
, s32 val
);
124 static int sd_getredbalance(struct gspca_dev
*gspca_dev
, s32
*val
);
125 static int sd_setbluebalance(struct gspca_dev
*gspca_dev
, s32 val
);
126 static int sd_getbluebalance(struct gspca_dev
*gspca_dev
, s32
*val
);
127 static int sd_setvflip(struct gspca_dev
*gspca_dev
, s32 val
);
128 static int sd_getvflip(struct gspca_dev
*gspca_dev
, s32
*val
);
129 static int sd_sethflip(struct gspca_dev
*gspca_dev
, s32 val
);
130 static int sd_gethflip(struct gspca_dev
*gspca_dev
, s32
*val
);
131 static int sd_setgain(struct gspca_dev
*gspca_dev
, s32 val
);
132 static int sd_getgain(struct gspca_dev
*gspca_dev
, s32
*val
);
133 static int sd_setexposure(struct gspca_dev
*gspca_dev
, s32 val
);
134 static int sd_getexposure(struct gspca_dev
*gspca_dev
, s32
*val
);
135 static int sd_setautoexposure(struct gspca_dev
*gspca_dev
, s32 val
);
136 static int sd_getautoexposure(struct gspca_dev
*gspca_dev
, s32
*val
);
138 static const struct dmi_system_id flip_dmi_table
[] = {
140 .ident
= "MSI MS-1034",
142 DMI_MATCH(DMI_SYS_VENDOR
, "MICRO-STAR INT'L CO.,LTD."),
143 DMI_MATCH(DMI_PRODUCT_NAME
, "MS-1034"),
144 DMI_MATCH(DMI_PRODUCT_VERSION
, "0341")
148 .ident
= "MSI MS-1632",
150 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
151 DMI_MATCH(DMI_BOARD_NAME
, "MS-1632")
155 .ident
= "MSI MS-1635X",
157 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
158 DMI_MATCH(DMI_BOARD_NAME
, "MS-1635X")
162 .ident
= "ASUSTeK W7J",
164 DMI_MATCH(DMI_BOARD_VENDOR
, "ASUSTeK Computer Inc."),
165 DMI_MATCH(DMI_BOARD_NAME
, "W7J ")
171 static const struct ctrl sd_ctrls
[] = {
173 #define BRIGHTNESS_IDX 0
175 .id
= V4L2_CID_BRIGHTNESS
,
176 .type
= V4L2_CTRL_TYPE_INTEGER
,
177 .name
= "Brightness",
181 #define BRIGHTNESS_DEFAULT 0x7f
182 .default_value
= BRIGHTNESS_DEFAULT
,
184 .set
= sd_setbrightness
,
185 .get
= sd_getbrightness
,
188 #define CONTRAST_IDX 1
190 .id
= V4L2_CID_CONTRAST
,
191 .type
= V4L2_CTRL_TYPE_INTEGER
,
196 #define CONTRAST_DEFAULT 0x7f
197 .default_value
= CONTRAST_DEFAULT
,
199 .set
= sd_setcontrast
,
200 .get
= sd_getcontrast
,
203 #define SATURATION_IDX 2
205 .id
= V4L2_CID_SATURATION
,
206 .type
= V4L2_CTRL_TYPE_INTEGER
,
207 .name
= "Saturation",
211 #define SATURATION_DEFAULT 0x7f
212 .default_value
= SATURATION_DEFAULT
,
214 .set
= sd_setsaturation
,
215 .get
= sd_getsaturation
,
221 .type
= V4L2_CTRL_TYPE_INTEGER
,
226 #define HUE_DEFAULT 0
227 .default_value
= HUE_DEFAULT
,
235 .id
= V4L2_CID_GAMMA
,
236 .type
= V4L2_CTRL_TYPE_INTEGER
,
241 #define GAMMA_DEFAULT 0x10
242 .default_value
= GAMMA_DEFAULT
,
250 .id
= V4L2_CID_BLUE_BALANCE
,
251 .type
= V4L2_CTRL_TYPE_INTEGER
,
252 .name
= "Blue Balance",
256 #define BLUE_DEFAULT 0x28
257 .default_value
= BLUE_DEFAULT
,
259 .set
= sd_setbluebalance
,
260 .get
= sd_getbluebalance
,
265 .id
= V4L2_CID_RED_BALANCE
,
266 .type
= V4L2_CTRL_TYPE_INTEGER
,
267 .name
= "Red Balance",
271 #define RED_DEFAULT 0x28
272 .default_value
= RED_DEFAULT
,
274 .set
= sd_setredbalance
,
275 .get
= sd_getredbalance
,
280 .id
= V4L2_CID_HFLIP
,
281 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
282 .name
= "Horizontal Flip",
286 #define HFLIP_DEFAULT 0
287 .default_value
= HFLIP_DEFAULT
,
295 .id
= V4L2_CID_VFLIP
,
296 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
297 .name
= "Vertical Flip",
301 #define VFLIP_DEFAULT 0
302 .default_value
= VFLIP_DEFAULT
,
308 #define EXPOSURE_IDX 9
310 .id
= V4L2_CID_EXPOSURE
,
311 .type
= V4L2_CTRL_TYPE_INTEGER
,
316 #define EXPOSURE_DEFAULT 0x33
317 .default_value
= EXPOSURE_DEFAULT
,
319 .set
= sd_setexposure
,
320 .get
= sd_getexposure
,
326 .type
= V4L2_CTRL_TYPE_INTEGER
,
331 #define GAIN_DEFAULT 0x00
332 .default_value
= GAIN_DEFAULT
,
338 #define AUTOGAIN_IDX 11
340 .id
= V4L2_CID_AUTOGAIN
,
341 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
342 .name
= "Auto Exposure",
346 #define AUTO_EXPOSURE_DEFAULT 1
347 .default_value
= AUTO_EXPOSURE_DEFAULT
,
349 .set
= sd_setautoexposure
,
350 .get
= sd_getautoexposure
,
354 static const struct v4l2_pix_format vga_mode
[] = {
355 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
357 .sizeimage
= 160 * 120 * 4 / 8 + 590,
358 .colorspace
= V4L2_COLORSPACE_JPEG
,
359 .priv
= SCALE_160x120
| MODE_JPEG
},
360 {160, 120, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
362 .sizeimage
= 160 * 120,
363 .colorspace
= V4L2_COLORSPACE_SRGB
,
364 .priv
= SCALE_160x120
| MODE_RAW
},
365 {160, 120, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
367 .sizeimage
= 240 * 120,
368 .colorspace
= V4L2_COLORSPACE_SRGB
,
369 .priv
= SCALE_160x120
},
370 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
372 .sizeimage
= 320 * 240 * 3 / 8 + 590,
373 .colorspace
= V4L2_COLORSPACE_JPEG
,
374 .priv
= SCALE_320x240
| MODE_JPEG
},
375 {320, 240, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
377 .sizeimage
= 320 * 240 ,
378 .colorspace
= V4L2_COLORSPACE_SRGB
,
379 .priv
= SCALE_320x240
| MODE_RAW
},
380 {320, 240, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
382 .sizeimage
= 480 * 240 ,
383 .colorspace
= V4L2_COLORSPACE_SRGB
,
384 .priv
= SCALE_320x240
},
385 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
387 .sizeimage
= 640 * 480 * 3 / 8 + 590,
388 .colorspace
= V4L2_COLORSPACE_JPEG
,
389 .priv
= SCALE_640x480
| MODE_JPEG
},
390 {640, 480, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
392 .sizeimage
= 640 * 480,
393 .colorspace
= V4L2_COLORSPACE_SRGB
,
394 .priv
= SCALE_640x480
| MODE_RAW
},
395 {640, 480, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
397 .sizeimage
= 960 * 480,
398 .colorspace
= V4L2_COLORSPACE_SRGB
,
399 .priv
= SCALE_640x480
},
402 static const struct v4l2_pix_format sxga_mode
[] = {
403 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
405 .sizeimage
= 160 * 120 * 4 / 8 + 590,
406 .colorspace
= V4L2_COLORSPACE_JPEG
,
407 .priv
= SCALE_160x120
| MODE_JPEG
},
408 {160, 120, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
410 .sizeimage
= 160 * 120,
411 .colorspace
= V4L2_COLORSPACE_SRGB
,
412 .priv
= SCALE_160x120
| MODE_RAW
},
413 {160, 120, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
415 .sizeimage
= 240 * 120,
416 .colorspace
= V4L2_COLORSPACE_SRGB
,
417 .priv
= SCALE_160x120
},
418 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
420 .sizeimage
= 320 * 240 * 3 / 8 + 590,
421 .colorspace
= V4L2_COLORSPACE_JPEG
,
422 .priv
= SCALE_320x240
| MODE_JPEG
},
423 {320, 240, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
425 .sizeimage
= 320 * 240 ,
426 .colorspace
= V4L2_COLORSPACE_SRGB
,
427 .priv
= SCALE_320x240
| MODE_RAW
},
428 {320, 240, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
430 .sizeimage
= 480 * 240 ,
431 .colorspace
= V4L2_COLORSPACE_SRGB
,
432 .priv
= SCALE_320x240
},
433 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
435 .sizeimage
= 640 * 480 * 3 / 8 + 590,
436 .colorspace
= V4L2_COLORSPACE_JPEG
,
437 .priv
= SCALE_640x480
| MODE_JPEG
},
438 {640, 480, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
440 .sizeimage
= 640 * 480,
441 .colorspace
= V4L2_COLORSPACE_SRGB
,
442 .priv
= SCALE_640x480
| MODE_RAW
},
443 {640, 480, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
445 .sizeimage
= 960 * 480,
446 .colorspace
= V4L2_COLORSPACE_SRGB
,
447 .priv
= SCALE_640x480
},
448 {1280, 1024, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
449 .bytesperline
= 1280,
450 .sizeimage
= 1280 * 1024,
451 .colorspace
= V4L2_COLORSPACE_SRGB
,
452 .priv
= SCALE_1280x1024
| MODE_RAW
| MODE_SXGA
},
455 static const struct v4l2_pix_format mono_mode
[] = {
456 {160, 120, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
458 .sizeimage
= 160 * 120,
459 .colorspace
= V4L2_COLORSPACE_SRGB
,
460 .priv
= SCALE_160x120
| MODE_RAW
},
461 {320, 240, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
463 .sizeimage
= 320 * 240 ,
464 .colorspace
= V4L2_COLORSPACE_SRGB
,
465 .priv
= SCALE_320x240
| MODE_RAW
},
466 {640, 480, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
468 .sizeimage
= 640 * 480,
469 .colorspace
= V4L2_COLORSPACE_SRGB
,
470 .priv
= SCALE_640x480
| MODE_RAW
},
471 {1280, 1024, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
472 .bytesperline
= 1280,
473 .sizeimage
= 1280 * 1024,
474 .colorspace
= V4L2_COLORSPACE_SRGB
,
475 .priv
= SCALE_1280x1024
| MODE_RAW
| MODE_SXGA
},
478 static const s16 hsv_red_x
[] = {
479 41, 44, 46, 48, 50, 52, 54, 56,
480 58, 60, 62, 64, 66, 68, 70, 72,
481 74, 76, 78, 80, 81, 83, 85, 87,
482 88, 90, 92, 93, 95, 97, 98, 100,
483 101, 102, 104, 105, 107, 108, 109, 110,
484 112, 113, 114, 115, 116, 117, 118, 119,
485 120, 121, 122, 123, 123, 124, 125, 125,
486 126, 127, 127, 128, 128, 129, 129, 129,
487 130, 130, 130, 130, 131, 131, 131, 131,
488 131, 131, 131, 131, 130, 130, 130, 130,
489 129, 129, 129, 128, 128, 127, 127, 126,
490 125, 125, 124, 123, 122, 122, 121, 120,
491 119, 118, 117, 116, 115, 114, 112, 111,
492 110, 109, 107, 106, 105, 103, 102, 101,
493 99, 98, 96, 94, 93, 91, 90, 88,
494 86, 84, 83, 81, 79, 77, 75, 74,
495 72, 70, 68, 66, 64, 62, 60, 58,
496 56, 54, 52, 49, 47, 45, 43, 41,
497 39, 36, 34, 32, 30, 28, 25, 23,
498 21, 19, 16, 14, 12, 9, 7, 5,
499 3, 0, -1, -3, -6, -8, -10, -12,
500 -15, -17, -19, -22, -24, -26, -28, -30,
501 -33, -35, -37, -39, -41, -44, -46, -48,
502 -50, -52, -54, -56, -58, -60, -62, -64,
503 -66, -68, -70, -72, -74, -76, -78, -80,
504 -81, -83, -85, -87, -88, -90, -92, -93,
505 -95, -97, -98, -100, -101, -102, -104, -105,
506 -107, -108, -109, -110, -112, -113, -114, -115,
507 -116, -117, -118, -119, -120, -121, -122, -123,
508 -123, -124, -125, -125, -126, -127, -127, -128,
509 -128, -128, -128, -128, -128, -128, -128, -128,
510 -128, -128, -128, -128, -128, -128, -128, -128,
511 -128, -128, -128, -128, -128, -128, -128, -128,
512 -128, -127, -127, -126, -125, -125, -124, -123,
513 -122, -122, -121, -120, -119, -118, -117, -116,
514 -115, -114, -112, -111, -110, -109, -107, -106,
515 -105, -103, -102, -101, -99, -98, -96, -94,
516 -93, -91, -90, -88, -86, -84, -83, -81,
517 -79, -77, -75, -74, -72, -70, -68, -66,
518 -64, -62, -60, -58, -56, -54, -52, -49,
519 -47, -45, -43, -41, -39, -36, -34, -32,
520 -30, -28, -25, -23, -21, -19, -16, -14,
521 -12, -9, -7, -5, -3, 0, 1, 3,
522 6, 8, 10, 12, 15, 17, 19, 22,
523 24, 26, 28, 30, 33, 35, 37, 39, 41
526 static const s16 hsv_red_y
[] = {
527 82, 80, 78, 76, 74, 73, 71, 69,
528 67, 65, 63, 61, 58, 56, 54, 52,
529 50, 48, 46, 44, 41, 39, 37, 35,
530 32, 30, 28, 26, 23, 21, 19, 16,
531 14, 12, 10, 7, 5, 3, 0, -1,
532 -3, -6, -8, -10, -13, -15, -17, -19,
533 -22, -24, -26, -29, -31, -33, -35, -38,
534 -40, -42, -44, -46, -48, -51, -53, -55,
535 -57, -59, -61, -63, -65, -67, -69, -71,
536 -73, -75, -77, -79, -81, -82, -84, -86,
537 -88, -89, -91, -93, -94, -96, -98, -99,
538 -101, -102, -104, -105, -106, -108, -109, -110,
539 -112, -113, -114, -115, -116, -117, -119, -120,
540 -120, -121, -122, -123, -124, -125, -126, -126,
541 -127, -128, -128, -128, -128, -128, -128, -128,
542 -128, -128, -128, -128, -128, -128, -128, -128,
543 -128, -128, -128, -128, -128, -128, -128, -128,
544 -128, -128, -128, -128, -128, -128, -128, -128,
545 -127, -127, -126, -125, -125, -124, -123, -122,
546 -121, -120, -119, -118, -117, -116, -115, -114,
547 -113, -111, -110, -109, -107, -106, -105, -103,
548 -102, -100, -99, -97, -96, -94, -92, -91,
549 -89, -87, -85, -84, -82, -80, -78, -76,
550 -74, -73, -71, -69, -67, -65, -63, -61,
551 -58, -56, -54, -52, -50, -48, -46, -44,
552 -41, -39, -37, -35, -32, -30, -28, -26,
553 -23, -21, -19, -16, -14, -12, -10, -7,
554 -5, -3, 0, 1, 3, 6, 8, 10,
555 13, 15, 17, 19, 22, 24, 26, 29,
556 31, 33, 35, 38, 40, 42, 44, 46,
557 48, 51, 53, 55, 57, 59, 61, 63,
558 65, 67, 69, 71, 73, 75, 77, 79,
559 81, 82, 84, 86, 88, 89, 91, 93,
560 94, 96, 98, 99, 101, 102, 104, 105,
561 106, 108, 109, 110, 112, 113, 114, 115,
562 116, 117, 119, 120, 120, 121, 122, 123,
563 124, 125, 126, 126, 127, 128, 128, 129,
564 129, 130, 130, 131, 131, 131, 131, 132,
565 132, 132, 132, 132, 132, 132, 132, 132,
566 132, 132, 132, 131, 131, 131, 130, 130,
567 130, 129, 129, 128, 127, 127, 126, 125,
568 125, 124, 123, 122, 121, 120, 119, 118,
569 117, 116, 115, 114, 113, 111, 110, 109,
570 107, 106, 105, 103, 102, 100, 99, 97,
571 96, 94, 92, 91, 89, 87, 85, 84, 82
574 static const s16 hsv_green_x
[] = {
575 -124, -124, -125, -125, -125, -125, -125, -125,
576 -125, -126, -126, -125, -125, -125, -125, -125,
577 -125, -124, -124, -124, -123, -123, -122, -122,
578 -121, -121, -120, -120, -119, -118, -117, -117,
579 -116, -115, -114, -113, -112, -111, -110, -109,
580 -108, -107, -105, -104, -103, -102, -100, -99,
581 -98, -96, -95, -93, -92, -91, -89, -87,
582 -86, -84, -83, -81, -79, -77, -76, -74,
583 -72, -70, -69, -67, -65, -63, -61, -59,
584 -57, -55, -53, -51, -49, -47, -45, -43,
585 -41, -39, -37, -35, -33, -30, -28, -26,
586 -24, -22, -20, -18, -15, -13, -11, -9,
587 -7, -4, -2, 0, 1, 3, 6, 8,
588 10, 12, 14, 17, 19, 21, 23, 25,
589 27, 29, 32, 34, 36, 38, 40, 42,
590 44, 46, 48, 50, 52, 54, 56, 58,
591 60, 62, 64, 66, 68, 70, 71, 73,
592 75, 77, 78, 80, 82, 83, 85, 87,
593 88, 90, 91, 93, 94, 96, 97, 98,
594 100, 101, 102, 104, 105, 106, 107, 108,
595 109, 111, 112, 113, 113, 114, 115, 116,
596 117, 118, 118, 119, 120, 120, 121, 122,
597 122, 123, 123, 124, 124, 124, 125, 125,
598 125, 125, 125, 125, 125, 126, 126, 125,
599 125, 125, 125, 125, 125, 124, 124, 124,
600 123, 123, 122, 122, 121, 121, 120, 120,
601 119, 118, 117, 117, 116, 115, 114, 113,
602 112, 111, 110, 109, 108, 107, 105, 104,
603 103, 102, 100, 99, 98, 96, 95, 93,
604 92, 91, 89, 87, 86, 84, 83, 81,
605 79, 77, 76, 74, 72, 70, 69, 67,
606 65, 63, 61, 59, 57, 55, 53, 51,
607 49, 47, 45, 43, 41, 39, 37, 35,
608 33, 30, 28, 26, 24, 22, 20, 18,
609 15, 13, 11, 9, 7, 4, 2, 0,
610 -1, -3, -6, -8, -10, -12, -14, -17,
611 -19, -21, -23, -25, -27, -29, -32, -34,
612 -36, -38, -40, -42, -44, -46, -48, -50,
613 -52, -54, -56, -58, -60, -62, -64, -66,
614 -68, -70, -71, -73, -75, -77, -78, -80,
615 -82, -83, -85, -87, -88, -90, -91, -93,
616 -94, -96, -97, -98, -100, -101, -102, -104,
617 -105, -106, -107, -108, -109, -111, -112, -113,
618 -113, -114, -115, -116, -117, -118, -118, -119,
619 -120, -120, -121, -122, -122, -123, -123, -124, -124
622 static const s16 hsv_green_y
[] = {
623 -100, -99, -98, -97, -95, -94, -93, -91,
624 -90, -89, -87, -86, -84, -83, -81, -80,
625 -78, -76, -75, -73, -71, -70, -68, -66,
626 -64, -63, -61, -59, -57, -55, -53, -51,
627 -49, -48, -46, -44, -42, -40, -38, -36,
628 -34, -32, -30, -27, -25, -23, -21, -19,
629 -17, -15, -13, -11, -9, -7, -4, -2,
630 0, 1, 3, 5, 7, 9, 11, 14,
631 16, 18, 20, 22, 24, 26, 28, 30,
632 32, 34, 36, 38, 40, 42, 44, 46,
633 48, 50, 52, 54, 56, 58, 59, 61,
634 63, 65, 67, 68, 70, 72, 74, 75,
635 77, 78, 80, 82, 83, 85, 86, 88,
636 89, 90, 92, 93, 95, 96, 97, 98,
637 100, 101, 102, 103, 104, 105, 106, 107,
638 108, 109, 110, 111, 112, 112, 113, 114,
639 115, 115, 116, 116, 117, 117, 118, 118,
640 119, 119, 119, 120, 120, 120, 120, 120,
641 121, 121, 121, 121, 121, 121, 120, 120,
642 120, 120, 120, 119, 119, 119, 118, 118,
643 117, 117, 116, 116, 115, 114, 114, 113,
644 112, 111, 111, 110, 109, 108, 107, 106,
645 105, 104, 103, 102, 100, 99, 98, 97,
646 95, 94, 93, 91, 90, 89, 87, 86,
647 84, 83, 81, 80, 78, 76, 75, 73,
648 71, 70, 68, 66, 64, 63, 61, 59,
649 57, 55, 53, 51, 49, 48, 46, 44,
650 42, 40, 38, 36, 34, 32, 30, 27,
651 25, 23, 21, 19, 17, 15, 13, 11,
652 9, 7, 4, 2, 0, -1, -3, -5,
653 -7, -9, -11, -14, -16, -18, -20, -22,
654 -24, -26, -28, -30, -32, -34, -36, -38,
655 -40, -42, -44, -46, -48, -50, -52, -54,
656 -56, -58, -59, -61, -63, -65, -67, -68,
657 -70, -72, -74, -75, -77, -78, -80, -82,
658 -83, -85, -86, -88, -89, -90, -92, -93,
659 -95, -96, -97, -98, -100, -101, -102, -103,
660 -104, -105, -106, -107, -108, -109, -110, -111,
661 -112, -112, -113, -114, -115, -115, -116, -116,
662 -117, -117, -118, -118, -119, -119, -119, -120,
663 -120, -120, -120, -120, -121, -121, -121, -121,
664 -121, -121, -120, -120, -120, -120, -120, -119,
665 -119, -119, -118, -118, -117, -117, -116, -116,
666 -115, -114, -114, -113, -112, -111, -111, -110,
667 -109, -108, -107, -106, -105, -104, -103, -102, -100
670 static const s16 hsv_blue_x
[] = {
671 112, 113, 114, 114, 115, 116, 117, 117,
672 118, 118, 119, 119, 120, 120, 120, 121,
673 121, 121, 122, 122, 122, 122, 122, 122,
674 122, 122, 122, 122, 122, 122, 121, 121,
675 121, 120, 120, 120, 119, 119, 118, 118,
676 117, 116, 116, 115, 114, 113, 113, 112,
677 111, 110, 109, 108, 107, 106, 105, 104,
678 103, 102, 100, 99, 98, 97, 95, 94,
679 93, 91, 90, 88, 87, 85, 84, 82,
680 80, 79, 77, 76, 74, 72, 70, 69,
681 67, 65, 63, 61, 60, 58, 56, 54,
682 52, 50, 48, 46, 44, 42, 40, 38,
683 36, 34, 32, 30, 28, 26, 24, 22,
684 19, 17, 15, 13, 11, 9, 7, 5,
685 2, 0, -1, -3, -5, -7, -9, -12,
686 -14, -16, -18, -20, -22, -24, -26, -28,
687 -31, -33, -35, -37, -39, -41, -43, -45,
688 -47, -49, -51, -53, -54, -56, -58, -60,
689 -62, -64, -66, -67, -69, -71, -73, -74,
690 -76, -78, -79, -81, -83, -84, -86, -87,
691 -89, -90, -92, -93, -94, -96, -97, -98,
692 -99, -101, -102, -103, -104, -105, -106, -107,
693 -108, -109, -110, -111, -112, -113, -114, -114,
694 -115, -116, -117, -117, -118, -118, -119, -119,
695 -120, -120, -120, -121, -121, -121, -122, -122,
696 -122, -122, -122, -122, -122, -122, -122, -122,
697 -122, -122, -121, -121, -121, -120, -120, -120,
698 -119, -119, -118, -118, -117, -116, -116, -115,
699 -114, -113, -113, -112, -111, -110, -109, -108,
700 -107, -106, -105, -104, -103, -102, -100, -99,
701 -98, -97, -95, -94, -93, -91, -90, -88,
702 -87, -85, -84, -82, -80, -79, -77, -76,
703 -74, -72, -70, -69, -67, -65, -63, -61,
704 -60, -58, -56, -54, -52, -50, -48, -46,
705 -44, -42, -40, -38, -36, -34, -32, -30,
706 -28, -26, -24, -22, -19, -17, -15, -13,
707 -11, -9, -7, -5, -2, 0, 1, 3,
708 5, 7, 9, 12, 14, 16, 18, 20,
709 22, 24, 26, 28, 31, 33, 35, 37,
710 39, 41, 43, 45, 47, 49, 51, 53,
711 54, 56, 58, 60, 62, 64, 66, 67,
712 69, 71, 73, 74, 76, 78, 79, 81,
713 83, 84, 86, 87, 89, 90, 92, 93,
714 94, 96, 97, 98, 99, 101, 102, 103,
715 104, 105, 106, 107, 108, 109, 110, 111, 112
718 static const s16 hsv_blue_y
[] = {
719 -11, -13, -15, -17, -19, -21, -23, -25,
720 -27, -29, -31, -33, -35, -37, -39, -41,
721 -43, -45, -46, -48, -50, -52, -54, -55,
722 -57, -59, -61, -62, -64, -66, -67, -69,
723 -71, -72, -74, -75, -77, -78, -80, -81,
724 -83, -84, -86, -87, -88, -90, -91, -92,
725 -93, -95, -96, -97, -98, -99, -100, -101,
726 -102, -103, -104, -105, -106, -106, -107, -108,
727 -109, -109, -110, -111, -111, -112, -112, -113,
728 -113, -114, -114, -114, -115, -115, -115, -115,
729 -116, -116, -116, -116, -116, -116, -116, -116,
730 -116, -115, -115, -115, -115, -114, -114, -114,
731 -113, -113, -112, -112, -111, -111, -110, -110,
732 -109, -108, -108, -107, -106, -105, -104, -103,
733 -102, -101, -100, -99, -98, -97, -96, -95,
734 -94, -93, -91, -90, -89, -88, -86, -85,
735 -84, -82, -81, -79, -78, -76, -75, -73,
736 -71, -70, -68, -67, -65, -63, -62, -60,
737 -58, -56, -55, -53, -51, -49, -47, -45,
738 -44, -42, -40, -38, -36, -34, -32, -30,
739 -28, -26, -24, -22, -20, -18, -16, -14,
740 -12, -10, -8, -6, -4, -2, 0, 1,
741 3, 5, 7, 9, 11, 13, 15, 17,
742 19, 21, 23, 25, 27, 29, 31, 33,
743 35, 37, 39, 41, 43, 45, 46, 48,
744 50, 52, 54, 55, 57, 59, 61, 62,
745 64, 66, 67, 69, 71, 72, 74, 75,
746 77, 78, 80, 81, 83, 84, 86, 87,
747 88, 90, 91, 92, 93, 95, 96, 97,
748 98, 99, 100, 101, 102, 103, 104, 105,
749 106, 106, 107, 108, 109, 109, 110, 111,
750 111, 112, 112, 113, 113, 114, 114, 114,
751 115, 115, 115, 115, 116, 116, 116, 116,
752 116, 116, 116, 116, 116, 115, 115, 115,
753 115, 114, 114, 114, 113, 113, 112, 112,
754 111, 111, 110, 110, 109, 108, 108, 107,
755 106, 105, 104, 103, 102, 101, 100, 99,
756 98, 97, 96, 95, 94, 93, 91, 90,
757 89, 88, 86, 85, 84, 82, 81, 79,
758 78, 76, 75, 73, 71, 70, 68, 67,
759 65, 63, 62, 60, 58, 56, 55, 53,
760 51, 49, 47, 45, 44, 42, 40, 38,
761 36, 34, 32, 30, 28, 26, 24, 22,
762 20, 18, 16, 14, 12, 10, 8, 6,
763 4, 2, 0, -1, -3, -5, -7, -9, -11
766 static u16 i2c_ident
[] = {
775 V4L2_IDENT_MT9M001C12ST
,
781 static u16 bridge_init
[][2] = {
782 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
783 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
784 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
785 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
786 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
787 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
788 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
789 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
790 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
791 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
792 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
793 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
794 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
795 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
796 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
797 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
798 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
799 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
800 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
804 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
805 static u8 ov_gain
[] = {
806 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
807 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
808 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
809 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
810 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
811 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
812 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
816 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
817 static u16 micron1_gain
[] = {
818 /* 1x 1.25x 1.5x 1.75x */
819 0x0020, 0x0028, 0x0030, 0x0038,
820 /* 2x 2.25x 2.5x 2.75x */
821 0x00a0, 0x00a4, 0x00a8, 0x00ac,
822 /* 3x 3.25x 3.5x 3.75x */
823 0x00b0, 0x00b4, 0x00b8, 0x00bc,
824 /* 4x 4.25x 4.5x 4.75x */
825 0x00c0, 0x00c4, 0x00c8, 0x00cc,
826 /* 5x 5.25x 5.5x 5.75x */
827 0x00d0, 0x00d4, 0x00d8, 0x00dc,
828 /* 6x 6.25x 6.5x 6.75x */
829 0x00e0, 0x00e4, 0x00e8, 0x00ec,
830 /* 7x 7.25x 7.5x 7.75x */
831 0x00f0, 0x00f4, 0x00f8, 0x00fc,
836 /* mt9m001 sensor uses a different gain formula then other micron sensors */
837 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
838 static u16 micron2_gain
[] = {
839 /* 1x 1.25x 1.5x 1.75x */
840 0x0008, 0x000a, 0x000c, 0x000e,
841 /* 2x 2.25x 2.5x 2.75x */
842 0x0010, 0x0012, 0x0014, 0x0016,
843 /* 3x 3.25x 3.5x 3.75x */
844 0x0018, 0x001a, 0x001c, 0x001e,
845 /* 4x 4.25x 4.5x 4.75x */
846 0x0020, 0x0051, 0x0052, 0x0053,
847 /* 5x 5.25x 5.5x 5.75x */
848 0x0054, 0x0055, 0x0056, 0x0057,
849 /* 6x 6.25x 6.5x 6.75x */
850 0x0058, 0x0059, 0x005a, 0x005b,
851 /* 7x 7.25x 7.5x 7.75x */
852 0x005c, 0x005d, 0x005e, 0x005f,
857 /* Gain = .5 + bit[7:0] / 16 */
858 static u8 hv7131r_gain
[] = {
859 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
860 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
861 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
862 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
863 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
864 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
865 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
869 static struct i2c_reg_u8 soi968_init
[] = {
870 {0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f},
871 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
872 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
873 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
874 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
875 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
876 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
877 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
878 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
879 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
880 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
883 static struct i2c_reg_u8 ov7660_init
[] = {
884 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
885 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
886 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
887 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
888 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6},
889 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
892 static struct i2c_reg_u8 ov7670_init
[] = {
893 {0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
894 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
895 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
896 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
897 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
898 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
899 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
900 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
901 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
902 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
903 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
904 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
905 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
906 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
907 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
908 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
909 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
910 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
911 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
912 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
913 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
914 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
915 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
916 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
917 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
918 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
919 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
920 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
921 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
922 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
923 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
924 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
925 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
926 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
927 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
928 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
929 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
930 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
931 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
932 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
933 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
934 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
935 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
936 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
937 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
938 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
939 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
940 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
941 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
942 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
943 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
944 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
945 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
949 static struct i2c_reg_u8 ov9650_init
[] = {
950 {0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78},
951 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
952 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
953 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
954 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
955 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
956 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
957 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
958 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
959 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
960 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
961 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
962 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
963 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
964 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
965 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
966 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
967 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
968 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
969 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
970 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
971 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
972 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
973 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
974 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
975 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
976 {0xaa, 0x92}, {0xab, 0x0a},
979 static struct i2c_reg_u8 ov9655_init
[] = {
980 {0x12, 0x80}, {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
981 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
982 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
983 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
984 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
985 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
986 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
987 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
988 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
989 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
990 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
991 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
992 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
993 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
994 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
995 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
996 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
997 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
998 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
999 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
1000 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
1001 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
1002 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
1003 {0x04, 0x03}, {0x00, 0x13},
1006 static struct i2c_reg_u16 mt9v112_init
[] = {
1007 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
1008 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
1009 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
1010 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
1011 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
1012 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
1013 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
1014 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
1015 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
1016 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
1017 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
1018 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1019 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
1020 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
1021 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
1022 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
1025 static struct i2c_reg_u16 mt9v111_init
[] = {
1026 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
1027 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
1028 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
1029 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
1030 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
1031 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
1032 {0x0e, 0x0008}, {0x20, 0x0000}
1035 static struct i2c_reg_u16 mt9v011_init
[] = {
1036 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
1037 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
1038 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
1039 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
1040 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
1041 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
1042 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
1043 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
1044 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
1045 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
1046 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
1047 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
1048 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
1049 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
1050 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
1051 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
1052 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
1053 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
1054 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
1055 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
1056 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
1057 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1058 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
1059 {0x06, 0x0029}, {0x05, 0x0009},
1062 static struct i2c_reg_u16 mt9m001_init
[] = {
1065 {0x04, 0x0500}, /* hres = 1280 */
1066 {0x03, 0x0400}, /* vres = 1024 */
1078 static struct i2c_reg_u16 mt9m111_init
[] = {
1079 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1080 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1081 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1085 static struct i2c_reg_u16 mt9m112_init
[] = {
1086 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1087 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1088 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1092 static struct i2c_reg_u8 hv7131r_init
[] = {
1093 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
1094 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
1095 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
1096 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
1097 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
1098 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
1099 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
1100 {0x23, 0x09}, {0x01, 0x08},
1103 static int reg_r(struct gspca_dev
*gspca_dev
, u16 reg
, u16 length
)
1105 struct usb_device
*dev
= gspca_dev
->dev
;
1107 result
= usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
1109 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
1115 if (unlikely(result
< 0 || result
!= length
)) {
1116 err("Read register failed 0x%02X", reg
);
1122 static int reg_w(struct gspca_dev
*gspca_dev
, u16 reg
,
1123 const u8
*buffer
, int length
)
1125 struct usb_device
*dev
= gspca_dev
->dev
;
1127 memcpy(gspca_dev
->usb_buf
, buffer
, length
);
1128 result
= usb_control_msg(dev
, usb_sndctrlpipe(dev
, 0),
1130 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
1136 if (unlikely(result
< 0 || result
!= length
)) {
1137 err("Write register failed index 0x%02X", reg
);
1143 static int reg_w1(struct gspca_dev
*gspca_dev
, u16 reg
, const u8 value
)
1145 u8 data
[1] = {value
};
1146 return reg_w(gspca_dev
, reg
, data
, 1);
1149 static int i2c_w(struct gspca_dev
*gspca_dev
, const u8
*buffer
)
1152 reg_w(gspca_dev
, 0x10c0, buffer
, 8);
1153 for (i
= 0; i
< 5; i
++) {
1154 reg_r(gspca_dev
, 0x10c0, 1);
1155 if (gspca_dev
->usb_buf
[0] & 0x04) {
1156 if (gspca_dev
->usb_buf
[0] & 0x08)
1165 static int i2c_w1(struct gspca_dev
*gspca_dev
, u8 reg
, u8 val
)
1167 struct sd
*sd
= (struct sd
*) gspca_dev
;
1172 * from the point of view of the bridge, the length
1173 * includes the address
1175 row
[0] = 0x81 | (2 << 4);
1176 row
[1] = sd
->i2c_addr
;
1184 return i2c_w(gspca_dev
, row
);
1187 static int i2c_w2(struct gspca_dev
*gspca_dev
, u8 reg
, u16 val
)
1189 struct sd
*sd
= (struct sd
*) gspca_dev
;
1193 * from the point of view of the bridge, the length
1194 * includes the address
1196 row
[0] = 0x81 | (3 << 4);
1197 row
[1] = sd
->i2c_addr
;
1199 row
[3] = (val
>> 8) & 0xff;
1200 row
[4] = val
& 0xff;
1205 return i2c_w(gspca_dev
, row
);
1208 static int i2c_r1(struct gspca_dev
*gspca_dev
, u8 reg
, u8
*val
)
1210 struct sd
*sd
= (struct sd
*) gspca_dev
;
1213 row
[0] = 0x81 | (1 << 4);
1214 row
[1] = sd
->i2c_addr
;
1221 if (i2c_w(gspca_dev
, row
) < 0)
1223 row
[0] = 0x81 | (1 << 4) | 0x02;
1225 if (i2c_w(gspca_dev
, row
) < 0)
1227 if (reg_r(gspca_dev
, 0x10c2, 5) < 0)
1229 *val
= gspca_dev
->usb_buf
[4];
1233 static int i2c_r2(struct gspca_dev
*gspca_dev
, u8 reg
, u16
*val
)
1235 struct sd
*sd
= (struct sd
*) gspca_dev
;
1238 row
[0] = 0x81 | (1 << 4);
1239 row
[1] = sd
->i2c_addr
;
1246 if (i2c_w(gspca_dev
, row
) < 0)
1248 row
[0] = 0x81 | (2 << 4) | 0x02;
1250 if (i2c_w(gspca_dev
, row
) < 0)
1252 if (reg_r(gspca_dev
, 0x10c2, 5) < 0)
1254 *val
= (gspca_dev
->usb_buf
[3] << 8) | gspca_dev
->usb_buf
[4];
1258 static int ov9650_init_sensor(struct gspca_dev
*gspca_dev
)
1262 struct sd
*sd
= (struct sd
*) gspca_dev
;
1264 if (i2c_r2(gspca_dev
, 0x1c, &id
) < 0)
1268 err("sensor id for ov9650 doesn't match (0x%04x)", id
);
1272 for (i
= 0; i
< ARRAY_SIZE(ov9650_init
); i
++) {
1273 if (i2c_w1(gspca_dev
, ov9650_init
[i
].reg
,
1274 ov9650_init
[i
].val
) < 0) {
1275 err("OV9650 sensor initialization failed");
1284 static int ov9655_init_sensor(struct gspca_dev
*gspca_dev
)
1287 struct sd
*sd
= (struct sd
*) gspca_dev
;
1289 for (i
= 0; i
< ARRAY_SIZE(ov9655_init
); i
++) {
1290 if (i2c_w1(gspca_dev
, ov9655_init
[i
].reg
,
1291 ov9655_init
[i
].val
) < 0) {
1292 err("OV9655 sensor initialization failed");
1296 /* disable hflip and vflip */
1297 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1303 static int soi968_init_sensor(struct gspca_dev
*gspca_dev
)
1306 struct sd
*sd
= (struct sd
*) gspca_dev
;
1308 for (i
= 0; i
< ARRAY_SIZE(soi968_init
); i
++) {
1309 if (i2c_w1(gspca_dev
, soi968_init
[i
].reg
,
1310 soi968_init
[i
].val
) < 0) {
1311 err("SOI968 sensor initialization failed");
1315 /* disable hflip and vflip */
1316 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
)
1317 | (1 << EXPOSURE_IDX
);
1323 static int ov7660_init_sensor(struct gspca_dev
*gspca_dev
)
1326 struct sd
*sd
= (struct sd
*) gspca_dev
;
1328 for (i
= 0; i
< ARRAY_SIZE(ov7660_init
); i
++) {
1329 if (i2c_w1(gspca_dev
, ov7660_init
[i
].reg
,
1330 ov7660_init
[i
].val
) < 0) {
1331 err("OV7660 sensor initialization failed");
1335 /* disable hflip and vflip */
1336 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1342 static int ov7670_init_sensor(struct gspca_dev
*gspca_dev
)
1345 struct sd
*sd
= (struct sd
*) gspca_dev
;
1347 for (i
= 0; i
< ARRAY_SIZE(ov7670_init
); i
++) {
1348 if (i2c_w1(gspca_dev
, ov7670_init
[i
].reg
,
1349 ov7670_init
[i
].val
) < 0) {
1350 err("OV7670 sensor initialization failed");
1354 /* disable hflip and vflip */
1355 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1361 static int mt9v_init_sensor(struct gspca_dev
*gspca_dev
)
1363 struct sd
*sd
= (struct sd
*) gspca_dev
;
1368 sd
->i2c_addr
= 0x5d;
1369 ret
= i2c_r2(gspca_dev
, 0xff, &value
);
1370 if ((ret
== 0) && (value
== 0x8243)) {
1371 for (i
= 0; i
< ARRAY_SIZE(mt9v011_init
); i
++) {
1372 if (i2c_w2(gspca_dev
, mt9v011_init
[i
].reg
,
1373 mt9v011_init
[i
].val
) < 0) {
1374 err("MT9V011 sensor initialization failed");
1380 sd
->sensor
= SENSOR_MT9V011
;
1381 info("MT9V011 sensor detected");
1385 sd
->i2c_addr
= 0x5c;
1386 i2c_w2(gspca_dev
, 0x01, 0x0004);
1387 ret
= i2c_r2(gspca_dev
, 0xff, &value
);
1388 if ((ret
== 0) && (value
== 0x823a)) {
1389 for (i
= 0; i
< ARRAY_SIZE(mt9v111_init
); i
++) {
1390 if (i2c_w2(gspca_dev
, mt9v111_init
[i
].reg
,
1391 mt9v111_init
[i
].val
) < 0) {
1392 err("MT9V111 sensor initialization failed");
1396 gspca_dev
->ctrl_dis
= (1 << EXPOSURE_IDX
)
1397 | (1 << AUTOGAIN_IDX
)
1401 sd
->sensor
= SENSOR_MT9V111
;
1402 info("MT9V111 sensor detected");
1406 sd
->i2c_addr
= 0x5d;
1407 ret
= i2c_w2(gspca_dev
, 0xf0, 0x0000);
1409 sd
->i2c_addr
= 0x48;
1410 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1412 ret
= i2c_r2(gspca_dev
, 0x00, &value
);
1413 if ((ret
== 0) && (value
== 0x1229)) {
1414 for (i
= 0; i
< ARRAY_SIZE(mt9v112_init
); i
++) {
1415 if (i2c_w2(gspca_dev
, mt9v112_init
[i
].reg
,
1416 mt9v112_init
[i
].val
) < 0) {
1417 err("MT9V112 sensor initialization failed");
1423 sd
->sensor
= SENSOR_MT9V112
;
1424 info("MT9V112 sensor detected");
1431 static int mt9m112_init_sensor(struct gspca_dev
*gspca_dev
)
1433 struct sd
*sd
= (struct sd
*) gspca_dev
;
1435 for (i
= 0; i
< ARRAY_SIZE(mt9m112_init
); i
++) {
1436 if (i2c_w2(gspca_dev
, mt9m112_init
[i
].reg
,
1437 mt9m112_init
[i
].val
) < 0) {
1438 err("MT9M112 sensor initialization failed");
1442 gspca_dev
->ctrl_dis
= (1 << EXPOSURE_IDX
) | (1 << AUTOGAIN_IDX
)
1449 static int mt9m111_init_sensor(struct gspca_dev
*gspca_dev
)
1451 struct sd
*sd
= (struct sd
*) gspca_dev
;
1453 for (i
= 0; i
< ARRAY_SIZE(mt9m111_init
); i
++) {
1454 if (i2c_w2(gspca_dev
, mt9m111_init
[i
].reg
,
1455 mt9m111_init
[i
].val
) < 0) {
1456 err("MT9M111 sensor initialization failed");
1460 gspca_dev
->ctrl_dis
= (1 << EXPOSURE_IDX
) | (1 << AUTOGAIN_IDX
)
1467 static int mt9m001_init_sensor(struct gspca_dev
*gspca_dev
)
1469 struct sd
*sd
= (struct sd
*) gspca_dev
;
1473 if (i2c_r2(gspca_dev
, 0x00, &id
) < 0)
1476 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
1480 info("MT9M001 color sensor detected");
1483 info("MT9M001 mono sensor detected");
1486 err("No MT9M001 chip detected, ID = %x\n", id
);
1490 for (i
= 0; i
< ARRAY_SIZE(mt9m001_init
); i
++) {
1491 if (i2c_w2(gspca_dev
, mt9m001_init
[i
].reg
,
1492 mt9m001_init
[i
].val
) < 0) {
1493 err("MT9M001 sensor initialization failed");
1497 /* disable hflip and vflip */
1498 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1504 static int hv7131r_init_sensor(struct gspca_dev
*gspca_dev
)
1507 struct sd
*sd
= (struct sd
*) gspca_dev
;
1509 for (i
= 0; i
< ARRAY_SIZE(hv7131r_init
); i
++) {
1510 if (i2c_w1(gspca_dev
, hv7131r_init
[i
].reg
,
1511 hv7131r_init
[i
].val
) < 0) {
1512 err("HV7131R Sensor initialization failed");
1521 static int set_cmatrix(struct gspca_dev
*gspca_dev
)
1523 struct sd
*sd
= (struct sd
*) gspca_dev
;
1524 s32 hue_coord
, hue_index
= 180 + sd
->hue
;
1527 memset(cmatrix
, 0, sizeof cmatrix
);
1528 cmatrix
[2] = (sd
->contrast
* 0x25 / 0x100) + 0x26;
1529 cmatrix
[0] = 0x13 + (cmatrix
[2] - 0x26) * 0x13 / 0x25;
1530 cmatrix
[4] = 0x07 + (cmatrix
[2] - 0x26) * 0x07 / 0x25;
1531 cmatrix
[18] = sd
->brightness
- 0x80;
1533 hue_coord
= (hsv_red_x
[hue_index
] * sd
->saturation
) >> 8;
1534 cmatrix
[6] = hue_coord
;
1535 cmatrix
[7] = (hue_coord
>> 8) & 0x0f;
1537 hue_coord
= (hsv_red_y
[hue_index
] * sd
->saturation
) >> 8;
1538 cmatrix
[8] = hue_coord
;
1539 cmatrix
[9] = (hue_coord
>> 8) & 0x0f;
1541 hue_coord
= (hsv_green_x
[hue_index
] * sd
->saturation
) >> 8;
1542 cmatrix
[10] = hue_coord
;
1543 cmatrix
[11] = (hue_coord
>> 8) & 0x0f;
1545 hue_coord
= (hsv_green_y
[hue_index
] * sd
->saturation
) >> 8;
1546 cmatrix
[12] = hue_coord
;
1547 cmatrix
[13] = (hue_coord
>> 8) & 0x0f;
1549 hue_coord
= (hsv_blue_x
[hue_index
] * sd
->saturation
) >> 8;
1550 cmatrix
[14] = hue_coord
;
1551 cmatrix
[15] = (hue_coord
>> 8) & 0x0f;
1553 hue_coord
= (hsv_blue_y
[hue_index
] * sd
->saturation
) >> 8;
1554 cmatrix
[16] = hue_coord
;
1555 cmatrix
[17] = (hue_coord
>> 8) & 0x0f;
1557 return reg_w(gspca_dev
, 0x10e1, cmatrix
, 21);
1560 static int set_gamma(struct gspca_dev
*gspca_dev
)
1562 struct sd
*sd
= (struct sd
*) gspca_dev
;
1564 u8 gval
= sd
->gamma
* 0xb8 / 0x100;
1568 gamma
[1] = 0x13 + (gval
* (0xcb - 0x13) / 0xb8);
1569 gamma
[2] = 0x25 + (gval
* (0xee - 0x25) / 0xb8);
1570 gamma
[3] = 0x37 + (gval
* (0xfa - 0x37) / 0xb8);
1571 gamma
[4] = 0x45 + (gval
* (0xfc - 0x45) / 0xb8);
1572 gamma
[5] = 0x55 + (gval
* (0xfb - 0x55) / 0xb8);
1573 gamma
[6] = 0x65 + (gval
* (0xfc - 0x65) / 0xb8);
1574 gamma
[7] = 0x74 + (gval
* (0xfd - 0x74) / 0xb8);
1575 gamma
[8] = 0x83 + (gval
* (0xfe - 0x83) / 0xb8);
1576 gamma
[9] = 0x92 + (gval
* (0xfc - 0x92) / 0xb8);
1577 gamma
[10] = 0xa1 + (gval
* (0xfc - 0xa1) / 0xb8);
1578 gamma
[11] = 0xb0 + (gval
* (0xfc - 0xb0) / 0xb8);
1579 gamma
[12] = 0xbf + (gval
* (0xfb - 0xbf) / 0xb8);
1580 gamma
[13] = 0xce + (gval
* (0xfb - 0xce) / 0xb8);
1581 gamma
[14] = 0xdf + (gval
* (0xfd - 0xdf) / 0xb8);
1582 gamma
[15] = 0xea + (gval
* (0xf9 - 0xea) / 0xb8);
1585 return reg_w(gspca_dev
, 0x1190, gamma
, 17);
1588 static int set_redblue(struct gspca_dev
*gspca_dev
)
1590 struct sd
*sd
= (struct sd
*) gspca_dev
;
1591 reg_w1(gspca_dev
, 0x118c, sd
->red
);
1592 reg_w1(gspca_dev
, 0x118f, sd
->blue
);
1596 static int set_hvflip(struct gspca_dev
*gspca_dev
)
1598 u8 value
, tslb
, hflip
, vflip
;
1600 struct sd
*sd
= (struct sd
*) gspca_dev
;
1602 if ((sd
->flags
& FLIP_DETECT
) && dmi_check_system(flip_dmi_table
)) {
1610 switch (sd
->sensor
) {
1612 i2c_r1(gspca_dev
, 0x1e, &value
);
1621 i2c_w1(gspca_dev
, 0x1e, value
);
1622 i2c_w1(gspca_dev
, 0x3a, tslb
);
1624 case SENSOR_MT9V111
:
1625 case SENSOR_MT9V011
:
1626 i2c_r2(gspca_dev
, 0x20, &value2
);
1632 i2c_w2(gspca_dev
, 0x20, value2
);
1634 case SENSOR_MT9M112
:
1635 case SENSOR_MT9M111
:
1636 case SENSOR_MT9V112
:
1637 i2c_r2(gspca_dev
, 0x20, &value2
);
1643 i2c_w2(gspca_dev
, 0x20, value2
);
1645 case SENSOR_HV7131R
:
1646 i2c_r1(gspca_dev
, 0x01, &value
);
1652 i2c_w1(gspca_dev
, 0x01, value
);
1658 static int set_exposure(struct gspca_dev
*gspca_dev
)
1660 struct sd
*sd
= (struct sd
*) gspca_dev
;
1661 u8 exp
[8] = {0x81, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1662 switch (sd
->sensor
) {
1669 exp
[3] = sd
->exposure
& 0xff;
1670 exp
[4] = sd
->exposure
>> 8;
1672 case SENSOR_MT9M001
:
1673 case SENSOR_MT9V112
:
1674 case SENSOR_MT9V011
:
1677 exp
[3] = sd
->exposure
>> 8;
1678 exp
[4] = sd
->exposure
& 0xff;
1680 case SENSOR_HV7131R
:
1683 exp
[3] = (sd
->exposure
>> 5) & 0xff;
1684 exp
[4] = (sd
->exposure
<< 3) & 0xff;
1690 i2c_w(gspca_dev
, exp
);
1694 static int set_gain(struct gspca_dev
*gspca_dev
)
1696 struct sd
*sd
= (struct sd
*) gspca_dev
;
1697 u8 gain
[8] = {0x81, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1698 switch (sd
->sensor
) {
1704 gain
[0] |= (2 << 4);
1705 gain
[3] = ov_gain
[sd
->gain
];
1707 case SENSOR_MT9V011
:
1708 gain
[0] |= (3 << 4);
1710 gain
[3] = micron1_gain
[sd
->gain
] >> 8;
1711 gain
[4] = micron1_gain
[sd
->gain
] & 0xff;
1713 case SENSOR_MT9V112
:
1714 gain
[0] |= (3 << 4);
1716 gain
[3] = micron1_gain
[sd
->gain
] >> 8;
1717 gain
[4] = micron1_gain
[sd
->gain
] & 0xff;
1719 case SENSOR_MT9M001
:
1720 gain
[0] |= (3 << 4);
1722 gain
[3] = micron2_gain
[sd
->gain
] >> 8;
1723 gain
[4] = micron2_gain
[sd
->gain
] & 0xff;
1725 case SENSOR_HV7131R
:
1726 gain
[0] |= (2 << 4);
1728 gain
[3] = hv7131r_gain
[sd
->gain
];
1733 i2c_w(gspca_dev
, gain
);
1737 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, s32 val
)
1739 struct sd
*sd
= (struct sd
*) gspca_dev
;
1741 sd
->brightness
= val
;
1742 if (gspca_dev
->streaming
)
1743 return set_cmatrix(gspca_dev
);
1747 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, s32
*val
)
1749 struct sd
*sd
= (struct sd
*) gspca_dev
;
1750 *val
= sd
->brightness
;
1755 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, s32 val
)
1757 struct sd
*sd
= (struct sd
*) gspca_dev
;
1760 if (gspca_dev
->streaming
)
1761 return set_cmatrix(gspca_dev
);
1765 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, s32
*val
)
1767 struct sd
*sd
= (struct sd
*) gspca_dev
;
1768 *val
= sd
->contrast
;
1772 static int sd_setsaturation(struct gspca_dev
*gspca_dev
, s32 val
)
1774 struct sd
*sd
= (struct sd
*) gspca_dev
;
1776 sd
->saturation
= val
;
1777 if (gspca_dev
->streaming
)
1778 return set_cmatrix(gspca_dev
);
1782 static int sd_getsaturation(struct gspca_dev
*gspca_dev
, s32
*val
)
1784 struct sd
*sd
= (struct sd
*) gspca_dev
;
1785 *val
= sd
->saturation
;
1789 static int sd_sethue(struct gspca_dev
*gspca_dev
, s32 val
)
1791 struct sd
*sd
= (struct sd
*) gspca_dev
;
1794 if (gspca_dev
->streaming
)
1795 return set_cmatrix(gspca_dev
);
1799 static int sd_gethue(struct gspca_dev
*gspca_dev
, s32
*val
)
1801 struct sd
*sd
= (struct sd
*) gspca_dev
;
1806 static int sd_setgamma(struct gspca_dev
*gspca_dev
, s32 val
)
1808 struct sd
*sd
= (struct sd
*) gspca_dev
;
1811 if (gspca_dev
->streaming
)
1812 return set_gamma(gspca_dev
);
1816 static int sd_getgamma(struct gspca_dev
*gspca_dev
, s32
*val
)
1818 struct sd
*sd
= (struct sd
*) gspca_dev
;
1823 static int sd_setredbalance(struct gspca_dev
*gspca_dev
, s32 val
)
1825 struct sd
*sd
= (struct sd
*) gspca_dev
;
1828 if (gspca_dev
->streaming
)
1829 return set_redblue(gspca_dev
);
1833 static int sd_getredbalance(struct gspca_dev
*gspca_dev
, s32
*val
)
1835 struct sd
*sd
= (struct sd
*) gspca_dev
;
1840 static int sd_setbluebalance(struct gspca_dev
*gspca_dev
, s32 val
)
1842 struct sd
*sd
= (struct sd
*) gspca_dev
;
1845 if (gspca_dev
->streaming
)
1846 return set_redblue(gspca_dev
);
1850 static int sd_getbluebalance(struct gspca_dev
*gspca_dev
, s32
*val
)
1852 struct sd
*sd
= (struct sd
*) gspca_dev
;
1857 static int sd_sethflip(struct gspca_dev
*gspca_dev
, s32 val
)
1859 struct sd
*sd
= (struct sd
*) gspca_dev
;
1862 if (gspca_dev
->streaming
)
1863 return set_hvflip(gspca_dev
);
1867 static int sd_gethflip(struct gspca_dev
*gspca_dev
, s32
*val
)
1869 struct sd
*sd
= (struct sd
*) gspca_dev
;
1874 static int sd_setvflip(struct gspca_dev
*gspca_dev
, s32 val
)
1876 struct sd
*sd
= (struct sd
*) gspca_dev
;
1879 if (gspca_dev
->streaming
)
1880 return set_hvflip(gspca_dev
);
1884 static int sd_getvflip(struct gspca_dev
*gspca_dev
, s32
*val
)
1886 struct sd
*sd
= (struct sd
*) gspca_dev
;
1891 static int sd_setexposure(struct gspca_dev
*gspca_dev
, s32 val
)
1893 struct sd
*sd
= (struct sd
*) gspca_dev
;
1896 if (gspca_dev
->streaming
)
1897 return set_exposure(gspca_dev
);
1901 static int sd_getexposure(struct gspca_dev
*gspca_dev
, s32
*val
)
1903 struct sd
*sd
= (struct sd
*) gspca_dev
;
1904 *val
= sd
->exposure
;
1908 static int sd_setgain(struct gspca_dev
*gspca_dev
, s32 val
)
1910 struct sd
*sd
= (struct sd
*) gspca_dev
;
1913 if (gspca_dev
->streaming
)
1914 return set_gain(gspca_dev
);
1918 static int sd_getgain(struct gspca_dev
*gspca_dev
, s32
*val
)
1920 struct sd
*sd
= (struct sd
*) gspca_dev
;
1925 static int sd_setautoexposure(struct gspca_dev
*gspca_dev
, s32 val
)
1927 struct sd
*sd
= (struct sd
*) gspca_dev
;
1928 sd
->auto_exposure
= val
;
1932 static int sd_getautoexposure(struct gspca_dev
*gspca_dev
, s32
*val
)
1934 struct sd
*sd
= (struct sd
*) gspca_dev
;
1935 *val
= sd
->auto_exposure
;
1939 #ifdef CONFIG_VIDEO_ADV_DEBUG
1940 static int sd_dbg_g_register(struct gspca_dev
*gspca_dev
,
1941 struct v4l2_dbg_register
*reg
)
1943 struct sd
*sd
= (struct sd
*) gspca_dev
;
1944 switch (reg
->match
.type
) {
1945 case V4L2_CHIP_MATCH_HOST
:
1946 if (reg
->match
.addr
!= 0)
1948 if (reg
->reg
< 0x1000 || reg
->reg
> 0x11ff)
1950 if (reg_r(gspca_dev
, reg
->reg
, 1) < 0)
1952 reg
->val
= gspca_dev
->usb_buf
[0];
1954 case V4L2_CHIP_MATCH_I2C_ADDR
:
1955 if (reg
->match
.addr
!= sd
->i2c_addr
)
1957 if (sd
->sensor
>= SENSOR_MT9V011
&&
1958 sd
->sensor
<= SENSOR_MT9M112
) {
1959 if (i2c_r2(gspca_dev
, reg
->reg
, (u16
*)®
->val
) < 0)
1962 if (i2c_r1(gspca_dev
, reg
->reg
, (u8
*)®
->val
) < 0)
1970 static int sd_dbg_s_register(struct gspca_dev
*gspca_dev
,
1971 struct v4l2_dbg_register
*reg
)
1973 struct sd
*sd
= (struct sd
*) gspca_dev
;
1974 switch (reg
->match
.type
) {
1975 case V4L2_CHIP_MATCH_HOST
:
1976 if (reg
->match
.addr
!= 0)
1978 if (reg
->reg
< 0x1000 || reg
->reg
> 0x11ff)
1980 if (reg_w1(gspca_dev
, reg
->reg
, reg
->val
) < 0)
1983 case V4L2_CHIP_MATCH_I2C_ADDR
:
1984 if (reg
->match
.addr
!= sd
->i2c_addr
)
1986 if (sd
->sensor
>= SENSOR_MT9V011
&&
1987 sd
->sensor
<= SENSOR_MT9M112
) {
1988 if (i2c_w2(gspca_dev
, reg
->reg
, reg
->val
) < 0)
1991 if (i2c_w1(gspca_dev
, reg
->reg
, reg
->val
) < 0)
2000 static int sd_chip_ident(struct gspca_dev
*gspca_dev
,
2001 struct v4l2_dbg_chip_ident
*chip
)
2003 struct sd
*sd
= (struct sd
*) gspca_dev
;
2005 switch (chip
->match
.type
) {
2006 case V4L2_CHIP_MATCH_HOST
:
2007 if (chip
->match
.addr
!= 0)
2010 chip
->ident
= V4L2_IDENT_SN9C20X
;
2012 case V4L2_CHIP_MATCH_I2C_ADDR
:
2013 if (chip
->match
.addr
!= sd
->i2c_addr
)
2016 chip
->ident
= i2c_ident
[sd
->sensor
];
2022 static int sd_config(struct gspca_dev
*gspca_dev
,
2023 const struct usb_device_id
*id
)
2025 struct sd
*sd
= (struct sd
*) gspca_dev
;
2028 cam
= &gspca_dev
->cam
;
2030 sd
->sensor
= (id
->driver_info
>> 8) & 0xff;
2031 sd
->i2c_addr
= id
->driver_info
& 0xff;
2032 sd
->flags
= (id
->driver_info
>> 16) & 0xff;
2034 switch (sd
->sensor
) {
2035 case SENSOR_MT9M112
:
2036 case SENSOR_MT9M111
:
2039 cam
->cam_mode
= sxga_mode
;
2040 cam
->nmodes
= ARRAY_SIZE(sxga_mode
);
2042 case SENSOR_MT9M001
:
2043 cam
->cam_mode
= mono_mode
;
2044 cam
->nmodes
= ARRAY_SIZE(mono_mode
);
2047 cam
->cam_mode
= vga_mode
;
2048 cam
->nmodes
= ARRAY_SIZE(vga_mode
);
2054 sd
->exposure_step
= 16;
2056 sd
->brightness
= BRIGHTNESS_DEFAULT
;
2057 sd
->contrast
= CONTRAST_DEFAULT
;
2058 sd
->saturation
= SATURATION_DEFAULT
;
2059 sd
->hue
= HUE_DEFAULT
;
2060 sd
->gamma
= GAMMA_DEFAULT
;
2061 sd
->red
= RED_DEFAULT
;
2062 sd
->blue
= BLUE_DEFAULT
;
2064 sd
->hflip
= HFLIP_DEFAULT
;
2065 sd
->vflip
= VFLIP_DEFAULT
;
2066 sd
->exposure
= EXPOSURE_DEFAULT
;
2067 sd
->gain
= GAIN_DEFAULT
;
2068 sd
->auto_exposure
= AUTO_EXPOSURE_DEFAULT
;
2075 static int sd_init(struct gspca_dev
*gspca_dev
)
2077 struct sd
*sd
= (struct sd
*) gspca_dev
;
2081 {0x80, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
2083 for (i
= 0; i
< ARRAY_SIZE(bridge_init
); i
++) {
2084 value
= bridge_init
[i
][1];
2085 if (reg_w(gspca_dev
, bridge_init
[i
][0], &value
, 1) < 0) {
2086 err("Device initialization failed");
2091 if (sd
->flags
& LED_REVERSE
)
2092 reg_w1(gspca_dev
, 0x1006, 0x00);
2094 reg_w1(gspca_dev
, 0x1006, 0x20);
2096 if (reg_w(gspca_dev
, 0x10c0, i2c_init
, 9) < 0) {
2097 err("Device initialization failed");
2101 switch (sd
->sensor
) {
2103 if (ov9650_init_sensor(gspca_dev
) < 0)
2105 info("OV9650 sensor detected");
2108 if (ov9655_init_sensor(gspca_dev
) < 0)
2110 info("OV9655 sensor detected");
2113 if (soi968_init_sensor(gspca_dev
) < 0)
2115 info("SOI968 sensor detected");
2118 if (ov7660_init_sensor(gspca_dev
) < 0)
2120 info("OV7660 sensor detected");
2123 if (ov7670_init_sensor(gspca_dev
) < 0)
2125 info("OV7670 sensor detected");
2127 case SENSOR_MT9VPRB
:
2128 if (mt9v_init_sensor(gspca_dev
) < 0)
2131 case SENSOR_MT9M111
:
2132 if (mt9m111_init_sensor(gspca_dev
) < 0)
2134 info("MT9M111 sensor detected");
2136 case SENSOR_MT9M112
:
2137 if (mt9m112_init_sensor(gspca_dev
) < 0)
2139 info("MT9M112 sensor detected");
2141 case SENSOR_MT9M001
:
2142 if (mt9m001_init_sensor(gspca_dev
) < 0)
2145 case SENSOR_HV7131R
:
2146 if (hv7131r_init_sensor(gspca_dev
) < 0)
2148 info("HV7131R sensor detected");
2151 info("Unsupported Sensor");
2158 static void configure_sensor_output(struct gspca_dev
*gspca_dev
, int mode
)
2160 struct sd
*sd
= (struct sd
*) gspca_dev
;
2162 switch (sd
->sensor
) {
2164 if (mode
& MODE_SXGA
) {
2165 i2c_w1(gspca_dev
, 0x17, 0x1d);
2166 i2c_w1(gspca_dev
, 0x18, 0xbd);
2167 i2c_w1(gspca_dev
, 0x19, 0x01);
2168 i2c_w1(gspca_dev
, 0x1a, 0x81);
2169 i2c_w1(gspca_dev
, 0x12, 0x00);
2173 i2c_w1(gspca_dev
, 0x17, 0x13);
2174 i2c_w1(gspca_dev
, 0x18, 0x63);
2175 i2c_w1(gspca_dev
, 0x19, 0x01);
2176 i2c_w1(gspca_dev
, 0x1a, 0x79);
2177 i2c_w1(gspca_dev
, 0x12, 0x40);
2183 if (mode
& MODE_SXGA
) {
2184 i2c_w1(gspca_dev
, 0x17, 0x1b);
2185 i2c_w1(gspca_dev
, 0x18, 0xbc);
2186 i2c_w1(gspca_dev
, 0x19, 0x01);
2187 i2c_w1(gspca_dev
, 0x1a, 0x82);
2188 i2c_r1(gspca_dev
, 0x12, &value
);
2189 i2c_w1(gspca_dev
, 0x12, value
& 0x07);
2191 i2c_w1(gspca_dev
, 0x17, 0x24);
2192 i2c_w1(gspca_dev
, 0x18, 0xc5);
2193 i2c_w1(gspca_dev
, 0x19, 0x00);
2194 i2c_w1(gspca_dev
, 0x1a, 0x3c);
2195 i2c_r1(gspca_dev
, 0x12, &value
);
2196 i2c_w1(gspca_dev
, 0x12, (value
& 0x7) | 0x40);
2199 case SENSOR_MT9M112
:
2200 case SENSOR_MT9M111
:
2201 if (mode
& MODE_SXGA
) {
2202 i2c_w2(gspca_dev
, 0xf0, 0x0002);
2203 i2c_w2(gspca_dev
, 0xc8, 0x970b);
2204 i2c_w2(gspca_dev
, 0xf0, 0x0000);
2206 i2c_w2(gspca_dev
, 0xf0, 0x0002);
2207 i2c_w2(gspca_dev
, 0xc8, 0x8000);
2208 i2c_w2(gspca_dev
, 0xf0, 0x0000);
2214 #define HW_WIN(mode, hstart, vstart) \
2215 ((const u8 []){hstart, 0, vstart, 0, \
2216 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
2217 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
2219 #define CLR_WIN(width, height) \
2221 {0, width >> 2, 0, height >> 1,\
2222 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
2224 static int sd_start(struct gspca_dev
*gspca_dev
)
2226 struct sd
*sd
= (struct sd
*) gspca_dev
;
2227 int mode
= gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
;
2228 int width
= gspca_dev
->width
;
2229 int height
= gspca_dev
->height
;
2232 jpeg_define(sd
->jpeg_hdr
, height
, width
,
2234 jpeg_set_qual(sd
->jpeg_hdr
, sd
->quality
);
2236 if (mode
& MODE_RAW
)
2238 else if (mode
& MODE_JPEG
)
2241 fmt
= 0x2f; /* YUV 420 */
2243 switch (mode
& SCALE_MASK
) {
2244 case SCALE_1280x1024
:
2246 info("Set 1280x1024");
2250 info("Set 640x480");
2254 info("Set 320x240");
2258 info("Set 160x120");
2262 configure_sensor_output(gspca_dev
, mode
);
2263 reg_w(gspca_dev
, 0x1100, &sd
->jpeg_hdr
[JPEG_QT0_OFFSET
], 64);
2264 reg_w(gspca_dev
, 0x1140, &sd
->jpeg_hdr
[JPEG_QT1_OFFSET
], 64);
2265 reg_w(gspca_dev
, 0x10fb, CLR_WIN(width
, height
), 5);
2266 reg_w(gspca_dev
, 0x1180, HW_WIN(mode
, sd
->hstart
, sd
->vstart
), 6);
2267 reg_w1(gspca_dev
, 0x1189, scale
);
2268 reg_w1(gspca_dev
, 0x10e0, fmt
);
2270 set_cmatrix(gspca_dev
);
2271 set_gamma(gspca_dev
);
2272 set_redblue(gspca_dev
);
2273 set_gain(gspca_dev
);
2274 set_exposure(gspca_dev
);
2275 set_hvflip(gspca_dev
);
2277 reg_w1(gspca_dev
, 0x1007, 0x20);
2279 reg_r(gspca_dev
, 0x1061, 1);
2280 reg_w1(gspca_dev
, 0x1061, gspca_dev
->usb_buf
[0] | 0x02);
2284 static void sd_stopN(struct gspca_dev
*gspca_dev
)
2286 reg_w1(gspca_dev
, 0x1007, 0x00);
2288 reg_r(gspca_dev
, 0x1061, 1);
2289 reg_w1(gspca_dev
, 0x1061, gspca_dev
->usb_buf
[0] & ~0x02);
2292 static void do_autoexposure(struct gspca_dev
*gspca_dev
, u16 avg_lum
)
2294 struct sd
*sd
= (struct sd
*) gspca_dev
;
2298 * some hardcoded values are present
2299 * like those for maximal/minimal exposure
2300 * and exposure steps
2302 if (avg_lum
< MIN_AVG_LUM
) {
2303 if (sd
->exposure
> 0x1770)
2306 new_exp
= sd
->exposure
+ sd
->exposure_step
;
2307 if (new_exp
> 0x1770)
2311 sd
->exposure
= new_exp
;
2312 set_exposure(gspca_dev
);
2314 sd
->older_step
= sd
->old_step
;
2317 if (sd
->old_step
^ sd
->older_step
)
2318 sd
->exposure_step
/= 2;
2320 sd
->exposure_step
+= 2;
2322 if (avg_lum
> MAX_AVG_LUM
) {
2323 if (sd
->exposure
< 0x10)
2325 new_exp
= sd
->exposure
- sd
->exposure_step
;
2326 if (new_exp
> 0x1700)
2330 sd
->exposure
= new_exp
;
2331 set_exposure(gspca_dev
);
2332 sd
->older_step
= sd
->old_step
;
2335 if (sd
->old_step
^ sd
->older_step
)
2336 sd
->exposure_step
/= 2;
2338 sd
->exposure_step
+= 2;
2342 static void do_autogain(struct gspca_dev
*gspca_dev
, u16 avg_lum
)
2344 struct sd
*sd
= (struct sd
*) gspca_dev
;
2346 if (avg_lum
< MIN_AVG_LUM
) {
2347 if (sd
->gain
+ 1 <= 28) {
2349 set_gain(gspca_dev
);
2352 if (avg_lum
> MAX_AVG_LUM
) {
2355 set_gain(gspca_dev
);
2360 static void sd_dqcallback(struct gspca_dev
*gspca_dev
)
2362 struct sd
*sd
= (struct sd
*) gspca_dev
;
2365 if (!sd
->auto_exposure
)
2368 avg_lum
= atomic_read(&sd
->avg_lum
);
2369 if (sd
->sensor
== SENSOR_SOI968
)
2370 do_autogain(gspca_dev
, avg_lum
);
2372 do_autoexposure(gspca_dev
, avg_lum
);
2375 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2376 static int sd_int_pkt_scan(struct gspca_dev
*gspca_dev
,
2377 u8
*data
, /* interrupt packet */
2378 int len
) /* interrupt packet length */
2380 struct sd
*sd
= (struct sd
*) gspca_dev
;
2382 if (!(sd
->flags
& HAS_NO_BUTTON
) && len
== 1) {
2383 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 1);
2384 input_sync(gspca_dev
->input_dev
);
2385 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 0);
2386 input_sync(gspca_dev
->input_dev
);
2393 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
2394 u8
*data
, /* isoc packet */
2395 int len
) /* iso packet length */
2397 struct sd
*sd
= (struct sd
*) gspca_dev
;
2399 static u8 frame_header
[] =
2400 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2401 if (len
== 64 && memcmp(data
, frame_header
, 6) == 0) {
2402 avg_lum
= ((data
[35] >> 2) & 3) |
2405 avg_lum
+= ((data
[35] >> 4) & 3) |
2408 avg_lum
+= ((data
[35] >> 6) & 3) |
2411 avg_lum
+= (data
[36] & 3) |
2414 avg_lum
+= ((data
[36] >> 2) & 3) |
2417 avg_lum
+= ((data
[36] >> 4) & 3) |
2420 avg_lum
+= ((data
[36] >> 6) & 3) |
2423 avg_lum
+= ((data
[44] >> 4) & 3) |
2427 atomic_set(&sd
->avg_lum
, avg_lum
);
2428 gspca_frame_add(gspca_dev
, LAST_PACKET
, NULL
, 0);
2431 if (gspca_dev
->last_packet_type
== LAST_PACKET
) {
2432 if (gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
2434 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
2435 sd
->jpeg_hdr
, JPEG_HDR_SZ
);
2436 gspca_frame_add(gspca_dev
, INTER_PACKET
,
2439 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
2443 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, len
);
2447 /* sub-driver description */
2448 static const struct sd_desc sd_desc
= {
2449 .name
= MODULE_NAME
,
2451 .nctrls
= ARRAY_SIZE(sd_ctrls
),
2452 .config
= sd_config
,
2456 .pkt_scan
= sd_pkt_scan
,
2457 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2458 .int_pkt_scan
= sd_int_pkt_scan
,
2460 .dq_callback
= sd_dqcallback
,
2461 #ifdef CONFIG_VIDEO_ADV_DEBUG
2462 .set_register
= sd_dbg_s_register
,
2463 .get_register
= sd_dbg_g_register
,
2465 .get_chip_ident
= sd_chip_ident
,
2468 #define SN9C20X(sensor, i2c_addr, flags) \
2469 .driver_info = ((flags & 0xff) << 16) \
2470 | (SENSOR_ ## sensor << 8) \
2473 static const struct usb_device_id device_table
[] = {
2474 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001
, 0x5d, 0)},
2475 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111
, 0x5d, 0)},
2476 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655
, 0x30, 0)},
2477 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112
, 0x5d, 0)},
2478 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968
, 0x30, LED_REVERSE
)},
2479 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650
, 0x30,
2480 (FLIP_DETECT
| HAS_NO_BUTTON
))},
2481 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650
, 0x30, 0)},
2482 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650
, 0x30, 0)},
2483 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670
, 0x21, 0)},
2484 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB
, 0x00, 0)},
2485 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660
, 0x21, 0)},
2486 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R
, 0x11, 0)},
2487 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650
, 0x30, 0)},
2488 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001
, 0x5d, 0)},
2489 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111
, 0x5d, 0)},
2490 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655
, 0x30, 0)},
2491 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112
, 0x5d, 0)},
2492 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968
, 0x30, 0)},
2493 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650
, 0x30, 0)},
2494 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670
, 0x21, 0)},
2495 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB
, 0x00, 0)},
2496 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655
, 0x30, 0)},
2497 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660
, 0x21, 0)},
2498 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R
, 0x11, 0)},
2499 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650
, 0x30, 0)},
2500 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660
, 0x21, 0)},
2501 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R
, 0x11, 0)},
2502 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112
, 0x5d, 0)},
2503 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112
, 0x5d, 0)},
2504 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R
, 0x11, 0)},
2505 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R
, 0x11, 0)},
2506 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R
, 0x11, 0)},
2507 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R
, 0x11, 0)},
2508 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111
, 0x5d, 0)},
2509 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111
, 0x5d, 0)},
2510 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111
, 0x5d, 0)},
2513 MODULE_DEVICE_TABLE(usb
, device_table
);
2515 /* -- device connect -- */
2516 static int sd_probe(struct usb_interface
*intf
,
2517 const struct usb_device_id
*id
)
2519 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
2523 static struct usb_driver sd_driver
= {
2524 .name
= MODULE_NAME
,
2525 .id_table
= device_table
,
2527 .disconnect
= gspca_disconnect
,
2529 .suspend
= gspca_suspend
,
2530 .resume
= gspca_resume
,
2531 .reset_resume
= gspca_resume
,
2535 /* -- module insert / remove -- */
2536 static int __init
sd_mod_init(void)
2538 return usb_register(&sd_driver
);
2540 static void __exit
sd_mod_exit(void)
2542 usb_deregister(&sd_driver
);
2545 module_init(sd_mod_init
);
2546 module_exit(sd_mod_exit
);