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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23 #include <linux/input.h>
28 #include <media/v4l2-chip-ident.h>
29 #include <linux/dmi.h>
31 MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, "
32 "microdia project <microdia@googlegroups.com>");
33 MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
34 MODULE_LICENSE("GPL");
36 #define MODULE_NAME "sn9c20x"
39 * Pixel format private data
41 #define SCALE_MASK 0x0f
42 #define SCALE_160x120 0
43 #define SCALE_320x240 1
44 #define SCALE_640x480 2
45 #define SCALE_1280x1024 3
47 #define MODE_JPEG 0x20
48 #define MODE_SXGA 0x80
50 #define SENSOR_OV9650 0
51 #define SENSOR_OV9655 1
52 #define SENSOR_SOI968 2
53 #define SENSOR_OV7660 3
54 #define SENSOR_OV7670 4
55 #define SENSOR_MT9V011 5
56 #define SENSOR_MT9V111 6
57 #define SENSOR_MT9V112 7
58 #define SENSOR_MT9M001 8
59 #define SENSOR_MT9M111 9
60 #define SENSOR_MT9M112 10
61 #define SENSOR_HV7131R 11
62 #define SENSOR_MT9VPRB 20
65 #define HAS_NO_BUTTON 0x1
66 #define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
67 #define FLIP_DETECT 0x4
69 /* specific webcam descriptor */
71 struct gspca_dev gspca_dev
;
73 #define MIN_AVG_LUM 80
74 #define MAX_AVG_LUM 130
99 u8 jpeg_hdr
[JPEG_HDR_SZ
];
115 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, s32 val
);
116 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, s32
*val
);
117 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, s32 val
);
118 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, s32
*val
);
119 static int sd_setsaturation(struct gspca_dev
*gspca_dev
, s32 val
);
120 static int sd_getsaturation(struct gspca_dev
*gspca_dev
, s32
*val
);
121 static int sd_sethue(struct gspca_dev
*gspca_dev
, s32 val
);
122 static int sd_gethue(struct gspca_dev
*gspca_dev
, s32
*val
);
123 static int sd_setgamma(struct gspca_dev
*gspca_dev
, s32 val
);
124 static int sd_getgamma(struct gspca_dev
*gspca_dev
, s32
*val
);
125 static int sd_setredbalance(struct gspca_dev
*gspca_dev
, s32 val
);
126 static int sd_getredbalance(struct gspca_dev
*gspca_dev
, s32
*val
);
127 static int sd_setbluebalance(struct gspca_dev
*gspca_dev
, s32 val
);
128 static int sd_getbluebalance(struct gspca_dev
*gspca_dev
, s32
*val
);
129 static int sd_setvflip(struct gspca_dev
*gspca_dev
, s32 val
);
130 static int sd_getvflip(struct gspca_dev
*gspca_dev
, s32
*val
);
131 static int sd_sethflip(struct gspca_dev
*gspca_dev
, s32 val
);
132 static int sd_gethflip(struct gspca_dev
*gspca_dev
, s32
*val
);
133 static int sd_setgain(struct gspca_dev
*gspca_dev
, s32 val
);
134 static int sd_getgain(struct gspca_dev
*gspca_dev
, s32
*val
);
135 static int sd_setexposure(struct gspca_dev
*gspca_dev
, s32 val
);
136 static int sd_getexposure(struct gspca_dev
*gspca_dev
, s32
*val
);
137 static int sd_setautoexposure(struct gspca_dev
*gspca_dev
, s32 val
);
138 static int sd_getautoexposure(struct gspca_dev
*gspca_dev
, s32
*val
);
140 static const struct dmi_system_id flip_dmi_table
[] = {
142 .ident
= "MSI MS-1034",
144 DMI_MATCH(DMI_SYS_VENDOR
, "MICRO-STAR INT'L CO.,LTD."),
145 DMI_MATCH(DMI_PRODUCT_NAME
, "MS-1034"),
146 DMI_MATCH(DMI_PRODUCT_VERSION
, "0341")
150 .ident
= "MSI MS-1632",
152 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
153 DMI_MATCH(DMI_BOARD_NAME
, "MS-1632")
157 .ident
= "MSI MS-1633X",
159 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
160 DMI_MATCH(DMI_BOARD_NAME
, "MS-1633X")
164 .ident
= "MSI MS-1635X",
166 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
167 DMI_MATCH(DMI_BOARD_NAME
, "MS-1635X")
171 .ident
= "ASUSTeK W7J",
173 DMI_MATCH(DMI_BOARD_VENDOR
, "ASUSTeK Computer Inc."),
174 DMI_MATCH(DMI_BOARD_NAME
, "W7J ")
180 static const struct ctrl sd_ctrls
[] = {
182 #define BRIGHTNESS_IDX 0
184 .id
= V4L2_CID_BRIGHTNESS
,
185 .type
= V4L2_CTRL_TYPE_INTEGER
,
186 .name
= "Brightness",
190 #define BRIGHTNESS_DEFAULT 0x7f
191 .default_value
= BRIGHTNESS_DEFAULT
,
193 .set
= sd_setbrightness
,
194 .get
= sd_getbrightness
,
197 #define CONTRAST_IDX 1
199 .id
= V4L2_CID_CONTRAST
,
200 .type
= V4L2_CTRL_TYPE_INTEGER
,
205 #define CONTRAST_DEFAULT 0x7f
206 .default_value
= CONTRAST_DEFAULT
,
208 .set
= sd_setcontrast
,
209 .get
= sd_getcontrast
,
212 #define SATURATION_IDX 2
214 .id
= V4L2_CID_SATURATION
,
215 .type
= V4L2_CTRL_TYPE_INTEGER
,
216 .name
= "Saturation",
220 #define SATURATION_DEFAULT 0x7f
221 .default_value
= SATURATION_DEFAULT
,
223 .set
= sd_setsaturation
,
224 .get
= sd_getsaturation
,
230 .type
= V4L2_CTRL_TYPE_INTEGER
,
235 #define HUE_DEFAULT 0
236 .default_value
= HUE_DEFAULT
,
244 .id
= V4L2_CID_GAMMA
,
245 .type
= V4L2_CTRL_TYPE_INTEGER
,
250 #define GAMMA_DEFAULT 0x10
251 .default_value
= GAMMA_DEFAULT
,
259 .id
= V4L2_CID_BLUE_BALANCE
,
260 .type
= V4L2_CTRL_TYPE_INTEGER
,
261 .name
= "Blue Balance",
265 #define BLUE_DEFAULT 0x28
266 .default_value
= BLUE_DEFAULT
,
268 .set
= sd_setbluebalance
,
269 .get
= sd_getbluebalance
,
274 .id
= V4L2_CID_RED_BALANCE
,
275 .type
= V4L2_CTRL_TYPE_INTEGER
,
276 .name
= "Red Balance",
280 #define RED_DEFAULT 0x28
281 .default_value
= RED_DEFAULT
,
283 .set
= sd_setredbalance
,
284 .get
= sd_getredbalance
,
289 .id
= V4L2_CID_HFLIP
,
290 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
291 .name
= "Horizontal Flip",
295 #define HFLIP_DEFAULT 0
296 .default_value
= HFLIP_DEFAULT
,
304 .id
= V4L2_CID_VFLIP
,
305 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
306 .name
= "Vertical Flip",
310 #define VFLIP_DEFAULT 0
311 .default_value
= VFLIP_DEFAULT
,
317 #define EXPOSURE_IDX 9
319 .id
= V4L2_CID_EXPOSURE
,
320 .type
= V4L2_CTRL_TYPE_INTEGER
,
325 #define EXPOSURE_DEFAULT 0x33
326 .default_value
= EXPOSURE_DEFAULT
,
328 .set
= sd_setexposure
,
329 .get
= sd_getexposure
,
335 .type
= V4L2_CTRL_TYPE_INTEGER
,
340 #define GAIN_DEFAULT 0x00
341 .default_value
= GAIN_DEFAULT
,
347 #define AUTOGAIN_IDX 11
349 .id
= V4L2_CID_AUTOGAIN
,
350 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
351 .name
= "Auto Exposure",
355 #define AUTO_EXPOSURE_DEFAULT 1
356 .default_value
= AUTO_EXPOSURE_DEFAULT
,
358 .set
= sd_setautoexposure
,
359 .get
= sd_getautoexposure
,
363 static const struct v4l2_pix_format vga_mode
[] = {
364 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
366 .sizeimage
= 160 * 120 * 4 / 8 + 590,
367 .colorspace
= V4L2_COLORSPACE_JPEG
,
368 .priv
= SCALE_160x120
| MODE_JPEG
},
369 {160, 120, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
371 .sizeimage
= 160 * 120,
372 .colorspace
= V4L2_COLORSPACE_SRGB
,
373 .priv
= SCALE_160x120
| MODE_RAW
},
374 {160, 120, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
376 .sizeimage
= 240 * 120,
377 .colorspace
= V4L2_COLORSPACE_SRGB
,
378 .priv
= SCALE_160x120
},
379 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
381 .sizeimage
= 320 * 240 * 4 / 8 + 590,
382 .colorspace
= V4L2_COLORSPACE_JPEG
,
383 .priv
= SCALE_320x240
| MODE_JPEG
},
384 {320, 240, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
386 .sizeimage
= 320 * 240 ,
387 .colorspace
= V4L2_COLORSPACE_SRGB
,
388 .priv
= SCALE_320x240
| MODE_RAW
},
389 {320, 240, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
391 .sizeimage
= 480 * 240 ,
392 .colorspace
= V4L2_COLORSPACE_SRGB
,
393 .priv
= SCALE_320x240
},
394 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
396 .sizeimage
= 640 * 480 * 4 / 8 + 590,
397 .colorspace
= V4L2_COLORSPACE_JPEG
,
398 .priv
= SCALE_640x480
| MODE_JPEG
},
399 {640, 480, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
401 .sizeimage
= 640 * 480,
402 .colorspace
= V4L2_COLORSPACE_SRGB
,
403 .priv
= SCALE_640x480
| MODE_RAW
},
404 {640, 480, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
406 .sizeimage
= 960 * 480,
407 .colorspace
= V4L2_COLORSPACE_SRGB
,
408 .priv
= SCALE_640x480
},
411 static const struct v4l2_pix_format sxga_mode
[] = {
412 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
414 .sizeimage
= 160 * 120 * 4 / 8 + 590,
415 .colorspace
= V4L2_COLORSPACE_JPEG
,
416 .priv
= SCALE_160x120
| MODE_JPEG
},
417 {160, 120, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
419 .sizeimage
= 160 * 120,
420 .colorspace
= V4L2_COLORSPACE_SRGB
,
421 .priv
= SCALE_160x120
| MODE_RAW
},
422 {160, 120, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
424 .sizeimage
= 240 * 120,
425 .colorspace
= V4L2_COLORSPACE_SRGB
,
426 .priv
= SCALE_160x120
},
427 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
429 .sizeimage
= 320 * 240 * 4 / 8 + 590,
430 .colorspace
= V4L2_COLORSPACE_JPEG
,
431 .priv
= SCALE_320x240
| MODE_JPEG
},
432 {320, 240, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
434 .sizeimage
= 320 * 240 ,
435 .colorspace
= V4L2_COLORSPACE_SRGB
,
436 .priv
= SCALE_320x240
| MODE_RAW
},
437 {320, 240, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
439 .sizeimage
= 480 * 240 ,
440 .colorspace
= V4L2_COLORSPACE_SRGB
,
441 .priv
= SCALE_320x240
},
442 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
444 .sizeimage
= 640 * 480 * 4 / 8 + 590,
445 .colorspace
= V4L2_COLORSPACE_JPEG
,
446 .priv
= SCALE_640x480
| MODE_JPEG
},
447 {640, 480, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
449 .sizeimage
= 640 * 480,
450 .colorspace
= V4L2_COLORSPACE_SRGB
,
451 .priv
= SCALE_640x480
| MODE_RAW
},
452 {640, 480, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
454 .sizeimage
= 960 * 480,
455 .colorspace
= V4L2_COLORSPACE_SRGB
,
456 .priv
= SCALE_640x480
},
457 {1280, 1024, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
458 .bytesperline
= 1280,
459 .sizeimage
= 1280 * 1024,
460 .colorspace
= V4L2_COLORSPACE_SRGB
,
461 .priv
= SCALE_1280x1024
| MODE_RAW
| MODE_SXGA
},
464 static const struct v4l2_pix_format mono_mode
[] = {
465 {160, 120, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
467 .sizeimage
= 160 * 120,
468 .colorspace
= V4L2_COLORSPACE_SRGB
,
469 .priv
= SCALE_160x120
| MODE_RAW
},
470 {320, 240, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
472 .sizeimage
= 320 * 240 ,
473 .colorspace
= V4L2_COLORSPACE_SRGB
,
474 .priv
= SCALE_320x240
| MODE_RAW
},
475 {640, 480, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
477 .sizeimage
= 640 * 480,
478 .colorspace
= V4L2_COLORSPACE_SRGB
,
479 .priv
= SCALE_640x480
| MODE_RAW
},
480 {1280, 1024, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
481 .bytesperline
= 1280,
482 .sizeimage
= 1280 * 1024,
483 .colorspace
= V4L2_COLORSPACE_SRGB
,
484 .priv
= SCALE_1280x1024
| MODE_RAW
| MODE_SXGA
},
487 static const s16 hsv_red_x
[] = {
488 41, 44, 46, 48, 50, 52, 54, 56,
489 58, 60, 62, 64, 66, 68, 70, 72,
490 74, 76, 78, 80, 81, 83, 85, 87,
491 88, 90, 92, 93, 95, 97, 98, 100,
492 101, 102, 104, 105, 107, 108, 109, 110,
493 112, 113, 114, 115, 116, 117, 118, 119,
494 120, 121, 122, 123, 123, 124, 125, 125,
495 126, 127, 127, 128, 128, 129, 129, 129,
496 130, 130, 130, 130, 131, 131, 131, 131,
497 131, 131, 131, 131, 130, 130, 130, 130,
498 129, 129, 129, 128, 128, 127, 127, 126,
499 125, 125, 124, 123, 122, 122, 121, 120,
500 119, 118, 117, 116, 115, 114, 112, 111,
501 110, 109, 107, 106, 105, 103, 102, 101,
502 99, 98, 96, 94, 93, 91, 90, 88,
503 86, 84, 83, 81, 79, 77, 75, 74,
504 72, 70, 68, 66, 64, 62, 60, 58,
505 56, 54, 52, 49, 47, 45, 43, 41,
506 39, 36, 34, 32, 30, 28, 25, 23,
507 21, 19, 16, 14, 12, 9, 7, 5,
508 3, 0, -1, -3, -6, -8, -10, -12,
509 -15, -17, -19, -22, -24, -26, -28, -30,
510 -33, -35, -37, -39, -41, -44, -46, -48,
511 -50, -52, -54, -56, -58, -60, -62, -64,
512 -66, -68, -70, -72, -74, -76, -78, -80,
513 -81, -83, -85, -87, -88, -90, -92, -93,
514 -95, -97, -98, -100, -101, -102, -104, -105,
515 -107, -108, -109, -110, -112, -113, -114, -115,
516 -116, -117, -118, -119, -120, -121, -122, -123,
517 -123, -124, -125, -125, -126, -127, -127, -128,
518 -128, -128, -128, -128, -128, -128, -128, -128,
519 -128, -128, -128, -128, -128, -128, -128, -128,
520 -128, -128, -128, -128, -128, -128, -128, -128,
521 -128, -127, -127, -126, -125, -125, -124, -123,
522 -122, -122, -121, -120, -119, -118, -117, -116,
523 -115, -114, -112, -111, -110, -109, -107, -106,
524 -105, -103, -102, -101, -99, -98, -96, -94,
525 -93, -91, -90, -88, -86, -84, -83, -81,
526 -79, -77, -75, -74, -72, -70, -68, -66,
527 -64, -62, -60, -58, -56, -54, -52, -49,
528 -47, -45, -43, -41, -39, -36, -34, -32,
529 -30, -28, -25, -23, -21, -19, -16, -14,
530 -12, -9, -7, -5, -3, 0, 1, 3,
531 6, 8, 10, 12, 15, 17, 19, 22,
532 24, 26, 28, 30, 33, 35, 37, 39, 41
535 static const s16 hsv_red_y
[] = {
536 82, 80, 78, 76, 74, 73, 71, 69,
537 67, 65, 63, 61, 58, 56, 54, 52,
538 50, 48, 46, 44, 41, 39, 37, 35,
539 32, 30, 28, 26, 23, 21, 19, 16,
540 14, 12, 10, 7, 5, 3, 0, -1,
541 -3, -6, -8, -10, -13, -15, -17, -19,
542 -22, -24, -26, -29, -31, -33, -35, -38,
543 -40, -42, -44, -46, -48, -51, -53, -55,
544 -57, -59, -61, -63, -65, -67, -69, -71,
545 -73, -75, -77, -79, -81, -82, -84, -86,
546 -88, -89, -91, -93, -94, -96, -98, -99,
547 -101, -102, -104, -105, -106, -108, -109, -110,
548 -112, -113, -114, -115, -116, -117, -119, -120,
549 -120, -121, -122, -123, -124, -125, -126, -126,
550 -127, -128, -128, -128, -128, -128, -128, -128,
551 -128, -128, -128, -128, -128, -128, -128, -128,
552 -128, -128, -128, -128, -128, -128, -128, -128,
553 -128, -128, -128, -128, -128, -128, -128, -128,
554 -127, -127, -126, -125, -125, -124, -123, -122,
555 -121, -120, -119, -118, -117, -116, -115, -114,
556 -113, -111, -110, -109, -107, -106, -105, -103,
557 -102, -100, -99, -97, -96, -94, -92, -91,
558 -89, -87, -85, -84, -82, -80, -78, -76,
559 -74, -73, -71, -69, -67, -65, -63, -61,
560 -58, -56, -54, -52, -50, -48, -46, -44,
561 -41, -39, -37, -35, -32, -30, -28, -26,
562 -23, -21, -19, -16, -14, -12, -10, -7,
563 -5, -3, 0, 1, 3, 6, 8, 10,
564 13, 15, 17, 19, 22, 24, 26, 29,
565 31, 33, 35, 38, 40, 42, 44, 46,
566 48, 51, 53, 55, 57, 59, 61, 63,
567 65, 67, 69, 71, 73, 75, 77, 79,
568 81, 82, 84, 86, 88, 89, 91, 93,
569 94, 96, 98, 99, 101, 102, 104, 105,
570 106, 108, 109, 110, 112, 113, 114, 115,
571 116, 117, 119, 120, 120, 121, 122, 123,
572 124, 125, 126, 126, 127, 128, 128, 129,
573 129, 130, 130, 131, 131, 131, 131, 132,
574 132, 132, 132, 132, 132, 132, 132, 132,
575 132, 132, 132, 131, 131, 131, 130, 130,
576 130, 129, 129, 128, 127, 127, 126, 125,
577 125, 124, 123, 122, 121, 120, 119, 118,
578 117, 116, 115, 114, 113, 111, 110, 109,
579 107, 106, 105, 103, 102, 100, 99, 97,
580 96, 94, 92, 91, 89, 87, 85, 84, 82
583 static const s16 hsv_green_x
[] = {
584 -124, -124, -125, -125, -125, -125, -125, -125,
585 -125, -126, -126, -125, -125, -125, -125, -125,
586 -125, -124, -124, -124, -123, -123, -122, -122,
587 -121, -121, -120, -120, -119, -118, -117, -117,
588 -116, -115, -114, -113, -112, -111, -110, -109,
589 -108, -107, -105, -104, -103, -102, -100, -99,
590 -98, -96, -95, -93, -92, -91, -89, -87,
591 -86, -84, -83, -81, -79, -77, -76, -74,
592 -72, -70, -69, -67, -65, -63, -61, -59,
593 -57, -55, -53, -51, -49, -47, -45, -43,
594 -41, -39, -37, -35, -33, -30, -28, -26,
595 -24, -22, -20, -18, -15, -13, -11, -9,
596 -7, -4, -2, 0, 1, 3, 6, 8,
597 10, 12, 14, 17, 19, 21, 23, 25,
598 27, 29, 32, 34, 36, 38, 40, 42,
599 44, 46, 48, 50, 52, 54, 56, 58,
600 60, 62, 64, 66, 68, 70, 71, 73,
601 75, 77, 78, 80, 82, 83, 85, 87,
602 88, 90, 91, 93, 94, 96, 97, 98,
603 100, 101, 102, 104, 105, 106, 107, 108,
604 109, 111, 112, 113, 113, 114, 115, 116,
605 117, 118, 118, 119, 120, 120, 121, 122,
606 122, 123, 123, 124, 124, 124, 125, 125,
607 125, 125, 125, 125, 125, 126, 126, 125,
608 125, 125, 125, 125, 125, 124, 124, 124,
609 123, 123, 122, 122, 121, 121, 120, 120,
610 119, 118, 117, 117, 116, 115, 114, 113,
611 112, 111, 110, 109, 108, 107, 105, 104,
612 103, 102, 100, 99, 98, 96, 95, 93,
613 92, 91, 89, 87, 86, 84, 83, 81,
614 79, 77, 76, 74, 72, 70, 69, 67,
615 65, 63, 61, 59, 57, 55, 53, 51,
616 49, 47, 45, 43, 41, 39, 37, 35,
617 33, 30, 28, 26, 24, 22, 20, 18,
618 15, 13, 11, 9, 7, 4, 2, 0,
619 -1, -3, -6, -8, -10, -12, -14, -17,
620 -19, -21, -23, -25, -27, -29, -32, -34,
621 -36, -38, -40, -42, -44, -46, -48, -50,
622 -52, -54, -56, -58, -60, -62, -64, -66,
623 -68, -70, -71, -73, -75, -77, -78, -80,
624 -82, -83, -85, -87, -88, -90, -91, -93,
625 -94, -96, -97, -98, -100, -101, -102, -104,
626 -105, -106, -107, -108, -109, -111, -112, -113,
627 -113, -114, -115, -116, -117, -118, -118, -119,
628 -120, -120, -121, -122, -122, -123, -123, -124, -124
631 static const s16 hsv_green_y
[] = {
632 -100, -99, -98, -97, -95, -94, -93, -91,
633 -90, -89, -87, -86, -84, -83, -81, -80,
634 -78, -76, -75, -73, -71, -70, -68, -66,
635 -64, -63, -61, -59, -57, -55, -53, -51,
636 -49, -48, -46, -44, -42, -40, -38, -36,
637 -34, -32, -30, -27, -25, -23, -21, -19,
638 -17, -15, -13, -11, -9, -7, -4, -2,
639 0, 1, 3, 5, 7, 9, 11, 14,
640 16, 18, 20, 22, 24, 26, 28, 30,
641 32, 34, 36, 38, 40, 42, 44, 46,
642 48, 50, 52, 54, 56, 58, 59, 61,
643 63, 65, 67, 68, 70, 72, 74, 75,
644 77, 78, 80, 82, 83, 85, 86, 88,
645 89, 90, 92, 93, 95, 96, 97, 98,
646 100, 101, 102, 103, 104, 105, 106, 107,
647 108, 109, 110, 111, 112, 112, 113, 114,
648 115, 115, 116, 116, 117, 117, 118, 118,
649 119, 119, 119, 120, 120, 120, 120, 120,
650 121, 121, 121, 121, 121, 121, 120, 120,
651 120, 120, 120, 119, 119, 119, 118, 118,
652 117, 117, 116, 116, 115, 114, 114, 113,
653 112, 111, 111, 110, 109, 108, 107, 106,
654 105, 104, 103, 102, 100, 99, 98, 97,
655 95, 94, 93, 91, 90, 89, 87, 86,
656 84, 83, 81, 80, 78, 76, 75, 73,
657 71, 70, 68, 66, 64, 63, 61, 59,
658 57, 55, 53, 51, 49, 48, 46, 44,
659 42, 40, 38, 36, 34, 32, 30, 27,
660 25, 23, 21, 19, 17, 15, 13, 11,
661 9, 7, 4, 2, 0, -1, -3, -5,
662 -7, -9, -11, -14, -16, -18, -20, -22,
663 -24, -26, -28, -30, -32, -34, -36, -38,
664 -40, -42, -44, -46, -48, -50, -52, -54,
665 -56, -58, -59, -61, -63, -65, -67, -68,
666 -70, -72, -74, -75, -77, -78, -80, -82,
667 -83, -85, -86, -88, -89, -90, -92, -93,
668 -95, -96, -97, -98, -100, -101, -102, -103,
669 -104, -105, -106, -107, -108, -109, -110, -111,
670 -112, -112, -113, -114, -115, -115, -116, -116,
671 -117, -117, -118, -118, -119, -119, -119, -120,
672 -120, -120, -120, -120, -121, -121, -121, -121,
673 -121, -121, -120, -120, -120, -120, -120, -119,
674 -119, -119, -118, -118, -117, -117, -116, -116,
675 -115, -114, -114, -113, -112, -111, -111, -110,
676 -109, -108, -107, -106, -105, -104, -103, -102, -100
679 static const s16 hsv_blue_x
[] = {
680 112, 113, 114, 114, 115, 116, 117, 117,
681 118, 118, 119, 119, 120, 120, 120, 121,
682 121, 121, 122, 122, 122, 122, 122, 122,
683 122, 122, 122, 122, 122, 122, 121, 121,
684 121, 120, 120, 120, 119, 119, 118, 118,
685 117, 116, 116, 115, 114, 113, 113, 112,
686 111, 110, 109, 108, 107, 106, 105, 104,
687 103, 102, 100, 99, 98, 97, 95, 94,
688 93, 91, 90, 88, 87, 85, 84, 82,
689 80, 79, 77, 76, 74, 72, 70, 69,
690 67, 65, 63, 61, 60, 58, 56, 54,
691 52, 50, 48, 46, 44, 42, 40, 38,
692 36, 34, 32, 30, 28, 26, 24, 22,
693 19, 17, 15, 13, 11, 9, 7, 5,
694 2, 0, -1, -3, -5, -7, -9, -12,
695 -14, -16, -18, -20, -22, -24, -26, -28,
696 -31, -33, -35, -37, -39, -41, -43, -45,
697 -47, -49, -51, -53, -54, -56, -58, -60,
698 -62, -64, -66, -67, -69, -71, -73, -74,
699 -76, -78, -79, -81, -83, -84, -86, -87,
700 -89, -90, -92, -93, -94, -96, -97, -98,
701 -99, -101, -102, -103, -104, -105, -106, -107,
702 -108, -109, -110, -111, -112, -113, -114, -114,
703 -115, -116, -117, -117, -118, -118, -119, -119,
704 -120, -120, -120, -121, -121, -121, -122, -122,
705 -122, -122, -122, -122, -122, -122, -122, -122,
706 -122, -122, -121, -121, -121, -120, -120, -120,
707 -119, -119, -118, -118, -117, -116, -116, -115,
708 -114, -113, -113, -112, -111, -110, -109, -108,
709 -107, -106, -105, -104, -103, -102, -100, -99,
710 -98, -97, -95, -94, -93, -91, -90, -88,
711 -87, -85, -84, -82, -80, -79, -77, -76,
712 -74, -72, -70, -69, -67, -65, -63, -61,
713 -60, -58, -56, -54, -52, -50, -48, -46,
714 -44, -42, -40, -38, -36, -34, -32, -30,
715 -28, -26, -24, -22, -19, -17, -15, -13,
716 -11, -9, -7, -5, -2, 0, 1, 3,
717 5, 7, 9, 12, 14, 16, 18, 20,
718 22, 24, 26, 28, 31, 33, 35, 37,
719 39, 41, 43, 45, 47, 49, 51, 53,
720 54, 56, 58, 60, 62, 64, 66, 67,
721 69, 71, 73, 74, 76, 78, 79, 81,
722 83, 84, 86, 87, 89, 90, 92, 93,
723 94, 96, 97, 98, 99, 101, 102, 103,
724 104, 105, 106, 107, 108, 109, 110, 111, 112
727 static const s16 hsv_blue_y
[] = {
728 -11, -13, -15, -17, -19, -21, -23, -25,
729 -27, -29, -31, -33, -35, -37, -39, -41,
730 -43, -45, -46, -48, -50, -52, -54, -55,
731 -57, -59, -61, -62, -64, -66, -67, -69,
732 -71, -72, -74, -75, -77, -78, -80, -81,
733 -83, -84, -86, -87, -88, -90, -91, -92,
734 -93, -95, -96, -97, -98, -99, -100, -101,
735 -102, -103, -104, -105, -106, -106, -107, -108,
736 -109, -109, -110, -111, -111, -112, -112, -113,
737 -113, -114, -114, -114, -115, -115, -115, -115,
738 -116, -116, -116, -116, -116, -116, -116, -116,
739 -116, -115, -115, -115, -115, -114, -114, -114,
740 -113, -113, -112, -112, -111, -111, -110, -110,
741 -109, -108, -108, -107, -106, -105, -104, -103,
742 -102, -101, -100, -99, -98, -97, -96, -95,
743 -94, -93, -91, -90, -89, -88, -86, -85,
744 -84, -82, -81, -79, -78, -76, -75, -73,
745 -71, -70, -68, -67, -65, -63, -62, -60,
746 -58, -56, -55, -53, -51, -49, -47, -45,
747 -44, -42, -40, -38, -36, -34, -32, -30,
748 -28, -26, -24, -22, -20, -18, -16, -14,
749 -12, -10, -8, -6, -4, -2, 0, 1,
750 3, 5, 7, 9, 11, 13, 15, 17,
751 19, 21, 23, 25, 27, 29, 31, 33,
752 35, 37, 39, 41, 43, 45, 46, 48,
753 50, 52, 54, 55, 57, 59, 61, 62,
754 64, 66, 67, 69, 71, 72, 74, 75,
755 77, 78, 80, 81, 83, 84, 86, 87,
756 88, 90, 91, 92, 93, 95, 96, 97,
757 98, 99, 100, 101, 102, 103, 104, 105,
758 106, 106, 107, 108, 109, 109, 110, 111,
759 111, 112, 112, 113, 113, 114, 114, 114,
760 115, 115, 115, 115, 116, 116, 116, 116,
761 116, 116, 116, 116, 116, 115, 115, 115,
762 115, 114, 114, 114, 113, 113, 112, 112,
763 111, 111, 110, 110, 109, 108, 108, 107,
764 106, 105, 104, 103, 102, 101, 100, 99,
765 98, 97, 96, 95, 94, 93, 91, 90,
766 89, 88, 86, 85, 84, 82, 81, 79,
767 78, 76, 75, 73, 71, 70, 68, 67,
768 65, 63, 62, 60, 58, 56, 55, 53,
769 51, 49, 47, 45, 44, 42, 40, 38,
770 36, 34, 32, 30, 28, 26, 24, 22,
771 20, 18, 16, 14, 12, 10, 8, 6,
772 4, 2, 0, -1, -3, -5, -7, -9, -11
775 static u16 i2c_ident
[] = {
784 V4L2_IDENT_MT9M001C12ST
,
790 static u16 bridge_init
[][2] = {
791 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
792 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
793 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
794 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
795 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
796 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
797 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
798 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
799 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
800 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
801 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
802 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
803 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
804 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
805 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
806 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
807 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
808 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
809 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
813 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
814 static u8 ov_gain
[] = {
815 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
816 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
817 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
818 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
819 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
820 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
821 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
825 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
826 static u16 micron1_gain
[] = {
827 /* 1x 1.25x 1.5x 1.75x */
828 0x0020, 0x0028, 0x0030, 0x0038,
829 /* 2x 2.25x 2.5x 2.75x */
830 0x00a0, 0x00a4, 0x00a8, 0x00ac,
831 /* 3x 3.25x 3.5x 3.75x */
832 0x00b0, 0x00b4, 0x00b8, 0x00bc,
833 /* 4x 4.25x 4.5x 4.75x */
834 0x00c0, 0x00c4, 0x00c8, 0x00cc,
835 /* 5x 5.25x 5.5x 5.75x */
836 0x00d0, 0x00d4, 0x00d8, 0x00dc,
837 /* 6x 6.25x 6.5x 6.75x */
838 0x00e0, 0x00e4, 0x00e8, 0x00ec,
839 /* 7x 7.25x 7.5x 7.75x */
840 0x00f0, 0x00f4, 0x00f8, 0x00fc,
845 /* mt9m001 sensor uses a different gain formula then other micron sensors */
846 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
847 static u16 micron2_gain
[] = {
848 /* 1x 1.25x 1.5x 1.75x */
849 0x0008, 0x000a, 0x000c, 0x000e,
850 /* 2x 2.25x 2.5x 2.75x */
851 0x0010, 0x0012, 0x0014, 0x0016,
852 /* 3x 3.25x 3.5x 3.75x */
853 0x0018, 0x001a, 0x001c, 0x001e,
854 /* 4x 4.25x 4.5x 4.75x */
855 0x0020, 0x0051, 0x0052, 0x0053,
856 /* 5x 5.25x 5.5x 5.75x */
857 0x0054, 0x0055, 0x0056, 0x0057,
858 /* 6x 6.25x 6.5x 6.75x */
859 0x0058, 0x0059, 0x005a, 0x005b,
860 /* 7x 7.25x 7.5x 7.75x */
861 0x005c, 0x005d, 0x005e, 0x005f,
866 /* Gain = .5 + bit[7:0] / 16 */
867 static u8 hv7131r_gain
[] = {
868 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
869 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
870 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
871 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
872 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
873 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
874 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
878 static struct i2c_reg_u8 soi968_init
[] = {
879 {0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f},
880 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
881 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
882 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
883 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
884 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
885 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
886 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
887 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
888 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
889 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
892 static struct i2c_reg_u8 ov7660_init
[] = {
893 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
894 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
895 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
896 /* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using
897 0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
898 {0x17, 0x10}, {0x18, 0x61},
899 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
900 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6},
901 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
904 static struct i2c_reg_u8 ov7670_init
[] = {
905 {0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
906 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
907 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
908 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
909 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
910 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
911 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
912 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
913 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
914 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
915 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
916 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
917 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
918 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
919 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
920 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
921 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
922 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
923 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
924 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
925 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
926 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
927 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
928 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
929 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
930 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
931 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
932 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
933 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
934 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
935 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
936 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
937 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
938 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
939 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
940 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
941 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
942 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
943 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
944 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
945 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
946 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
947 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
948 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
949 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
950 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
951 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
952 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
953 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
954 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
955 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
956 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
957 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
961 static struct i2c_reg_u8 ov9650_init
[] = {
962 {0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78},
963 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
964 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
965 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
966 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
967 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
968 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
969 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
970 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
971 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
972 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
973 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
974 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
975 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
976 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
977 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
978 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
979 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
980 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
981 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
982 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
983 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
984 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
985 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
986 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
987 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
988 {0xaa, 0x92}, {0xab, 0x0a},
991 static struct i2c_reg_u8 ov9655_init
[] = {
992 {0x12, 0x80}, {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
993 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
994 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
995 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
996 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
997 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
998 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
999 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
1000 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
1001 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
1002 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
1003 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
1004 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
1005 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
1006 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
1007 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
1008 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
1009 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
1010 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
1011 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
1012 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
1013 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
1014 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
1015 {0x04, 0x03}, {0x00, 0x13},
1018 static struct i2c_reg_u16 mt9v112_init
[] = {
1019 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
1020 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
1021 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
1022 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
1023 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
1024 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
1025 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
1026 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
1027 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
1028 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
1029 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
1030 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1031 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
1032 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
1033 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
1034 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
1037 static struct i2c_reg_u16 mt9v111_init
[] = {
1038 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
1039 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
1040 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
1041 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
1042 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
1043 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
1044 {0x0e, 0x0008}, {0x20, 0x0000}
1047 static struct i2c_reg_u16 mt9v011_init
[] = {
1048 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
1049 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
1050 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
1051 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
1052 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
1053 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
1054 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
1055 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
1056 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
1057 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
1058 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
1059 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
1060 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
1061 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
1062 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
1063 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
1064 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
1065 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
1066 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
1067 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
1068 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
1069 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1070 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
1071 {0x06, 0x0029}, {0x05, 0x0009},
1074 static struct i2c_reg_u16 mt9m001_init
[] = {
1077 {0x04, 0x0500}, /* hres = 1280 */
1078 {0x03, 0x0400}, /* vres = 1024 */
1090 static struct i2c_reg_u16 mt9m111_init
[] = {
1091 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1092 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1093 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1097 static struct i2c_reg_u16 mt9m112_init
[] = {
1098 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1099 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1100 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1104 static struct i2c_reg_u8 hv7131r_init
[] = {
1105 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
1106 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
1107 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
1108 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
1109 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
1110 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
1111 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
1112 {0x23, 0x09}, {0x01, 0x08},
1115 static int reg_r(struct gspca_dev
*gspca_dev
, u16 reg
, u16 length
)
1117 struct usb_device
*dev
= gspca_dev
->dev
;
1119 result
= usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
1121 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
1127 if (unlikely(result
< 0 || result
!= length
)) {
1128 pr_err("Read register failed 0x%02X\n", reg
);
1134 static int reg_w(struct gspca_dev
*gspca_dev
, u16 reg
,
1135 const u8
*buffer
, int length
)
1137 struct usb_device
*dev
= gspca_dev
->dev
;
1139 memcpy(gspca_dev
->usb_buf
, buffer
, length
);
1140 result
= usb_control_msg(dev
, usb_sndctrlpipe(dev
, 0),
1142 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
1148 if (unlikely(result
< 0 || result
!= length
)) {
1149 pr_err("Write register failed index 0x%02X\n", reg
);
1155 static int reg_w1(struct gspca_dev
*gspca_dev
, u16 reg
, const u8 value
)
1157 u8 data
[1] = {value
};
1158 return reg_w(gspca_dev
, reg
, data
, 1);
1161 static int i2c_w(struct gspca_dev
*gspca_dev
, const u8
*buffer
)
1164 reg_w(gspca_dev
, 0x10c0, buffer
, 8);
1165 for (i
= 0; i
< 5; i
++) {
1166 reg_r(gspca_dev
, 0x10c0, 1);
1167 if (gspca_dev
->usb_buf
[0] & 0x04) {
1168 if (gspca_dev
->usb_buf
[0] & 0x08)
1177 static int i2c_w1(struct gspca_dev
*gspca_dev
, u8 reg
, u8 val
)
1179 struct sd
*sd
= (struct sd
*) gspca_dev
;
1184 * from the point of view of the bridge, the length
1185 * includes the address
1187 row
[0] = 0x81 | (2 << 4);
1188 row
[1] = sd
->i2c_addr
;
1196 return i2c_w(gspca_dev
, row
);
1199 static int i2c_w2(struct gspca_dev
*gspca_dev
, u8 reg
, u16 val
)
1201 struct sd
*sd
= (struct sd
*) gspca_dev
;
1205 * from the point of view of the bridge, the length
1206 * includes the address
1208 row
[0] = 0x81 | (3 << 4);
1209 row
[1] = sd
->i2c_addr
;
1211 row
[3] = (val
>> 8) & 0xff;
1212 row
[4] = val
& 0xff;
1217 return i2c_w(gspca_dev
, row
);
1220 static int i2c_r1(struct gspca_dev
*gspca_dev
, u8 reg
, u8
*val
)
1222 struct sd
*sd
= (struct sd
*) gspca_dev
;
1225 row
[0] = 0x81 | (1 << 4);
1226 row
[1] = sd
->i2c_addr
;
1233 if (i2c_w(gspca_dev
, row
) < 0)
1235 row
[0] = 0x81 | (1 << 4) | 0x02;
1237 if (i2c_w(gspca_dev
, row
) < 0)
1239 if (reg_r(gspca_dev
, 0x10c2, 5) < 0)
1241 *val
= gspca_dev
->usb_buf
[4];
1245 static int i2c_r2(struct gspca_dev
*gspca_dev
, u8 reg
, u16
*val
)
1247 struct sd
*sd
= (struct sd
*) gspca_dev
;
1250 row
[0] = 0x81 | (1 << 4);
1251 row
[1] = sd
->i2c_addr
;
1258 if (i2c_w(gspca_dev
, row
) < 0)
1260 row
[0] = 0x81 | (2 << 4) | 0x02;
1262 if (i2c_w(gspca_dev
, row
) < 0)
1264 if (reg_r(gspca_dev
, 0x10c2, 5) < 0)
1266 *val
= (gspca_dev
->usb_buf
[3] << 8) | gspca_dev
->usb_buf
[4];
1270 static int ov9650_init_sensor(struct gspca_dev
*gspca_dev
)
1274 struct sd
*sd
= (struct sd
*) gspca_dev
;
1276 if (i2c_r2(gspca_dev
, 0x1c, &id
) < 0)
1280 pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id
);
1284 for (i
= 0; i
< ARRAY_SIZE(ov9650_init
); i
++) {
1285 if (i2c_w1(gspca_dev
, ov9650_init
[i
].reg
,
1286 ov9650_init
[i
].val
) < 0) {
1287 pr_err("OV9650 sensor initialization failed\n");
1296 static int ov9655_init_sensor(struct gspca_dev
*gspca_dev
)
1299 struct sd
*sd
= (struct sd
*) gspca_dev
;
1301 for (i
= 0; i
< ARRAY_SIZE(ov9655_init
); i
++) {
1302 if (i2c_w1(gspca_dev
, ov9655_init
[i
].reg
,
1303 ov9655_init
[i
].val
) < 0) {
1304 pr_err("OV9655 sensor initialization failed\n");
1308 /* disable hflip and vflip */
1309 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1315 static int soi968_init_sensor(struct gspca_dev
*gspca_dev
)
1318 struct sd
*sd
= (struct sd
*) gspca_dev
;
1320 for (i
= 0; i
< ARRAY_SIZE(soi968_init
); i
++) {
1321 if (i2c_w1(gspca_dev
, soi968_init
[i
].reg
,
1322 soi968_init
[i
].val
) < 0) {
1323 pr_err("SOI968 sensor initialization failed\n");
1327 /* disable hflip and vflip */
1328 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
)
1329 | (1 << EXPOSURE_IDX
);
1335 static int ov7660_init_sensor(struct gspca_dev
*gspca_dev
)
1338 struct sd
*sd
= (struct sd
*) gspca_dev
;
1340 for (i
= 0; i
< ARRAY_SIZE(ov7660_init
); i
++) {
1341 if (i2c_w1(gspca_dev
, ov7660_init
[i
].reg
,
1342 ov7660_init
[i
].val
) < 0) {
1343 pr_err("OV7660 sensor initialization failed\n");
1352 static int ov7670_init_sensor(struct gspca_dev
*gspca_dev
)
1355 struct sd
*sd
= (struct sd
*) gspca_dev
;
1357 for (i
= 0; i
< ARRAY_SIZE(ov7670_init
); i
++) {
1358 if (i2c_w1(gspca_dev
, ov7670_init
[i
].reg
,
1359 ov7670_init
[i
].val
) < 0) {
1360 pr_err("OV7670 sensor initialization failed\n");
1364 /* disable hflip and vflip */
1365 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1371 static int mt9v_init_sensor(struct gspca_dev
*gspca_dev
)
1373 struct sd
*sd
= (struct sd
*) gspca_dev
;
1378 sd
->i2c_addr
= 0x5d;
1379 ret
= i2c_r2(gspca_dev
, 0xff, &value
);
1380 if ((ret
== 0) && (value
== 0x8243)) {
1381 for (i
= 0; i
< ARRAY_SIZE(mt9v011_init
); i
++) {
1382 if (i2c_w2(gspca_dev
, mt9v011_init
[i
].reg
,
1383 mt9v011_init
[i
].val
) < 0) {
1384 pr_err("MT9V011 sensor initialization failed\n");
1390 sd
->sensor
= SENSOR_MT9V011
;
1391 pr_info("MT9V011 sensor detected\n");
1395 sd
->i2c_addr
= 0x5c;
1396 i2c_w2(gspca_dev
, 0x01, 0x0004);
1397 ret
= i2c_r2(gspca_dev
, 0xff, &value
);
1398 if ((ret
== 0) && (value
== 0x823a)) {
1399 for (i
= 0; i
< ARRAY_SIZE(mt9v111_init
); i
++) {
1400 if (i2c_w2(gspca_dev
, mt9v111_init
[i
].reg
,
1401 mt9v111_init
[i
].val
) < 0) {
1402 pr_err("MT9V111 sensor initialization failed\n");
1406 gspca_dev
->ctrl_dis
= (1 << EXPOSURE_IDX
)
1407 | (1 << AUTOGAIN_IDX
)
1411 sd
->sensor
= SENSOR_MT9V111
;
1412 pr_info("MT9V111 sensor detected\n");
1416 sd
->i2c_addr
= 0x5d;
1417 ret
= i2c_w2(gspca_dev
, 0xf0, 0x0000);
1419 sd
->i2c_addr
= 0x48;
1420 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1422 ret
= i2c_r2(gspca_dev
, 0x00, &value
);
1423 if ((ret
== 0) && (value
== 0x1229)) {
1424 for (i
= 0; i
< ARRAY_SIZE(mt9v112_init
); i
++) {
1425 if (i2c_w2(gspca_dev
, mt9v112_init
[i
].reg
,
1426 mt9v112_init
[i
].val
) < 0) {
1427 pr_err("MT9V112 sensor initialization failed\n");
1433 sd
->sensor
= SENSOR_MT9V112
;
1434 pr_info("MT9V112 sensor detected\n");
1441 static int mt9m112_init_sensor(struct gspca_dev
*gspca_dev
)
1443 struct sd
*sd
= (struct sd
*) gspca_dev
;
1445 for (i
= 0; i
< ARRAY_SIZE(mt9m112_init
); i
++) {
1446 if (i2c_w2(gspca_dev
, mt9m112_init
[i
].reg
,
1447 mt9m112_init
[i
].val
) < 0) {
1448 pr_err("MT9M112 sensor initialization failed\n");
1452 gspca_dev
->ctrl_dis
= (1 << EXPOSURE_IDX
) | (1 << AUTOGAIN_IDX
)
1459 static int mt9m111_init_sensor(struct gspca_dev
*gspca_dev
)
1461 struct sd
*sd
= (struct sd
*) gspca_dev
;
1463 for (i
= 0; i
< ARRAY_SIZE(mt9m111_init
); i
++) {
1464 if (i2c_w2(gspca_dev
, mt9m111_init
[i
].reg
,
1465 mt9m111_init
[i
].val
) < 0) {
1466 pr_err("MT9M111 sensor initialization failed\n");
1470 gspca_dev
->ctrl_dis
= (1 << EXPOSURE_IDX
) | (1 << AUTOGAIN_IDX
)
1477 static int mt9m001_init_sensor(struct gspca_dev
*gspca_dev
)
1479 struct sd
*sd
= (struct sd
*) gspca_dev
;
1483 if (i2c_r2(gspca_dev
, 0x00, &id
) < 0)
1486 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
1490 pr_info("MT9M001 color sensor detected\n");
1493 pr_info("MT9M001 mono sensor detected\n");
1496 pr_err("No MT9M001 chip detected, ID = %x\n\n", id
);
1500 for (i
= 0; i
< ARRAY_SIZE(mt9m001_init
); i
++) {
1501 if (i2c_w2(gspca_dev
, mt9m001_init
[i
].reg
,
1502 mt9m001_init
[i
].val
) < 0) {
1503 pr_err("MT9M001 sensor initialization failed\n");
1507 /* disable hflip and vflip */
1508 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1514 static int hv7131r_init_sensor(struct gspca_dev
*gspca_dev
)
1517 struct sd
*sd
= (struct sd
*) gspca_dev
;
1519 for (i
= 0; i
< ARRAY_SIZE(hv7131r_init
); i
++) {
1520 if (i2c_w1(gspca_dev
, hv7131r_init
[i
].reg
,
1521 hv7131r_init
[i
].val
) < 0) {
1522 pr_err("HV7131R Sensor initialization failed\n");
1531 static int set_cmatrix(struct gspca_dev
*gspca_dev
)
1533 struct sd
*sd
= (struct sd
*) gspca_dev
;
1534 s32 hue_coord
, hue_index
= 180 + sd
->hue
;
1537 memset(cmatrix
, 0, sizeof cmatrix
);
1538 cmatrix
[2] = (sd
->contrast
* 0x25 / 0x100) + 0x26;
1539 cmatrix
[0] = 0x13 + (cmatrix
[2] - 0x26) * 0x13 / 0x25;
1540 cmatrix
[4] = 0x07 + (cmatrix
[2] - 0x26) * 0x07 / 0x25;
1541 cmatrix
[18] = sd
->brightness
- 0x80;
1543 hue_coord
= (hsv_red_x
[hue_index
] * sd
->saturation
) >> 8;
1544 cmatrix
[6] = hue_coord
;
1545 cmatrix
[7] = (hue_coord
>> 8) & 0x0f;
1547 hue_coord
= (hsv_red_y
[hue_index
] * sd
->saturation
) >> 8;
1548 cmatrix
[8] = hue_coord
;
1549 cmatrix
[9] = (hue_coord
>> 8) & 0x0f;
1551 hue_coord
= (hsv_green_x
[hue_index
] * sd
->saturation
) >> 8;
1552 cmatrix
[10] = hue_coord
;
1553 cmatrix
[11] = (hue_coord
>> 8) & 0x0f;
1555 hue_coord
= (hsv_green_y
[hue_index
] * sd
->saturation
) >> 8;
1556 cmatrix
[12] = hue_coord
;
1557 cmatrix
[13] = (hue_coord
>> 8) & 0x0f;
1559 hue_coord
= (hsv_blue_x
[hue_index
] * sd
->saturation
) >> 8;
1560 cmatrix
[14] = hue_coord
;
1561 cmatrix
[15] = (hue_coord
>> 8) & 0x0f;
1563 hue_coord
= (hsv_blue_y
[hue_index
] * sd
->saturation
) >> 8;
1564 cmatrix
[16] = hue_coord
;
1565 cmatrix
[17] = (hue_coord
>> 8) & 0x0f;
1567 return reg_w(gspca_dev
, 0x10e1, cmatrix
, 21);
1570 static int set_gamma(struct gspca_dev
*gspca_dev
)
1572 struct sd
*sd
= (struct sd
*) gspca_dev
;
1574 u8 gval
= sd
->gamma
* 0xb8 / 0x100;
1578 gamma
[1] = 0x13 + (gval
* (0xcb - 0x13) / 0xb8);
1579 gamma
[2] = 0x25 + (gval
* (0xee - 0x25) / 0xb8);
1580 gamma
[3] = 0x37 + (gval
* (0xfa - 0x37) / 0xb8);
1581 gamma
[4] = 0x45 + (gval
* (0xfc - 0x45) / 0xb8);
1582 gamma
[5] = 0x55 + (gval
* (0xfb - 0x55) / 0xb8);
1583 gamma
[6] = 0x65 + (gval
* (0xfc - 0x65) / 0xb8);
1584 gamma
[7] = 0x74 + (gval
* (0xfd - 0x74) / 0xb8);
1585 gamma
[8] = 0x83 + (gval
* (0xfe - 0x83) / 0xb8);
1586 gamma
[9] = 0x92 + (gval
* (0xfc - 0x92) / 0xb8);
1587 gamma
[10] = 0xa1 + (gval
* (0xfc - 0xa1) / 0xb8);
1588 gamma
[11] = 0xb0 + (gval
* (0xfc - 0xb0) / 0xb8);
1589 gamma
[12] = 0xbf + (gval
* (0xfb - 0xbf) / 0xb8);
1590 gamma
[13] = 0xce + (gval
* (0xfb - 0xce) / 0xb8);
1591 gamma
[14] = 0xdf + (gval
* (0xfd - 0xdf) / 0xb8);
1592 gamma
[15] = 0xea + (gval
* (0xf9 - 0xea) / 0xb8);
1595 return reg_w(gspca_dev
, 0x1190, gamma
, 17);
1598 static int set_redblue(struct gspca_dev
*gspca_dev
)
1600 struct sd
*sd
= (struct sd
*) gspca_dev
;
1601 reg_w1(gspca_dev
, 0x118c, sd
->red
);
1602 reg_w1(gspca_dev
, 0x118f, sd
->blue
);
1606 static int set_hvflip(struct gspca_dev
*gspca_dev
)
1608 u8 value
, tslb
, hflip
, vflip
;
1610 struct sd
*sd
= (struct sd
*) gspca_dev
;
1612 if ((sd
->flags
& FLIP_DETECT
) && dmi_check_system(flip_dmi_table
)) {
1620 switch (sd
->sensor
) {
1630 reg_w1(gspca_dev
, 0x1182, sd
->vstart
);
1631 i2c_w1(gspca_dev
, 0x1e, value
);
1634 i2c_r1(gspca_dev
, 0x1e, &value
);
1643 i2c_w1(gspca_dev
, 0x1e, value
);
1644 i2c_w1(gspca_dev
, 0x3a, tslb
);
1646 case SENSOR_MT9V111
:
1647 case SENSOR_MT9V011
:
1648 i2c_r2(gspca_dev
, 0x20, &value2
);
1654 i2c_w2(gspca_dev
, 0x20, value2
);
1656 case SENSOR_MT9M112
:
1657 case SENSOR_MT9M111
:
1658 case SENSOR_MT9V112
:
1659 i2c_r2(gspca_dev
, 0x20, &value2
);
1665 i2c_w2(gspca_dev
, 0x20, value2
);
1667 case SENSOR_HV7131R
:
1668 i2c_r1(gspca_dev
, 0x01, &value
);
1674 i2c_w1(gspca_dev
, 0x01, value
);
1680 static int set_exposure(struct gspca_dev
*gspca_dev
)
1682 struct sd
*sd
= (struct sd
*) gspca_dev
;
1683 u8 exp
[8] = {0x81, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1684 switch (sd
->sensor
) {
1691 exp
[3] = sd
->exposure
& 0xff;
1692 exp
[4] = sd
->exposure
>> 8;
1694 case SENSOR_MT9M001
:
1695 case SENSOR_MT9V112
:
1696 case SENSOR_MT9V011
:
1699 exp
[3] = sd
->exposure
>> 8;
1700 exp
[4] = sd
->exposure
& 0xff;
1702 case SENSOR_HV7131R
:
1705 exp
[3] = (sd
->exposure
>> 5) & 0xff;
1706 exp
[4] = (sd
->exposure
<< 3) & 0xff;
1712 i2c_w(gspca_dev
, exp
);
1716 static int set_gain(struct gspca_dev
*gspca_dev
)
1718 struct sd
*sd
= (struct sd
*) gspca_dev
;
1719 u8 gain
[8] = {0x81, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1720 switch (sd
->sensor
) {
1726 gain
[0] |= (2 << 4);
1727 gain
[3] = ov_gain
[sd
->gain
];
1729 case SENSOR_MT9V011
:
1730 gain
[0] |= (3 << 4);
1732 gain
[3] = micron1_gain
[sd
->gain
] >> 8;
1733 gain
[4] = micron1_gain
[sd
->gain
] & 0xff;
1735 case SENSOR_MT9V112
:
1736 gain
[0] |= (3 << 4);
1738 gain
[3] = micron1_gain
[sd
->gain
] >> 8;
1739 gain
[4] = micron1_gain
[sd
->gain
] & 0xff;
1741 case SENSOR_MT9M001
:
1742 gain
[0] |= (3 << 4);
1744 gain
[3] = micron2_gain
[sd
->gain
] >> 8;
1745 gain
[4] = micron2_gain
[sd
->gain
] & 0xff;
1747 case SENSOR_HV7131R
:
1748 gain
[0] |= (2 << 4);
1750 gain
[3] = hv7131r_gain
[sd
->gain
];
1755 i2c_w(gspca_dev
, gain
);
1759 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, s32 val
)
1761 struct sd
*sd
= (struct sd
*) gspca_dev
;
1763 sd
->brightness
= val
;
1764 if (gspca_dev
->streaming
)
1765 return set_cmatrix(gspca_dev
);
1769 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, s32
*val
)
1771 struct sd
*sd
= (struct sd
*) gspca_dev
;
1772 *val
= sd
->brightness
;
1777 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, s32 val
)
1779 struct sd
*sd
= (struct sd
*) gspca_dev
;
1782 if (gspca_dev
->streaming
)
1783 return set_cmatrix(gspca_dev
);
1787 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, s32
*val
)
1789 struct sd
*sd
= (struct sd
*) gspca_dev
;
1790 *val
= sd
->contrast
;
1794 static int sd_setsaturation(struct gspca_dev
*gspca_dev
, s32 val
)
1796 struct sd
*sd
= (struct sd
*) gspca_dev
;
1798 sd
->saturation
= val
;
1799 if (gspca_dev
->streaming
)
1800 return set_cmatrix(gspca_dev
);
1804 static int sd_getsaturation(struct gspca_dev
*gspca_dev
, s32
*val
)
1806 struct sd
*sd
= (struct sd
*) gspca_dev
;
1807 *val
= sd
->saturation
;
1811 static int sd_sethue(struct gspca_dev
*gspca_dev
, s32 val
)
1813 struct sd
*sd
= (struct sd
*) gspca_dev
;
1816 if (gspca_dev
->streaming
)
1817 return set_cmatrix(gspca_dev
);
1821 static int sd_gethue(struct gspca_dev
*gspca_dev
, s32
*val
)
1823 struct sd
*sd
= (struct sd
*) gspca_dev
;
1828 static int sd_setgamma(struct gspca_dev
*gspca_dev
, s32 val
)
1830 struct sd
*sd
= (struct sd
*) gspca_dev
;
1833 if (gspca_dev
->streaming
)
1834 return set_gamma(gspca_dev
);
1838 static int sd_getgamma(struct gspca_dev
*gspca_dev
, s32
*val
)
1840 struct sd
*sd
= (struct sd
*) gspca_dev
;
1845 static int sd_setredbalance(struct gspca_dev
*gspca_dev
, s32 val
)
1847 struct sd
*sd
= (struct sd
*) gspca_dev
;
1850 if (gspca_dev
->streaming
)
1851 return set_redblue(gspca_dev
);
1855 static int sd_getredbalance(struct gspca_dev
*gspca_dev
, s32
*val
)
1857 struct sd
*sd
= (struct sd
*) gspca_dev
;
1862 static int sd_setbluebalance(struct gspca_dev
*gspca_dev
, s32 val
)
1864 struct sd
*sd
= (struct sd
*) gspca_dev
;
1867 if (gspca_dev
->streaming
)
1868 return set_redblue(gspca_dev
);
1872 static int sd_getbluebalance(struct gspca_dev
*gspca_dev
, s32
*val
)
1874 struct sd
*sd
= (struct sd
*) gspca_dev
;
1879 static int sd_sethflip(struct gspca_dev
*gspca_dev
, s32 val
)
1881 struct sd
*sd
= (struct sd
*) gspca_dev
;
1884 if (gspca_dev
->streaming
)
1885 return set_hvflip(gspca_dev
);
1889 static int sd_gethflip(struct gspca_dev
*gspca_dev
, s32
*val
)
1891 struct sd
*sd
= (struct sd
*) gspca_dev
;
1896 static int sd_setvflip(struct gspca_dev
*gspca_dev
, s32 val
)
1898 struct sd
*sd
= (struct sd
*) gspca_dev
;
1901 if (gspca_dev
->streaming
)
1902 return set_hvflip(gspca_dev
);
1906 static int sd_getvflip(struct gspca_dev
*gspca_dev
, s32
*val
)
1908 struct sd
*sd
= (struct sd
*) gspca_dev
;
1913 static int sd_setexposure(struct gspca_dev
*gspca_dev
, s32 val
)
1915 struct sd
*sd
= (struct sd
*) gspca_dev
;
1918 if (gspca_dev
->streaming
)
1919 return set_exposure(gspca_dev
);
1923 static int sd_getexposure(struct gspca_dev
*gspca_dev
, s32
*val
)
1925 struct sd
*sd
= (struct sd
*) gspca_dev
;
1926 *val
= sd
->exposure
;
1930 static int sd_setgain(struct gspca_dev
*gspca_dev
, s32 val
)
1932 struct sd
*sd
= (struct sd
*) gspca_dev
;
1935 if (gspca_dev
->streaming
)
1936 return set_gain(gspca_dev
);
1940 static int sd_getgain(struct gspca_dev
*gspca_dev
, s32
*val
)
1942 struct sd
*sd
= (struct sd
*) gspca_dev
;
1947 static int sd_setautoexposure(struct gspca_dev
*gspca_dev
, s32 val
)
1949 struct sd
*sd
= (struct sd
*) gspca_dev
;
1950 sd
->auto_exposure
= val
;
1954 static int sd_getautoexposure(struct gspca_dev
*gspca_dev
, s32
*val
)
1956 struct sd
*sd
= (struct sd
*) gspca_dev
;
1957 *val
= sd
->auto_exposure
;
1961 #ifdef CONFIG_VIDEO_ADV_DEBUG
1962 static int sd_dbg_g_register(struct gspca_dev
*gspca_dev
,
1963 struct v4l2_dbg_register
*reg
)
1965 struct sd
*sd
= (struct sd
*) gspca_dev
;
1966 switch (reg
->match
.type
) {
1967 case V4L2_CHIP_MATCH_HOST
:
1968 if (reg
->match
.addr
!= 0)
1970 if (reg
->reg
< 0x1000 || reg
->reg
> 0x11ff)
1972 if (reg_r(gspca_dev
, reg
->reg
, 1) < 0)
1974 reg
->val
= gspca_dev
->usb_buf
[0];
1976 case V4L2_CHIP_MATCH_I2C_ADDR
:
1977 if (reg
->match
.addr
!= sd
->i2c_addr
)
1979 if (sd
->sensor
>= SENSOR_MT9V011
&&
1980 sd
->sensor
<= SENSOR_MT9M112
) {
1981 if (i2c_r2(gspca_dev
, reg
->reg
, (u16
*)®
->val
) < 0)
1984 if (i2c_r1(gspca_dev
, reg
->reg
, (u8
*)®
->val
) < 0)
1992 static int sd_dbg_s_register(struct gspca_dev
*gspca_dev
,
1993 struct v4l2_dbg_register
*reg
)
1995 struct sd
*sd
= (struct sd
*) gspca_dev
;
1996 switch (reg
->match
.type
) {
1997 case V4L2_CHIP_MATCH_HOST
:
1998 if (reg
->match
.addr
!= 0)
2000 if (reg
->reg
< 0x1000 || reg
->reg
> 0x11ff)
2002 if (reg_w1(gspca_dev
, reg
->reg
, reg
->val
) < 0)
2005 case V4L2_CHIP_MATCH_I2C_ADDR
:
2006 if (reg
->match
.addr
!= sd
->i2c_addr
)
2008 if (sd
->sensor
>= SENSOR_MT9V011
&&
2009 sd
->sensor
<= SENSOR_MT9M112
) {
2010 if (i2c_w2(gspca_dev
, reg
->reg
, reg
->val
) < 0)
2013 if (i2c_w1(gspca_dev
, reg
->reg
, reg
->val
) < 0)
2022 static int sd_chip_ident(struct gspca_dev
*gspca_dev
,
2023 struct v4l2_dbg_chip_ident
*chip
)
2025 struct sd
*sd
= (struct sd
*) gspca_dev
;
2027 switch (chip
->match
.type
) {
2028 case V4L2_CHIP_MATCH_HOST
:
2029 if (chip
->match
.addr
!= 0)
2032 chip
->ident
= V4L2_IDENT_SN9C20X
;
2034 case V4L2_CHIP_MATCH_I2C_ADDR
:
2035 if (chip
->match
.addr
!= sd
->i2c_addr
)
2038 chip
->ident
= i2c_ident
[sd
->sensor
];
2044 static int sd_config(struct gspca_dev
*gspca_dev
,
2045 const struct usb_device_id
*id
)
2047 struct sd
*sd
= (struct sd
*) gspca_dev
;
2050 cam
= &gspca_dev
->cam
;
2051 cam
->needs_full_bandwidth
= 1;
2053 sd
->sensor
= (id
->driver_info
>> 8) & 0xff;
2054 sd
->i2c_addr
= id
->driver_info
& 0xff;
2055 sd
->flags
= (id
->driver_info
>> 16) & 0xff;
2057 switch (sd
->sensor
) {
2058 case SENSOR_MT9M112
:
2059 case SENSOR_MT9M111
:
2062 cam
->cam_mode
= sxga_mode
;
2063 cam
->nmodes
= ARRAY_SIZE(sxga_mode
);
2065 case SENSOR_MT9M001
:
2066 cam
->cam_mode
= mono_mode
;
2067 cam
->nmodes
= ARRAY_SIZE(mono_mode
);
2070 cam
->cam_mode
= vga_mode
;
2071 cam
->nmodes
= ARRAY_SIZE(vga_mode
);
2077 sd
->exposure_step
= 16;
2079 sd
->brightness
= BRIGHTNESS_DEFAULT
;
2080 sd
->contrast
= CONTRAST_DEFAULT
;
2081 sd
->saturation
= SATURATION_DEFAULT
;
2082 sd
->hue
= HUE_DEFAULT
;
2083 sd
->gamma
= GAMMA_DEFAULT
;
2084 sd
->red
= RED_DEFAULT
;
2085 sd
->blue
= BLUE_DEFAULT
;
2087 sd
->hflip
= HFLIP_DEFAULT
;
2088 sd
->vflip
= VFLIP_DEFAULT
;
2089 sd
->exposure
= EXPOSURE_DEFAULT
;
2090 sd
->gain
= GAIN_DEFAULT
;
2091 sd
->auto_exposure
= AUTO_EXPOSURE_DEFAULT
;
2098 static int sd_init(struct gspca_dev
*gspca_dev
)
2100 struct sd
*sd
= (struct sd
*) gspca_dev
;
2104 {0x80, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
2106 for (i
= 0; i
< ARRAY_SIZE(bridge_init
); i
++) {
2107 value
= bridge_init
[i
][1];
2108 if (reg_w(gspca_dev
, bridge_init
[i
][0], &value
, 1) < 0) {
2109 pr_err("Device initialization failed\n");
2114 if (sd
->flags
& LED_REVERSE
)
2115 reg_w1(gspca_dev
, 0x1006, 0x00);
2117 reg_w1(gspca_dev
, 0x1006, 0x20);
2119 if (reg_w(gspca_dev
, 0x10c0, i2c_init
, 9) < 0) {
2120 pr_err("Device initialization failed\n");
2124 switch (sd
->sensor
) {
2126 if (ov9650_init_sensor(gspca_dev
) < 0)
2128 pr_info("OV9650 sensor detected\n");
2131 if (ov9655_init_sensor(gspca_dev
) < 0)
2133 pr_info("OV9655 sensor detected\n");
2136 if (soi968_init_sensor(gspca_dev
) < 0)
2138 pr_info("SOI968 sensor detected\n");
2141 if (ov7660_init_sensor(gspca_dev
) < 0)
2143 pr_info("OV7660 sensor detected\n");
2146 if (ov7670_init_sensor(gspca_dev
) < 0)
2148 pr_info("OV7670 sensor detected\n");
2150 case SENSOR_MT9VPRB
:
2151 if (mt9v_init_sensor(gspca_dev
) < 0)
2154 case SENSOR_MT9M111
:
2155 if (mt9m111_init_sensor(gspca_dev
) < 0)
2157 pr_info("MT9M111 sensor detected\n");
2159 case SENSOR_MT9M112
:
2160 if (mt9m112_init_sensor(gspca_dev
) < 0)
2162 pr_info("MT9M112 sensor detected\n");
2164 case SENSOR_MT9M001
:
2165 if (mt9m001_init_sensor(gspca_dev
) < 0)
2168 case SENSOR_HV7131R
:
2169 if (hv7131r_init_sensor(gspca_dev
) < 0)
2171 pr_info("HV7131R sensor detected\n");
2174 pr_info("Unsupported Sensor\n");
2181 static void configure_sensor_output(struct gspca_dev
*gspca_dev
, int mode
)
2183 struct sd
*sd
= (struct sd
*) gspca_dev
;
2185 switch (sd
->sensor
) {
2187 if (mode
& MODE_SXGA
) {
2188 i2c_w1(gspca_dev
, 0x17, 0x1d);
2189 i2c_w1(gspca_dev
, 0x18, 0xbd);
2190 i2c_w1(gspca_dev
, 0x19, 0x01);
2191 i2c_w1(gspca_dev
, 0x1a, 0x81);
2192 i2c_w1(gspca_dev
, 0x12, 0x00);
2196 i2c_w1(gspca_dev
, 0x17, 0x13);
2197 i2c_w1(gspca_dev
, 0x18, 0x63);
2198 i2c_w1(gspca_dev
, 0x19, 0x01);
2199 i2c_w1(gspca_dev
, 0x1a, 0x79);
2200 i2c_w1(gspca_dev
, 0x12, 0x40);
2206 if (mode
& MODE_SXGA
) {
2207 i2c_w1(gspca_dev
, 0x17, 0x1b);
2208 i2c_w1(gspca_dev
, 0x18, 0xbc);
2209 i2c_w1(gspca_dev
, 0x19, 0x01);
2210 i2c_w1(gspca_dev
, 0x1a, 0x82);
2211 i2c_r1(gspca_dev
, 0x12, &value
);
2212 i2c_w1(gspca_dev
, 0x12, value
& 0x07);
2214 i2c_w1(gspca_dev
, 0x17, 0x24);
2215 i2c_w1(gspca_dev
, 0x18, 0xc5);
2216 i2c_w1(gspca_dev
, 0x19, 0x00);
2217 i2c_w1(gspca_dev
, 0x1a, 0x3c);
2218 i2c_r1(gspca_dev
, 0x12, &value
);
2219 i2c_w1(gspca_dev
, 0x12, (value
& 0x7) | 0x40);
2222 case SENSOR_MT9M112
:
2223 case SENSOR_MT9M111
:
2224 if (mode
& MODE_SXGA
) {
2225 i2c_w2(gspca_dev
, 0xf0, 0x0002);
2226 i2c_w2(gspca_dev
, 0xc8, 0x970b);
2227 i2c_w2(gspca_dev
, 0xf0, 0x0000);
2229 i2c_w2(gspca_dev
, 0xf0, 0x0002);
2230 i2c_w2(gspca_dev
, 0xc8, 0x8000);
2231 i2c_w2(gspca_dev
, 0xf0, 0x0000);
2237 static int sd_isoc_init(struct gspca_dev
*gspca_dev
)
2239 struct usb_interface
*intf
;
2240 u32 flags
= gspca_dev
->cam
.cam_mode
[(int)gspca_dev
->curr_mode
].priv
;
2243 * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth
2244 * than our regular bandwidth calculations reserve, so we force the
2245 * use of a specific altsetting when using the SN9C20X_I420 fmt.
2247 if (!(flags
& (MODE_RAW
| MODE_JPEG
))) {
2248 intf
= usb_ifnum_to_if(gspca_dev
->dev
, gspca_dev
->iface
);
2250 if (intf
->num_altsetting
!= 9) {
2251 pr_warn("sn9c20x camera with unknown number of alt "
2252 "settings (%d), please report!\n",
2253 intf
->num_altsetting
);
2254 gspca_dev
->alt
= intf
->num_altsetting
;
2258 switch (gspca_dev
->width
) {
2259 case 160: /* 160x120 */
2262 case 320: /* 320x240 */
2265 default: /* >= 640x480 */
2273 #define HW_WIN(mode, hstart, vstart) \
2274 ((const u8 []){hstart, 0, vstart, 0, \
2275 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
2276 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
2278 #define CLR_WIN(width, height) \
2280 {0, width >> 2, 0, height >> 1,\
2281 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
2283 static int sd_start(struct gspca_dev
*gspca_dev
)
2285 struct sd
*sd
= (struct sd
*) gspca_dev
;
2286 int mode
= gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
;
2287 int width
= gspca_dev
->width
;
2288 int height
= gspca_dev
->height
;
2291 jpeg_define(sd
->jpeg_hdr
, height
, width
,
2293 jpeg_set_qual(sd
->jpeg_hdr
, sd
->quality
);
2295 if (mode
& MODE_RAW
)
2297 else if (mode
& MODE_JPEG
)
2300 fmt
= 0x2f; /* YUV 420 */
2302 switch (mode
& SCALE_MASK
) {
2303 case SCALE_1280x1024
:
2305 pr_info("Set 1280x1024\n");
2309 pr_info("Set 640x480\n");
2313 pr_info("Set 320x240\n");
2317 pr_info("Set 160x120\n");
2321 configure_sensor_output(gspca_dev
, mode
);
2322 reg_w(gspca_dev
, 0x1100, &sd
->jpeg_hdr
[JPEG_QT0_OFFSET
], 64);
2323 reg_w(gspca_dev
, 0x1140, &sd
->jpeg_hdr
[JPEG_QT1_OFFSET
], 64);
2324 reg_w(gspca_dev
, 0x10fb, CLR_WIN(width
, height
), 5);
2325 reg_w(gspca_dev
, 0x1180, HW_WIN(mode
, sd
->hstart
, sd
->vstart
), 6);
2326 reg_w1(gspca_dev
, 0x1189, scale
);
2327 reg_w1(gspca_dev
, 0x10e0, fmt
);
2329 set_cmatrix(gspca_dev
);
2330 set_gamma(gspca_dev
);
2331 set_redblue(gspca_dev
);
2332 set_gain(gspca_dev
);
2333 set_exposure(gspca_dev
);
2334 set_hvflip(gspca_dev
);
2336 reg_w1(gspca_dev
, 0x1007, 0x20);
2338 reg_r(gspca_dev
, 0x1061, 1);
2339 reg_w1(gspca_dev
, 0x1061, gspca_dev
->usb_buf
[0] | 0x02);
2343 static void sd_stopN(struct gspca_dev
*gspca_dev
)
2345 reg_w1(gspca_dev
, 0x1007, 0x00);
2347 reg_r(gspca_dev
, 0x1061, 1);
2348 reg_w1(gspca_dev
, 0x1061, gspca_dev
->usb_buf
[0] & ~0x02);
2351 static void do_autoexposure(struct gspca_dev
*gspca_dev
, u16 avg_lum
)
2353 struct sd
*sd
= (struct sd
*) gspca_dev
;
2357 * some hardcoded values are present
2358 * like those for maximal/minimal exposure
2359 * and exposure steps
2361 if (avg_lum
< MIN_AVG_LUM
) {
2362 if (sd
->exposure
> 0x1770)
2365 new_exp
= sd
->exposure
+ sd
->exposure_step
;
2366 if (new_exp
> 0x1770)
2370 sd
->exposure
= new_exp
;
2371 set_exposure(gspca_dev
);
2373 sd
->older_step
= sd
->old_step
;
2376 if (sd
->old_step
^ sd
->older_step
)
2377 sd
->exposure_step
/= 2;
2379 sd
->exposure_step
+= 2;
2381 if (avg_lum
> MAX_AVG_LUM
) {
2382 if (sd
->exposure
< 0x10)
2384 new_exp
= sd
->exposure
- sd
->exposure_step
;
2385 if (new_exp
> 0x1700)
2389 sd
->exposure
= new_exp
;
2390 set_exposure(gspca_dev
);
2391 sd
->older_step
= sd
->old_step
;
2394 if (sd
->old_step
^ sd
->older_step
)
2395 sd
->exposure_step
/= 2;
2397 sd
->exposure_step
+= 2;
2401 static void do_autogain(struct gspca_dev
*gspca_dev
, u16 avg_lum
)
2403 struct sd
*sd
= (struct sd
*) gspca_dev
;
2405 if (avg_lum
< MIN_AVG_LUM
) {
2406 if (sd
->gain
+ 1 <= 28) {
2408 set_gain(gspca_dev
);
2411 if (avg_lum
> MAX_AVG_LUM
) {
2414 set_gain(gspca_dev
);
2419 static void sd_dqcallback(struct gspca_dev
*gspca_dev
)
2421 struct sd
*sd
= (struct sd
*) gspca_dev
;
2424 if (!sd
->auto_exposure
)
2427 avg_lum
= atomic_read(&sd
->avg_lum
);
2428 if (sd
->sensor
== SENSOR_SOI968
)
2429 do_autogain(gspca_dev
, avg_lum
);
2431 do_autoexposure(gspca_dev
, avg_lum
);
2434 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2435 static int sd_int_pkt_scan(struct gspca_dev
*gspca_dev
,
2436 u8
*data
, /* interrupt packet */
2437 int len
) /* interrupt packet length */
2439 struct sd
*sd
= (struct sd
*) gspca_dev
;
2441 if (!(sd
->flags
& HAS_NO_BUTTON
) && len
== 1) {
2442 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 1);
2443 input_sync(gspca_dev
->input_dev
);
2444 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 0);
2445 input_sync(gspca_dev
->input_dev
);
2452 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
2453 u8
*data
, /* isoc packet */
2454 int len
) /* iso packet length */
2456 struct sd
*sd
= (struct sd
*) gspca_dev
;
2458 static u8 frame_header
[] =
2459 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2460 if (len
== 64 && memcmp(data
, frame_header
, 6) == 0) {
2461 avg_lum
= ((data
[35] >> 2) & 3) |
2464 avg_lum
+= ((data
[35] >> 4) & 3) |
2467 avg_lum
+= ((data
[35] >> 6) & 3) |
2470 avg_lum
+= (data
[36] & 3) |
2473 avg_lum
+= ((data
[36] >> 2) & 3) |
2476 avg_lum
+= ((data
[36] >> 4) & 3) |
2479 avg_lum
+= ((data
[36] >> 6) & 3) |
2482 avg_lum
+= ((data
[44] >> 4) & 3) |
2486 atomic_set(&sd
->avg_lum
, avg_lum
);
2487 gspca_frame_add(gspca_dev
, LAST_PACKET
, NULL
, 0);
2490 if (gspca_dev
->last_packet_type
== LAST_PACKET
) {
2491 if (gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
2493 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
2494 sd
->jpeg_hdr
, JPEG_HDR_SZ
);
2495 gspca_frame_add(gspca_dev
, INTER_PACKET
,
2498 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
2502 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, len
);
2506 /* sub-driver description */
2507 static const struct sd_desc sd_desc
= {
2508 .name
= MODULE_NAME
,
2510 .nctrls
= ARRAY_SIZE(sd_ctrls
),
2511 .config
= sd_config
,
2513 .isoc_init
= sd_isoc_init
,
2516 .pkt_scan
= sd_pkt_scan
,
2517 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2518 .int_pkt_scan
= sd_int_pkt_scan
,
2520 .dq_callback
= sd_dqcallback
,
2521 #ifdef CONFIG_VIDEO_ADV_DEBUG
2522 .set_register
= sd_dbg_s_register
,
2523 .get_register
= sd_dbg_g_register
,
2525 .get_chip_ident
= sd_chip_ident
,
2528 #define SN9C20X(sensor, i2c_addr, flags) \
2529 .driver_info = ((flags & 0xff) << 16) \
2530 | (SENSOR_ ## sensor << 8) \
2533 static const struct usb_device_id device_table
[] = {
2534 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001
, 0x5d, 0)},
2535 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111
, 0x5d, 0)},
2536 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655
, 0x30, 0)},
2537 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112
, 0x5d, 0)},
2538 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968
, 0x30, LED_REVERSE
)},
2539 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650
, 0x30,
2540 (FLIP_DETECT
| HAS_NO_BUTTON
))},
2541 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650
, 0x30, 0)},
2542 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650
, 0x30, 0)},
2543 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670
, 0x21, 0)},
2544 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB
, 0x00, 0)},
2545 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660
, 0x21, FLIP_DETECT
)},
2546 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R
, 0x11, 0)},
2547 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650
, 0x30, 0)},
2548 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001
, 0x5d, 0)},
2549 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111
, 0x5d, 0)},
2550 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655
, 0x30, 0)},
2551 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112
, 0x5d, 0)},
2552 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968
, 0x30, 0)},
2553 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650
, 0x30, 0)},
2554 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670
, 0x21, 0)},
2555 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB
, 0x00, 0)},
2556 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655
, 0x30, LED_REVERSE
)},
2557 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660
, 0x21, LED_REVERSE
)},
2558 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R
, 0x11, 0)},
2559 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650
, 0x30, 0)},
2560 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660
, 0x21, 0)},
2561 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R
, 0x11, 0)},
2562 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112
, 0x5d, 0)},
2563 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112
, 0x5d, 0)},
2564 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R
, 0x11, 0)},
2565 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R
, 0x11, 0)},
2566 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R
, 0x11, 0)},
2567 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R
, 0x11, 0)},
2568 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111
, 0x5d, 0)},
2569 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111
, 0x5d, 0)},
2570 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111
, 0x5d, 0)},
2573 MODULE_DEVICE_TABLE(usb
, device_table
);
2575 /* -- device connect -- */
2576 static int sd_probe(struct usb_interface
*intf
,
2577 const struct usb_device_id
*id
)
2579 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
2583 static struct usb_driver sd_driver
= {
2584 .name
= MODULE_NAME
,
2585 .id_table
= device_table
,
2587 .disconnect
= gspca_disconnect
,
2589 .suspend
= gspca_suspend
,
2590 .resume
= gspca_resume
,
2591 .reset_resume
= gspca_resume
,
2595 module_usb_driver(sd_driver
);