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 #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
22 #include <linux/kthread.h>
23 #include <linux/freezer.h>
24 #include <linux/usb/input.h>
25 #include <linux/input.h>
31 #include <media/v4l2-chip-ident.h>
33 MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, "
34 "microdia project <microdia@googlegroups.com>");
35 MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
36 MODULE_LICENSE("GPL");
38 #define MODULE_NAME "sn9c20x"
41 #define MODE_JPEG 0x20
42 #define MODE_SXGA 0x80
44 #define SENSOR_OV9650 0
45 #define SENSOR_OV9655 1
46 #define SENSOR_SOI968 2
47 #define SENSOR_OV7660 3
48 #define SENSOR_OV7670 4
49 #define SENSOR_MT9V011 5
50 #define SENSOR_MT9V111 6
51 #define SENSOR_MT9V112 7
52 #define SENSOR_MT9M001 8
53 #define SENSOR_MT9M111 9
54 #define SENSOR_HV7131R 10
55 #define SENSOR_MT9VPRB 20
57 /* specific webcam descriptor */
59 struct gspca_dev gspca_dev
;
61 #define MIN_AVG_LUM 80
62 #define MAX_AVG_LUM 130
90 #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
91 struct input_dev
*input_dev
;
93 struct task_struct
*input_task
;
107 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, s32 val
);
108 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, s32
*val
);
109 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, s32 val
);
110 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, s32
*val
);
111 static int sd_setsaturation(struct gspca_dev
*gspca_dev
, s32 val
);
112 static int sd_getsaturation(struct gspca_dev
*gspca_dev
, s32
*val
);
113 static int sd_sethue(struct gspca_dev
*gspca_dev
, s32 val
);
114 static int sd_gethue(struct gspca_dev
*gspca_dev
, s32
*val
);
115 static int sd_setgamma(struct gspca_dev
*gspca_dev
, s32 val
);
116 static int sd_getgamma(struct gspca_dev
*gspca_dev
, s32
*val
);
117 static int sd_setredbalance(struct gspca_dev
*gspca_dev
, s32 val
);
118 static int sd_getredbalance(struct gspca_dev
*gspca_dev
, s32
*val
);
119 static int sd_setbluebalance(struct gspca_dev
*gspca_dev
, s32 val
);
120 static int sd_getbluebalance(struct gspca_dev
*gspca_dev
, s32
*val
);
121 static int sd_setvflip(struct gspca_dev
*gspca_dev
, s32 val
);
122 static int sd_getvflip(struct gspca_dev
*gspca_dev
, s32
*val
);
123 static int sd_sethflip(struct gspca_dev
*gspca_dev
, s32 val
);
124 static int sd_gethflip(struct gspca_dev
*gspca_dev
, s32
*val
);
125 static int sd_setgain(struct gspca_dev
*gspca_dev
, s32 val
);
126 static int sd_getgain(struct gspca_dev
*gspca_dev
, s32
*val
);
127 static int sd_setexposure(struct gspca_dev
*gspca_dev
, s32 val
);
128 static int sd_getexposure(struct gspca_dev
*gspca_dev
, s32
*val
);
129 static int sd_setautoexposure(struct gspca_dev
*gspca_dev
, s32 val
);
130 static int sd_getautoexposure(struct gspca_dev
*gspca_dev
, s32
*val
);
132 static struct ctrl sd_ctrls
[] = {
134 #define BRIGHTNESS_IDX 0
136 .id
= V4L2_CID_BRIGHTNESS
,
137 .type
= V4L2_CTRL_TYPE_INTEGER
,
138 .name
= "Brightness",
142 #define BRIGHTNESS_DEFAULT 0x7f
143 .default_value
= BRIGHTNESS_DEFAULT
,
145 .set
= sd_setbrightness
,
146 .get
= sd_getbrightness
,
149 #define CONTRAST_IDX 1
151 .id
= V4L2_CID_CONTRAST
,
152 .type
= V4L2_CTRL_TYPE_INTEGER
,
157 #define CONTRAST_DEFAULT 0x7f
158 .default_value
= CONTRAST_DEFAULT
,
160 .set
= sd_setcontrast
,
161 .get
= sd_getcontrast
,
164 #define SATURATION_IDX 2
166 .id
= V4L2_CID_SATURATION
,
167 .type
= V4L2_CTRL_TYPE_INTEGER
,
168 .name
= "Saturation",
172 #define SATURATION_DEFAULT 0x7f
173 .default_value
= SATURATION_DEFAULT
,
175 .set
= sd_setsaturation
,
176 .get
= sd_getsaturation
,
182 .type
= V4L2_CTRL_TYPE_INTEGER
,
187 #define HUE_DEFAULT 0
188 .default_value
= HUE_DEFAULT
,
196 .id
= V4L2_CID_GAMMA
,
197 .type
= V4L2_CTRL_TYPE_INTEGER
,
202 #define GAMMA_DEFAULT 0x10
203 .default_value
= GAMMA_DEFAULT
,
211 .id
= V4L2_CID_BLUE_BALANCE
,
212 .type
= V4L2_CTRL_TYPE_INTEGER
,
213 .name
= "Blue Balance",
217 #define BLUE_DEFAULT 0x28
218 .default_value
= BLUE_DEFAULT
,
220 .set
= sd_setbluebalance
,
221 .get
= sd_getbluebalance
,
226 .id
= V4L2_CID_RED_BALANCE
,
227 .type
= V4L2_CTRL_TYPE_INTEGER
,
228 .name
= "Red Balance",
232 #define RED_DEFAULT 0x28
233 .default_value
= RED_DEFAULT
,
235 .set
= sd_setredbalance
,
236 .get
= sd_getredbalance
,
241 .id
= V4L2_CID_HFLIP
,
242 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
243 .name
= "Horizontal Flip",
247 #define HFLIP_DEFAULT 0
248 .default_value
= HFLIP_DEFAULT
,
256 .id
= V4L2_CID_VFLIP
,
257 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
258 .name
= "Vertical Flip",
262 #define VFLIP_DEFAULT 0
263 .default_value
= VFLIP_DEFAULT
,
269 #define EXPOSURE_IDX 9
271 .id
= V4L2_CID_EXPOSURE
,
272 .type
= V4L2_CTRL_TYPE_INTEGER
,
277 #define EXPOSURE_DEFAULT 0x33
278 .default_value
= EXPOSURE_DEFAULT
,
280 .set
= sd_setexposure
,
281 .get
= sd_getexposure
,
287 .type
= V4L2_CTRL_TYPE_INTEGER
,
292 #define GAIN_DEFAULT 0x00
293 .default_value
= GAIN_DEFAULT
,
299 #define AUTOGAIN_IDX 11
301 .id
= V4L2_CID_AUTOGAIN
,
302 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
303 .name
= "Auto Exposure",
307 #define AUTO_EXPOSURE_DEFAULT 1
308 .default_value
= AUTO_EXPOSURE_DEFAULT
,
310 .set
= sd_setautoexposure
,
311 .get
= sd_getautoexposure
,
315 static const struct v4l2_pix_format vga_mode
[] = {
316 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
318 .sizeimage
= 240 * 120,
319 .colorspace
= V4L2_COLORSPACE_JPEG
,
320 .priv
= 0 | MODE_JPEG
},
321 {160, 120, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
323 .sizeimage
= 160 * 120,
324 .colorspace
= V4L2_COLORSPACE_SRGB
,
325 .priv
= 0 | MODE_RAW
},
326 {160, 120, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
328 .sizeimage
= 240 * 120,
329 .colorspace
= V4L2_COLORSPACE_SRGB
,
331 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
333 .sizeimage
= 480 * 240 ,
334 .colorspace
= V4L2_COLORSPACE_JPEG
,
335 .priv
= 1 | MODE_JPEG
},
336 {320, 240, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
338 .sizeimage
= 320 * 240 ,
339 .colorspace
= V4L2_COLORSPACE_SRGB
,
340 .priv
= 1 | MODE_RAW
},
341 {320, 240, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
343 .sizeimage
= 480 * 240 ,
344 .colorspace
= V4L2_COLORSPACE_SRGB
,
346 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
348 .sizeimage
= 960 * 480,
349 .colorspace
= V4L2_COLORSPACE_JPEG
,
350 .priv
= 2 | MODE_JPEG
},
351 {640, 480, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
353 .sizeimage
= 640 * 480,
354 .colorspace
= V4L2_COLORSPACE_SRGB
,
355 .priv
= 2 | MODE_RAW
},
356 {640, 480, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
358 .sizeimage
= 960 * 480,
359 .colorspace
= V4L2_COLORSPACE_SRGB
,
363 static const struct v4l2_pix_format sxga_mode
[] = {
364 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
366 .sizeimage
= 240 * 120,
367 .colorspace
= V4L2_COLORSPACE_JPEG
,
368 .priv
= 0 | MODE_JPEG
},
369 {160, 120, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
371 .sizeimage
= 160 * 120,
372 .colorspace
= V4L2_COLORSPACE_SRGB
,
373 .priv
= 0 | MODE_RAW
},
374 {160, 120, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
376 .sizeimage
= 240 * 120,
377 .colorspace
= V4L2_COLORSPACE_SRGB
,
379 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
381 .sizeimage
= 480 * 240 ,
382 .colorspace
= V4L2_COLORSPACE_JPEG
,
383 .priv
= 1 | MODE_JPEG
},
384 {320, 240, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
386 .sizeimage
= 320 * 240 ,
387 .colorspace
= V4L2_COLORSPACE_SRGB
,
388 .priv
= 1 | MODE_RAW
},
389 {320, 240, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
391 .sizeimage
= 480 * 240 ,
392 .colorspace
= V4L2_COLORSPACE_SRGB
,
394 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
396 .sizeimage
= 960 * 480,
397 .colorspace
= V4L2_COLORSPACE_JPEG
,
398 .priv
= 2 | MODE_JPEG
},
399 {640, 480, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
401 .sizeimage
= 640 * 480,
402 .colorspace
= V4L2_COLORSPACE_SRGB
,
403 .priv
= 2 | MODE_RAW
},
404 {640, 480, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
406 .sizeimage
= 960 * 480,
407 .colorspace
= V4L2_COLORSPACE_SRGB
,
409 {1280, 1024, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
410 .bytesperline
= 1280,
411 .sizeimage
= (1280 * 1024) + 64,
412 .colorspace
= V4L2_COLORSPACE_SRGB
,
413 .priv
= 3 | MODE_RAW
| MODE_SXGA
},
416 static const s16 hsv_red_x
[] = {
417 41, 44, 46, 48, 50, 52, 54, 56,
418 58, 60, 62, 64, 66, 68, 70, 72,
419 74, 76, 78, 80, 81, 83, 85, 87,
420 88, 90, 92, 93, 95, 97, 98, 100,
421 101, 102, 104, 105, 107, 108, 109, 110,
422 112, 113, 114, 115, 116, 117, 118, 119,
423 120, 121, 122, 123, 123, 124, 125, 125,
424 126, 127, 127, 128, 128, 129, 129, 129,
425 130, 130, 130, 130, 131, 131, 131, 131,
426 131, 131, 131, 131, 130, 130, 130, 130,
427 129, 129, 129, 128, 128, 127, 127, 126,
428 125, 125, 124, 123, 122, 122, 121, 120,
429 119, 118, 117, 116, 115, 114, 112, 111,
430 110, 109, 107, 106, 105, 103, 102, 101,
431 99, 98, 96, 94, 93, 91, 90, 88,
432 86, 84, 83, 81, 79, 77, 75, 74,
433 72, 70, 68, 66, 64, 62, 60, 58,
434 56, 54, 52, 49, 47, 45, 43, 41,
435 39, 36, 34, 32, 30, 28, 25, 23,
436 21, 19, 16, 14, 12, 9, 7, 5,
437 3, 0, -1, -3, -6, -8, -10, -12,
438 -15, -17, -19, -22, -24, -26, -28, -30,
439 -33, -35, -37, -39, -41, -44, -46, -48,
440 -50, -52, -54, -56, -58, -60, -62, -64,
441 -66, -68, -70, -72, -74, -76, -78, -80,
442 -81, -83, -85, -87, -88, -90, -92, -93,
443 -95, -97, -98, -100, -101, -102, -104, -105,
444 -107, -108, -109, -110, -112, -113, -114, -115,
445 -116, -117, -118, -119, -120, -121, -122, -123,
446 -123, -124, -125, -125, -126, -127, -127, -128,
447 -128, -128, -128, -128, -128, -128, -128, -128,
448 -128, -128, -128, -128, -128, -128, -128, -128,
449 -128, -128, -128, -128, -128, -128, -128, -128,
450 -128, -127, -127, -126, -125, -125, -124, -123,
451 -122, -122, -121, -120, -119, -118, -117, -116,
452 -115, -114, -112, -111, -110, -109, -107, -106,
453 -105, -103, -102, -101, -99, -98, -96, -94,
454 -93, -91, -90, -88, -86, -84, -83, -81,
455 -79, -77, -75, -74, -72, -70, -68, -66,
456 -64, -62, -60, -58, -56, -54, -52, -49,
457 -47, -45, -43, -41, -39, -36, -34, -32,
458 -30, -28, -25, -23, -21, -19, -16, -14,
459 -12, -9, -7, -5, -3, 0, 1, 3,
460 6, 8, 10, 12, 15, 17, 19, 22,
461 24, 26, 28, 30, 33, 35, 37, 39, 41
464 static const s16 hsv_red_y
[] = {
465 82, 80, 78, 76, 74, 73, 71, 69,
466 67, 65, 63, 61, 58, 56, 54, 52,
467 50, 48, 46, 44, 41, 39, 37, 35,
468 32, 30, 28, 26, 23, 21, 19, 16,
469 14, 12, 10, 7, 5, 3, 0, -1,
470 -3, -6, -8, -10, -13, -15, -17, -19,
471 -22, -24, -26, -29, -31, -33, -35, -38,
472 -40, -42, -44, -46, -48, -51, -53, -55,
473 -57, -59, -61, -63, -65, -67, -69, -71,
474 -73, -75, -77, -79, -81, -82, -84, -86,
475 -88, -89, -91, -93, -94, -96, -98, -99,
476 -101, -102, -104, -105, -106, -108, -109, -110,
477 -112, -113, -114, -115, -116, -117, -119, -120,
478 -120, -121, -122, -123, -124, -125, -126, -126,
479 -127, -128, -128, -128, -128, -128, -128, -128,
480 -128, -128, -128, -128, -128, -128, -128, -128,
481 -128, -128, -128, -128, -128, -128, -128, -128,
482 -128, -128, -128, -128, -128, -128, -128, -128,
483 -127, -127, -126, -125, -125, -124, -123, -122,
484 -121, -120, -119, -118, -117, -116, -115, -114,
485 -113, -111, -110, -109, -107, -106, -105, -103,
486 -102, -100, -99, -97, -96, -94, -92, -91,
487 -89, -87, -85, -84, -82, -80, -78, -76,
488 -74, -73, -71, -69, -67, -65, -63, -61,
489 -58, -56, -54, -52, -50, -48, -46, -44,
490 -41, -39, -37, -35, -32, -30, -28, -26,
491 -23, -21, -19, -16, -14, -12, -10, -7,
492 -5, -3, 0, 1, 3, 6, 8, 10,
493 13, 15, 17, 19, 22, 24, 26, 29,
494 31, 33, 35, 38, 40, 42, 44, 46,
495 48, 51, 53, 55, 57, 59, 61, 63,
496 65, 67, 69, 71, 73, 75, 77, 79,
497 81, 82, 84, 86, 88, 89, 91, 93,
498 94, 96, 98, 99, 101, 102, 104, 105,
499 106, 108, 109, 110, 112, 113, 114, 115,
500 116, 117, 119, 120, 120, 121, 122, 123,
501 124, 125, 126, 126, 127, 128, 128, 129,
502 129, 130, 130, 131, 131, 131, 131, 132,
503 132, 132, 132, 132, 132, 132, 132, 132,
504 132, 132, 132, 131, 131, 131, 130, 130,
505 130, 129, 129, 128, 127, 127, 126, 125,
506 125, 124, 123, 122, 121, 120, 119, 118,
507 117, 116, 115, 114, 113, 111, 110, 109,
508 107, 106, 105, 103, 102, 100, 99, 97,
509 96, 94, 92, 91, 89, 87, 85, 84, 82
512 static const s16 hsv_green_x
[] = {
513 -124, -124, -125, -125, -125, -125, -125, -125,
514 -125, -126, -126, -125, -125, -125, -125, -125,
515 -125, -124, -124, -124, -123, -123, -122, -122,
516 -121, -121, -120, -120, -119, -118, -117, -117,
517 -116, -115, -114, -113, -112, -111, -110, -109,
518 -108, -107, -105, -104, -103, -102, -100, -99,
519 -98, -96, -95, -93, -92, -91, -89, -87,
520 -86, -84, -83, -81, -79, -77, -76, -74,
521 -72, -70, -69, -67, -65, -63, -61, -59,
522 -57, -55, -53, -51, -49, -47, -45, -43,
523 -41, -39, -37, -35, -33, -30, -28, -26,
524 -24, -22, -20, -18, -15, -13, -11, -9,
525 -7, -4, -2, 0, 1, 3, 6, 8,
526 10, 12, 14, 17, 19, 21, 23, 25,
527 27, 29, 32, 34, 36, 38, 40, 42,
528 44, 46, 48, 50, 52, 54, 56, 58,
529 60, 62, 64, 66, 68, 70, 71, 73,
530 75, 77, 78, 80, 82, 83, 85, 87,
531 88, 90, 91, 93, 94, 96, 97, 98,
532 100, 101, 102, 104, 105, 106, 107, 108,
533 109, 111, 112, 113, 113, 114, 115, 116,
534 117, 118, 118, 119, 120, 120, 121, 122,
535 122, 123, 123, 124, 124, 124, 125, 125,
536 125, 125, 125, 125, 125, 126, 126, 125,
537 125, 125, 125, 125, 125, 124, 124, 124,
538 123, 123, 122, 122, 121, 121, 120, 120,
539 119, 118, 117, 117, 116, 115, 114, 113,
540 112, 111, 110, 109, 108, 107, 105, 104,
541 103, 102, 100, 99, 98, 96, 95, 93,
542 92, 91, 89, 87, 86, 84, 83, 81,
543 79, 77, 76, 74, 72, 70, 69, 67,
544 65, 63, 61, 59, 57, 55, 53, 51,
545 49, 47, 45, 43, 41, 39, 37, 35,
546 33, 30, 28, 26, 24, 22, 20, 18,
547 15, 13, 11, 9, 7, 4, 2, 0,
548 -1, -3, -6, -8, -10, -12, -14, -17,
549 -19, -21, -23, -25, -27, -29, -32, -34,
550 -36, -38, -40, -42, -44, -46, -48, -50,
551 -52, -54, -56, -58, -60, -62, -64, -66,
552 -68, -70, -71, -73, -75, -77, -78, -80,
553 -82, -83, -85, -87, -88, -90, -91, -93,
554 -94, -96, -97, -98, -100, -101, -102, -104,
555 -105, -106, -107, -108, -109, -111, -112, -113,
556 -113, -114, -115, -116, -117, -118, -118, -119,
557 -120, -120, -121, -122, -122, -123, -123, -124, -124
560 static const s16 hsv_green_y
[] = {
561 -100, -99, -98, -97, -95, -94, -93, -91,
562 -90, -89, -87, -86, -84, -83, -81, -80,
563 -78, -76, -75, -73, -71, -70, -68, -66,
564 -64, -63, -61, -59, -57, -55, -53, -51,
565 -49, -48, -46, -44, -42, -40, -38, -36,
566 -34, -32, -30, -27, -25, -23, -21, -19,
567 -17, -15, -13, -11, -9, -7, -4, -2,
568 0, 1, 3, 5, 7, 9, 11, 14,
569 16, 18, 20, 22, 24, 26, 28, 30,
570 32, 34, 36, 38, 40, 42, 44, 46,
571 48, 50, 52, 54, 56, 58, 59, 61,
572 63, 65, 67, 68, 70, 72, 74, 75,
573 77, 78, 80, 82, 83, 85, 86, 88,
574 89, 90, 92, 93, 95, 96, 97, 98,
575 100, 101, 102, 103, 104, 105, 106, 107,
576 108, 109, 110, 111, 112, 112, 113, 114,
577 115, 115, 116, 116, 117, 117, 118, 118,
578 119, 119, 119, 120, 120, 120, 120, 120,
579 121, 121, 121, 121, 121, 121, 120, 120,
580 120, 120, 120, 119, 119, 119, 118, 118,
581 117, 117, 116, 116, 115, 114, 114, 113,
582 112, 111, 111, 110, 109, 108, 107, 106,
583 105, 104, 103, 102, 100, 99, 98, 97,
584 95, 94, 93, 91, 90, 89, 87, 86,
585 84, 83, 81, 80, 78, 76, 75, 73,
586 71, 70, 68, 66, 64, 63, 61, 59,
587 57, 55, 53, 51, 49, 48, 46, 44,
588 42, 40, 38, 36, 34, 32, 30, 27,
589 25, 23, 21, 19, 17, 15, 13, 11,
590 9, 7, 4, 2, 0, -1, -3, -5,
591 -7, -9, -11, -14, -16, -18, -20, -22,
592 -24, -26, -28, -30, -32, -34, -36, -38,
593 -40, -42, -44, -46, -48, -50, -52, -54,
594 -56, -58, -59, -61, -63, -65, -67, -68,
595 -70, -72, -74, -75, -77, -78, -80, -82,
596 -83, -85, -86, -88, -89, -90, -92, -93,
597 -95, -96, -97, -98, -100, -101, -102, -103,
598 -104, -105, -106, -107, -108, -109, -110, -111,
599 -112, -112, -113, -114, -115, -115, -116, -116,
600 -117, -117, -118, -118, -119, -119, -119, -120,
601 -120, -120, -120, -120, -121, -121, -121, -121,
602 -121, -121, -120, -120, -120, -120, -120, -119,
603 -119, -119, -118, -118, -117, -117, -116, -116,
604 -115, -114, -114, -113, -112, -111, -111, -110,
605 -109, -108, -107, -106, -105, -104, -103, -102, -100
608 static const s16 hsv_blue_x
[] = {
609 112, 113, 114, 114, 115, 116, 117, 117,
610 118, 118, 119, 119, 120, 120, 120, 121,
611 121, 121, 122, 122, 122, 122, 122, 122,
612 122, 122, 122, 122, 122, 122, 121, 121,
613 121, 120, 120, 120, 119, 119, 118, 118,
614 117, 116, 116, 115, 114, 113, 113, 112,
615 111, 110, 109, 108, 107, 106, 105, 104,
616 103, 102, 100, 99, 98, 97, 95, 94,
617 93, 91, 90, 88, 87, 85, 84, 82,
618 80, 79, 77, 76, 74, 72, 70, 69,
619 67, 65, 63, 61, 60, 58, 56, 54,
620 52, 50, 48, 46, 44, 42, 40, 38,
621 36, 34, 32, 30, 28, 26, 24, 22,
622 19, 17, 15, 13, 11, 9, 7, 5,
623 2, 0, -1, -3, -5, -7, -9, -12,
624 -14, -16, -18, -20, -22, -24, -26, -28,
625 -31, -33, -35, -37, -39, -41, -43, -45,
626 -47, -49, -51, -53, -54, -56, -58, -60,
627 -62, -64, -66, -67, -69, -71, -73, -74,
628 -76, -78, -79, -81, -83, -84, -86, -87,
629 -89, -90, -92, -93, -94, -96, -97, -98,
630 -99, -101, -102, -103, -104, -105, -106, -107,
631 -108, -109, -110, -111, -112, -113, -114, -114,
632 -115, -116, -117, -117, -118, -118, -119, -119,
633 -120, -120, -120, -121, -121, -121, -122, -122,
634 -122, -122, -122, -122, -122, -122, -122, -122,
635 -122, -122, -121, -121, -121, -120, -120, -120,
636 -119, -119, -118, -118, -117, -116, -116, -115,
637 -114, -113, -113, -112, -111, -110, -109, -108,
638 -107, -106, -105, -104, -103, -102, -100, -99,
639 -98, -97, -95, -94, -93, -91, -90, -88,
640 -87, -85, -84, -82, -80, -79, -77, -76,
641 -74, -72, -70, -69, -67, -65, -63, -61,
642 -60, -58, -56, -54, -52, -50, -48, -46,
643 -44, -42, -40, -38, -36, -34, -32, -30,
644 -28, -26, -24, -22, -19, -17, -15, -13,
645 -11, -9, -7, -5, -2, 0, 1, 3,
646 5, 7, 9, 12, 14, 16, 18, 20,
647 22, 24, 26, 28, 31, 33, 35, 37,
648 39, 41, 43, 45, 47, 49, 51, 53,
649 54, 56, 58, 60, 62, 64, 66, 67,
650 69, 71, 73, 74, 76, 78, 79, 81,
651 83, 84, 86, 87, 89, 90, 92, 93,
652 94, 96, 97, 98, 99, 101, 102, 103,
653 104, 105, 106, 107, 108, 109, 110, 111, 112
656 static const s16 hsv_blue_y
[] = {
657 -11, -13, -15, -17, -19, -21, -23, -25,
658 -27, -29, -31, -33, -35, -37, -39, -41,
659 -43, -45, -46, -48, -50, -52, -54, -55,
660 -57, -59, -61, -62, -64, -66, -67, -69,
661 -71, -72, -74, -75, -77, -78, -80, -81,
662 -83, -84, -86, -87, -88, -90, -91, -92,
663 -93, -95, -96, -97, -98, -99, -100, -101,
664 -102, -103, -104, -105, -106, -106, -107, -108,
665 -109, -109, -110, -111, -111, -112, -112, -113,
666 -113, -114, -114, -114, -115, -115, -115, -115,
667 -116, -116, -116, -116, -116, -116, -116, -116,
668 -116, -115, -115, -115, -115, -114, -114, -114,
669 -113, -113, -112, -112, -111, -111, -110, -110,
670 -109, -108, -108, -107, -106, -105, -104, -103,
671 -102, -101, -100, -99, -98, -97, -96, -95,
672 -94, -93, -91, -90, -89, -88, -86, -85,
673 -84, -82, -81, -79, -78, -76, -75, -73,
674 -71, -70, -68, -67, -65, -63, -62, -60,
675 -58, -56, -55, -53, -51, -49, -47, -45,
676 -44, -42, -40, -38, -36, -34, -32, -30,
677 -28, -26, -24, -22, -20, -18, -16, -14,
678 -12, -10, -8, -6, -4, -2, 0, 1,
679 3, 5, 7, 9, 11, 13, 15, 17,
680 19, 21, 23, 25, 27, 29, 31, 33,
681 35, 37, 39, 41, 43, 45, 46, 48,
682 50, 52, 54, 55, 57, 59, 61, 62,
683 64, 66, 67, 69, 71, 72, 74, 75,
684 77, 78, 80, 81, 83, 84, 86, 87,
685 88, 90, 91, 92, 93, 95, 96, 97,
686 98, 99, 100, 101, 102, 103, 104, 105,
687 106, 106, 107, 108, 109, 109, 110, 111,
688 111, 112, 112, 113, 113, 114, 114, 114,
689 115, 115, 115, 115, 116, 116, 116, 116,
690 116, 116, 116, 116, 116, 115, 115, 115,
691 115, 114, 114, 114, 113, 113, 112, 112,
692 111, 111, 110, 110, 109, 108, 108, 107,
693 106, 105, 104, 103, 102, 101, 100, 99,
694 98, 97, 96, 95, 94, 93, 91, 90,
695 89, 88, 86, 85, 84, 82, 81, 79,
696 78, 76, 75, 73, 71, 70, 68, 67,
697 65, 63, 62, 60, 58, 56, 55, 53,
698 51, 49, 47, 45, 44, 42, 40, 38,
699 36, 34, 32, 30, 28, 26, 24, 22,
700 20, 18, 16, 14, 12, 10, 8, 6,
701 4, 2, 0, -1, -3, -5, -7, -9, -11
704 static u16 i2c_ident
[] = {
713 V4L2_IDENT_MT9M001C12ST
,
718 static u16 bridge_init
[][2] = {
719 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
720 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
721 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
722 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
723 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
724 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
725 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
726 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
727 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
728 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
729 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
730 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
731 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
732 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
733 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
734 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
735 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
736 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
737 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80}
740 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
741 static u8 ov_gain
[] = {
742 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
743 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
744 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
745 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
746 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
747 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
748 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
752 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
753 static u16 micron1_gain
[] = {
754 /* 1x 1.25x 1.5x 1.75x */
755 0x0020, 0x0028, 0x0030, 0x0038,
756 /* 2x 2.25x 2.5x 2.75x */
757 0x00a0, 0x00a4, 0x00a8, 0x00ac,
758 /* 3x 3.25x 3.5x 3.75x */
759 0x00b0, 0x00b4, 0x00b8, 0x00bc,
760 /* 4x 4.25x 4.5x 4.75x */
761 0x00c0, 0x00c4, 0x00c8, 0x00cc,
762 /* 5x 5.25x 5.5x 5.75x */
763 0x00d0, 0x00d4, 0x00d8, 0x00dc,
764 /* 6x 6.25x 6.5x 6.75x */
765 0x00e0, 0x00e4, 0x00e8, 0x00ec,
766 /* 7x 7.25x 7.5x 7.75x */
767 0x00f0, 0x00f4, 0x00f8, 0x00fc,
772 /* mt9m001 sensor uses a different gain formula then other micron sensors */
773 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
774 static u16 micron2_gain
[] = {
775 /* 1x 1.25x 1.5x 1.75x */
776 0x0008, 0x000a, 0x000c, 0x000e,
777 /* 2x 2.25x 2.5x 2.75x */
778 0x0010, 0x0012, 0x0014, 0x0016,
779 /* 3x 3.25x 3.5x 3.75x */
780 0x0018, 0x001a, 0x001c, 0x001e,
781 /* 4x 4.25x 4.5x 4.75x */
782 0x0020, 0x0051, 0x0052, 0x0053,
783 /* 5x 5.25x 5.5x 5.75x */
784 0x0054, 0x0055, 0x0056, 0x0057,
785 /* 6x 6.25x 6.5x 6.75x */
786 0x0058, 0x0059, 0x005a, 0x005b,
787 /* 7x 7.25x 7.5x 7.75x */
788 0x005c, 0x005d, 0x005e, 0x005f,
793 /* Gain = .5 + bit[7:0] / 16 */
794 static u8 hv7131r_gain
[] = {
795 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
796 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
797 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
798 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
799 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
800 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
801 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
805 static struct i2c_reg_u8 soi968_init
[] = {
806 {0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f},
807 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
808 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
809 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
810 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
811 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
812 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
813 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
814 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
815 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
816 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
819 static struct i2c_reg_u8 ov7660_init
[] = {
820 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
821 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
822 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
823 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
824 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6},
825 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
828 static struct i2c_reg_u8 ov7670_init
[] = {
829 {0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
830 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
831 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
832 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
833 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
834 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
835 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
836 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
837 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
838 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
839 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
840 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
841 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
842 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
843 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
844 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
845 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
846 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
847 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
848 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
849 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
850 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
851 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
852 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
853 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
854 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
855 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
856 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
857 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
858 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
859 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
860 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
861 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
862 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
863 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
864 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
865 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
866 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
867 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
868 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
869 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
870 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
871 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
872 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
873 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
874 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
875 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
876 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
877 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
878 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
879 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
880 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
881 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
885 static struct i2c_reg_u8 ov9650_init
[] = {
886 {0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78},
887 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
888 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
889 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
890 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
891 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
892 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
893 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
894 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
895 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
896 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
897 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
898 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
899 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
900 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
901 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
902 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
903 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
904 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
905 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
906 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
907 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
908 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
909 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
910 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
911 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
912 {0xaa, 0x92}, {0xab, 0x0a},
915 static struct i2c_reg_u8 ov9655_init
[] = {
916 {0x12, 0x80}, {0x12, 0x01}, {0x0d, 0x00}, {0x0e, 0x61},
917 {0x11, 0x80}, {0x13, 0xba}, {0x14, 0x2e}, {0x16, 0x24},
918 {0x1e, 0x04}, {0x1e, 0x04}, {0x1e, 0x04}, {0x27, 0x08},
919 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x32, 0xbf},
920 {0x34, 0x3d}, {0x35, 0x00}, {0x36, 0xf8}, {0x38, 0x12},
921 {0x39, 0x57}, {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c},
922 {0x3d, 0x19}, {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40},
923 {0x42, 0x80}, {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a},
924 {0x48, 0x3c}, {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc},
925 {0x4d, 0xdc}, {0x4e, 0xdc}, {0x69, 0x02}, {0x6c, 0x04},
926 {0x6f, 0x9e}, {0x70, 0x05}, {0x71, 0x78}, {0x77, 0x02},
927 {0x8a, 0x23}, {0x8c, 0x0d}, {0x90, 0x7e}, {0x91, 0x7c},
928 {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68}, {0xa6, 0x60},
929 {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92}, {0xab, 0x04},
930 {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80}, {0xaf, 0x80},
931 {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00}, {0xb6, 0xaf},
932 {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44}, {0xbe, 0x3b},
933 {0xbf, 0x3a}, {0xc0, 0xe2}, {0xc1, 0xc8}, {0xc2, 0x01},
934 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
935 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x12, 0x61},
936 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
937 {0x03, 0x12}, {0x17, 0x14}, {0x18, 0x00}, {0x19, 0x01},
938 {0x1a, 0x3d}, {0x32, 0xbf}, {0x11, 0x80}, {0x2a, 0x10},
939 {0x2b, 0x0a}, {0x92, 0x00}, {0x93, 0x00}, {0x1e, 0x04},
940 {0x1e, 0x04}, {0x10, 0x7c}, {0x04, 0x03}, {0xa1, 0x00},
941 {0x2d, 0x00}, {0x2e, 0x00}, {0x00, 0x00}, {0x01, 0x80},
942 {0x02, 0x80}, {0x12, 0x61}, {0x36, 0xfa}, {0x8c, 0x8d},
943 {0xc0, 0xaa}, {0x69, 0x0a}, {0x03, 0x12}, {0x17, 0x14},
944 {0x18, 0x00}, {0x19, 0x01}, {0x1a, 0x3d}, {0x32, 0xbf},
945 {0x11, 0x80}, {0x2a, 0x10}, {0x2b, 0x0a}, {0x92, 0x00},
946 {0x93, 0x00}, {0x04, 0x01}, {0x10, 0x1f}, {0xa1, 0x00},
947 {0x00, 0x0a}, {0xa1, 0x00}, {0x10, 0x5d}, {0x04, 0x03},
948 {0x00, 0x01}, {0xa1, 0x00}, {0x10, 0x7c}, {0x04, 0x03},
949 {0x00, 0x03}, {0x00, 0x0a}, {0x00, 0x10}, {0x00, 0x13},
952 static struct i2c_reg_u16 mt9v112_init
[] = {
953 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
954 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
955 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
956 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
957 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
958 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
959 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
960 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
961 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
962 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
963 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
964 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
965 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
966 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
967 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
968 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
971 static struct i2c_reg_u16 mt9v111_init
[] = {
972 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
973 {0x01, 0x0001}, {0x02, 0x0016}, {0x03, 0x01e1},
974 {0x04, 0x0281}, {0x05, 0x0004}, {0x07, 0x3002},
975 {0x21, 0x0000}, {0x25, 0x4024}, {0x26, 0xff03},
976 {0x27, 0xff10}, {0x2b, 0x7828}, {0x2c, 0xb43c},
977 {0x2d, 0xf0a0}, {0x2e, 0x0c64}, {0x2f, 0x0064},
978 {0x67, 0x4010}, {0x06, 0x301e}, {0x08, 0x0480},
979 {0x01, 0x0004}, {0x02, 0x0016}, {0x03, 0x01e6},
980 {0x04, 0x0286}, {0x05, 0x0004}, {0x06, 0x0000},
981 {0x07, 0x3002}, {0x08, 0x0008}, {0x0c, 0x0000},
982 {0x0d, 0x0000}, {0x0e, 0x0000}, {0x0f, 0x0000},
983 {0x10, 0x0000}, {0x11, 0x0000}, {0x12, 0x00b0},
984 {0x13, 0x007c}, {0x14, 0x0000}, {0x15, 0x0000},
985 {0x16, 0x0000}, {0x17, 0x0000}, {0x18, 0x0000},
986 {0x19, 0x0000}, {0x1a, 0x0000}, {0x1b, 0x0000},
987 {0x1c, 0x0000}, {0x1d, 0x0000}, {0x30, 0x0000},
988 {0x30, 0x0005}, {0x31, 0x0000}, {0x02, 0x0016},
989 {0x03, 0x01e1}, {0x04, 0x0281}, {0x05, 0x0004},
990 {0x06, 0x0000}, {0x07, 0x3002}, {0x06, 0x002d},
991 {0x05, 0x0004}, {0x09, 0x0064}, {0x2b, 0x00a0},
992 {0x2c, 0x00a0}, {0x2d, 0x00a0}, {0x2e, 0x00a0},
993 {0x02, 0x0016}, {0x03, 0x01e1}, {0x04, 0x0281},
994 {0x05, 0x0004}, {0x06, 0x002d}, {0x07, 0x3002},
995 {0x0e, 0x0008}, {0x06, 0x002d}, {0x05, 0x0004},
998 static struct i2c_reg_u16 mt9v011_init
[] = {
999 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
1000 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
1001 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
1002 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
1003 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
1004 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
1005 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
1006 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
1007 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
1008 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
1009 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
1010 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
1011 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
1012 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
1013 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
1014 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
1015 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
1016 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
1017 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
1018 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
1019 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
1020 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1021 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
1022 {0x06, 0x0029}, {0x05, 0x0009},
1025 static struct i2c_reg_u16 mt9m001_init
[] = {
1026 {0x0d, 0x0001}, {0x0d, 0x0000}, {0x01, 0x000e},
1027 {0x02, 0x0014}, {0x03, 0x03c1}, {0x04, 0x0501},
1028 {0x05, 0x0083}, {0x06, 0x0006}, {0x0d, 0x0002},
1029 {0x0a, 0x0000}, {0x0c, 0x0000}, {0x11, 0x0000},
1030 {0x1e, 0x8000}, {0x5f, 0x8904}, {0x60, 0x0000},
1031 {0x61, 0x0000}, {0x62, 0x0498}, {0x63, 0x0000},
1032 {0x64, 0x0000}, {0x20, 0x111d}, {0x06, 0x00f2},
1033 {0x05, 0x0013}, {0x09, 0x10f2}, {0x07, 0x0003},
1034 {0x2b, 0x002a}, {0x2d, 0x002a}, {0x2c, 0x002a},
1035 {0x2e, 0x0029}, {0x07, 0x0002},
1038 static struct i2c_reg_u16 mt9m111_init
[] = {
1039 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1040 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1041 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1045 static struct i2c_reg_u8 hv7131r_init
[] = {
1046 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
1047 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
1048 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
1049 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
1050 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
1051 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
1052 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
1053 {0x23, 0x09}, {0x01, 0x08},
1056 static int reg_r(struct gspca_dev
*gspca_dev
, u16 reg
, u16 length
)
1058 struct usb_device
*dev
= gspca_dev
->dev
;
1060 result
= usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
1062 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
1068 if (unlikely(result
< 0 || result
!= length
)) {
1069 err("Read register failed 0x%02X", reg
);
1075 static int reg_w(struct gspca_dev
*gspca_dev
, u16 reg
,
1076 const u8
*buffer
, int length
)
1078 struct usb_device
*dev
= gspca_dev
->dev
;
1080 memcpy(gspca_dev
->usb_buf
, buffer
, length
);
1081 result
= usb_control_msg(dev
, usb_sndctrlpipe(dev
, 0),
1083 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
1089 if (unlikely(result
< 0 || result
!= length
)) {
1090 err("Write register failed index 0x%02X", reg
);
1096 static int reg_w1(struct gspca_dev
*gspca_dev
, u16 reg
, const u8 value
)
1098 u8 data
[1] = {value
};
1099 return reg_w(gspca_dev
, reg
, data
, 1);
1102 static int i2c_w(struct gspca_dev
*gspca_dev
, const u8
*buffer
)
1105 reg_w(gspca_dev
, 0x10c0, buffer
, 8);
1106 for (i
= 0; i
< 5; i
++) {
1107 reg_r(gspca_dev
, 0x10c0, 1);
1108 if (gspca_dev
->usb_buf
[0] & 0x04) {
1109 if (gspca_dev
->usb_buf
[0] & 0x08)
1118 static int i2c_w1(struct gspca_dev
*gspca_dev
, u8 reg
, u8 val
)
1120 struct sd
*sd
= (struct sd
*) gspca_dev
;
1125 * from the point of view of the bridge, the length
1126 * includes the address
1128 row
[0] = 0x81 | (2 << 4);
1129 row
[1] = sd
->i2c_addr
;
1137 return i2c_w(gspca_dev
, row
);
1140 static int i2c_w2(struct gspca_dev
*gspca_dev
, u8 reg
, u16 val
)
1142 struct sd
*sd
= (struct sd
*) gspca_dev
;
1146 * from the point of view of the bridge, the length
1147 * includes the address
1149 row
[0] = 0x81 | (3 << 4);
1150 row
[1] = sd
->i2c_addr
;
1152 row
[3] = (val
>> 8) & 0xff;
1153 row
[4] = val
& 0xff;
1158 return i2c_w(gspca_dev
, row
);
1161 int i2c_r1(struct gspca_dev
*gspca_dev
, u8 reg
, u8
*val
)
1163 struct sd
*sd
= (struct sd
*) gspca_dev
;
1166 row
[0] = 0x81 | (1 << 4);
1167 row
[1] = sd
->i2c_addr
;
1174 if (i2c_w(gspca_dev
, row
) < 0)
1176 row
[0] = 0x81 | (1 << 4) | 0x02;
1178 if (i2c_w(gspca_dev
, row
) < 0)
1180 if (reg_r(gspca_dev
, 0x10c2, 5) < 0)
1182 *val
= gspca_dev
->usb_buf
[4];
1186 int i2c_r2(struct gspca_dev
*gspca_dev
, u8 reg
, u16
*val
)
1188 struct sd
*sd
= (struct sd
*) gspca_dev
;
1191 row
[0] = 0x81 | (1 << 4);
1192 row
[1] = sd
->i2c_addr
;
1199 if (i2c_w(gspca_dev
, row
) < 0)
1201 row
[0] = 0x81 | (2 << 4) | 0x02;
1203 if (i2c_w(gspca_dev
, row
) < 0)
1205 if (reg_r(gspca_dev
, 0x10c2, 5) < 0)
1207 *val
= (gspca_dev
->usb_buf
[3] << 8) | gspca_dev
->usb_buf
[4];
1211 static int ov9650_init_sensor(struct gspca_dev
*gspca_dev
)
1214 struct sd
*sd
= (struct sd
*) gspca_dev
;
1216 for (i
= 0; i
< ARRAY_SIZE(ov9650_init
); i
++) {
1217 if (i2c_w1(gspca_dev
, ov9650_init
[i
].reg
,
1218 ov9650_init
[i
].val
) < 0) {
1219 err("OV9650 sensor initialization failed");
1228 static int ov9655_init_sensor(struct gspca_dev
*gspca_dev
)
1231 struct sd
*sd
= (struct sd
*) gspca_dev
;
1233 for (i
= 0; i
< ARRAY_SIZE(ov9655_init
); i
++) {
1234 if (i2c_w1(gspca_dev
, ov9655_init
[i
].reg
,
1235 ov9655_init
[i
].val
) < 0) {
1236 err("OV9655 sensor initialization failed");
1240 /* disable hflip and vflip */
1241 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1247 static int soi968_init_sensor(struct gspca_dev
*gspca_dev
)
1250 struct sd
*sd
= (struct sd
*) gspca_dev
;
1252 for (i
= 0; i
< ARRAY_SIZE(soi968_init
); i
++) {
1253 if (i2c_w1(gspca_dev
, soi968_init
[i
].reg
,
1254 soi968_init
[i
].val
) < 0) {
1255 err("SOI968 sensor initialization failed");
1259 /* disable hflip and vflip */
1260 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
) | (1 << EXPOSURE_IDX
);
1266 static int ov7660_init_sensor(struct gspca_dev
*gspca_dev
)
1269 struct sd
*sd
= (struct sd
*) gspca_dev
;
1271 for (i
= 0; i
< ARRAY_SIZE(ov7660_init
); i
++) {
1272 if (i2c_w1(gspca_dev
, ov7660_init
[i
].reg
,
1273 ov7660_init
[i
].val
) < 0) {
1274 err("OV7660 sensor initialization failed");
1278 /* disable hflip and vflip */
1279 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1285 static int ov7670_init_sensor(struct gspca_dev
*gspca_dev
)
1288 struct sd
*sd
= (struct sd
*) gspca_dev
;
1290 for (i
= 0; i
< ARRAY_SIZE(ov7670_init
); i
++) {
1291 if (i2c_w1(gspca_dev
, ov7670_init
[i
].reg
,
1292 ov7670_init
[i
].val
) < 0) {
1293 err("OV7670 sensor initialization failed");
1297 /* disable hflip and vflip */
1298 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1304 static int mt9v_init_sensor(struct gspca_dev
*gspca_dev
)
1306 struct sd
*sd
= (struct sd
*) gspca_dev
;
1311 sd
->i2c_addr
= 0x5d;
1312 ret
= i2c_r2(gspca_dev
, 0xff, &value
);
1313 if ((ret
== 0) && (value
== 0x8243)) {
1314 for (i
= 0; i
< ARRAY_SIZE(mt9v011_init
); i
++) {
1315 if (i2c_w2(gspca_dev
, mt9v011_init
[i
].reg
,
1316 mt9v011_init
[i
].val
) < 0) {
1317 err("MT9V011 sensor initialization failed");
1323 sd
->sensor
= SENSOR_MT9V011
;
1324 info("MT9V011 sensor detected");
1328 sd
->i2c_addr
= 0x5c;
1329 i2c_w2(gspca_dev
, 0x01, 0x0004);
1330 ret
= i2c_r2(gspca_dev
, 0xff, &value
);
1331 if ((ret
== 0) && (value
== 0x823a)) {
1332 for (i
= 0; i
< ARRAY_SIZE(mt9v111_init
); i
++) {
1333 if (i2c_w2(gspca_dev
, mt9v111_init
[i
].reg
,
1334 mt9v111_init
[i
].val
) < 0) {
1335 err("MT9V111 sensor initialization failed");
1341 sd
->sensor
= SENSOR_MT9V111
;
1342 info("MT9V111 sensor detected");
1346 sd
->i2c_addr
= 0x5d;
1347 ret
= i2c_w2(gspca_dev
, 0xf0, 0x0000);
1349 sd
->i2c_addr
= 0x48;
1350 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1352 ret
= i2c_r2(gspca_dev
, 0x00, &value
);
1353 if ((ret
== 0) && (value
== 0x1229)) {
1354 for (i
= 0; i
< ARRAY_SIZE(mt9v112_init
); i
++) {
1355 if (i2c_w2(gspca_dev
, mt9v112_init
[i
].reg
,
1356 mt9v112_init
[i
].val
) < 0) {
1357 err("MT9V112 sensor initialization failed");
1363 sd
->sensor
= SENSOR_MT9V112
;
1364 info("MT9V112 sensor detected");
1371 static int mt9m111_init_sensor(struct gspca_dev
*gspca_dev
)
1373 struct sd
*sd
= (struct sd
*) gspca_dev
;
1375 for (i
= 0; i
< ARRAY_SIZE(mt9m111_init
); i
++) {
1376 if (i2c_w2(gspca_dev
, mt9m111_init
[i
].reg
,
1377 mt9m111_init
[i
].val
) < 0) {
1378 err("MT9M111 sensor initialization failed");
1382 gspca_dev
->ctrl_dis
= (1 << EXPOSURE_IDX
) | (1 << AUTOGAIN_IDX
) | (1 << GAIN_IDX
);
1388 static int mt9m001_init_sensor(struct gspca_dev
*gspca_dev
)
1390 struct sd
*sd
= (struct sd
*) gspca_dev
;
1392 for (i
= 0; i
< ARRAY_SIZE(mt9m001_init
); i
++) {
1393 if (i2c_w2(gspca_dev
, mt9m001_init
[i
].reg
,
1394 mt9m001_init
[i
].val
) < 0) {
1395 err("MT9M001 sensor initialization failed");
1399 /* disable hflip and vflip */
1400 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1406 static int hv7131r_init_sensor(struct gspca_dev
*gspca_dev
)
1409 struct sd
*sd
= (struct sd
*) gspca_dev
;
1411 for (i
= 0; i
< ARRAY_SIZE(hv7131r_init
); i
++) {
1412 if (i2c_w1(gspca_dev
, hv7131r_init
[i
].reg
,
1413 hv7131r_init
[i
].val
) < 0) {
1414 err("HV7131R Sensor initialization failed");
1423 #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
1424 static int input_kthread(void *data
)
1426 struct gspca_dev
*gspca_dev
= (struct gspca_dev
*)data
;
1427 struct sd
*sd
= (struct sd
*) gspca_dev
;
1429 DECLARE_WAIT_QUEUE_HEAD(wait
);
1432 if (kthread_should_stop())
1435 if (reg_r(gspca_dev
, 0x1005, 1) < 0)
1438 input_report_key(sd
->input_dev
,
1440 gspca_dev
->usb_buf
[0] & sd
->input_gpio
);
1441 input_sync(sd
->input_dev
);
1443 wait_event_freezable_timeout(wait
,
1444 kthread_should_stop(),
1445 msecs_to_jiffies(100));
1451 static int sn9c20x_input_init(struct gspca_dev
*gspca_dev
)
1453 struct sd
*sd
= (struct sd
*) gspca_dev
;
1454 if (sd
->input_gpio
== 0)
1457 sd
->input_dev
= input_allocate_device();
1461 sd
->input_dev
->name
= "SN9C20X Webcam";
1463 sd
->input_dev
->phys
= kasprintf(GFP_KERNEL
, "usb-%s-%s",
1464 gspca_dev
->dev
->bus
->bus_name
,
1465 gspca_dev
->dev
->devpath
);
1467 if (!sd
->input_dev
->phys
)
1470 usb_to_input_id(gspca_dev
->dev
, &sd
->input_dev
->id
);
1471 sd
->input_dev
->dev
.parent
= &gspca_dev
->dev
->dev
;
1473 set_bit(EV_KEY
, sd
->input_dev
->evbit
);
1474 set_bit(KEY_CAMERA
, sd
->input_dev
->keybit
);
1476 if (input_register_device(sd
->input_dev
))
1479 sd
->input_task
= kthread_run(input_kthread
, gspca_dev
, "sn9c20x/%d",
1480 gspca_dev
->vdev
.minor
);
1482 if (IS_ERR(sd
->input_task
))
1488 static void sn9c20x_input_cleanup(struct gspca_dev
*gspca_dev
)
1490 struct sd
*sd
= (struct sd
*) gspca_dev
;
1491 if (sd
->input_task
!= NULL
&& !IS_ERR(sd
->input_task
))
1492 kthread_stop(sd
->input_task
);
1494 if (sd
->input_dev
!= NULL
) {
1495 input_unregister_device(sd
->input_dev
);
1496 kfree(sd
->input_dev
->phys
);
1497 input_free_device(sd
->input_dev
);
1498 sd
->input_dev
= NULL
;
1503 static int set_cmatrix(struct gspca_dev
*gspca_dev
)
1505 struct sd
*sd
= (struct sd
*) gspca_dev
;
1506 s32 hue_coord
, hue_index
= 180 + sd
->hue
;
1508 memset(cmatrix
, 0, 21);
1510 cmatrix
[2] = (sd
->contrast
* 0x25 / 0x100) + 0x26;
1511 cmatrix
[0] = 0x13 + (cmatrix
[2] - 0x26) * 0x13 / 0x25;
1512 cmatrix
[4] = 0x07 + (cmatrix
[2] - 0x26) * 0x07 / 0x25;
1513 cmatrix
[18] = sd
->brightness
- 0x80;
1515 hue_coord
= (hsv_red_x
[hue_index
] * sd
->saturation
) >> 8;
1516 cmatrix
[6] = (unsigned char)(hue_coord
& 0xff);
1517 cmatrix
[7] = (unsigned char)((hue_coord
>> 8) & 0x0f);
1519 hue_coord
= (hsv_red_y
[hue_index
] * sd
->saturation
) >> 8;
1520 cmatrix
[8] = (unsigned char)(hue_coord
& 0xff);
1521 cmatrix
[9] = (unsigned char)((hue_coord
>> 8) & 0x0f);
1523 hue_coord
= (hsv_green_x
[hue_index
] * sd
->saturation
) >> 8;
1524 cmatrix
[10] = (unsigned char)(hue_coord
& 0xff);
1525 cmatrix
[11] = (unsigned char)((hue_coord
>> 8) & 0x0f);
1527 hue_coord
= (hsv_green_y
[hue_index
] * sd
->saturation
) >> 8;
1528 cmatrix
[12] = (unsigned char)(hue_coord
& 0xff);
1529 cmatrix
[13] = (unsigned char)((hue_coord
>> 8) & 0x0f);
1531 hue_coord
= (hsv_blue_x
[hue_index
] * sd
->saturation
) >> 8;
1532 cmatrix
[14] = (unsigned char)(hue_coord
& 0xff);
1533 cmatrix
[15] = (unsigned char)((hue_coord
>> 8) & 0x0f);
1535 hue_coord
= (hsv_blue_y
[hue_index
] * sd
->saturation
) >> 8;
1536 cmatrix
[16] = (unsigned char)(hue_coord
& 0xff);
1537 cmatrix
[17] = (unsigned char)((hue_coord
>> 8) & 0x0f);
1539 return reg_w(gspca_dev
, 0x10e1, cmatrix
, 21);
1542 static int set_gamma(struct gspca_dev
*gspca_dev
)
1544 struct sd
*sd
= (struct sd
*) gspca_dev
;
1546 u8 gval
= sd
->gamma
* 0xb8 / 0x100;
1550 gamma
[1] = 0x13 + (gval
* (0xcb - 0x13) / 0xb8);
1551 gamma
[2] = 0x25 + (gval
* (0xee - 0x25) / 0xb8);
1552 gamma
[3] = 0x37 + (gval
* (0xfa - 0x37) / 0xb8);
1553 gamma
[4] = 0x45 + (gval
* (0xfc - 0x45) / 0xb8);
1554 gamma
[5] = 0x55 + (gval
* (0xfb - 0x55) / 0xb8);
1555 gamma
[6] = 0x65 + (gval
* (0xfc - 0x65) / 0xb8);
1556 gamma
[7] = 0x74 + (gval
* (0xfd - 0x74) / 0xb8);
1557 gamma
[8] = 0x83 + (gval
* (0xfe - 0x83) / 0xb8);
1558 gamma
[9] = 0x92 + (gval
* (0xfc - 0x92) / 0xb8);
1559 gamma
[10] = 0xa1 + (gval
* (0xfc - 0xa1) / 0xb8);
1560 gamma
[11] = 0xb0 + (gval
* (0xfc - 0xb0) / 0xb8);
1561 gamma
[12] = 0xbf + (gval
* (0xfb - 0xbf) / 0xb8);
1562 gamma
[13] = 0xce + (gval
* (0xfb - 0xce) / 0xb8);
1563 gamma
[14] = 0xdf + (gval
* (0xfd - 0xdf) / 0xb8);
1564 gamma
[15] = 0xea + (gval
* (0xf9 - 0xea) / 0xb8);
1567 return reg_w(gspca_dev
, 0x1190, gamma
, 17);
1570 static int set_redblue(struct gspca_dev
*gspca_dev
)
1572 struct sd
*sd
= (struct sd
*) gspca_dev
;
1573 reg_w1(gspca_dev
, 0x118c, sd
->red
);
1574 reg_w1(gspca_dev
, 0x118f, sd
->blue
);
1578 static int set_hvflip(struct gspca_dev
*gspca_dev
)
1582 struct sd
*sd
= (struct sd
*) gspca_dev
;
1583 switch (sd
->sensor
) {
1585 i2c_r1(gspca_dev
, 0x1e, &value
);
1594 i2c_w1(gspca_dev
, 0x1e, value
);
1595 i2c_w1(gspca_dev
, 0x3a, tslb
);
1597 case SENSOR_MT9V111
:
1598 case SENSOR_MT9V011
:
1599 i2c_r2(gspca_dev
, 0x20, &value2
);
1605 i2c_w2(gspca_dev
, 0x20, value2
);
1607 case SENSOR_MT9M111
:
1608 case SENSOR_MT9V112
:
1609 i2c_r2(gspca_dev
, 0x20, &value2
);
1615 i2c_w2(gspca_dev
, 0x20, value2
);
1617 case SENSOR_HV7131R
:
1618 i2c_r1(gspca_dev
, 0x01, &value
);
1624 i2c_w1(gspca_dev
, 0x01, value
);
1630 static int set_exposure(struct gspca_dev
*gspca_dev
)
1632 struct sd
*sd
= (struct sd
*) gspca_dev
;
1633 u8 exp
[8] = {0x81, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1634 switch (sd
->sensor
) {
1641 exp
[3] = sd
->exposure
& 0xff;
1642 exp
[4] = sd
->exposure
>> 8;
1644 case SENSOR_MT9M001
:
1645 case SENSOR_MT9V112
:
1646 case SENSOR_MT9V111
:
1647 case SENSOR_MT9V011
:
1650 exp
[3] = sd
->exposure
>> 8;
1651 exp
[4] = sd
->exposure
& 0xff;
1653 case SENSOR_HV7131R
:
1656 exp
[3] = ((sd
->exposure
* 0xffffff) / 0xffff) >> 16;
1657 exp
[4] = ((sd
->exposure
* 0xffffff) / 0xffff) >> 8;
1658 exp
[5] = ((sd
->exposure
* 0xffffff) / 0xffff) & 0xff;
1663 i2c_w(gspca_dev
, exp
);
1667 static int set_gain(struct gspca_dev
*gspca_dev
)
1669 struct sd
*sd
= (struct sd
*) gspca_dev
;
1670 u8 gain
[8] = {0x81, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1671 switch (sd
->sensor
) {
1677 gain
[0] |= (2 << 4);
1678 gain
[3] = ov_gain
[sd
->gain
];
1680 case SENSOR_MT9V011
:
1681 case SENSOR_MT9V111
:
1682 gain
[0] |= (3 << 4);
1684 gain
[3] = micron1_gain
[sd
->gain
] >> 8;
1685 gain
[4] = micron1_gain
[sd
->gain
] & 0xff;
1687 case SENSOR_MT9V112
:
1688 gain
[0] |= (3 << 4);
1690 gain
[3] = micron1_gain
[sd
->gain
] >> 8;
1691 gain
[4] = micron1_gain
[sd
->gain
] & 0xff;
1693 case SENSOR_MT9M001
:
1694 gain
[0] |= (3 << 4);
1696 gain
[3] = micron2_gain
[sd
->gain
] >> 8;
1697 gain
[4] = micron2_gain
[sd
->gain
] & 0xff;
1699 case SENSOR_HV7131R
:
1700 gain
[0] |= (2 << 4);
1702 gain
[3] = hv7131r_gain
[sd
->gain
];
1707 i2c_w(gspca_dev
, gain
);
1711 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, s32 val
)
1713 struct sd
*sd
= (struct sd
*) gspca_dev
;
1715 sd
->brightness
= val
;
1716 if (gspca_dev
->streaming
)
1717 return set_cmatrix(gspca_dev
);
1721 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, s32
*val
)
1723 struct sd
*sd
= (struct sd
*) gspca_dev
;
1724 *val
= sd
->brightness
;
1729 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, s32 val
)
1731 struct sd
*sd
= (struct sd
*) gspca_dev
;
1734 if (gspca_dev
->streaming
)
1735 return set_cmatrix(gspca_dev
);
1739 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, s32
*val
)
1741 struct sd
*sd
= (struct sd
*) gspca_dev
;
1742 *val
= sd
->contrast
;
1746 static int sd_setsaturation(struct gspca_dev
*gspca_dev
, s32 val
)
1748 struct sd
*sd
= (struct sd
*) gspca_dev
;
1750 sd
->saturation
= val
;
1751 if (gspca_dev
->streaming
)
1752 return set_cmatrix(gspca_dev
);
1756 static int sd_getsaturation(struct gspca_dev
*gspca_dev
, s32
*val
)
1758 struct sd
*sd
= (struct sd
*) gspca_dev
;
1759 *val
= sd
->saturation
;
1763 static int sd_sethue(struct gspca_dev
*gspca_dev
, s32 val
)
1765 struct sd
*sd
= (struct sd
*) gspca_dev
;
1768 if (gspca_dev
->streaming
)
1769 return set_cmatrix(gspca_dev
);
1773 static int sd_gethue(struct gspca_dev
*gspca_dev
, s32
*val
)
1775 struct sd
*sd
= (struct sd
*) gspca_dev
;
1780 static int sd_setgamma(struct gspca_dev
*gspca_dev
, s32 val
)
1782 struct sd
*sd
= (struct sd
*) gspca_dev
;
1785 if (gspca_dev
->streaming
)
1786 return set_gamma(gspca_dev
);
1790 static int sd_getgamma(struct gspca_dev
*gspca_dev
, s32
*val
)
1792 struct sd
*sd
= (struct sd
*) gspca_dev
;
1797 static int sd_setredbalance(struct gspca_dev
*gspca_dev
, s32 val
)
1799 struct sd
*sd
= (struct sd
*) gspca_dev
;
1802 if (gspca_dev
->streaming
)
1803 return set_redblue(gspca_dev
);
1807 static int sd_getredbalance(struct gspca_dev
*gspca_dev
, s32
*val
)
1809 struct sd
*sd
= (struct sd
*) gspca_dev
;
1814 static int sd_setbluebalance(struct gspca_dev
*gspca_dev
, s32 val
)
1816 struct sd
*sd
= (struct sd
*) gspca_dev
;
1819 if (gspca_dev
->streaming
)
1820 return set_redblue(gspca_dev
);
1824 static int sd_getbluebalance(struct gspca_dev
*gspca_dev
, s32
*val
)
1826 struct sd
*sd
= (struct sd
*) gspca_dev
;
1831 static int sd_sethflip(struct gspca_dev
*gspca_dev
, s32 val
)
1833 struct sd
*sd
= (struct sd
*) gspca_dev
;
1836 if (gspca_dev
->streaming
)
1837 return set_hvflip(gspca_dev
);
1841 static int sd_gethflip(struct gspca_dev
*gspca_dev
, s32
*val
)
1843 struct sd
*sd
= (struct sd
*) gspca_dev
;
1848 static int sd_setvflip(struct gspca_dev
*gspca_dev
, s32 val
)
1850 struct sd
*sd
= (struct sd
*) gspca_dev
;
1853 if (gspca_dev
->streaming
)
1854 return set_hvflip(gspca_dev
);
1858 static int sd_getvflip(struct gspca_dev
*gspca_dev
, s32
*val
)
1860 struct sd
*sd
= (struct sd
*) gspca_dev
;
1865 static int sd_setexposure(struct gspca_dev
*gspca_dev
, s32 val
)
1867 struct sd
*sd
= (struct sd
*) gspca_dev
;
1870 if (gspca_dev
->streaming
)
1871 return set_exposure(gspca_dev
);
1875 static int sd_getexposure(struct gspca_dev
*gspca_dev
, s32
*val
)
1877 struct sd
*sd
= (struct sd
*) gspca_dev
;
1878 *val
= sd
->exposure
;
1882 static int sd_setgain(struct gspca_dev
*gspca_dev
, s32 val
)
1884 struct sd
*sd
= (struct sd
*) gspca_dev
;
1887 if (gspca_dev
->streaming
)
1888 return set_gain(gspca_dev
);
1892 static int sd_getgain(struct gspca_dev
*gspca_dev
, s32
*val
)
1894 struct sd
*sd
= (struct sd
*) gspca_dev
;
1899 static int sd_setautoexposure(struct gspca_dev
*gspca_dev
, s32 val
)
1901 struct sd
*sd
= (struct sd
*) gspca_dev
;
1902 sd
->auto_exposure
= val
;
1906 static int sd_getautoexposure(struct gspca_dev
*gspca_dev
, s32
*val
)
1908 struct sd
*sd
= (struct sd
*) gspca_dev
;
1909 *val
= sd
->auto_exposure
;
1913 #ifdef CONFIG_VIDEO_ADV_DEBUG
1914 static int sd_dbg_g_register(struct gspca_dev
*gspca_dev
,
1915 struct v4l2_dbg_register
*reg
)
1917 struct sd
*sd
= (struct sd
*) gspca_dev
;
1918 switch (reg
->match
.type
) {
1919 case V4L2_CHIP_MATCH_HOST
:
1920 if (reg
->match
.addr
!= 0)
1922 if (reg
->reg
< 0x1000 || reg
->reg
> 0x11ff)
1924 if (reg_r(gspca_dev
, reg
->reg
, 1) < 0)
1926 reg
->val
= gspca_dev
->usb_buf
[0];
1928 case V4L2_CHIP_MATCH_I2C_ADDR
:
1929 if (reg
->match
.addr
!= sd
->i2c_addr
)
1931 if (sd
->sensor
>= SENSOR_MT9V011
&&
1932 sd
->sensor
<= SENSOR_MT9M111
) {
1933 if (i2c_r2(gspca_dev
, reg
->reg
, (u16
*)®
->val
) < 0)
1936 if (i2c_r1(gspca_dev
, reg
->reg
, (u8
*)®
->val
) < 0)
1944 static int sd_dbg_s_register(struct gspca_dev
*gspca_dev
,
1945 struct v4l2_dbg_register
*reg
)
1947 struct sd
*sd
= (struct sd
*) gspca_dev
;
1948 switch (reg
->match
.type
) {
1949 case V4L2_CHIP_MATCH_HOST
:
1950 if (reg
->match
.addr
!= 0)
1952 if (reg
->reg
< 0x1000 || reg
->reg
> 0x11ff)
1954 if (reg_w1(gspca_dev
, reg
->reg
, reg
->val
) < 0)
1957 case V4L2_CHIP_MATCH_I2C_ADDR
:
1958 if (reg
->match
.addr
!= sd
->i2c_addr
)
1960 if (sd
->sensor
>= SENSOR_MT9V011
&&
1961 sd
->sensor
<= SENSOR_MT9M111
) {
1962 if (i2c_w2(gspca_dev
, reg
->reg
, reg
->val
) < 0)
1965 if (i2c_w1(gspca_dev
, reg
->reg
, reg
->val
) < 0)
1974 static int sd_chip_ident(struct gspca_dev
*gspca_dev
,
1975 struct v4l2_dbg_chip_ident
*chip
)
1977 struct sd
*sd
= (struct sd
*) gspca_dev
;
1979 switch (chip
->match
.type
) {
1980 case V4L2_CHIP_MATCH_HOST
:
1981 if (chip
->match
.addr
!= 0)
1984 chip
->ident
= V4L2_IDENT_SN9C20X
;
1986 case V4L2_CHIP_MATCH_I2C_ADDR
:
1987 if (chip
->match
.addr
!= sd
->i2c_addr
)
1990 chip
->ident
= i2c_ident
[sd
->sensor
];
1996 static int sd_config(struct gspca_dev
*gspca_dev
,
1997 const struct usb_device_id
*id
)
1999 struct sd
*sd
= (struct sd
*) gspca_dev
;
2002 cam
= &gspca_dev
->cam
;
2004 sd
->sensor
= (id
->driver_info
>> 8) & 0xff;
2005 sd
->i2c_addr
= id
->driver_info
& 0xff;
2007 switch (sd
->sensor
) {
2008 case SENSOR_MT9M111
:
2011 cam
->cam_mode
= sxga_mode
;
2012 cam
->nmodes
= ARRAY_SIZE(sxga_mode
);
2015 cam
->cam_mode
= vga_mode
;
2016 cam
->nmodes
= ARRAY_SIZE(vga_mode
);
2021 sd
->exposure_step
= 16;
2023 sd
->brightness
= BRIGHTNESS_DEFAULT
;
2024 sd
->contrast
= CONTRAST_DEFAULT
;
2025 sd
->saturation
= SATURATION_DEFAULT
;
2026 sd
->hue
= HUE_DEFAULT
;
2027 sd
->gamma
= GAMMA_DEFAULT
;
2028 sd
->red
= RED_DEFAULT
;
2029 sd
->blue
= BLUE_DEFAULT
;
2031 sd
->hflip
= HFLIP_DEFAULT
;
2032 sd
->vflip
= VFLIP_DEFAULT
;
2033 sd
->exposure
= EXPOSURE_DEFAULT
;
2034 sd
->gain
= GAIN_DEFAULT
;
2035 sd
->auto_exposure
= AUTO_EXPOSURE_DEFAULT
;
2039 #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
2040 sd
->input_gpio
= (id
->driver_info
>> 16) & 0xff;
2041 if (sn9c20x_input_init(gspca_dev
) < 0)
2047 static int sd_init(struct gspca_dev
*gspca_dev
)
2049 struct sd
*sd
= (struct sd
*) gspca_dev
;
2053 {0x80, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
2055 for (i
= 0; i
< ARRAY_SIZE(bridge_init
); i
++) {
2056 value
= bridge_init
[i
][1];
2057 if (reg_w(gspca_dev
, bridge_init
[i
][0], &value
, 1) < 0) {
2058 err("Device initialization failed");
2063 if (reg_w(gspca_dev
, 0x10c0, i2c_init
, 9) < 0) {
2064 err("Device initialization failed");
2068 switch (sd
->sensor
) {
2070 if (ov9650_init_sensor(gspca_dev
) < 0)
2072 info("OV9650 sensor detected");
2075 if (ov9655_init_sensor(gspca_dev
) < 0)
2077 info("OV9655 sensor detected");
2080 if (soi968_init_sensor(gspca_dev
) < 0)
2082 info("SOI968 sensor detected");
2085 if (ov7660_init_sensor(gspca_dev
) < 0)
2087 info("OV7660 sensor detected");
2090 if (ov7670_init_sensor(gspca_dev
) < 0)
2092 info("OV7670 sensor detected");
2094 case SENSOR_MT9VPRB
:
2095 if (mt9v_init_sensor(gspca_dev
) < 0)
2098 case SENSOR_MT9M111
:
2099 if (mt9m111_init_sensor(gspca_dev
) < 0)
2101 info("MT9M111 sensor detected");
2103 case SENSOR_MT9M001
:
2104 if (mt9m001_init_sensor(gspca_dev
) < 0)
2106 info("MT9M001 sensor detected");
2108 case SENSOR_HV7131R
:
2109 if (hv7131r_init_sensor(gspca_dev
) < 0)
2111 info("HV7131R sensor detected");
2114 info("Unsupported Sensor");
2121 static void configure_sensor_output(struct gspca_dev
*gspca_dev
, int mode
)
2123 struct sd
*sd
= (struct sd
*) gspca_dev
;
2125 switch (sd
->sensor
) {
2127 if (mode
& MODE_SXGA
) {
2128 i2c_w1(gspca_dev
, 0x17, 0x1d);
2129 i2c_w1(gspca_dev
, 0x18, 0xbd);
2130 i2c_w1(gspca_dev
, 0x19, 0x01);
2131 i2c_w1(gspca_dev
, 0x1a, 0x81);
2132 i2c_w1(gspca_dev
, 0x12, 0x00);
2136 i2c_w1(gspca_dev
, 0x17, 0x13);
2137 i2c_w1(gspca_dev
, 0x18, 0x63);
2138 i2c_w1(gspca_dev
, 0x19, 0x01);
2139 i2c_w1(gspca_dev
, 0x1a, 0x79);
2140 i2c_w1(gspca_dev
, 0x12, 0x40);
2146 if (mode
& MODE_SXGA
) {
2147 i2c_w1(gspca_dev
, 0x17, 0x1b);
2148 i2c_w1(gspca_dev
, 0x18, 0xbc);
2149 i2c_w1(gspca_dev
, 0x19, 0x01);
2150 i2c_w1(gspca_dev
, 0x1a, 0x82);
2151 i2c_r1(gspca_dev
, 0x12, &value
);
2152 i2c_w1(gspca_dev
, 0x12, value
& 0x07);
2154 i2c_w1(gspca_dev
, 0x17, 0x24);
2155 i2c_w1(gspca_dev
, 0x18, 0xc5);
2156 i2c_w1(gspca_dev
, 0x19, 0x00);
2157 i2c_w1(gspca_dev
, 0x1a, 0x3c);
2158 i2c_r1(gspca_dev
, 0x12, &value
);
2159 i2c_w1(gspca_dev
, 0x12, (value
& 0x7) | 0x40);
2162 case SENSOR_MT9M111
:
2163 if (mode
& MODE_SXGA
) {
2164 i2c_w2(gspca_dev
, 0xf0, 0x0002);
2165 i2c_w2(gspca_dev
, 0xc8, 0x970b);
2166 i2c_w2(gspca_dev
, 0xf0, 0x0000);
2168 i2c_w2(gspca_dev
, 0xf0, 0x0002);
2169 i2c_w2(gspca_dev
, 0xc8, 0x8000);
2170 i2c_w2(gspca_dev
, 0xf0, 0x0000);
2176 #define HW_WIN(mode, hstart, vstart) \
2177 ((const u8 []){hstart & 0xff, hstart >> 8, \
2178 vstart & 0xff, vstart >> 8, \
2179 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
2180 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
2182 #define CLR_WIN(width, height) \
2184 {0, width >> 2, 0, height >> 1,\
2185 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
2187 static int sd_start(struct gspca_dev
*gspca_dev
)
2189 struct sd
*sd
= (struct sd
*) gspca_dev
;
2190 int mode
= gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
;
2191 int width
= gspca_dev
->width
;
2192 int height
= gspca_dev
->height
;
2195 sd
->jpeg_hdr
= kmalloc(JPEG_HDR_SZ
, GFP_KERNEL
);
2196 if (sd
->jpeg_hdr
== NULL
)
2199 jpeg_define(sd
->jpeg_hdr
, height
, width
,
2201 jpeg_set_qual(sd
->jpeg_hdr
, sd
->quality
);
2203 if (mode
& MODE_RAW
)
2205 else if (mode
& MODE_JPEG
)
2210 switch (mode
& 0x0f) {
2213 info("Set 1280x1024");
2217 info("Set 640x480");
2221 info("Set 320x240");
2225 info("Set 160x120");
2229 configure_sensor_output(gspca_dev
, mode
);
2230 reg_w(gspca_dev
, 0x1100, sd
->jpeg_hdr
+ JPEG_QT0_OFFSET
, 64);
2231 reg_w(gspca_dev
, 0x1140, sd
->jpeg_hdr
+ JPEG_QT1_OFFSET
, 64);
2232 reg_w(gspca_dev
, 0x10fb, CLR_WIN(width
, height
), 5);
2233 reg_w(gspca_dev
, 0x1180, HW_WIN(mode
, sd
->hstart
, sd
->vstart
), 6);
2234 reg_w1(gspca_dev
, 0x1189, scale
);
2235 reg_w1(gspca_dev
, 0x10e0, fmt
);
2237 set_cmatrix(gspca_dev
);
2238 set_gamma(gspca_dev
);
2239 set_redblue(gspca_dev
);
2240 set_gain(gspca_dev
);
2241 set_exposure(gspca_dev
);
2242 set_hvflip(gspca_dev
);
2244 reg_r(gspca_dev
, 0x1061, 1);
2245 reg_w1(gspca_dev
, 0x1061, gspca_dev
->usb_buf
[0] | 0x02);
2249 static void sd_stopN(struct gspca_dev
*gspca_dev
)
2251 reg_r(gspca_dev
, 0x1061, 1);
2252 reg_w1(gspca_dev
, 0x1061, gspca_dev
->usb_buf
[0] & ~0x02);
2255 static void sd_stop0(struct gspca_dev
*gspca_dev
)
2257 struct sd
*sd
= (struct sd
*) gspca_dev
;
2258 kfree(sd
->jpeg_hdr
);
2261 static void do_autoexposure(struct gspca_dev
*gspca_dev
, u16 avg_lum
)
2263 struct sd
*sd
= (struct sd
*) gspca_dev
;
2267 * some hardcoded values are present
2268 * like those for maximal/minimal exposure
2269 * and exposure steps
2271 if (avg_lum
< MIN_AVG_LUM
) {
2272 if (sd
->exposure
> 0x1770)
2275 new_exp
= sd
->exposure
+ sd
->exposure_step
;
2276 if (new_exp
> 0x1770)
2280 sd
->exposure
= new_exp
;
2281 set_exposure(gspca_dev
);
2283 sd
->older_step
= sd
->old_step
;
2286 if (sd
->old_step
^ sd
->older_step
)
2287 sd
->exposure_step
/= 2;
2289 sd
->exposure_step
+= 2;
2291 if (avg_lum
> MAX_AVG_LUM
) {
2292 if (sd
->exposure
< 0x10)
2294 new_exp
= sd
->exposure
- sd
->exposure_step
;
2295 if (new_exp
> 0x1700)
2299 sd
->exposure
= new_exp
;
2300 set_exposure(gspca_dev
);
2301 sd
->older_step
= sd
->old_step
;
2304 if (sd
->old_step
^ sd
->older_step
)
2305 sd
->exposure_step
/= 2;
2307 sd
->exposure_step
+= 2;
2311 static void do_autogain(struct gspca_dev
*gspca_dev
, u16 avg_lum
)
2313 struct sd
*sd
= (struct sd
*) gspca_dev
;
2315 if (avg_lum
< MIN_AVG_LUM
) {
2316 if (sd
->gain
+ 1 <= 28) {
2318 set_gain(gspca_dev
);
2321 if (avg_lum
> MAX_AVG_LUM
) {
2322 if (sd
->gain
- 1 >= 0) {
2324 set_gain(gspca_dev
);
2329 static void sd_dqcallback(struct gspca_dev
*gspca_dev
)
2331 struct sd
*sd
= (struct sd
*) gspca_dev
;
2334 if (!sd
->auto_exposure
)
2337 avg_lum
= atomic_read(&sd
->avg_lum
);
2338 if (sd
->sensor
== SENSOR_SOI968
)
2339 do_autogain(gspca_dev
, avg_lum
);
2341 do_autoexposure(gspca_dev
, avg_lum
);
2344 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
2345 struct gspca_frame
*frame
, /* target */
2346 u8
*data
, /* isoc packet */
2347 int len
) /* iso packet length */
2349 struct sd
*sd
= (struct sd
*) gspca_dev
;
2351 static unsigned char frame_header
[] =
2352 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2353 if (len
== 64 && memcmp(data
, frame_header
, 6) == 0) {
2354 avg_lum
= ((data
[35] >> 2) & 3) |
2357 avg_lum
+= ((data
[35] >> 4) & 3) |
2360 avg_lum
+= ((data
[35] >> 6) & 3) |
2363 avg_lum
+= (data
[36] & 3) |
2366 avg_lum
+= ((data
[36] >> 2) & 3) |
2369 avg_lum
+= ((data
[36] >> 4) & 3) |
2372 avg_lum
+= ((data
[36] >> 6) & 3) |
2375 avg_lum
+= ((data
[44] >> 4) & 3) |
2379 atomic_set(&sd
->avg_lum
, avg_lum
);
2380 gspca_frame_add(gspca_dev
, LAST_PACKET
,
2384 if (gspca_dev
->last_packet_type
== LAST_PACKET
) {
2385 if (gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
2387 gspca_frame_add(gspca_dev
, FIRST_PACKET
, frame
,
2388 sd
->jpeg_hdr
, JPEG_HDR_SZ
);
2389 gspca_frame_add(gspca_dev
, INTER_PACKET
, frame
,
2392 gspca_frame_add(gspca_dev
, FIRST_PACKET
, frame
,
2396 gspca_frame_add(gspca_dev
, INTER_PACKET
, frame
, data
, len
);
2400 /* sub-driver description */
2401 static const struct sd_desc sd_desc
= {
2402 .name
= MODULE_NAME
,
2404 .nctrls
= ARRAY_SIZE(sd_ctrls
),
2405 .config
= sd_config
,
2410 .pkt_scan
= sd_pkt_scan
,
2411 .dq_callback
= sd_dqcallback
,
2412 #ifdef CONFIG_VIDEO_ADV_DEBUG
2413 .set_register
= sd_dbg_s_register
,
2414 .get_register
= sd_dbg_g_register
,
2416 .get_chip_ident
= sd_chip_ident
,
2419 #define SN9C20X(sensor, i2c_addr, button_mask) \
2420 .driver_info = (button_mask << 16) \
2421 | (SENSOR_ ## sensor << 8) \
2424 static const __devinitdata
struct usb_device_id device_table
[] = {
2425 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001
, 0x5d, 0)},
2426 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111
, 0x5d, 0)},
2427 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655
, 0x30, 0)},
2428 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968
, 0x30, 0x10)},
2429 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650
, 0x30, 0)},
2430 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650
, 0x30, 0)},
2431 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650
, 0x30, 0)},
2432 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670
, 0x21, 0)},
2433 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB
, 0x00, 0)},
2434 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660
, 0x21, 0)},
2435 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R
, 0x11, 0)},
2436 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650
, 0x30, 0)},
2437 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001
, 0x5d, 0)},
2438 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111
, 0x5d, 0)},
2439 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655
, 0x30, 0)},
2440 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968
, 0x30, 0)},
2441 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650
, 0x30, 0)},
2442 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670
, 0x21, 0)},
2443 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB
, 0x00, 0)},
2444 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655
, 0x30, 0)},
2445 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660
, 0x21, 0)},
2446 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R
, 0x11, 0)},
2447 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650
, 0x30, 0)},
2448 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660
, 0x21, 0)},
2449 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R
, 0x11, 0)},
2450 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R
, 0x11, 0)},
2451 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R
, 0x11, 0)},
2452 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R
, 0x11, 0)},
2453 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R
, 0x11, 0)},
2454 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111
, 0x5d, 0)},
2455 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111
, 0x5d, 0)},
2456 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111
, 0x5d, 0)},
2459 MODULE_DEVICE_TABLE(usb
, device_table
);
2461 /* -- device connect -- */
2462 static int sd_probe(struct usb_interface
*intf
,
2463 const struct usb_device_id
*id
)
2465 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
2469 static void sd_disconnect(struct usb_interface
*intf
)
2471 #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
2472 struct gspca_dev
*gspca_dev
= usb_get_intfdata(intf
);
2474 sn9c20x_input_cleanup(gspca_dev
);
2477 gspca_disconnect(intf
);
2480 static struct usb_driver sd_driver
= {
2481 .name
= MODULE_NAME
,
2482 .id_table
= device_table
,
2484 .disconnect
= sd_disconnect
,
2486 .suspend
= gspca_suspend
,
2487 .resume
= gspca_resume
,
2488 .reset_resume
= gspca_resume
,
2492 /* -- module insert / remove -- */
2493 static int __init
sd_mod_init(void)
2496 ret
= usb_register(&sd_driver
);
2502 static void __exit
sd_mod_exit(void)
2504 usb_deregister(&sd_driver
);
2505 info("deregistered");
2508 module_init(sd_mod_init
);
2509 module_exit(sd_mod_exit
);