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-1633X",
157 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
158 DMI_MATCH(DMI_BOARD_NAME
, "MS-1633X")
162 .ident
= "MSI MS-1635X",
164 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
165 DMI_MATCH(DMI_BOARD_NAME
, "MS-1635X")
169 .ident
= "ASUSTeK W7J",
171 DMI_MATCH(DMI_BOARD_VENDOR
, "ASUSTeK Computer Inc."),
172 DMI_MATCH(DMI_BOARD_NAME
, "W7J ")
178 static const struct ctrl sd_ctrls
[] = {
180 #define BRIGHTNESS_IDX 0
182 .id
= V4L2_CID_BRIGHTNESS
,
183 .type
= V4L2_CTRL_TYPE_INTEGER
,
184 .name
= "Brightness",
188 #define BRIGHTNESS_DEFAULT 0x7f
189 .default_value
= BRIGHTNESS_DEFAULT
,
191 .set
= sd_setbrightness
,
192 .get
= sd_getbrightness
,
195 #define CONTRAST_IDX 1
197 .id
= V4L2_CID_CONTRAST
,
198 .type
= V4L2_CTRL_TYPE_INTEGER
,
203 #define CONTRAST_DEFAULT 0x7f
204 .default_value
= CONTRAST_DEFAULT
,
206 .set
= sd_setcontrast
,
207 .get
= sd_getcontrast
,
210 #define SATURATION_IDX 2
212 .id
= V4L2_CID_SATURATION
,
213 .type
= V4L2_CTRL_TYPE_INTEGER
,
214 .name
= "Saturation",
218 #define SATURATION_DEFAULT 0x7f
219 .default_value
= SATURATION_DEFAULT
,
221 .set
= sd_setsaturation
,
222 .get
= sd_getsaturation
,
228 .type
= V4L2_CTRL_TYPE_INTEGER
,
233 #define HUE_DEFAULT 0
234 .default_value
= HUE_DEFAULT
,
242 .id
= V4L2_CID_GAMMA
,
243 .type
= V4L2_CTRL_TYPE_INTEGER
,
248 #define GAMMA_DEFAULT 0x10
249 .default_value
= GAMMA_DEFAULT
,
257 .id
= V4L2_CID_BLUE_BALANCE
,
258 .type
= V4L2_CTRL_TYPE_INTEGER
,
259 .name
= "Blue Balance",
263 #define BLUE_DEFAULT 0x28
264 .default_value
= BLUE_DEFAULT
,
266 .set
= sd_setbluebalance
,
267 .get
= sd_getbluebalance
,
272 .id
= V4L2_CID_RED_BALANCE
,
273 .type
= V4L2_CTRL_TYPE_INTEGER
,
274 .name
= "Red Balance",
278 #define RED_DEFAULT 0x28
279 .default_value
= RED_DEFAULT
,
281 .set
= sd_setredbalance
,
282 .get
= sd_getredbalance
,
287 .id
= V4L2_CID_HFLIP
,
288 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
289 .name
= "Horizontal Flip",
293 #define HFLIP_DEFAULT 0
294 .default_value
= HFLIP_DEFAULT
,
302 .id
= V4L2_CID_VFLIP
,
303 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
304 .name
= "Vertical Flip",
308 #define VFLIP_DEFAULT 0
309 .default_value
= VFLIP_DEFAULT
,
315 #define EXPOSURE_IDX 9
317 .id
= V4L2_CID_EXPOSURE
,
318 .type
= V4L2_CTRL_TYPE_INTEGER
,
323 #define EXPOSURE_DEFAULT 0x33
324 .default_value
= EXPOSURE_DEFAULT
,
326 .set
= sd_setexposure
,
327 .get
= sd_getexposure
,
333 .type
= V4L2_CTRL_TYPE_INTEGER
,
338 #define GAIN_DEFAULT 0x00
339 .default_value
= GAIN_DEFAULT
,
345 #define AUTOGAIN_IDX 11
347 .id
= V4L2_CID_AUTOGAIN
,
348 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
349 .name
= "Auto Exposure",
353 #define AUTO_EXPOSURE_DEFAULT 1
354 .default_value
= AUTO_EXPOSURE_DEFAULT
,
356 .set
= sd_setautoexposure
,
357 .get
= sd_getautoexposure
,
361 static const struct v4l2_pix_format vga_mode
[] = {
362 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
364 .sizeimage
= 160 * 120 * 4 / 8 + 590,
365 .colorspace
= V4L2_COLORSPACE_JPEG
,
366 .priv
= SCALE_160x120
| MODE_JPEG
},
367 {160, 120, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
369 .sizeimage
= 160 * 120,
370 .colorspace
= V4L2_COLORSPACE_SRGB
,
371 .priv
= SCALE_160x120
| MODE_RAW
},
372 {160, 120, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
374 .sizeimage
= 240 * 120,
375 .colorspace
= V4L2_COLORSPACE_SRGB
,
376 .priv
= SCALE_160x120
},
377 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
379 .sizeimage
= 320 * 240 * 4 / 8 + 590,
380 .colorspace
= V4L2_COLORSPACE_JPEG
,
381 .priv
= SCALE_320x240
| MODE_JPEG
},
382 {320, 240, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
384 .sizeimage
= 320 * 240 ,
385 .colorspace
= V4L2_COLORSPACE_SRGB
,
386 .priv
= SCALE_320x240
| MODE_RAW
},
387 {320, 240, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
389 .sizeimage
= 480 * 240 ,
390 .colorspace
= V4L2_COLORSPACE_SRGB
,
391 .priv
= SCALE_320x240
},
392 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
394 .sizeimage
= 640 * 480 * 4 / 8 + 590,
395 .colorspace
= V4L2_COLORSPACE_JPEG
,
396 .priv
= SCALE_640x480
| MODE_JPEG
},
397 {640, 480, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
399 .sizeimage
= 640 * 480,
400 .colorspace
= V4L2_COLORSPACE_SRGB
,
401 .priv
= SCALE_640x480
| MODE_RAW
},
402 {640, 480, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
404 .sizeimage
= 960 * 480,
405 .colorspace
= V4L2_COLORSPACE_SRGB
,
406 .priv
= SCALE_640x480
},
409 static const struct v4l2_pix_format sxga_mode
[] = {
410 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
412 .sizeimage
= 160 * 120 * 4 / 8 + 590,
413 .colorspace
= V4L2_COLORSPACE_JPEG
,
414 .priv
= SCALE_160x120
| MODE_JPEG
},
415 {160, 120, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
417 .sizeimage
= 160 * 120,
418 .colorspace
= V4L2_COLORSPACE_SRGB
,
419 .priv
= SCALE_160x120
| MODE_RAW
},
420 {160, 120, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
422 .sizeimage
= 240 * 120,
423 .colorspace
= V4L2_COLORSPACE_SRGB
,
424 .priv
= SCALE_160x120
},
425 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
427 .sizeimage
= 320 * 240 * 4 / 8 + 590,
428 .colorspace
= V4L2_COLORSPACE_JPEG
,
429 .priv
= SCALE_320x240
| MODE_JPEG
},
430 {320, 240, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
432 .sizeimage
= 320 * 240 ,
433 .colorspace
= V4L2_COLORSPACE_SRGB
,
434 .priv
= SCALE_320x240
| MODE_RAW
},
435 {320, 240, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
437 .sizeimage
= 480 * 240 ,
438 .colorspace
= V4L2_COLORSPACE_SRGB
,
439 .priv
= SCALE_320x240
},
440 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
442 .sizeimage
= 640 * 480 * 4 / 8 + 590,
443 .colorspace
= V4L2_COLORSPACE_JPEG
,
444 .priv
= SCALE_640x480
| MODE_JPEG
},
445 {640, 480, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
447 .sizeimage
= 640 * 480,
448 .colorspace
= V4L2_COLORSPACE_SRGB
,
449 .priv
= SCALE_640x480
| MODE_RAW
},
450 {640, 480, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
452 .sizeimage
= 960 * 480,
453 .colorspace
= V4L2_COLORSPACE_SRGB
,
454 .priv
= SCALE_640x480
},
455 {1280, 1024, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
456 .bytesperline
= 1280,
457 .sizeimage
= 1280 * 1024,
458 .colorspace
= V4L2_COLORSPACE_SRGB
,
459 .priv
= SCALE_1280x1024
| MODE_RAW
| MODE_SXGA
},
462 static const struct v4l2_pix_format mono_mode
[] = {
463 {160, 120, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
465 .sizeimage
= 160 * 120,
466 .colorspace
= V4L2_COLORSPACE_SRGB
,
467 .priv
= SCALE_160x120
| MODE_RAW
},
468 {320, 240, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
470 .sizeimage
= 320 * 240 ,
471 .colorspace
= V4L2_COLORSPACE_SRGB
,
472 .priv
= SCALE_320x240
| MODE_RAW
},
473 {640, 480, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
475 .sizeimage
= 640 * 480,
476 .colorspace
= V4L2_COLORSPACE_SRGB
,
477 .priv
= SCALE_640x480
| MODE_RAW
},
478 {1280, 1024, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
479 .bytesperline
= 1280,
480 .sizeimage
= 1280 * 1024,
481 .colorspace
= V4L2_COLORSPACE_SRGB
,
482 .priv
= SCALE_1280x1024
| MODE_RAW
| MODE_SXGA
},
485 static const s16 hsv_red_x
[] = {
486 41, 44, 46, 48, 50, 52, 54, 56,
487 58, 60, 62, 64, 66, 68, 70, 72,
488 74, 76, 78, 80, 81, 83, 85, 87,
489 88, 90, 92, 93, 95, 97, 98, 100,
490 101, 102, 104, 105, 107, 108, 109, 110,
491 112, 113, 114, 115, 116, 117, 118, 119,
492 120, 121, 122, 123, 123, 124, 125, 125,
493 126, 127, 127, 128, 128, 129, 129, 129,
494 130, 130, 130, 130, 131, 131, 131, 131,
495 131, 131, 131, 131, 130, 130, 130, 130,
496 129, 129, 129, 128, 128, 127, 127, 126,
497 125, 125, 124, 123, 122, 122, 121, 120,
498 119, 118, 117, 116, 115, 114, 112, 111,
499 110, 109, 107, 106, 105, 103, 102, 101,
500 99, 98, 96, 94, 93, 91, 90, 88,
501 86, 84, 83, 81, 79, 77, 75, 74,
502 72, 70, 68, 66, 64, 62, 60, 58,
503 56, 54, 52, 49, 47, 45, 43, 41,
504 39, 36, 34, 32, 30, 28, 25, 23,
505 21, 19, 16, 14, 12, 9, 7, 5,
506 3, 0, -1, -3, -6, -8, -10, -12,
507 -15, -17, -19, -22, -24, -26, -28, -30,
508 -33, -35, -37, -39, -41, -44, -46, -48,
509 -50, -52, -54, -56, -58, -60, -62, -64,
510 -66, -68, -70, -72, -74, -76, -78, -80,
511 -81, -83, -85, -87, -88, -90, -92, -93,
512 -95, -97, -98, -100, -101, -102, -104, -105,
513 -107, -108, -109, -110, -112, -113, -114, -115,
514 -116, -117, -118, -119, -120, -121, -122, -123,
515 -123, -124, -125, -125, -126, -127, -127, -128,
516 -128, -128, -128, -128, -128, -128, -128, -128,
517 -128, -128, -128, -128, -128, -128, -128, -128,
518 -128, -128, -128, -128, -128, -128, -128, -128,
519 -128, -127, -127, -126, -125, -125, -124, -123,
520 -122, -122, -121, -120, -119, -118, -117, -116,
521 -115, -114, -112, -111, -110, -109, -107, -106,
522 -105, -103, -102, -101, -99, -98, -96, -94,
523 -93, -91, -90, -88, -86, -84, -83, -81,
524 -79, -77, -75, -74, -72, -70, -68, -66,
525 -64, -62, -60, -58, -56, -54, -52, -49,
526 -47, -45, -43, -41, -39, -36, -34, -32,
527 -30, -28, -25, -23, -21, -19, -16, -14,
528 -12, -9, -7, -5, -3, 0, 1, 3,
529 6, 8, 10, 12, 15, 17, 19, 22,
530 24, 26, 28, 30, 33, 35, 37, 39, 41
533 static const s16 hsv_red_y
[] = {
534 82, 80, 78, 76, 74, 73, 71, 69,
535 67, 65, 63, 61, 58, 56, 54, 52,
536 50, 48, 46, 44, 41, 39, 37, 35,
537 32, 30, 28, 26, 23, 21, 19, 16,
538 14, 12, 10, 7, 5, 3, 0, -1,
539 -3, -6, -8, -10, -13, -15, -17, -19,
540 -22, -24, -26, -29, -31, -33, -35, -38,
541 -40, -42, -44, -46, -48, -51, -53, -55,
542 -57, -59, -61, -63, -65, -67, -69, -71,
543 -73, -75, -77, -79, -81, -82, -84, -86,
544 -88, -89, -91, -93, -94, -96, -98, -99,
545 -101, -102, -104, -105, -106, -108, -109, -110,
546 -112, -113, -114, -115, -116, -117, -119, -120,
547 -120, -121, -122, -123, -124, -125, -126, -126,
548 -127, -128, -128, -128, -128, -128, -128, -128,
549 -128, -128, -128, -128, -128, -128, -128, -128,
550 -128, -128, -128, -128, -128, -128, -128, -128,
551 -128, -128, -128, -128, -128, -128, -128, -128,
552 -127, -127, -126, -125, -125, -124, -123, -122,
553 -121, -120, -119, -118, -117, -116, -115, -114,
554 -113, -111, -110, -109, -107, -106, -105, -103,
555 -102, -100, -99, -97, -96, -94, -92, -91,
556 -89, -87, -85, -84, -82, -80, -78, -76,
557 -74, -73, -71, -69, -67, -65, -63, -61,
558 -58, -56, -54, -52, -50, -48, -46, -44,
559 -41, -39, -37, -35, -32, -30, -28, -26,
560 -23, -21, -19, -16, -14, -12, -10, -7,
561 -5, -3, 0, 1, 3, 6, 8, 10,
562 13, 15, 17, 19, 22, 24, 26, 29,
563 31, 33, 35, 38, 40, 42, 44, 46,
564 48, 51, 53, 55, 57, 59, 61, 63,
565 65, 67, 69, 71, 73, 75, 77, 79,
566 81, 82, 84, 86, 88, 89, 91, 93,
567 94, 96, 98, 99, 101, 102, 104, 105,
568 106, 108, 109, 110, 112, 113, 114, 115,
569 116, 117, 119, 120, 120, 121, 122, 123,
570 124, 125, 126, 126, 127, 128, 128, 129,
571 129, 130, 130, 131, 131, 131, 131, 132,
572 132, 132, 132, 132, 132, 132, 132, 132,
573 132, 132, 132, 131, 131, 131, 130, 130,
574 130, 129, 129, 128, 127, 127, 126, 125,
575 125, 124, 123, 122, 121, 120, 119, 118,
576 117, 116, 115, 114, 113, 111, 110, 109,
577 107, 106, 105, 103, 102, 100, 99, 97,
578 96, 94, 92, 91, 89, 87, 85, 84, 82
581 static const s16 hsv_green_x
[] = {
582 -124, -124, -125, -125, -125, -125, -125, -125,
583 -125, -126, -126, -125, -125, -125, -125, -125,
584 -125, -124, -124, -124, -123, -123, -122, -122,
585 -121, -121, -120, -120, -119, -118, -117, -117,
586 -116, -115, -114, -113, -112, -111, -110, -109,
587 -108, -107, -105, -104, -103, -102, -100, -99,
588 -98, -96, -95, -93, -92, -91, -89, -87,
589 -86, -84, -83, -81, -79, -77, -76, -74,
590 -72, -70, -69, -67, -65, -63, -61, -59,
591 -57, -55, -53, -51, -49, -47, -45, -43,
592 -41, -39, -37, -35, -33, -30, -28, -26,
593 -24, -22, -20, -18, -15, -13, -11, -9,
594 -7, -4, -2, 0, 1, 3, 6, 8,
595 10, 12, 14, 17, 19, 21, 23, 25,
596 27, 29, 32, 34, 36, 38, 40, 42,
597 44, 46, 48, 50, 52, 54, 56, 58,
598 60, 62, 64, 66, 68, 70, 71, 73,
599 75, 77, 78, 80, 82, 83, 85, 87,
600 88, 90, 91, 93, 94, 96, 97, 98,
601 100, 101, 102, 104, 105, 106, 107, 108,
602 109, 111, 112, 113, 113, 114, 115, 116,
603 117, 118, 118, 119, 120, 120, 121, 122,
604 122, 123, 123, 124, 124, 124, 125, 125,
605 125, 125, 125, 125, 125, 126, 126, 125,
606 125, 125, 125, 125, 125, 124, 124, 124,
607 123, 123, 122, 122, 121, 121, 120, 120,
608 119, 118, 117, 117, 116, 115, 114, 113,
609 112, 111, 110, 109, 108, 107, 105, 104,
610 103, 102, 100, 99, 98, 96, 95, 93,
611 92, 91, 89, 87, 86, 84, 83, 81,
612 79, 77, 76, 74, 72, 70, 69, 67,
613 65, 63, 61, 59, 57, 55, 53, 51,
614 49, 47, 45, 43, 41, 39, 37, 35,
615 33, 30, 28, 26, 24, 22, 20, 18,
616 15, 13, 11, 9, 7, 4, 2, 0,
617 -1, -3, -6, -8, -10, -12, -14, -17,
618 -19, -21, -23, -25, -27, -29, -32, -34,
619 -36, -38, -40, -42, -44, -46, -48, -50,
620 -52, -54, -56, -58, -60, -62, -64, -66,
621 -68, -70, -71, -73, -75, -77, -78, -80,
622 -82, -83, -85, -87, -88, -90, -91, -93,
623 -94, -96, -97, -98, -100, -101, -102, -104,
624 -105, -106, -107, -108, -109, -111, -112, -113,
625 -113, -114, -115, -116, -117, -118, -118, -119,
626 -120, -120, -121, -122, -122, -123, -123, -124, -124
629 static const s16 hsv_green_y
[] = {
630 -100, -99, -98, -97, -95, -94, -93, -91,
631 -90, -89, -87, -86, -84, -83, -81, -80,
632 -78, -76, -75, -73, -71, -70, -68, -66,
633 -64, -63, -61, -59, -57, -55, -53, -51,
634 -49, -48, -46, -44, -42, -40, -38, -36,
635 -34, -32, -30, -27, -25, -23, -21, -19,
636 -17, -15, -13, -11, -9, -7, -4, -2,
637 0, 1, 3, 5, 7, 9, 11, 14,
638 16, 18, 20, 22, 24, 26, 28, 30,
639 32, 34, 36, 38, 40, 42, 44, 46,
640 48, 50, 52, 54, 56, 58, 59, 61,
641 63, 65, 67, 68, 70, 72, 74, 75,
642 77, 78, 80, 82, 83, 85, 86, 88,
643 89, 90, 92, 93, 95, 96, 97, 98,
644 100, 101, 102, 103, 104, 105, 106, 107,
645 108, 109, 110, 111, 112, 112, 113, 114,
646 115, 115, 116, 116, 117, 117, 118, 118,
647 119, 119, 119, 120, 120, 120, 120, 120,
648 121, 121, 121, 121, 121, 121, 120, 120,
649 120, 120, 120, 119, 119, 119, 118, 118,
650 117, 117, 116, 116, 115, 114, 114, 113,
651 112, 111, 111, 110, 109, 108, 107, 106,
652 105, 104, 103, 102, 100, 99, 98, 97,
653 95, 94, 93, 91, 90, 89, 87, 86,
654 84, 83, 81, 80, 78, 76, 75, 73,
655 71, 70, 68, 66, 64, 63, 61, 59,
656 57, 55, 53, 51, 49, 48, 46, 44,
657 42, 40, 38, 36, 34, 32, 30, 27,
658 25, 23, 21, 19, 17, 15, 13, 11,
659 9, 7, 4, 2, 0, -1, -3, -5,
660 -7, -9, -11, -14, -16, -18, -20, -22,
661 -24, -26, -28, -30, -32, -34, -36, -38,
662 -40, -42, -44, -46, -48, -50, -52, -54,
663 -56, -58, -59, -61, -63, -65, -67, -68,
664 -70, -72, -74, -75, -77, -78, -80, -82,
665 -83, -85, -86, -88, -89, -90, -92, -93,
666 -95, -96, -97, -98, -100, -101, -102, -103,
667 -104, -105, -106, -107, -108, -109, -110, -111,
668 -112, -112, -113, -114, -115, -115, -116, -116,
669 -117, -117, -118, -118, -119, -119, -119, -120,
670 -120, -120, -120, -120, -121, -121, -121, -121,
671 -121, -121, -120, -120, -120, -120, -120, -119,
672 -119, -119, -118, -118, -117, -117, -116, -116,
673 -115, -114, -114, -113, -112, -111, -111, -110,
674 -109, -108, -107, -106, -105, -104, -103, -102, -100
677 static const s16 hsv_blue_x
[] = {
678 112, 113, 114, 114, 115, 116, 117, 117,
679 118, 118, 119, 119, 120, 120, 120, 121,
680 121, 121, 122, 122, 122, 122, 122, 122,
681 122, 122, 122, 122, 122, 122, 121, 121,
682 121, 120, 120, 120, 119, 119, 118, 118,
683 117, 116, 116, 115, 114, 113, 113, 112,
684 111, 110, 109, 108, 107, 106, 105, 104,
685 103, 102, 100, 99, 98, 97, 95, 94,
686 93, 91, 90, 88, 87, 85, 84, 82,
687 80, 79, 77, 76, 74, 72, 70, 69,
688 67, 65, 63, 61, 60, 58, 56, 54,
689 52, 50, 48, 46, 44, 42, 40, 38,
690 36, 34, 32, 30, 28, 26, 24, 22,
691 19, 17, 15, 13, 11, 9, 7, 5,
692 2, 0, -1, -3, -5, -7, -9, -12,
693 -14, -16, -18, -20, -22, -24, -26, -28,
694 -31, -33, -35, -37, -39, -41, -43, -45,
695 -47, -49, -51, -53, -54, -56, -58, -60,
696 -62, -64, -66, -67, -69, -71, -73, -74,
697 -76, -78, -79, -81, -83, -84, -86, -87,
698 -89, -90, -92, -93, -94, -96, -97, -98,
699 -99, -101, -102, -103, -104, -105, -106, -107,
700 -108, -109, -110, -111, -112, -113, -114, -114,
701 -115, -116, -117, -117, -118, -118, -119, -119,
702 -120, -120, -120, -121, -121, -121, -122, -122,
703 -122, -122, -122, -122, -122, -122, -122, -122,
704 -122, -122, -121, -121, -121, -120, -120, -120,
705 -119, -119, -118, -118, -117, -116, -116, -115,
706 -114, -113, -113, -112, -111, -110, -109, -108,
707 -107, -106, -105, -104, -103, -102, -100, -99,
708 -98, -97, -95, -94, -93, -91, -90, -88,
709 -87, -85, -84, -82, -80, -79, -77, -76,
710 -74, -72, -70, -69, -67, -65, -63, -61,
711 -60, -58, -56, -54, -52, -50, -48, -46,
712 -44, -42, -40, -38, -36, -34, -32, -30,
713 -28, -26, -24, -22, -19, -17, -15, -13,
714 -11, -9, -7, -5, -2, 0, 1, 3,
715 5, 7, 9, 12, 14, 16, 18, 20,
716 22, 24, 26, 28, 31, 33, 35, 37,
717 39, 41, 43, 45, 47, 49, 51, 53,
718 54, 56, 58, 60, 62, 64, 66, 67,
719 69, 71, 73, 74, 76, 78, 79, 81,
720 83, 84, 86, 87, 89, 90, 92, 93,
721 94, 96, 97, 98, 99, 101, 102, 103,
722 104, 105, 106, 107, 108, 109, 110, 111, 112
725 static const s16 hsv_blue_y
[] = {
726 -11, -13, -15, -17, -19, -21, -23, -25,
727 -27, -29, -31, -33, -35, -37, -39, -41,
728 -43, -45, -46, -48, -50, -52, -54, -55,
729 -57, -59, -61, -62, -64, -66, -67, -69,
730 -71, -72, -74, -75, -77, -78, -80, -81,
731 -83, -84, -86, -87, -88, -90, -91, -92,
732 -93, -95, -96, -97, -98, -99, -100, -101,
733 -102, -103, -104, -105, -106, -106, -107, -108,
734 -109, -109, -110, -111, -111, -112, -112, -113,
735 -113, -114, -114, -114, -115, -115, -115, -115,
736 -116, -116, -116, -116, -116, -116, -116, -116,
737 -116, -115, -115, -115, -115, -114, -114, -114,
738 -113, -113, -112, -112, -111, -111, -110, -110,
739 -109, -108, -108, -107, -106, -105, -104, -103,
740 -102, -101, -100, -99, -98, -97, -96, -95,
741 -94, -93, -91, -90, -89, -88, -86, -85,
742 -84, -82, -81, -79, -78, -76, -75, -73,
743 -71, -70, -68, -67, -65, -63, -62, -60,
744 -58, -56, -55, -53, -51, -49, -47, -45,
745 -44, -42, -40, -38, -36, -34, -32, -30,
746 -28, -26, -24, -22, -20, -18, -16, -14,
747 -12, -10, -8, -6, -4, -2, 0, 1,
748 3, 5, 7, 9, 11, 13, 15, 17,
749 19, 21, 23, 25, 27, 29, 31, 33,
750 35, 37, 39, 41, 43, 45, 46, 48,
751 50, 52, 54, 55, 57, 59, 61, 62,
752 64, 66, 67, 69, 71, 72, 74, 75,
753 77, 78, 80, 81, 83, 84, 86, 87,
754 88, 90, 91, 92, 93, 95, 96, 97,
755 98, 99, 100, 101, 102, 103, 104, 105,
756 106, 106, 107, 108, 109, 109, 110, 111,
757 111, 112, 112, 113, 113, 114, 114, 114,
758 115, 115, 115, 115, 116, 116, 116, 116,
759 116, 116, 116, 116, 116, 115, 115, 115,
760 115, 114, 114, 114, 113, 113, 112, 112,
761 111, 111, 110, 110, 109, 108, 108, 107,
762 106, 105, 104, 103, 102, 101, 100, 99,
763 98, 97, 96, 95, 94, 93, 91, 90,
764 89, 88, 86, 85, 84, 82, 81, 79,
765 78, 76, 75, 73, 71, 70, 68, 67,
766 65, 63, 62, 60, 58, 56, 55, 53,
767 51, 49, 47, 45, 44, 42, 40, 38,
768 36, 34, 32, 30, 28, 26, 24, 22,
769 20, 18, 16, 14, 12, 10, 8, 6,
770 4, 2, 0, -1, -3, -5, -7, -9, -11
773 static u16 i2c_ident
[] = {
782 V4L2_IDENT_MT9M001C12ST
,
788 static u16 bridge_init
[][2] = {
789 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
790 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
791 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
792 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
793 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
794 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
795 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
796 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
797 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
798 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
799 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
800 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
801 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
802 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
803 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
804 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
805 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
806 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
807 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
811 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
812 static u8 ov_gain
[] = {
813 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
814 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
815 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
816 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
817 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
818 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
819 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
823 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
824 static u16 micron1_gain
[] = {
825 /* 1x 1.25x 1.5x 1.75x */
826 0x0020, 0x0028, 0x0030, 0x0038,
827 /* 2x 2.25x 2.5x 2.75x */
828 0x00a0, 0x00a4, 0x00a8, 0x00ac,
829 /* 3x 3.25x 3.5x 3.75x */
830 0x00b0, 0x00b4, 0x00b8, 0x00bc,
831 /* 4x 4.25x 4.5x 4.75x */
832 0x00c0, 0x00c4, 0x00c8, 0x00cc,
833 /* 5x 5.25x 5.5x 5.75x */
834 0x00d0, 0x00d4, 0x00d8, 0x00dc,
835 /* 6x 6.25x 6.5x 6.75x */
836 0x00e0, 0x00e4, 0x00e8, 0x00ec,
837 /* 7x 7.25x 7.5x 7.75x */
838 0x00f0, 0x00f4, 0x00f8, 0x00fc,
843 /* mt9m001 sensor uses a different gain formula then other micron sensors */
844 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
845 static u16 micron2_gain
[] = {
846 /* 1x 1.25x 1.5x 1.75x */
847 0x0008, 0x000a, 0x000c, 0x000e,
848 /* 2x 2.25x 2.5x 2.75x */
849 0x0010, 0x0012, 0x0014, 0x0016,
850 /* 3x 3.25x 3.5x 3.75x */
851 0x0018, 0x001a, 0x001c, 0x001e,
852 /* 4x 4.25x 4.5x 4.75x */
853 0x0020, 0x0051, 0x0052, 0x0053,
854 /* 5x 5.25x 5.5x 5.75x */
855 0x0054, 0x0055, 0x0056, 0x0057,
856 /* 6x 6.25x 6.5x 6.75x */
857 0x0058, 0x0059, 0x005a, 0x005b,
858 /* 7x 7.25x 7.5x 7.75x */
859 0x005c, 0x005d, 0x005e, 0x005f,
864 /* Gain = .5 + bit[7:0] / 16 */
865 static u8 hv7131r_gain
[] = {
866 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
867 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
868 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
869 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
870 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
871 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
872 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
876 static struct i2c_reg_u8 soi968_init
[] = {
877 {0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f},
878 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
879 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
880 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
881 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
882 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
883 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
884 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
885 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
886 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
887 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
890 static struct i2c_reg_u8 ov7660_init
[] = {
891 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
892 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
893 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
894 /* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using
895 0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
896 {0x17, 0x10}, {0x18, 0x61},
897 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
898 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6},
899 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
902 static struct i2c_reg_u8 ov7670_init
[] = {
903 {0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
904 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
905 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
906 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
907 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
908 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
909 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
910 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
911 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
912 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
913 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
914 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
915 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
916 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
917 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
918 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
919 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
920 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
921 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
922 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
923 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
924 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
925 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
926 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
927 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
928 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
929 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
930 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
931 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
932 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
933 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
934 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
935 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
936 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
937 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
938 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
939 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
940 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
941 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
942 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
943 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
944 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
945 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
946 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
947 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
948 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
949 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
950 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
951 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
952 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
953 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
954 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
955 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
959 static struct i2c_reg_u8 ov9650_init
[] = {
960 {0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78},
961 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
962 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
963 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
964 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
965 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
966 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
967 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
968 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
969 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
970 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
971 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
972 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
973 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
974 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
975 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
976 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
977 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
978 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
979 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
980 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
981 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
982 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
983 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
984 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
985 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
986 {0xaa, 0x92}, {0xab, 0x0a},
989 static struct i2c_reg_u8 ov9655_init
[] = {
990 {0x12, 0x80}, {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
991 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
992 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
993 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
994 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
995 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
996 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
997 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
998 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
999 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
1000 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
1001 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
1002 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
1003 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
1004 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
1005 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
1006 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
1007 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
1008 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
1009 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
1010 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
1011 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
1012 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
1013 {0x04, 0x03}, {0x00, 0x13},
1016 static struct i2c_reg_u16 mt9v112_init
[] = {
1017 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
1018 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
1019 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
1020 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
1021 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
1022 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
1023 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
1024 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
1025 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
1026 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
1027 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
1028 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1029 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
1030 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
1031 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
1032 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
1035 static struct i2c_reg_u16 mt9v111_init
[] = {
1036 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
1037 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
1038 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
1039 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
1040 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
1041 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
1042 {0x0e, 0x0008}, {0x20, 0x0000}
1045 static struct i2c_reg_u16 mt9v011_init
[] = {
1046 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
1047 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
1048 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
1049 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
1050 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
1051 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
1052 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
1053 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
1054 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
1055 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
1056 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
1057 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
1058 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
1059 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
1060 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
1061 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
1062 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
1063 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
1064 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
1065 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
1066 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
1067 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1068 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
1069 {0x06, 0x0029}, {0x05, 0x0009},
1072 static struct i2c_reg_u16 mt9m001_init
[] = {
1075 {0x04, 0x0500}, /* hres = 1280 */
1076 {0x03, 0x0400}, /* vres = 1024 */
1088 static struct i2c_reg_u16 mt9m111_init
[] = {
1089 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1090 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1091 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1095 static struct i2c_reg_u16 mt9m112_init
[] = {
1096 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1097 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1098 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1102 static struct i2c_reg_u8 hv7131r_init
[] = {
1103 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
1104 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
1105 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
1106 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
1107 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
1108 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
1109 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
1110 {0x23, 0x09}, {0x01, 0x08},
1113 static int reg_r(struct gspca_dev
*gspca_dev
, u16 reg
, u16 length
)
1115 struct usb_device
*dev
= gspca_dev
->dev
;
1117 result
= usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
1119 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
1125 if (unlikely(result
< 0 || result
!= length
)) {
1126 err("Read register failed 0x%02X", reg
);
1132 static int reg_w(struct gspca_dev
*gspca_dev
, u16 reg
,
1133 const u8
*buffer
, int length
)
1135 struct usb_device
*dev
= gspca_dev
->dev
;
1137 memcpy(gspca_dev
->usb_buf
, buffer
, length
);
1138 result
= usb_control_msg(dev
, usb_sndctrlpipe(dev
, 0),
1140 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
1146 if (unlikely(result
< 0 || result
!= length
)) {
1147 err("Write register failed index 0x%02X", reg
);
1153 static int reg_w1(struct gspca_dev
*gspca_dev
, u16 reg
, const u8 value
)
1155 u8 data
[1] = {value
};
1156 return reg_w(gspca_dev
, reg
, data
, 1);
1159 static int i2c_w(struct gspca_dev
*gspca_dev
, const u8
*buffer
)
1162 reg_w(gspca_dev
, 0x10c0, buffer
, 8);
1163 for (i
= 0; i
< 5; i
++) {
1164 reg_r(gspca_dev
, 0x10c0, 1);
1165 if (gspca_dev
->usb_buf
[0] & 0x04) {
1166 if (gspca_dev
->usb_buf
[0] & 0x08)
1175 static int i2c_w1(struct gspca_dev
*gspca_dev
, u8 reg
, u8 val
)
1177 struct sd
*sd
= (struct sd
*) gspca_dev
;
1182 * from the point of view of the bridge, the length
1183 * includes the address
1185 row
[0] = 0x81 | (2 << 4);
1186 row
[1] = sd
->i2c_addr
;
1194 return i2c_w(gspca_dev
, row
);
1197 static int i2c_w2(struct gspca_dev
*gspca_dev
, u8 reg
, u16 val
)
1199 struct sd
*sd
= (struct sd
*) gspca_dev
;
1203 * from the point of view of the bridge, the length
1204 * includes the address
1206 row
[0] = 0x81 | (3 << 4);
1207 row
[1] = sd
->i2c_addr
;
1209 row
[3] = (val
>> 8) & 0xff;
1210 row
[4] = val
& 0xff;
1215 return i2c_w(gspca_dev
, row
);
1218 static int i2c_r1(struct gspca_dev
*gspca_dev
, u8 reg
, u8
*val
)
1220 struct sd
*sd
= (struct sd
*) gspca_dev
;
1223 row
[0] = 0x81 | (1 << 4);
1224 row
[1] = sd
->i2c_addr
;
1231 if (i2c_w(gspca_dev
, row
) < 0)
1233 row
[0] = 0x81 | (1 << 4) | 0x02;
1235 if (i2c_w(gspca_dev
, row
) < 0)
1237 if (reg_r(gspca_dev
, 0x10c2, 5) < 0)
1239 *val
= gspca_dev
->usb_buf
[4];
1243 static int i2c_r2(struct gspca_dev
*gspca_dev
, u8 reg
, u16
*val
)
1245 struct sd
*sd
= (struct sd
*) gspca_dev
;
1248 row
[0] = 0x81 | (1 << 4);
1249 row
[1] = sd
->i2c_addr
;
1256 if (i2c_w(gspca_dev
, row
) < 0)
1258 row
[0] = 0x81 | (2 << 4) | 0x02;
1260 if (i2c_w(gspca_dev
, row
) < 0)
1262 if (reg_r(gspca_dev
, 0x10c2, 5) < 0)
1264 *val
= (gspca_dev
->usb_buf
[3] << 8) | gspca_dev
->usb_buf
[4];
1268 static int ov9650_init_sensor(struct gspca_dev
*gspca_dev
)
1272 struct sd
*sd
= (struct sd
*) gspca_dev
;
1274 if (i2c_r2(gspca_dev
, 0x1c, &id
) < 0)
1278 err("sensor id for ov9650 doesn't match (0x%04x)", id
);
1282 for (i
= 0; i
< ARRAY_SIZE(ov9650_init
); i
++) {
1283 if (i2c_w1(gspca_dev
, ov9650_init
[i
].reg
,
1284 ov9650_init
[i
].val
) < 0) {
1285 err("OV9650 sensor initialization failed");
1294 static int ov9655_init_sensor(struct gspca_dev
*gspca_dev
)
1297 struct sd
*sd
= (struct sd
*) gspca_dev
;
1299 for (i
= 0; i
< ARRAY_SIZE(ov9655_init
); i
++) {
1300 if (i2c_w1(gspca_dev
, ov9655_init
[i
].reg
,
1301 ov9655_init
[i
].val
) < 0) {
1302 err("OV9655 sensor initialization failed");
1306 /* disable hflip and vflip */
1307 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1313 static int soi968_init_sensor(struct gspca_dev
*gspca_dev
)
1316 struct sd
*sd
= (struct sd
*) gspca_dev
;
1318 for (i
= 0; i
< ARRAY_SIZE(soi968_init
); i
++) {
1319 if (i2c_w1(gspca_dev
, soi968_init
[i
].reg
,
1320 soi968_init
[i
].val
) < 0) {
1321 err("SOI968 sensor initialization failed");
1325 /* disable hflip and vflip */
1326 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
)
1327 | (1 << EXPOSURE_IDX
);
1333 static int ov7660_init_sensor(struct gspca_dev
*gspca_dev
)
1336 struct sd
*sd
= (struct sd
*) gspca_dev
;
1338 for (i
= 0; i
< ARRAY_SIZE(ov7660_init
); i
++) {
1339 if (i2c_w1(gspca_dev
, ov7660_init
[i
].reg
,
1340 ov7660_init
[i
].val
) < 0) {
1341 err("OV7660 sensor initialization failed");
1350 static int ov7670_init_sensor(struct gspca_dev
*gspca_dev
)
1353 struct sd
*sd
= (struct sd
*) gspca_dev
;
1355 for (i
= 0; i
< ARRAY_SIZE(ov7670_init
); i
++) {
1356 if (i2c_w1(gspca_dev
, ov7670_init
[i
].reg
,
1357 ov7670_init
[i
].val
) < 0) {
1358 err("OV7670 sensor initialization failed");
1362 /* disable hflip and vflip */
1363 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1369 static int mt9v_init_sensor(struct gspca_dev
*gspca_dev
)
1371 struct sd
*sd
= (struct sd
*) gspca_dev
;
1376 sd
->i2c_addr
= 0x5d;
1377 ret
= i2c_r2(gspca_dev
, 0xff, &value
);
1378 if ((ret
== 0) && (value
== 0x8243)) {
1379 for (i
= 0; i
< ARRAY_SIZE(mt9v011_init
); i
++) {
1380 if (i2c_w2(gspca_dev
, mt9v011_init
[i
].reg
,
1381 mt9v011_init
[i
].val
) < 0) {
1382 err("MT9V011 sensor initialization failed");
1388 sd
->sensor
= SENSOR_MT9V011
;
1389 info("MT9V011 sensor detected");
1393 sd
->i2c_addr
= 0x5c;
1394 i2c_w2(gspca_dev
, 0x01, 0x0004);
1395 ret
= i2c_r2(gspca_dev
, 0xff, &value
);
1396 if ((ret
== 0) && (value
== 0x823a)) {
1397 for (i
= 0; i
< ARRAY_SIZE(mt9v111_init
); i
++) {
1398 if (i2c_w2(gspca_dev
, mt9v111_init
[i
].reg
,
1399 mt9v111_init
[i
].val
) < 0) {
1400 err("MT9V111 sensor initialization failed");
1404 gspca_dev
->ctrl_dis
= (1 << EXPOSURE_IDX
)
1405 | (1 << AUTOGAIN_IDX
)
1409 sd
->sensor
= SENSOR_MT9V111
;
1410 info("MT9V111 sensor detected");
1414 sd
->i2c_addr
= 0x5d;
1415 ret
= i2c_w2(gspca_dev
, 0xf0, 0x0000);
1417 sd
->i2c_addr
= 0x48;
1418 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1420 ret
= i2c_r2(gspca_dev
, 0x00, &value
);
1421 if ((ret
== 0) && (value
== 0x1229)) {
1422 for (i
= 0; i
< ARRAY_SIZE(mt9v112_init
); i
++) {
1423 if (i2c_w2(gspca_dev
, mt9v112_init
[i
].reg
,
1424 mt9v112_init
[i
].val
) < 0) {
1425 err("MT9V112 sensor initialization failed");
1431 sd
->sensor
= SENSOR_MT9V112
;
1432 info("MT9V112 sensor detected");
1439 static int mt9m112_init_sensor(struct gspca_dev
*gspca_dev
)
1441 struct sd
*sd
= (struct sd
*) gspca_dev
;
1443 for (i
= 0; i
< ARRAY_SIZE(mt9m112_init
); i
++) {
1444 if (i2c_w2(gspca_dev
, mt9m112_init
[i
].reg
,
1445 mt9m112_init
[i
].val
) < 0) {
1446 err("MT9M112 sensor initialization failed");
1450 gspca_dev
->ctrl_dis
= (1 << EXPOSURE_IDX
) | (1 << AUTOGAIN_IDX
)
1457 static int mt9m111_init_sensor(struct gspca_dev
*gspca_dev
)
1459 struct sd
*sd
= (struct sd
*) gspca_dev
;
1461 for (i
= 0; i
< ARRAY_SIZE(mt9m111_init
); i
++) {
1462 if (i2c_w2(gspca_dev
, mt9m111_init
[i
].reg
,
1463 mt9m111_init
[i
].val
) < 0) {
1464 err("MT9M111 sensor initialization failed");
1468 gspca_dev
->ctrl_dis
= (1 << EXPOSURE_IDX
) | (1 << AUTOGAIN_IDX
)
1475 static int mt9m001_init_sensor(struct gspca_dev
*gspca_dev
)
1477 struct sd
*sd
= (struct sd
*) gspca_dev
;
1481 if (i2c_r2(gspca_dev
, 0x00, &id
) < 0)
1484 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
1488 info("MT9M001 color sensor detected");
1491 info("MT9M001 mono sensor detected");
1494 err("No MT9M001 chip detected, ID = %x\n", id
);
1498 for (i
= 0; i
< ARRAY_SIZE(mt9m001_init
); i
++) {
1499 if (i2c_w2(gspca_dev
, mt9m001_init
[i
].reg
,
1500 mt9m001_init
[i
].val
) < 0) {
1501 err("MT9M001 sensor initialization failed");
1505 /* disable hflip and vflip */
1506 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1512 static int hv7131r_init_sensor(struct gspca_dev
*gspca_dev
)
1515 struct sd
*sd
= (struct sd
*) gspca_dev
;
1517 for (i
= 0; i
< ARRAY_SIZE(hv7131r_init
); i
++) {
1518 if (i2c_w1(gspca_dev
, hv7131r_init
[i
].reg
,
1519 hv7131r_init
[i
].val
) < 0) {
1520 err("HV7131R Sensor initialization failed");
1529 static int set_cmatrix(struct gspca_dev
*gspca_dev
)
1531 struct sd
*sd
= (struct sd
*) gspca_dev
;
1532 s32 hue_coord
, hue_index
= 180 + sd
->hue
;
1535 memset(cmatrix
, 0, sizeof cmatrix
);
1536 cmatrix
[2] = (sd
->contrast
* 0x25 / 0x100) + 0x26;
1537 cmatrix
[0] = 0x13 + (cmatrix
[2] - 0x26) * 0x13 / 0x25;
1538 cmatrix
[4] = 0x07 + (cmatrix
[2] - 0x26) * 0x07 / 0x25;
1539 cmatrix
[18] = sd
->brightness
- 0x80;
1541 hue_coord
= (hsv_red_x
[hue_index
] * sd
->saturation
) >> 8;
1542 cmatrix
[6] = hue_coord
;
1543 cmatrix
[7] = (hue_coord
>> 8) & 0x0f;
1545 hue_coord
= (hsv_red_y
[hue_index
] * sd
->saturation
) >> 8;
1546 cmatrix
[8] = hue_coord
;
1547 cmatrix
[9] = (hue_coord
>> 8) & 0x0f;
1549 hue_coord
= (hsv_green_x
[hue_index
] * sd
->saturation
) >> 8;
1550 cmatrix
[10] = hue_coord
;
1551 cmatrix
[11] = (hue_coord
>> 8) & 0x0f;
1553 hue_coord
= (hsv_green_y
[hue_index
] * sd
->saturation
) >> 8;
1554 cmatrix
[12] = hue_coord
;
1555 cmatrix
[13] = (hue_coord
>> 8) & 0x0f;
1557 hue_coord
= (hsv_blue_x
[hue_index
] * sd
->saturation
) >> 8;
1558 cmatrix
[14] = hue_coord
;
1559 cmatrix
[15] = (hue_coord
>> 8) & 0x0f;
1561 hue_coord
= (hsv_blue_y
[hue_index
] * sd
->saturation
) >> 8;
1562 cmatrix
[16] = hue_coord
;
1563 cmatrix
[17] = (hue_coord
>> 8) & 0x0f;
1565 return reg_w(gspca_dev
, 0x10e1, cmatrix
, 21);
1568 static int set_gamma(struct gspca_dev
*gspca_dev
)
1570 struct sd
*sd
= (struct sd
*) gspca_dev
;
1572 u8 gval
= sd
->gamma
* 0xb8 / 0x100;
1576 gamma
[1] = 0x13 + (gval
* (0xcb - 0x13) / 0xb8);
1577 gamma
[2] = 0x25 + (gval
* (0xee - 0x25) / 0xb8);
1578 gamma
[3] = 0x37 + (gval
* (0xfa - 0x37) / 0xb8);
1579 gamma
[4] = 0x45 + (gval
* (0xfc - 0x45) / 0xb8);
1580 gamma
[5] = 0x55 + (gval
* (0xfb - 0x55) / 0xb8);
1581 gamma
[6] = 0x65 + (gval
* (0xfc - 0x65) / 0xb8);
1582 gamma
[7] = 0x74 + (gval
* (0xfd - 0x74) / 0xb8);
1583 gamma
[8] = 0x83 + (gval
* (0xfe - 0x83) / 0xb8);
1584 gamma
[9] = 0x92 + (gval
* (0xfc - 0x92) / 0xb8);
1585 gamma
[10] = 0xa1 + (gval
* (0xfc - 0xa1) / 0xb8);
1586 gamma
[11] = 0xb0 + (gval
* (0xfc - 0xb0) / 0xb8);
1587 gamma
[12] = 0xbf + (gval
* (0xfb - 0xbf) / 0xb8);
1588 gamma
[13] = 0xce + (gval
* (0xfb - 0xce) / 0xb8);
1589 gamma
[14] = 0xdf + (gval
* (0xfd - 0xdf) / 0xb8);
1590 gamma
[15] = 0xea + (gval
* (0xf9 - 0xea) / 0xb8);
1593 return reg_w(gspca_dev
, 0x1190, gamma
, 17);
1596 static int set_redblue(struct gspca_dev
*gspca_dev
)
1598 struct sd
*sd
= (struct sd
*) gspca_dev
;
1599 reg_w1(gspca_dev
, 0x118c, sd
->red
);
1600 reg_w1(gspca_dev
, 0x118f, sd
->blue
);
1604 static int set_hvflip(struct gspca_dev
*gspca_dev
)
1606 u8 value
, tslb
, hflip
, vflip
;
1608 struct sd
*sd
= (struct sd
*) gspca_dev
;
1610 if ((sd
->flags
& FLIP_DETECT
) && dmi_check_system(flip_dmi_table
)) {
1618 switch (sd
->sensor
) {
1628 reg_w1(gspca_dev
, 0x1182, sd
->vstart
);
1629 i2c_w1(gspca_dev
, 0x1e, value
);
1632 i2c_r1(gspca_dev
, 0x1e, &value
);
1641 i2c_w1(gspca_dev
, 0x1e, value
);
1642 i2c_w1(gspca_dev
, 0x3a, tslb
);
1644 case SENSOR_MT9V111
:
1645 case SENSOR_MT9V011
:
1646 i2c_r2(gspca_dev
, 0x20, &value2
);
1652 i2c_w2(gspca_dev
, 0x20, value2
);
1654 case SENSOR_MT9M112
:
1655 case SENSOR_MT9M111
:
1656 case SENSOR_MT9V112
:
1657 i2c_r2(gspca_dev
, 0x20, &value2
);
1663 i2c_w2(gspca_dev
, 0x20, value2
);
1665 case SENSOR_HV7131R
:
1666 i2c_r1(gspca_dev
, 0x01, &value
);
1672 i2c_w1(gspca_dev
, 0x01, value
);
1678 static int set_exposure(struct gspca_dev
*gspca_dev
)
1680 struct sd
*sd
= (struct sd
*) gspca_dev
;
1681 u8 exp
[8] = {0x81, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1682 switch (sd
->sensor
) {
1689 exp
[3] = sd
->exposure
& 0xff;
1690 exp
[4] = sd
->exposure
>> 8;
1692 case SENSOR_MT9M001
:
1693 case SENSOR_MT9V112
:
1694 case SENSOR_MT9V011
:
1697 exp
[3] = sd
->exposure
>> 8;
1698 exp
[4] = sd
->exposure
& 0xff;
1700 case SENSOR_HV7131R
:
1703 exp
[3] = (sd
->exposure
>> 5) & 0xff;
1704 exp
[4] = (sd
->exposure
<< 3) & 0xff;
1710 i2c_w(gspca_dev
, exp
);
1714 static int set_gain(struct gspca_dev
*gspca_dev
)
1716 struct sd
*sd
= (struct sd
*) gspca_dev
;
1717 u8 gain
[8] = {0x81, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1718 switch (sd
->sensor
) {
1724 gain
[0] |= (2 << 4);
1725 gain
[3] = ov_gain
[sd
->gain
];
1727 case SENSOR_MT9V011
:
1728 gain
[0] |= (3 << 4);
1730 gain
[3] = micron1_gain
[sd
->gain
] >> 8;
1731 gain
[4] = micron1_gain
[sd
->gain
] & 0xff;
1733 case SENSOR_MT9V112
:
1734 gain
[0] |= (3 << 4);
1736 gain
[3] = micron1_gain
[sd
->gain
] >> 8;
1737 gain
[4] = micron1_gain
[sd
->gain
] & 0xff;
1739 case SENSOR_MT9M001
:
1740 gain
[0] |= (3 << 4);
1742 gain
[3] = micron2_gain
[sd
->gain
] >> 8;
1743 gain
[4] = micron2_gain
[sd
->gain
] & 0xff;
1745 case SENSOR_HV7131R
:
1746 gain
[0] |= (2 << 4);
1748 gain
[3] = hv7131r_gain
[sd
->gain
];
1753 i2c_w(gspca_dev
, gain
);
1757 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, s32 val
)
1759 struct sd
*sd
= (struct sd
*) gspca_dev
;
1761 sd
->brightness
= val
;
1762 if (gspca_dev
->streaming
)
1763 return set_cmatrix(gspca_dev
);
1767 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, s32
*val
)
1769 struct sd
*sd
= (struct sd
*) gspca_dev
;
1770 *val
= sd
->brightness
;
1775 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, s32 val
)
1777 struct sd
*sd
= (struct sd
*) gspca_dev
;
1780 if (gspca_dev
->streaming
)
1781 return set_cmatrix(gspca_dev
);
1785 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, s32
*val
)
1787 struct sd
*sd
= (struct sd
*) gspca_dev
;
1788 *val
= sd
->contrast
;
1792 static int sd_setsaturation(struct gspca_dev
*gspca_dev
, s32 val
)
1794 struct sd
*sd
= (struct sd
*) gspca_dev
;
1796 sd
->saturation
= val
;
1797 if (gspca_dev
->streaming
)
1798 return set_cmatrix(gspca_dev
);
1802 static int sd_getsaturation(struct gspca_dev
*gspca_dev
, s32
*val
)
1804 struct sd
*sd
= (struct sd
*) gspca_dev
;
1805 *val
= sd
->saturation
;
1809 static int sd_sethue(struct gspca_dev
*gspca_dev
, s32 val
)
1811 struct sd
*sd
= (struct sd
*) gspca_dev
;
1814 if (gspca_dev
->streaming
)
1815 return set_cmatrix(gspca_dev
);
1819 static int sd_gethue(struct gspca_dev
*gspca_dev
, s32
*val
)
1821 struct sd
*sd
= (struct sd
*) gspca_dev
;
1826 static int sd_setgamma(struct gspca_dev
*gspca_dev
, s32 val
)
1828 struct sd
*sd
= (struct sd
*) gspca_dev
;
1831 if (gspca_dev
->streaming
)
1832 return set_gamma(gspca_dev
);
1836 static int sd_getgamma(struct gspca_dev
*gspca_dev
, s32
*val
)
1838 struct sd
*sd
= (struct sd
*) gspca_dev
;
1843 static int sd_setredbalance(struct gspca_dev
*gspca_dev
, s32 val
)
1845 struct sd
*sd
= (struct sd
*) gspca_dev
;
1848 if (gspca_dev
->streaming
)
1849 return set_redblue(gspca_dev
);
1853 static int sd_getredbalance(struct gspca_dev
*gspca_dev
, s32
*val
)
1855 struct sd
*sd
= (struct sd
*) gspca_dev
;
1860 static int sd_setbluebalance(struct gspca_dev
*gspca_dev
, s32 val
)
1862 struct sd
*sd
= (struct sd
*) gspca_dev
;
1865 if (gspca_dev
->streaming
)
1866 return set_redblue(gspca_dev
);
1870 static int sd_getbluebalance(struct gspca_dev
*gspca_dev
, s32
*val
)
1872 struct sd
*sd
= (struct sd
*) gspca_dev
;
1877 static int sd_sethflip(struct gspca_dev
*gspca_dev
, s32 val
)
1879 struct sd
*sd
= (struct sd
*) gspca_dev
;
1882 if (gspca_dev
->streaming
)
1883 return set_hvflip(gspca_dev
);
1887 static int sd_gethflip(struct gspca_dev
*gspca_dev
, s32
*val
)
1889 struct sd
*sd
= (struct sd
*) gspca_dev
;
1894 static int sd_setvflip(struct gspca_dev
*gspca_dev
, s32 val
)
1896 struct sd
*sd
= (struct sd
*) gspca_dev
;
1899 if (gspca_dev
->streaming
)
1900 return set_hvflip(gspca_dev
);
1904 static int sd_getvflip(struct gspca_dev
*gspca_dev
, s32
*val
)
1906 struct sd
*sd
= (struct sd
*) gspca_dev
;
1911 static int sd_setexposure(struct gspca_dev
*gspca_dev
, s32 val
)
1913 struct sd
*sd
= (struct sd
*) gspca_dev
;
1916 if (gspca_dev
->streaming
)
1917 return set_exposure(gspca_dev
);
1921 static int sd_getexposure(struct gspca_dev
*gspca_dev
, s32
*val
)
1923 struct sd
*sd
= (struct sd
*) gspca_dev
;
1924 *val
= sd
->exposure
;
1928 static int sd_setgain(struct gspca_dev
*gspca_dev
, s32 val
)
1930 struct sd
*sd
= (struct sd
*) gspca_dev
;
1933 if (gspca_dev
->streaming
)
1934 return set_gain(gspca_dev
);
1938 static int sd_getgain(struct gspca_dev
*gspca_dev
, s32
*val
)
1940 struct sd
*sd
= (struct sd
*) gspca_dev
;
1945 static int sd_setautoexposure(struct gspca_dev
*gspca_dev
, s32 val
)
1947 struct sd
*sd
= (struct sd
*) gspca_dev
;
1948 sd
->auto_exposure
= val
;
1952 static int sd_getautoexposure(struct gspca_dev
*gspca_dev
, s32
*val
)
1954 struct sd
*sd
= (struct sd
*) gspca_dev
;
1955 *val
= sd
->auto_exposure
;
1959 #ifdef CONFIG_VIDEO_ADV_DEBUG
1960 static int sd_dbg_g_register(struct gspca_dev
*gspca_dev
,
1961 struct v4l2_dbg_register
*reg
)
1963 struct sd
*sd
= (struct sd
*) gspca_dev
;
1964 switch (reg
->match
.type
) {
1965 case V4L2_CHIP_MATCH_HOST
:
1966 if (reg
->match
.addr
!= 0)
1968 if (reg
->reg
< 0x1000 || reg
->reg
> 0x11ff)
1970 if (reg_r(gspca_dev
, reg
->reg
, 1) < 0)
1972 reg
->val
= gspca_dev
->usb_buf
[0];
1974 case V4L2_CHIP_MATCH_I2C_ADDR
:
1975 if (reg
->match
.addr
!= sd
->i2c_addr
)
1977 if (sd
->sensor
>= SENSOR_MT9V011
&&
1978 sd
->sensor
<= SENSOR_MT9M112
) {
1979 if (i2c_r2(gspca_dev
, reg
->reg
, (u16
*)®
->val
) < 0)
1982 if (i2c_r1(gspca_dev
, reg
->reg
, (u8
*)®
->val
) < 0)
1990 static int sd_dbg_s_register(struct gspca_dev
*gspca_dev
,
1991 struct v4l2_dbg_register
*reg
)
1993 struct sd
*sd
= (struct sd
*) gspca_dev
;
1994 switch (reg
->match
.type
) {
1995 case V4L2_CHIP_MATCH_HOST
:
1996 if (reg
->match
.addr
!= 0)
1998 if (reg
->reg
< 0x1000 || reg
->reg
> 0x11ff)
2000 if (reg_w1(gspca_dev
, reg
->reg
, reg
->val
) < 0)
2003 case V4L2_CHIP_MATCH_I2C_ADDR
:
2004 if (reg
->match
.addr
!= sd
->i2c_addr
)
2006 if (sd
->sensor
>= SENSOR_MT9V011
&&
2007 sd
->sensor
<= SENSOR_MT9M112
) {
2008 if (i2c_w2(gspca_dev
, reg
->reg
, reg
->val
) < 0)
2011 if (i2c_w1(gspca_dev
, reg
->reg
, reg
->val
) < 0)
2020 static int sd_chip_ident(struct gspca_dev
*gspca_dev
,
2021 struct v4l2_dbg_chip_ident
*chip
)
2023 struct sd
*sd
= (struct sd
*) gspca_dev
;
2025 switch (chip
->match
.type
) {
2026 case V4L2_CHIP_MATCH_HOST
:
2027 if (chip
->match
.addr
!= 0)
2030 chip
->ident
= V4L2_IDENT_SN9C20X
;
2032 case V4L2_CHIP_MATCH_I2C_ADDR
:
2033 if (chip
->match
.addr
!= sd
->i2c_addr
)
2036 chip
->ident
= i2c_ident
[sd
->sensor
];
2042 static int sd_config(struct gspca_dev
*gspca_dev
,
2043 const struct usb_device_id
*id
)
2045 struct sd
*sd
= (struct sd
*) gspca_dev
;
2048 cam
= &gspca_dev
->cam
;
2050 sd
->sensor
= (id
->driver_info
>> 8) & 0xff;
2051 sd
->i2c_addr
= id
->driver_info
& 0xff;
2052 sd
->flags
= (id
->driver_info
>> 16) & 0xff;
2054 switch (sd
->sensor
) {
2055 case SENSOR_MT9M112
:
2056 case SENSOR_MT9M111
:
2059 cam
->cam_mode
= sxga_mode
;
2060 cam
->nmodes
= ARRAY_SIZE(sxga_mode
);
2062 case SENSOR_MT9M001
:
2063 cam
->cam_mode
= mono_mode
;
2064 cam
->nmodes
= ARRAY_SIZE(mono_mode
);
2067 cam
->cam_mode
= vga_mode
;
2068 cam
->nmodes
= ARRAY_SIZE(vga_mode
);
2074 sd
->exposure_step
= 16;
2076 sd
->brightness
= BRIGHTNESS_DEFAULT
;
2077 sd
->contrast
= CONTRAST_DEFAULT
;
2078 sd
->saturation
= SATURATION_DEFAULT
;
2079 sd
->hue
= HUE_DEFAULT
;
2080 sd
->gamma
= GAMMA_DEFAULT
;
2081 sd
->red
= RED_DEFAULT
;
2082 sd
->blue
= BLUE_DEFAULT
;
2084 sd
->hflip
= HFLIP_DEFAULT
;
2085 sd
->vflip
= VFLIP_DEFAULT
;
2086 sd
->exposure
= EXPOSURE_DEFAULT
;
2087 sd
->gain
= GAIN_DEFAULT
;
2088 sd
->auto_exposure
= AUTO_EXPOSURE_DEFAULT
;
2095 static int sd_init(struct gspca_dev
*gspca_dev
)
2097 struct sd
*sd
= (struct sd
*) gspca_dev
;
2101 {0x80, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
2103 for (i
= 0; i
< ARRAY_SIZE(bridge_init
); i
++) {
2104 value
= bridge_init
[i
][1];
2105 if (reg_w(gspca_dev
, bridge_init
[i
][0], &value
, 1) < 0) {
2106 err("Device initialization failed");
2111 if (sd
->flags
& LED_REVERSE
)
2112 reg_w1(gspca_dev
, 0x1006, 0x00);
2114 reg_w1(gspca_dev
, 0x1006, 0x20);
2116 if (reg_w(gspca_dev
, 0x10c0, i2c_init
, 9) < 0) {
2117 err("Device initialization failed");
2121 switch (sd
->sensor
) {
2123 if (ov9650_init_sensor(gspca_dev
) < 0)
2125 info("OV9650 sensor detected");
2128 if (ov9655_init_sensor(gspca_dev
) < 0)
2130 info("OV9655 sensor detected");
2133 if (soi968_init_sensor(gspca_dev
) < 0)
2135 info("SOI968 sensor detected");
2138 if (ov7660_init_sensor(gspca_dev
) < 0)
2140 info("OV7660 sensor detected");
2143 if (ov7670_init_sensor(gspca_dev
) < 0)
2145 info("OV7670 sensor detected");
2147 case SENSOR_MT9VPRB
:
2148 if (mt9v_init_sensor(gspca_dev
) < 0)
2151 case SENSOR_MT9M111
:
2152 if (mt9m111_init_sensor(gspca_dev
) < 0)
2154 info("MT9M111 sensor detected");
2156 case SENSOR_MT9M112
:
2157 if (mt9m112_init_sensor(gspca_dev
) < 0)
2159 info("MT9M112 sensor detected");
2161 case SENSOR_MT9M001
:
2162 if (mt9m001_init_sensor(gspca_dev
) < 0)
2165 case SENSOR_HV7131R
:
2166 if (hv7131r_init_sensor(gspca_dev
) < 0)
2168 info("HV7131R sensor detected");
2171 info("Unsupported Sensor");
2178 static void configure_sensor_output(struct gspca_dev
*gspca_dev
, int mode
)
2180 struct sd
*sd
= (struct sd
*) gspca_dev
;
2182 switch (sd
->sensor
) {
2184 if (mode
& MODE_SXGA
) {
2185 i2c_w1(gspca_dev
, 0x17, 0x1d);
2186 i2c_w1(gspca_dev
, 0x18, 0xbd);
2187 i2c_w1(gspca_dev
, 0x19, 0x01);
2188 i2c_w1(gspca_dev
, 0x1a, 0x81);
2189 i2c_w1(gspca_dev
, 0x12, 0x00);
2193 i2c_w1(gspca_dev
, 0x17, 0x13);
2194 i2c_w1(gspca_dev
, 0x18, 0x63);
2195 i2c_w1(gspca_dev
, 0x19, 0x01);
2196 i2c_w1(gspca_dev
, 0x1a, 0x79);
2197 i2c_w1(gspca_dev
, 0x12, 0x40);
2203 if (mode
& MODE_SXGA
) {
2204 i2c_w1(gspca_dev
, 0x17, 0x1b);
2205 i2c_w1(gspca_dev
, 0x18, 0xbc);
2206 i2c_w1(gspca_dev
, 0x19, 0x01);
2207 i2c_w1(gspca_dev
, 0x1a, 0x82);
2208 i2c_r1(gspca_dev
, 0x12, &value
);
2209 i2c_w1(gspca_dev
, 0x12, value
& 0x07);
2211 i2c_w1(gspca_dev
, 0x17, 0x24);
2212 i2c_w1(gspca_dev
, 0x18, 0xc5);
2213 i2c_w1(gspca_dev
, 0x19, 0x00);
2214 i2c_w1(gspca_dev
, 0x1a, 0x3c);
2215 i2c_r1(gspca_dev
, 0x12, &value
);
2216 i2c_w1(gspca_dev
, 0x12, (value
& 0x7) | 0x40);
2219 case SENSOR_MT9M112
:
2220 case SENSOR_MT9M111
:
2221 if (mode
& MODE_SXGA
) {
2222 i2c_w2(gspca_dev
, 0xf0, 0x0002);
2223 i2c_w2(gspca_dev
, 0xc8, 0x970b);
2224 i2c_w2(gspca_dev
, 0xf0, 0x0000);
2226 i2c_w2(gspca_dev
, 0xf0, 0x0002);
2227 i2c_w2(gspca_dev
, 0xc8, 0x8000);
2228 i2c_w2(gspca_dev
, 0xf0, 0x0000);
2234 #define HW_WIN(mode, hstart, vstart) \
2235 ((const u8 []){hstart, 0, vstart, 0, \
2236 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
2237 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
2239 #define CLR_WIN(width, height) \
2241 {0, width >> 2, 0, height >> 1,\
2242 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
2244 static int sd_start(struct gspca_dev
*gspca_dev
)
2246 struct sd
*sd
= (struct sd
*) gspca_dev
;
2247 int mode
= gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
;
2248 int width
= gspca_dev
->width
;
2249 int height
= gspca_dev
->height
;
2252 jpeg_define(sd
->jpeg_hdr
, height
, width
,
2254 jpeg_set_qual(sd
->jpeg_hdr
, sd
->quality
);
2256 if (mode
& MODE_RAW
)
2258 else if (mode
& MODE_JPEG
)
2261 fmt
= 0x2f; /* YUV 420 */
2263 switch (mode
& SCALE_MASK
) {
2264 case SCALE_1280x1024
:
2266 info("Set 1280x1024");
2270 info("Set 640x480");
2274 info("Set 320x240");
2278 info("Set 160x120");
2282 configure_sensor_output(gspca_dev
, mode
);
2283 reg_w(gspca_dev
, 0x1100, &sd
->jpeg_hdr
[JPEG_QT0_OFFSET
], 64);
2284 reg_w(gspca_dev
, 0x1140, &sd
->jpeg_hdr
[JPEG_QT1_OFFSET
], 64);
2285 reg_w(gspca_dev
, 0x10fb, CLR_WIN(width
, height
), 5);
2286 reg_w(gspca_dev
, 0x1180, HW_WIN(mode
, sd
->hstart
, sd
->vstart
), 6);
2287 reg_w1(gspca_dev
, 0x1189, scale
);
2288 reg_w1(gspca_dev
, 0x10e0, fmt
);
2290 set_cmatrix(gspca_dev
);
2291 set_gamma(gspca_dev
);
2292 set_redblue(gspca_dev
);
2293 set_gain(gspca_dev
);
2294 set_exposure(gspca_dev
);
2295 set_hvflip(gspca_dev
);
2297 reg_w1(gspca_dev
, 0x1007, 0x20);
2299 reg_r(gspca_dev
, 0x1061, 1);
2300 reg_w1(gspca_dev
, 0x1061, gspca_dev
->usb_buf
[0] | 0x02);
2304 static void sd_stopN(struct gspca_dev
*gspca_dev
)
2306 reg_w1(gspca_dev
, 0x1007, 0x00);
2308 reg_r(gspca_dev
, 0x1061, 1);
2309 reg_w1(gspca_dev
, 0x1061, gspca_dev
->usb_buf
[0] & ~0x02);
2312 static void do_autoexposure(struct gspca_dev
*gspca_dev
, u16 avg_lum
)
2314 struct sd
*sd
= (struct sd
*) gspca_dev
;
2318 * some hardcoded values are present
2319 * like those for maximal/minimal exposure
2320 * and exposure steps
2322 if (avg_lum
< MIN_AVG_LUM
) {
2323 if (sd
->exposure
> 0x1770)
2326 new_exp
= sd
->exposure
+ sd
->exposure_step
;
2327 if (new_exp
> 0x1770)
2331 sd
->exposure
= new_exp
;
2332 set_exposure(gspca_dev
);
2334 sd
->older_step
= sd
->old_step
;
2337 if (sd
->old_step
^ sd
->older_step
)
2338 sd
->exposure_step
/= 2;
2340 sd
->exposure_step
+= 2;
2342 if (avg_lum
> MAX_AVG_LUM
) {
2343 if (sd
->exposure
< 0x10)
2345 new_exp
= sd
->exposure
- sd
->exposure_step
;
2346 if (new_exp
> 0x1700)
2350 sd
->exposure
= new_exp
;
2351 set_exposure(gspca_dev
);
2352 sd
->older_step
= sd
->old_step
;
2355 if (sd
->old_step
^ sd
->older_step
)
2356 sd
->exposure_step
/= 2;
2358 sd
->exposure_step
+= 2;
2362 static void do_autogain(struct gspca_dev
*gspca_dev
, u16 avg_lum
)
2364 struct sd
*sd
= (struct sd
*) gspca_dev
;
2366 if (avg_lum
< MIN_AVG_LUM
) {
2367 if (sd
->gain
+ 1 <= 28) {
2369 set_gain(gspca_dev
);
2372 if (avg_lum
> MAX_AVG_LUM
) {
2375 set_gain(gspca_dev
);
2380 static void sd_dqcallback(struct gspca_dev
*gspca_dev
)
2382 struct sd
*sd
= (struct sd
*) gspca_dev
;
2385 if (!sd
->auto_exposure
)
2388 avg_lum
= atomic_read(&sd
->avg_lum
);
2389 if (sd
->sensor
== SENSOR_SOI968
)
2390 do_autogain(gspca_dev
, avg_lum
);
2392 do_autoexposure(gspca_dev
, avg_lum
);
2395 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2396 static int sd_int_pkt_scan(struct gspca_dev
*gspca_dev
,
2397 u8
*data
, /* interrupt packet */
2398 int len
) /* interrupt packet length */
2400 struct sd
*sd
= (struct sd
*) gspca_dev
;
2402 if (!(sd
->flags
& HAS_NO_BUTTON
) && len
== 1) {
2403 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 1);
2404 input_sync(gspca_dev
->input_dev
);
2405 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 0);
2406 input_sync(gspca_dev
->input_dev
);
2413 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
2414 u8
*data
, /* isoc packet */
2415 int len
) /* iso packet length */
2417 struct sd
*sd
= (struct sd
*) gspca_dev
;
2419 static u8 frame_header
[] =
2420 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2421 if (len
== 64 && memcmp(data
, frame_header
, 6) == 0) {
2422 avg_lum
= ((data
[35] >> 2) & 3) |
2425 avg_lum
+= ((data
[35] >> 4) & 3) |
2428 avg_lum
+= ((data
[35] >> 6) & 3) |
2431 avg_lum
+= (data
[36] & 3) |
2434 avg_lum
+= ((data
[36] >> 2) & 3) |
2437 avg_lum
+= ((data
[36] >> 4) & 3) |
2440 avg_lum
+= ((data
[36] >> 6) & 3) |
2443 avg_lum
+= ((data
[44] >> 4) & 3) |
2447 atomic_set(&sd
->avg_lum
, avg_lum
);
2448 gspca_frame_add(gspca_dev
, LAST_PACKET
, NULL
, 0);
2451 if (gspca_dev
->last_packet_type
== LAST_PACKET
) {
2452 if (gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
2454 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
2455 sd
->jpeg_hdr
, JPEG_HDR_SZ
);
2456 gspca_frame_add(gspca_dev
, INTER_PACKET
,
2459 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
2463 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, len
);
2467 /* sub-driver description */
2468 static const struct sd_desc sd_desc
= {
2469 .name
= MODULE_NAME
,
2471 .nctrls
= ARRAY_SIZE(sd_ctrls
),
2472 .config
= sd_config
,
2476 .pkt_scan
= sd_pkt_scan
,
2477 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2478 .int_pkt_scan
= sd_int_pkt_scan
,
2480 .dq_callback
= sd_dqcallback
,
2481 #ifdef CONFIG_VIDEO_ADV_DEBUG
2482 .set_register
= sd_dbg_s_register
,
2483 .get_register
= sd_dbg_g_register
,
2485 .get_chip_ident
= sd_chip_ident
,
2488 #define SN9C20X(sensor, i2c_addr, flags) \
2489 .driver_info = ((flags & 0xff) << 16) \
2490 | (SENSOR_ ## sensor << 8) \
2493 static const struct usb_device_id device_table
[] = {
2494 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001
, 0x5d, 0)},
2495 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111
, 0x5d, 0)},
2496 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655
, 0x30, 0)},
2497 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112
, 0x5d, 0)},
2498 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968
, 0x30, LED_REVERSE
)},
2499 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650
, 0x30,
2500 (FLIP_DETECT
| HAS_NO_BUTTON
))},
2501 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650
, 0x30, 0)},
2502 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650
, 0x30, 0)},
2503 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670
, 0x21, 0)},
2504 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB
, 0x00, 0)},
2505 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660
, 0x21, FLIP_DETECT
)},
2506 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R
, 0x11, 0)},
2507 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650
, 0x30, 0)},
2508 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001
, 0x5d, 0)},
2509 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111
, 0x5d, 0)},
2510 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655
, 0x30, 0)},
2511 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112
, 0x5d, 0)},
2512 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968
, 0x30, 0)},
2513 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650
, 0x30, 0)},
2514 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670
, 0x21, 0)},
2515 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB
, 0x00, 0)},
2516 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655
, 0x30, 0)},
2517 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660
, 0x21, LED_REVERSE
)},
2518 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R
, 0x11, 0)},
2519 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650
, 0x30, 0)},
2520 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660
, 0x21, 0)},
2521 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R
, 0x11, 0)},
2522 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112
, 0x5d, 0)},
2523 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112
, 0x5d, 0)},
2524 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R
, 0x11, 0)},
2525 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R
, 0x11, 0)},
2526 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R
, 0x11, 0)},
2527 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R
, 0x11, 0)},
2528 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111
, 0x5d, 0)},
2529 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111
, 0x5d, 0)},
2530 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111
, 0x5d, 0)},
2533 MODULE_DEVICE_TABLE(usb
, device_table
);
2535 /* -- device connect -- */
2536 static int sd_probe(struct usb_interface
*intf
,
2537 const struct usb_device_id
*id
)
2539 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
2543 static struct usb_driver sd_driver
= {
2544 .name
= MODULE_NAME
,
2545 .id_table
= device_table
,
2547 .disconnect
= gspca_disconnect
,
2549 .suspend
= gspca_suspend
,
2550 .resume
= gspca_resume
,
2551 .reset_resume
= gspca_resume
,
2555 /* -- module insert / remove -- */
2556 static int __init
sd_mod_init(void)
2558 return usb_register(&sd_driver
);
2560 static void __exit
sd_mod_exit(void)
2562 usb_deregister(&sd_driver
);
2565 module_init(sd_mod_init
);
2566 module_exit(sd_mod_exit
);