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
;
97 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, s32 val
);
98 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, s32
*val
);
99 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, s32 val
);
100 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, s32
*val
);
101 static int sd_setsaturation(struct gspca_dev
*gspca_dev
, s32 val
);
102 static int sd_getsaturation(struct gspca_dev
*gspca_dev
, s32
*val
);
103 static int sd_sethue(struct gspca_dev
*gspca_dev
, s32 val
);
104 static int sd_gethue(struct gspca_dev
*gspca_dev
, s32
*val
);
105 static int sd_setgamma(struct gspca_dev
*gspca_dev
, s32 val
);
106 static int sd_getgamma(struct gspca_dev
*gspca_dev
, s32
*val
);
107 static int sd_setredbalance(struct gspca_dev
*gspca_dev
, s32 val
);
108 static int sd_getredbalance(struct gspca_dev
*gspca_dev
, s32
*val
);
109 static int sd_setbluebalance(struct gspca_dev
*gspca_dev
, s32 val
);
110 static int sd_getbluebalance(struct gspca_dev
*gspca_dev
, s32
*val
);
111 static int sd_setvflip(struct gspca_dev
*gspca_dev
, s32 val
);
112 static int sd_getvflip(struct gspca_dev
*gspca_dev
, s32
*val
);
113 static int sd_sethflip(struct gspca_dev
*gspca_dev
, s32 val
);
114 static int sd_gethflip(struct gspca_dev
*gspca_dev
, s32
*val
);
115 static int sd_setgain(struct gspca_dev
*gspca_dev
, s32 val
);
116 static int sd_getgain(struct gspca_dev
*gspca_dev
, s32
*val
);
117 static int sd_setexposure(struct gspca_dev
*gspca_dev
, s32 val
);
118 static int sd_getexposure(struct gspca_dev
*gspca_dev
, s32
*val
);
119 static int sd_setautoexposure(struct gspca_dev
*gspca_dev
, s32 val
);
120 static int sd_getautoexposure(struct gspca_dev
*gspca_dev
, s32
*val
);
122 static struct ctrl sd_ctrls
[] = {
124 #define BRIGHTNESS_IDX 0
126 .id
= V4L2_CID_BRIGHTNESS
,
127 .type
= V4L2_CTRL_TYPE_INTEGER
,
128 .name
= "Brightness",
132 #define BRIGHTNESS_DEFAULT 0x7f
133 .default_value
= BRIGHTNESS_DEFAULT
,
135 .set
= sd_setbrightness
,
136 .get
= sd_getbrightness
,
139 #define CONTRAST_IDX 1
141 .id
= V4L2_CID_CONTRAST
,
142 .type
= V4L2_CTRL_TYPE_INTEGER
,
147 #define CONTRAST_DEFAULT 0x7f
148 .default_value
= CONTRAST_DEFAULT
,
150 .set
= sd_setcontrast
,
151 .get
= sd_getcontrast
,
154 #define SATURATION_IDX 2
156 .id
= V4L2_CID_SATURATION
,
157 .type
= V4L2_CTRL_TYPE_INTEGER
,
158 .name
= "Saturation",
162 #define SATURATION_DEFAULT 0x7f
163 .default_value
= SATURATION_DEFAULT
,
165 .set
= sd_setsaturation
,
166 .get
= sd_getsaturation
,
172 .type
= V4L2_CTRL_TYPE_INTEGER
,
177 #define HUE_DEFAULT 0
178 .default_value
= HUE_DEFAULT
,
186 .id
= V4L2_CID_GAMMA
,
187 .type
= V4L2_CTRL_TYPE_INTEGER
,
192 #define GAMMA_DEFAULT 0x10
193 .default_value
= GAMMA_DEFAULT
,
201 .id
= V4L2_CID_BLUE_BALANCE
,
202 .type
= V4L2_CTRL_TYPE_INTEGER
,
203 .name
= "Blue Balance",
207 #define BLUE_DEFAULT 0x28
208 .default_value
= BLUE_DEFAULT
,
210 .set
= sd_setbluebalance
,
211 .get
= sd_getbluebalance
,
216 .id
= V4L2_CID_RED_BALANCE
,
217 .type
= V4L2_CTRL_TYPE_INTEGER
,
218 .name
= "Red Balance",
222 #define RED_DEFAULT 0x28
223 .default_value
= RED_DEFAULT
,
225 .set
= sd_setredbalance
,
226 .get
= sd_getredbalance
,
231 .id
= V4L2_CID_HFLIP
,
232 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
233 .name
= "Horizontal Flip",
237 #define HFLIP_DEFAULT 0
238 .default_value
= HFLIP_DEFAULT
,
246 .id
= V4L2_CID_VFLIP
,
247 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
248 .name
= "Vertical Flip",
252 #define VFLIP_DEFAULT 0
253 .default_value
= VFLIP_DEFAULT
,
259 #define EXPOSURE_IDX 9
261 .id
= V4L2_CID_EXPOSURE
,
262 .type
= V4L2_CTRL_TYPE_INTEGER
,
267 #define EXPOSURE_DEFAULT 0x33
268 .default_value
= EXPOSURE_DEFAULT
,
270 .set
= sd_setexposure
,
271 .get
= sd_getexposure
,
277 .type
= V4L2_CTRL_TYPE_INTEGER
,
282 #define GAIN_DEFAULT 0x00
283 .default_value
= GAIN_DEFAULT
,
289 #define AUTOGAIN_IDX 11
291 .id
= V4L2_CID_AUTOGAIN
,
292 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
293 .name
= "Auto Exposure",
297 #define AUTO_EXPOSURE_DEFAULT 1
298 .default_value
= AUTO_EXPOSURE_DEFAULT
,
300 .set
= sd_setautoexposure
,
301 .get
= sd_getautoexposure
,
305 static const struct v4l2_pix_format vga_mode
[] = {
306 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
308 .sizeimage
= 240 * 120,
309 .colorspace
= V4L2_COLORSPACE_JPEG
,
310 .priv
= 0 | MODE_JPEG
},
311 {160, 120, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
313 .sizeimage
= 160 * 120,
314 .colorspace
= V4L2_COLORSPACE_SRGB
,
315 .priv
= 0 | MODE_RAW
},
316 {160, 120, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
318 .sizeimage
= 240 * 120,
319 .colorspace
= V4L2_COLORSPACE_SRGB
,
321 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
323 .sizeimage
= 480 * 240 ,
324 .colorspace
= V4L2_COLORSPACE_JPEG
,
325 .priv
= 1 | MODE_JPEG
},
326 {320, 240, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
328 .sizeimage
= 320 * 240 ,
329 .colorspace
= V4L2_COLORSPACE_SRGB
,
330 .priv
= 1 | MODE_RAW
},
331 {320, 240, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
333 .sizeimage
= 480 * 240 ,
334 .colorspace
= V4L2_COLORSPACE_SRGB
,
336 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
338 .sizeimage
= 960 * 480,
339 .colorspace
= V4L2_COLORSPACE_JPEG
,
340 .priv
= 2 | MODE_JPEG
},
341 {640, 480, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
343 .sizeimage
= 640 * 480,
344 .colorspace
= V4L2_COLORSPACE_SRGB
,
345 .priv
= 2 | MODE_RAW
},
346 {640, 480, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
348 .sizeimage
= 960 * 480,
349 .colorspace
= V4L2_COLORSPACE_SRGB
,
353 static const struct v4l2_pix_format sxga_mode
[] = {
354 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
356 .sizeimage
= 240 * 120,
357 .colorspace
= V4L2_COLORSPACE_JPEG
,
358 .priv
= 0 | MODE_JPEG
},
359 {160, 120, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
361 .sizeimage
= 160 * 120,
362 .colorspace
= V4L2_COLORSPACE_SRGB
,
363 .priv
= 0 | MODE_RAW
},
364 {160, 120, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
366 .sizeimage
= 240 * 120,
367 .colorspace
= V4L2_COLORSPACE_SRGB
,
369 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
371 .sizeimage
= 480 * 240 ,
372 .colorspace
= V4L2_COLORSPACE_JPEG
,
373 .priv
= 1 | MODE_JPEG
},
374 {320, 240, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
376 .sizeimage
= 320 * 240 ,
377 .colorspace
= V4L2_COLORSPACE_SRGB
,
378 .priv
= 1 | MODE_RAW
},
379 {320, 240, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
381 .sizeimage
= 480 * 240 ,
382 .colorspace
= V4L2_COLORSPACE_SRGB
,
384 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
386 .sizeimage
= 960 * 480,
387 .colorspace
= V4L2_COLORSPACE_JPEG
,
388 .priv
= 2 | MODE_JPEG
},
389 {640, 480, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
391 .sizeimage
= 640 * 480,
392 .colorspace
= V4L2_COLORSPACE_SRGB
,
393 .priv
= 2 | MODE_RAW
},
394 {640, 480, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
396 .sizeimage
= 960 * 480,
397 .colorspace
= V4L2_COLORSPACE_SRGB
,
399 {1280, 1024, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
400 .bytesperline
= 1280,
401 .sizeimage
= (1280 * 1024) + 64,
402 .colorspace
= V4L2_COLORSPACE_SRGB
,
403 .priv
= 3 | MODE_RAW
| MODE_SXGA
},
406 static const int hsv_red_x
[] = {
407 41, 44, 46, 48, 50, 52, 54, 56,
408 58, 60, 62, 64, 66, 68, 70, 72,
409 74, 76, 78, 80, 81, 83, 85, 87,
410 88, 90, 92, 93, 95, 97, 98, 100,
411 101, 102, 104, 105, 107, 108, 109, 110,
412 112, 113, 114, 115, 116, 117, 118, 119,
413 120, 121, 122, 123, 123, 124, 125, 125,
414 126, 127, 127, 128, 128, 129, 129, 129,
415 130, 130, 130, 130, 131, 131, 131, 131,
416 131, 131, 131, 131, 130, 130, 130, 130,
417 129, 129, 129, 128, 128, 127, 127, 126,
418 125, 125, 124, 123, 122, 122, 121, 120,
419 119, 118, 117, 116, 115, 114, 112, 111,
420 110, 109, 107, 106, 105, 103, 102, 101,
421 99, 98, 96, 94, 93, 91, 90, 88,
422 86, 84, 83, 81, 79, 77, 75, 74,
423 72, 70, 68, 66, 64, 62, 60, 58,
424 56, 54, 52, 49, 47, 45, 43, 41,
425 39, 36, 34, 32, 30, 28, 25, 23,
426 21, 19, 16, 14, 12, 9, 7, 5,
427 3, 0, -1, -3, -6, -8, -10, -12,
428 -15, -17, -19, -22, -24, -26, -28, -30,
429 -33, -35, -37, -39, -41, -44, -46, -48,
430 -50, -52, -54, -56, -58, -60, -62, -64,
431 -66, -68, -70, -72, -74, -76, -78, -80,
432 -81, -83, -85, -87, -88, -90, -92, -93,
433 -95, -97, -98, -100, -101, -102, -104, -105,
434 -107, -108, -109, -110, -112, -113, -114, -115,
435 -116, -117, -118, -119, -120, -121, -122, -123,
436 -123, -124, -125, -125, -126, -127, -127, -128,
437 -128, -128, -128, -128, -128, -128, -128, -128,
438 -128, -128, -128, -128, -128, -128, -128, -128,
439 -128, -128, -128, -128, -128, -128, -128, -128,
440 -128, -127, -127, -126, -125, -125, -124, -123,
441 -122, -122, -121, -120, -119, -118, -117, -116,
442 -115, -114, -112, -111, -110, -109, -107, -106,
443 -105, -103, -102, -101, -99, -98, -96, -94,
444 -93, -91, -90, -88, -86, -84, -83, -81,
445 -79, -77, -75, -74, -72, -70, -68, -66,
446 -64, -62, -60, -58, -56, -54, -52, -49,
447 -47, -45, -43, -41, -39, -36, -34, -32,
448 -30, -28, -25, -23, -21, -19, -16, -14,
449 -12, -9, -7, -5, -3, 0, 1, 3,
450 6, 8, 10, 12, 15, 17, 19, 22,
451 24, 26, 28, 30, 33, 35, 37, 39, 41
454 static const int hsv_red_y
[] = {
455 82, 80, 78, 76, 74, 73, 71, 69,
456 67, 65, 63, 61, 58, 56, 54, 52,
457 50, 48, 46, 44, 41, 39, 37, 35,
458 32, 30, 28, 26, 23, 21, 19, 16,
459 14, 12, 10, 7, 5, 3, 0, -1,
460 -3, -6, -8, -10, -13, -15, -17, -19,
461 -22, -24, -26, -29, -31, -33, -35, -38,
462 -40, -42, -44, -46, -48, -51, -53, -55,
463 -57, -59, -61, -63, -65, -67, -69, -71,
464 -73, -75, -77, -79, -81, -82, -84, -86,
465 -88, -89, -91, -93, -94, -96, -98, -99,
466 -101, -102, -104, -105, -106, -108, -109, -110,
467 -112, -113, -114, -115, -116, -117, -119, -120,
468 -120, -121, -122, -123, -124, -125, -126, -126,
469 -127, -128, -128, -128, -128, -128, -128, -128,
470 -128, -128, -128, -128, -128, -128, -128, -128,
471 -128, -128, -128, -128, -128, -128, -128, -128,
472 -128, -128, -128, -128, -128, -128, -128, -128,
473 -127, -127, -126, -125, -125, -124, -123, -122,
474 -121, -120, -119, -118, -117, -116, -115, -114,
475 -113, -111, -110, -109, -107, -106, -105, -103,
476 -102, -100, -99, -97, -96, -94, -92, -91,
477 -89, -87, -85, -84, -82, -80, -78, -76,
478 -74, -73, -71, -69, -67, -65, -63, -61,
479 -58, -56, -54, -52, -50, -48, -46, -44,
480 -41, -39, -37, -35, -32, -30, -28, -26,
481 -23, -21, -19, -16, -14, -12, -10, -7,
482 -5, -3, 0, 1, 3, 6, 8, 10,
483 13, 15, 17, 19, 22, 24, 26, 29,
484 31, 33, 35, 38, 40, 42, 44, 46,
485 48, 51, 53, 55, 57, 59, 61, 63,
486 65, 67, 69, 71, 73, 75, 77, 79,
487 81, 82, 84, 86, 88, 89, 91, 93,
488 94, 96, 98, 99, 101, 102, 104, 105,
489 106, 108, 109, 110, 112, 113, 114, 115,
490 116, 117, 119, 120, 120, 121, 122, 123,
491 124, 125, 126, 126, 127, 128, 128, 129,
492 129, 130, 130, 131, 131, 131, 131, 132,
493 132, 132, 132, 132, 132, 132, 132, 132,
494 132, 132, 132, 131, 131, 131, 130, 130,
495 130, 129, 129, 128, 127, 127, 126, 125,
496 125, 124, 123, 122, 121, 120, 119, 118,
497 117, 116, 115, 114, 113, 111, 110, 109,
498 107, 106, 105, 103, 102, 100, 99, 97,
499 96, 94, 92, 91, 89, 87, 85, 84, 82
502 static const int hsv_green_x
[] = {
503 -124, -124, -125, -125, -125, -125, -125, -125,
504 -125, -126, -126, -125, -125, -125, -125, -125,
505 -125, -124, -124, -124, -123, -123, -122, -122,
506 -121, -121, -120, -120, -119, -118, -117, -117,
507 -116, -115, -114, -113, -112, -111, -110, -109,
508 -108, -107, -105, -104, -103, -102, -100, -99,
509 -98, -96, -95, -93, -92, -91, -89, -87,
510 -86, -84, -83, -81, -79, -77, -76, -74,
511 -72, -70, -69, -67, -65, -63, -61, -59,
512 -57, -55, -53, -51, -49, -47, -45, -43,
513 -41, -39, -37, -35, -33, -30, -28, -26,
514 -24, -22, -20, -18, -15, -13, -11, -9,
515 -7, -4, -2, 0, 1, 3, 6, 8,
516 10, 12, 14, 17, 19, 21, 23, 25,
517 27, 29, 32, 34, 36, 38, 40, 42,
518 44, 46, 48, 50, 52, 54, 56, 58,
519 60, 62, 64, 66, 68, 70, 71, 73,
520 75, 77, 78, 80, 82, 83, 85, 87,
521 88, 90, 91, 93, 94, 96, 97, 98,
522 100, 101, 102, 104, 105, 106, 107, 108,
523 109, 111, 112, 113, 113, 114, 115, 116,
524 117, 118, 118, 119, 120, 120, 121, 122,
525 122, 123, 123, 124, 124, 124, 125, 125,
526 125, 125, 125, 125, 125, 126, 126, 125,
527 125, 125, 125, 125, 125, 124, 124, 124,
528 123, 123, 122, 122, 121, 121, 120, 120,
529 119, 118, 117, 117, 116, 115, 114, 113,
530 112, 111, 110, 109, 108, 107, 105, 104,
531 103, 102, 100, 99, 98, 96, 95, 93,
532 92, 91, 89, 87, 86, 84, 83, 81,
533 79, 77, 76, 74, 72, 70, 69, 67,
534 65, 63, 61, 59, 57, 55, 53, 51,
535 49, 47, 45, 43, 41, 39, 37, 35,
536 33, 30, 28, 26, 24, 22, 20, 18,
537 15, 13, 11, 9, 7, 4, 2, 0,
538 -1, -3, -6, -8, -10, -12, -14, -17,
539 -19, -21, -23, -25, -27, -29, -32, -34,
540 -36, -38, -40, -42, -44, -46, -48, -50,
541 -52, -54, -56, -58, -60, -62, -64, -66,
542 -68, -70, -71, -73, -75, -77, -78, -80,
543 -82, -83, -85, -87, -88, -90, -91, -93,
544 -94, -96, -97, -98, -100, -101, -102, -104,
545 -105, -106, -107, -108, -109, -111, -112, -113,
546 -113, -114, -115, -116, -117, -118, -118, -119,
547 -120, -120, -121, -122, -122, -123, -123, -124, -124
550 static const int hsv_green_y
[] = {
551 -100, -99, -98, -97, -95, -94, -93, -91,
552 -90, -89, -87, -86, -84, -83, -81, -80,
553 -78, -76, -75, -73, -71, -70, -68, -66,
554 -64, -63, -61, -59, -57, -55, -53, -51,
555 -49, -48, -46, -44, -42, -40, -38, -36,
556 -34, -32, -30, -27, -25, -23, -21, -19,
557 -17, -15, -13, -11, -9, -7, -4, -2,
558 0, 1, 3, 5, 7, 9, 11, 14,
559 16, 18, 20, 22, 24, 26, 28, 30,
560 32, 34, 36, 38, 40, 42, 44, 46,
561 48, 50, 52, 54, 56, 58, 59, 61,
562 63, 65, 67, 68, 70, 72, 74, 75,
563 77, 78, 80, 82, 83, 85, 86, 88,
564 89, 90, 92, 93, 95, 96, 97, 98,
565 100, 101, 102, 103, 104, 105, 106, 107,
566 108, 109, 110, 111, 112, 112, 113, 114,
567 115, 115, 116, 116, 117, 117, 118, 118,
568 119, 119, 119, 120, 120, 120, 120, 120,
569 121, 121, 121, 121, 121, 121, 120, 120,
570 120, 120, 120, 119, 119, 119, 118, 118,
571 117, 117, 116, 116, 115, 114, 114, 113,
572 112, 111, 111, 110, 109, 108, 107, 106,
573 105, 104, 103, 102, 100, 99, 98, 97,
574 95, 94, 93, 91, 90, 89, 87, 86,
575 84, 83, 81, 80, 78, 76, 75, 73,
576 71, 70, 68, 66, 64, 63, 61, 59,
577 57, 55, 53, 51, 49, 48, 46, 44,
578 42, 40, 38, 36, 34, 32, 30, 27,
579 25, 23, 21, 19, 17, 15, 13, 11,
580 9, 7, 4, 2, 0, -1, -3, -5,
581 -7, -9, -11, -14, -16, -18, -20, -22,
582 -24, -26, -28, -30, -32, -34, -36, -38,
583 -40, -42, -44, -46, -48, -50, -52, -54,
584 -56, -58, -59, -61, -63, -65, -67, -68,
585 -70, -72, -74, -75, -77, -78, -80, -82,
586 -83, -85, -86, -88, -89, -90, -92, -93,
587 -95, -96, -97, -98, -100, -101, -102, -103,
588 -104, -105, -106, -107, -108, -109, -110, -111,
589 -112, -112, -113, -114, -115, -115, -116, -116,
590 -117, -117, -118, -118, -119, -119, -119, -120,
591 -120, -120, -120, -120, -121, -121, -121, -121,
592 -121, -121, -120, -120, -120, -120, -120, -119,
593 -119, -119, -118, -118, -117, -117, -116, -116,
594 -115, -114, -114, -113, -112, -111, -111, -110,
595 -109, -108, -107, -106, -105, -104, -103, -102, -100
598 static const int hsv_blue_x
[] = {
599 112, 113, 114, 114, 115, 116, 117, 117,
600 118, 118, 119, 119, 120, 120, 120, 121,
601 121, 121, 122, 122, 122, 122, 122, 122,
602 122, 122, 122, 122, 122, 122, 121, 121,
603 121, 120, 120, 120, 119, 119, 118, 118,
604 117, 116, 116, 115, 114, 113, 113, 112,
605 111, 110, 109, 108, 107, 106, 105, 104,
606 103, 102, 100, 99, 98, 97, 95, 94,
607 93, 91, 90, 88, 87, 85, 84, 82,
608 80, 79, 77, 76, 74, 72, 70, 69,
609 67, 65, 63, 61, 60, 58, 56, 54,
610 52, 50, 48, 46, 44, 42, 40, 38,
611 36, 34, 32, 30, 28, 26, 24, 22,
612 19, 17, 15, 13, 11, 9, 7, 5,
613 2, 0, -1, -3, -5, -7, -9, -12,
614 -14, -16, -18, -20, -22, -24, -26, -28,
615 -31, -33, -35, -37, -39, -41, -43, -45,
616 -47, -49, -51, -53, -54, -56, -58, -60,
617 -62, -64, -66, -67, -69, -71, -73, -74,
618 -76, -78, -79, -81, -83, -84, -86, -87,
619 -89, -90, -92, -93, -94, -96, -97, -98,
620 -99, -101, -102, -103, -104, -105, -106, -107,
621 -108, -109, -110, -111, -112, -113, -114, -114,
622 -115, -116, -117, -117, -118, -118, -119, -119,
623 -120, -120, -120, -121, -121, -121, -122, -122,
624 -122, -122, -122, -122, -122, -122, -122, -122,
625 -122, -122, -121, -121, -121, -120, -120, -120,
626 -119, -119, -118, -118, -117, -116, -116, -115,
627 -114, -113, -113, -112, -111, -110, -109, -108,
628 -107, -106, -105, -104, -103, -102, -100, -99,
629 -98, -97, -95, -94, -93, -91, -90, -88,
630 -87, -85, -84, -82, -80, -79, -77, -76,
631 -74, -72, -70, -69, -67, -65, -63, -61,
632 -60, -58, -56, -54, -52, -50, -48, -46,
633 -44, -42, -40, -38, -36, -34, -32, -30,
634 -28, -26, -24, -22, -19, -17, -15, -13,
635 -11, -9, -7, -5, -2, 0, 1, 3,
636 5, 7, 9, 12, 14, 16, 18, 20,
637 22, 24, 26, 28, 31, 33, 35, 37,
638 39, 41, 43, 45, 47, 49, 51, 53,
639 54, 56, 58, 60, 62, 64, 66, 67,
640 69, 71, 73, 74, 76, 78, 79, 81,
641 83, 84, 86, 87, 89, 90, 92, 93,
642 94, 96, 97, 98, 99, 101, 102, 103,
643 104, 105, 106, 107, 108, 109, 110, 111, 112
646 static const int hsv_blue_y
[] = {
647 -11, -13, -15, -17, -19, -21, -23, -25,
648 -27, -29, -31, -33, -35, -37, -39, -41,
649 -43, -45, -46, -48, -50, -52, -54, -55,
650 -57, -59, -61, -62, -64, -66, -67, -69,
651 -71, -72, -74, -75, -77, -78, -80, -81,
652 -83, -84, -86, -87, -88, -90, -91, -92,
653 -93, -95, -96, -97, -98, -99, -100, -101,
654 -102, -103, -104, -105, -106, -106, -107, -108,
655 -109, -109, -110, -111, -111, -112, -112, -113,
656 -113, -114, -114, -114, -115, -115, -115, -115,
657 -116, -116, -116, -116, -116, -116, -116, -116,
658 -116, -115, -115, -115, -115, -114, -114, -114,
659 -113, -113, -112, -112, -111, -111, -110, -110,
660 -109, -108, -108, -107, -106, -105, -104, -103,
661 -102, -101, -100, -99, -98, -97, -96, -95,
662 -94, -93, -91, -90, -89, -88, -86, -85,
663 -84, -82, -81, -79, -78, -76, -75, -73,
664 -71, -70, -68, -67, -65, -63, -62, -60,
665 -58, -56, -55, -53, -51, -49, -47, -45,
666 -44, -42, -40, -38, -36, -34, -32, -30,
667 -28, -26, -24, -22, -20, -18, -16, -14,
668 -12, -10, -8, -6, -4, -2, 0, 1,
669 3, 5, 7, 9, 11, 13, 15, 17,
670 19, 21, 23, 25, 27, 29, 31, 33,
671 35, 37, 39, 41, 43, 45, 46, 48,
672 50, 52, 54, 55, 57, 59, 61, 62,
673 64, 66, 67, 69, 71, 72, 74, 75,
674 77, 78, 80, 81, 83, 84, 86, 87,
675 88, 90, 91, 92, 93, 95, 96, 97,
676 98, 99, 100, 101, 102, 103, 104, 105,
677 106, 106, 107, 108, 109, 109, 110, 111,
678 111, 112, 112, 113, 113, 114, 114, 114,
679 115, 115, 115, 115, 116, 116, 116, 116,
680 116, 116, 116, 116, 116, 115, 115, 115,
681 115, 114, 114, 114, 113, 113, 112, 112,
682 111, 111, 110, 110, 109, 108, 108, 107,
683 106, 105, 104, 103, 102, 101, 100, 99,
684 98, 97, 96, 95, 94, 93, 91, 90,
685 89, 88, 86, 85, 84, 82, 81, 79,
686 78, 76, 75, 73, 71, 70, 68, 67,
687 65, 63, 62, 60, 58, 56, 55, 53,
688 51, 49, 47, 45, 44, 42, 40, 38,
689 36, 34, 32, 30, 28, 26, 24, 22,
690 20, 18, 16, 14, 12, 10, 8, 6,
691 4, 2, 0, -1, -3, -5, -7, -9, -11
694 static u16 i2c_ident
[] = {
703 V4L2_IDENT_MT9M001C12ST
,
708 static u16 bridge_init
[][2] = {
709 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
710 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
711 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
712 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
713 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
714 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
715 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
716 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
717 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
718 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
719 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
720 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
721 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
722 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
723 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
724 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
725 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
726 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
727 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80}
730 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
731 static u8 ov_gain
[] = {
732 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
733 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
734 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
735 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
736 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
737 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
738 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
742 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
743 static u16 micron1_gain
[] = {
744 /* 1x 1.25x 1.5x 1.75x */
745 0x0020, 0x0028, 0x0030, 0x0038,
746 /* 2x 2.25x 2.5x 2.75x */
747 0x00a0, 0x00a4, 0x00a8, 0x00ac,
748 /* 3x 3.25x 3.5x 3.75x */
749 0x00b0, 0x00b4, 0x00b8, 0x00bc,
750 /* 4x 4.25x 4.5x 4.75x */
751 0x00c0, 0x00c4, 0x00c8, 0x00cc,
752 /* 5x 5.25x 5.5x 5.75x */
753 0x00d0, 0x00d4, 0x00d8, 0x00dc,
754 /* 6x 6.25x 6.5x 6.75x */
755 0x00e0, 0x00e4, 0x00e8, 0x00ec,
756 /* 7x 7.25x 7.5x 7.75x */
757 0x00f0, 0x00f4, 0x00f8, 0x00fc,
762 /* mt9m001 sensor uses a different gain formula then other micron sensors */
763 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
764 static u16 micron2_gain
[] = {
765 /* 1x 1.25x 1.5x 1.75x */
766 0x0008, 0x000a, 0x000c, 0x000e,
767 /* 2x 2.25x 2.5x 2.75x */
768 0x0010, 0x0012, 0x0014, 0x0016,
769 /* 3x 3.25x 3.5x 3.75x */
770 0x0018, 0x001a, 0x001c, 0x001e,
771 /* 4x 4.25x 4.5x 4.75x */
772 0x0020, 0x0051, 0x0052, 0x0053,
773 /* 5x 5.25x 5.5x 5.75x */
774 0x0054, 0x0055, 0x0056, 0x0057,
775 /* 6x 6.25x 6.5x 6.75x */
776 0x0058, 0x0059, 0x005a, 0x005b,
777 /* 7x 7.25x 7.5x 7.75x */
778 0x005c, 0x005d, 0x005e, 0x005f,
783 /* Gain = .5 + bit[7:0] / 16 */
784 static u8 hv7131r_gain
[] = {
785 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
786 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
787 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
788 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
789 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
790 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
791 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
795 static u8 soi968_init
[][2] = {
796 {0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f},
797 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
798 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
799 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
800 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
801 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
802 {0x13, 0x8a}, {0x12, 0x40}, {0x17, 0x13},
803 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
804 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
805 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
806 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
809 static u8 ov7660_init
[][2] = {
810 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
811 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
812 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
813 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
814 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6},
815 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
818 static u8 ov7670_init
[][2] = {
819 {0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
820 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
821 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
822 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
823 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
824 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
825 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
826 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
827 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
828 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
829 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
830 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
831 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
832 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
833 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
834 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
835 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
836 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
837 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
838 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
839 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
840 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
841 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
842 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
843 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
844 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
845 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
846 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
847 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
848 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
849 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
850 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
851 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
852 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
853 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
854 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
855 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
856 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
857 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
858 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
859 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
860 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
861 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
862 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
863 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
864 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
865 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
866 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
867 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
868 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
869 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
870 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
871 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
875 static u8 ov9650_init
[][2] = {
876 {0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78},
877 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
878 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
879 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
880 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
881 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
882 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
883 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
884 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
885 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
886 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
887 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
888 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
889 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
890 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
891 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
892 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
893 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
894 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
895 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
896 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
897 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
898 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
899 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
900 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
901 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
902 {0xaa, 0x92}, {0xab, 0x0a},
905 static u8 ov9655_init
[][2] = {
906 {0x12, 0x80}, {0x12, 0x01}, {0x0d, 0x00}, {0x0e, 0x61},
907 {0x11, 0x80}, {0x13, 0xba}, {0x14, 0x2e}, {0x16, 0x24},
908 {0x1e, 0x04}, {0x1e, 0x04}, {0x1e, 0x04}, {0x27, 0x08},
909 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x32, 0xbf},
910 {0x34, 0x3d}, {0x35, 0x00}, {0x36, 0xf8}, {0x38, 0x12},
911 {0x39, 0x57}, {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c},
912 {0x3d, 0x19}, {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40},
913 {0x42, 0x80}, {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a},
914 {0x48, 0x3c}, {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc},
915 {0x4d, 0xdc}, {0x4e, 0xdc}, {0x69, 0x02}, {0x6c, 0x04},
916 {0x6f, 0x9e}, {0x70, 0x05}, {0x71, 0x78}, {0x77, 0x02},
917 {0x8a, 0x23}, {0x8c, 0x0d}, {0x90, 0x7e}, {0x91, 0x7c},
918 {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68}, {0xa6, 0x60},
919 {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92}, {0xab, 0x04},
920 {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80}, {0xaf, 0x80},
921 {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00}, {0xb6, 0xaf},
922 {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44}, {0xbe, 0x3b},
923 {0xbf, 0x3a}, {0xc0, 0xe2}, {0xc1, 0xc8}, {0xc2, 0x01},
924 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
925 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x12, 0x61},
926 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
927 {0x03, 0x12}, {0x17, 0x14}, {0x18, 0x00}, {0x19, 0x01},
928 {0x1a, 0x3d}, {0x32, 0xbf}, {0x11, 0x80}, {0x2a, 0x10},
929 {0x2b, 0x0a}, {0x92, 0x00}, {0x93, 0x00}, {0x1e, 0x04},
930 {0x1e, 0x04}, {0x10, 0x7c}, {0x04, 0x03}, {0xa1, 0x00},
931 {0x2d, 0x00}, {0x2e, 0x00}, {0x00, 0x00}, {0x01, 0x80},
932 {0x02, 0x80}, {0x12, 0x61}, {0x36, 0xfa}, {0x8c, 0x8d},
933 {0xc0, 0xaa}, {0x69, 0x0a}, {0x03, 0x12}, {0x17, 0x14},
934 {0x18, 0x00}, {0x19, 0x01}, {0x1a, 0x3d}, {0x32, 0xbf},
935 {0x11, 0x80}, {0x2a, 0x10}, {0x2b, 0x0a}, {0x92, 0x00},
936 {0x93, 0x00}, {0x04, 0x01}, {0x10, 0x1f}, {0xa1, 0x00},
937 {0x00, 0x0a}, {0xa1, 0x00}, {0x10, 0x5d}, {0x04, 0x03},
938 {0x00, 0x01}, {0xa1, 0x00}, {0x10, 0x7c}, {0x04, 0x03},
939 {0x00, 0x03}, {0x00, 0x0a}, {0x00, 0x10}, {0x00, 0x13},
942 static u16 mt9v112_init
[][2] = {
943 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
944 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
945 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
946 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
947 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
948 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
949 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
950 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
951 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
952 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
953 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
954 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
955 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
956 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
957 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
958 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
961 static u16 mt9v111_init
[][2] = {
962 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
963 {0x01, 0x0001}, {0x02, 0x0016}, {0x03, 0x01e1},
964 {0x04, 0x0281}, {0x05, 0x0004}, {0x07, 0x3002},
965 {0x21, 0x0000}, {0x25, 0x4024}, {0x26, 0xff03},
966 {0x27, 0xff10}, {0x2b, 0x7828}, {0x2c, 0xb43c},
967 {0x2d, 0xf0a0}, {0x2e, 0x0c64}, {0x2f, 0x0064},
968 {0x67, 0x4010}, {0x06, 0x301e}, {0x08, 0x0480},
969 {0x01, 0x0004}, {0x02, 0x0016}, {0x03, 0x01e6},
970 {0x04, 0x0286}, {0x05, 0x0004}, {0x06, 0x0000},
971 {0x07, 0x3002}, {0x08, 0x0008}, {0x0c, 0x0000},
972 {0x0d, 0x0000}, {0x0e, 0x0000}, {0x0f, 0x0000},
973 {0x10, 0x0000}, {0x11, 0x0000}, {0x12, 0x00b0},
974 {0x13, 0x007c}, {0x14, 0x0000}, {0x15, 0x0000},
975 {0x16, 0x0000}, {0x17, 0x0000}, {0x18, 0x0000},
976 {0x19, 0x0000}, {0x1a, 0x0000}, {0x1b, 0x0000},
977 {0x1c, 0x0000}, {0x1d, 0x0000}, {0x30, 0x0000},
978 {0x30, 0x0005}, {0x31, 0x0000}, {0x02, 0x0016},
979 {0x03, 0x01e1}, {0x04, 0x0281}, {0x05, 0x0004},
980 {0x06, 0x0000}, {0x07, 0x3002}, {0x06, 0x002d},
981 {0x05, 0x0004}, {0x09, 0x0064}, {0x2b, 0x00a0},
982 {0x2c, 0x00a0}, {0x2d, 0x00a0}, {0x2e, 0x00a0},
983 {0x02, 0x0016}, {0x03, 0x01e1}, {0x04, 0x0281},
984 {0x05, 0x0004}, {0x06, 0x002d}, {0x07, 0x3002},
985 {0x0e, 0x0008}, {0x06, 0x002d}, {0x05, 0x0004},
988 static u16 mt9v011_init
[][2] = {
989 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
990 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
991 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
992 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
993 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
994 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
995 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
996 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
997 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
998 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
999 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
1000 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
1001 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
1002 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
1003 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
1004 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
1005 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
1006 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
1007 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
1008 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
1009 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
1010 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1011 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
1012 {0x06, 0x0029}, {0x05, 0x0009},
1015 static u16 mt9m001_init
[][2] = {
1016 {0x0d, 0x0001}, {0x0d, 0x0000}, {0x01, 0x000e},
1017 {0x02, 0x0014}, {0x03, 0x03c1}, {0x04, 0x0501},
1018 {0x05, 0x0083}, {0x06, 0x0006}, {0x0d, 0x0002},
1019 {0x0a, 0x0000}, {0x0c, 0x0000}, {0x11, 0x0000},
1020 {0x1e, 0x8000}, {0x5f, 0x8904}, {0x60, 0x0000},
1021 {0x61, 0x0000}, {0x62, 0x0498}, {0x63, 0x0000},
1022 {0x64, 0x0000}, {0x20, 0x111d}, {0x06, 0x00f2},
1023 {0x05, 0x0013}, {0x09, 0x10f2}, {0x07, 0x0003},
1024 {0x2b, 0x002a}, {0x2d, 0x002a}, {0x2c, 0x002a},
1025 {0x2e, 0x0029}, {0x07, 0x0002},
1028 static u16 mt9m111_init
[][2] = {
1029 {0xf0, 0x0000}, {0x0d, 0x0008}, {0x0d, 0x0009},
1030 {0x0d, 0x0008}, {0xf0, 0x0001}, {0x3a, 0x4300},
1031 {0x9b, 0x4300}, {0xa1, 0x0280}, {0xa4, 0x0200},
1032 {0x06, 0x308e}, {0xf0, 0x0000},
1035 static u8 hv7131r_init
[][2] = {
1036 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
1037 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
1038 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
1039 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
1040 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
1041 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
1042 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
1043 {0x23, 0x09}, {0x01, 0x08},
1046 int reg_r(struct gspca_dev
*gspca_dev
, u16 reg
, u16 length
)
1048 struct usb_device
*dev
= gspca_dev
->dev
;
1050 result
= usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
1052 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
1058 if (unlikely(result
< 0 || result
!= length
)) {
1059 err("Read register failed 0x%02X", reg
);
1065 int reg_w(struct gspca_dev
*gspca_dev
, u16 reg
, const u8
*buffer
, int length
)
1067 struct usb_device
*dev
= gspca_dev
->dev
;
1069 memcpy(gspca_dev
->usb_buf
, buffer
, length
);
1070 result
= usb_control_msg(dev
, usb_sndctrlpipe(dev
, 0),
1072 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
1078 if (unlikely(result
< 0 || result
!= length
)) {
1079 err("Write register failed index 0x%02X", reg
);
1085 int reg_w1(struct gspca_dev
*gspca_dev
, u16 reg
, const u8 value
)
1087 u8 data
[1] = {value
};
1088 return reg_w(gspca_dev
, reg
, data
, 1);
1091 int i2c_w(struct gspca_dev
*gspca_dev
, const u8
*buffer
)
1094 reg_w(gspca_dev
, 0x10c0, buffer
, 8);
1095 for (i
= 0; i
< 5; i
++) {
1096 reg_r(gspca_dev
, 0x10c0, 1);
1097 if (gspca_dev
->usb_buf
[0] & 0x04) {
1098 if (gspca_dev
->usb_buf
[0] & 0x08)
1107 int i2c_w1(struct gspca_dev
*gspca_dev
, u8 reg
, u8 val
)
1109 struct sd
*sd
= (struct sd
*) gspca_dev
;
1114 * from the point of view of the bridge, the length
1115 * includes the address
1117 row
[0] = 0x81 | (2 << 4);
1118 row
[1] = sd
->i2c_addr
;
1126 return i2c_w(gspca_dev
, row
);
1129 int i2c_w2(struct gspca_dev
*gspca_dev
, u8 reg
, u16 val
)
1131 struct sd
*sd
= (struct sd
*) gspca_dev
;
1135 * from the point of view of the bridge, the length
1136 * includes the address
1138 row
[0] = 0x81 | (3 << 4);
1139 row
[1] = sd
->i2c_addr
;
1141 row
[3] = (val
>> 8) & 0xff;
1142 row
[4] = val
& 0xff;
1147 return i2c_w(gspca_dev
, row
);
1150 int i2c_r1(struct gspca_dev
*gspca_dev
, u8 reg
, u8
*val
)
1152 struct sd
*sd
= (struct sd
*) gspca_dev
;
1155 row
[0] = 0x81 | 0x10;
1156 row
[1] = sd
->i2c_addr
;
1163 reg_w(gspca_dev
, 0x10c0, row
, 8);
1165 row
[0] = 0x81 | (2 << 4) | 0x02;
1167 reg_w(gspca_dev
, 0x10c0, row
, 8);
1169 reg_r(gspca_dev
, 0x10c2, 5);
1170 *val
= gspca_dev
->usb_buf
[3];
1174 int i2c_r2(struct gspca_dev
*gspca_dev
, u8 reg
, u16
*val
)
1176 struct sd
*sd
= (struct sd
*) gspca_dev
;
1179 row
[0] = 0x81 | 0x10;
1180 row
[1] = sd
->i2c_addr
;
1187 reg_w(gspca_dev
, 0x10c0, row
, 8);
1189 row
[0] = 0x81 | (3 << 4) | 0x02;
1191 reg_w(gspca_dev
, 0x10c0, row
, 8);
1193 reg_r(gspca_dev
, 0x10c2, 5);
1194 *val
= (gspca_dev
->usb_buf
[2] << 8) | gspca_dev
->usb_buf
[3];
1198 static int ov9650_init_sensor(struct gspca_dev
*gspca_dev
)
1201 struct sd
*sd
= (struct sd
*) gspca_dev
;
1203 for (i
= 0; i
< ARRAY_SIZE(ov9650_init
); i
++) {
1204 if (i2c_w1(gspca_dev
, ov9650_init
[i
][0],
1205 ov9650_init
[i
][1]) < 0) {
1206 err("OV9650 sensor initialization failed");
1215 static int ov9655_init_sensor(struct gspca_dev
*gspca_dev
)
1218 struct sd
*sd
= (struct sd
*) gspca_dev
;
1220 for (i
= 0; i
< ARRAY_SIZE(ov9655_init
); i
++) {
1221 if (i2c_w1(gspca_dev
, ov9655_init
[i
][0],
1222 ov9655_init
[i
][1]) < 0) {
1223 err("OV9655 sensor initialization failed");
1227 /* disable hflip and vflip */
1228 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1234 static int soi968_init_sensor(struct gspca_dev
*gspca_dev
)
1237 struct sd
*sd
= (struct sd
*) gspca_dev
;
1239 for (i
= 0; i
< ARRAY_SIZE(soi968_init
); i
++) {
1240 if (i2c_w1(gspca_dev
, soi968_init
[i
][0],
1241 soi968_init
[i
][1]) < 0) {
1242 err("SOI968 sensor initialization failed");
1246 /* disable hflip and vflip */
1247 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1253 static int ov7660_init_sensor(struct gspca_dev
*gspca_dev
)
1256 struct sd
*sd
= (struct sd
*) gspca_dev
;
1258 for (i
= 0; i
< ARRAY_SIZE(ov7660_init
); i
++) {
1259 if (i2c_w1(gspca_dev
, ov7660_init
[i
][0],
1260 ov7660_init
[i
][1]) < 0) {
1261 err("OV7660 sensor initialization failed");
1265 /* disable hflip and vflip */
1266 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1272 static int ov7670_init_sensor(struct gspca_dev
*gspca_dev
)
1275 struct sd
*sd
= (struct sd
*) gspca_dev
;
1277 for (i
= 0; i
< ARRAY_SIZE(ov7670_init
); i
++) {
1278 if (i2c_w1(gspca_dev
, ov7670_init
[i
][0],
1279 ov7670_init
[i
][1]) < 0) {
1280 err("OV7670 sensor initialization failed");
1284 /* disable hflip and vflip */
1285 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1291 static int mt9v_init_sensor(struct gspca_dev
*gspca_dev
)
1293 struct sd
*sd
= (struct sd
*) gspca_dev
;
1298 sd
->i2c_addr
= 0x5d;
1299 ret
= i2c_r2(gspca_dev
, 0xff, &value
);
1300 if ((ret
== 0) && (value
== 0x8243)) {
1301 for (i
= 0; i
< ARRAY_SIZE(mt9v011_init
); i
++) {
1302 if (i2c_w2(gspca_dev
, mt9v011_init
[i
][0],
1303 mt9v011_init
[i
][1]) < 0) {
1304 err("MT9V011 sensor initialization failed");
1310 sd
->sensor
= SENSOR_MT9V011
;
1311 info("MT9V011 sensor detected");
1315 sd
->i2c_addr
= 0x5c;
1316 i2c_w2(gspca_dev
, 0x01, 0x0004);
1317 ret
= i2c_r2(gspca_dev
, 0xff, &value
);
1318 if ((ret
== 0) && (value
== 0x823a)) {
1319 for (i
= 0; i
< ARRAY_SIZE(mt9v111_init
); i
++) {
1320 if (i2c_w2(gspca_dev
, mt9v111_init
[i
][0],
1321 mt9v111_init
[i
][1]) < 0) {
1322 err("MT9V111 sensor initialization failed");
1328 sd
->sensor
= SENSOR_MT9V111
;
1329 info("MT9V111 sensor detected");
1333 sd
->i2c_addr
= 0x5d;
1334 ret
= i2c_w2(gspca_dev
, 0xf0, 0x0000);
1336 sd
->i2c_addr
= 0x48;
1337 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1339 ret
= i2c_r2(gspca_dev
, 0x00, &value
);
1340 if ((ret
== 0) && (value
== 0x1229)) {
1341 for (i
= 0; i
< ARRAY_SIZE(mt9v112_init
); i
++) {
1342 if (i2c_w2(gspca_dev
, mt9v112_init
[i
][0],
1343 mt9v112_init
[i
][1]) < 0) {
1344 err("MT9V112 sensor initialization failed");
1350 sd
->sensor
= SENSOR_MT9V112
;
1351 info("MT9V112 sensor detected");
1358 static int mt9m111_init_sensor(struct gspca_dev
*gspca_dev
)
1360 struct sd
*sd
= (struct sd
*) gspca_dev
;
1362 for (i
= 0; i
< ARRAY_SIZE(mt9m111_init
); i
++) {
1363 if (i2c_w2(gspca_dev
, mt9m111_init
[i
][0],
1364 mt9m111_init
[i
][1]) < 0) {
1365 err("MT9M111 sensor initialization failed");
1374 static int mt9m001_init_sensor(struct gspca_dev
*gspca_dev
)
1376 struct sd
*sd
= (struct sd
*) gspca_dev
;
1378 for (i
= 0; i
< ARRAY_SIZE(mt9m001_init
); i
++) {
1379 if (i2c_w2(gspca_dev
, mt9m001_init
[i
][0],
1380 mt9m001_init
[i
][1]) < 0) {
1381 err("MT9M001 sensor initialization failed");
1385 /* disable hflip and vflip */
1386 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1392 static int hv7131r_init_sensor(struct gspca_dev
*gspca_dev
)
1395 struct sd
*sd
= (struct sd
*) gspca_dev
;
1397 for (i
= 0; i
< ARRAY_SIZE(hv7131r_init
); i
++) {
1398 if (i2c_w1(gspca_dev
, hv7131r_init
[i
][0],
1399 hv7131r_init
[i
][1]) < 0) {
1400 err("HV7131R Sensor initialization failed");
1409 #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
1410 static int input_kthread(void *data
)
1412 struct gspca_dev
*gspca_dev
= (struct gspca_dev
*)data
;
1413 struct sd
*sd
= (struct sd
*) gspca_dev
;
1415 DECLARE_WAIT_QUEUE_HEAD(wait
);
1418 if (kthread_should_stop())
1421 if (reg_r(gspca_dev
, 0x1005, 1) < 0)
1424 input_report_key(sd
->input_dev
,
1426 gspca_dev
->usb_buf
[0] & sd
->input_gpio
);
1427 input_sync(sd
->input_dev
);
1429 wait_event_freezable_timeout(wait
,
1430 kthread_should_stop(),
1431 msecs_to_jiffies(100));
1437 static int sn9c20x_input_init(struct gspca_dev
*gspca_dev
)
1439 struct sd
*sd
= (struct sd
*) gspca_dev
;
1440 if (sd
->input_gpio
== 0)
1443 sd
->input_dev
= input_allocate_device();
1447 sd
->input_dev
->name
= "SN9C20X Webcam";
1449 sd
->input_dev
->phys
= kasprintf(GFP_KERNEL
, "usb-%s-%s",
1450 gspca_dev
->dev
->bus
->bus_name
,
1451 gspca_dev
->dev
->devpath
);
1453 if (!sd
->input_dev
->phys
)
1456 usb_to_input_id(gspca_dev
->dev
, &sd
->input_dev
->id
);
1457 sd
->input_dev
->dev
.parent
= &gspca_dev
->dev
->dev
;
1459 set_bit(EV_KEY
, sd
->input_dev
->evbit
);
1460 set_bit(KEY_CAMERA
, sd
->input_dev
->keybit
);
1462 if (input_register_device(sd
->input_dev
))
1465 sd
->input_task
= kthread_run(input_kthread
, gspca_dev
, "sn9c20x/%d",
1466 gspca_dev
->vdev
.minor
);
1468 if (IS_ERR(sd
->input_task
))
1474 static void sn9c20x_input_cleanup(struct gspca_dev
*gspca_dev
)
1476 struct sd
*sd
= (struct sd
*) gspca_dev
;
1477 if (sd
->input_task
!= NULL
&& !IS_ERR(sd
->input_task
))
1478 kthread_stop(sd
->input_task
);
1480 if (sd
->input_dev
!= NULL
) {
1481 input_unregister_device(sd
->input_dev
);
1482 kfree(sd
->input_dev
->phys
);
1483 input_free_device(sd
->input_dev
);
1484 sd
->input_dev
= NULL
;
1489 static int set_cmatrix(struct gspca_dev
*gspca_dev
)
1491 struct sd
*sd
= (struct sd
*) gspca_dev
;
1492 s32 hue_coord
, hue_index
= 180 + sd
->hue
;
1494 memset(cmatrix
, 0, 21);
1496 cmatrix
[2] = (sd
->contrast
* 0x25 / 0x100) + 0x26;
1497 cmatrix
[0] = 0x13 + (cmatrix
[2] - 0x26) * 0x13 / 0x25;
1498 cmatrix
[4] = 0x07 + (cmatrix
[2] - 0x26) * 0x07 / 0x25;
1499 cmatrix
[18] = sd
->brightness
- 0x80;
1501 hue_coord
= (hsv_red_x
[hue_index
] * sd
->saturation
) >> 8;
1502 cmatrix
[6] = (unsigned char)(hue_coord
& 0xff);
1503 cmatrix
[7] = (unsigned char)((hue_coord
>> 8) & 0x0f);
1505 hue_coord
= (hsv_red_y
[hue_index
] * sd
->saturation
) >> 8;
1506 cmatrix
[8] = (unsigned char)(hue_coord
& 0xff);
1507 cmatrix
[9] = (unsigned char)((hue_coord
>> 8) & 0x0f);
1509 hue_coord
= (hsv_green_x
[hue_index
] * sd
->saturation
) >> 8;
1510 cmatrix
[10] = (unsigned char)(hue_coord
& 0xff);
1511 cmatrix
[11] = (unsigned char)((hue_coord
>> 8) & 0x0f);
1513 hue_coord
= (hsv_green_y
[hue_index
] * sd
->saturation
) >> 8;
1514 cmatrix
[12] = (unsigned char)(hue_coord
& 0xff);
1515 cmatrix
[13] = (unsigned char)((hue_coord
>> 8) & 0x0f);
1517 hue_coord
= (hsv_blue_x
[hue_index
] * sd
->saturation
) >> 8;
1518 cmatrix
[14] = (unsigned char)(hue_coord
& 0xff);
1519 cmatrix
[15] = (unsigned char)((hue_coord
>> 8) & 0x0f);
1521 hue_coord
= (hsv_blue_y
[hue_index
] * sd
->saturation
) >> 8;
1522 cmatrix
[16] = (unsigned char)(hue_coord
& 0xff);
1523 cmatrix
[17] = (unsigned char)((hue_coord
>> 8) & 0x0f);
1525 return reg_w(gspca_dev
, 0x10e1, cmatrix
, 21);
1528 static int set_gamma(struct gspca_dev
*gspca_dev
)
1530 struct sd
*sd
= (struct sd
*) gspca_dev
;
1532 u8 gval
= sd
->gamma
* 0xb8 / 0x100;
1536 gamma
[1] = 0x13 + (gval
* (0xcb - 0x13) / 0xb8);
1537 gamma
[2] = 0x25 + (gval
* (0xee - 0x25) / 0xb8);
1538 gamma
[3] = 0x37 + (gval
* (0xfa - 0x37) / 0xb8);
1539 gamma
[4] = 0x45 + (gval
* (0xfc - 0x45) / 0xb8);
1540 gamma
[5] = 0x55 + (gval
* (0xfb - 0x55) / 0xb8);
1541 gamma
[6] = 0x65 + (gval
* (0xfc - 0x65) / 0xb8);
1542 gamma
[7] = 0x74 + (gval
* (0xfd - 0x74) / 0xb8);
1543 gamma
[8] = 0x83 + (gval
* (0xfe - 0x83) / 0xb8);
1544 gamma
[9] = 0x92 + (gval
* (0xfc - 0x92) / 0xb8);
1545 gamma
[10] = 0xa1 + (gval
* (0xfc - 0xa1) / 0xb8);
1546 gamma
[11] = 0xb0 + (gval
* (0xfc - 0xb0) / 0xb8);
1547 gamma
[12] = 0xbf + (gval
* (0xfb - 0xbf) / 0xb8);
1548 gamma
[13] = 0xce + (gval
* (0xfb - 0xce) / 0xb8);
1549 gamma
[14] = 0xdf + (gval
* (0xfd - 0xdf) / 0xb8);
1550 gamma
[15] = 0xea + (gval
* (0xf9 - 0xea) / 0xb8);
1553 return reg_w(gspca_dev
, 0x1190, gamma
, 17);
1556 static int set_redblue(struct gspca_dev
*gspca_dev
)
1558 struct sd
*sd
= (struct sd
*) gspca_dev
;
1559 reg_w1(gspca_dev
, 0x118c, sd
->red
);
1560 reg_w1(gspca_dev
, 0x118f, sd
->blue
);
1564 static int set_hvflip(struct gspca_dev
*gspca_dev
)
1568 struct sd
*sd
= (struct sd
*) gspca_dev
;
1569 switch (sd
->sensor
) {
1571 i2c_r1(gspca_dev
, 0x1e, &value
);
1580 i2c_w1(gspca_dev
, 0x1e, value
);
1581 i2c_w1(gspca_dev
, 0x3a, tslb
);
1583 case SENSOR_MT9V111
:
1584 case SENSOR_MT9V011
:
1585 i2c_r2(gspca_dev
, 0x20, &value2
);
1591 i2c_w2(gspca_dev
, 0x20, value2
);
1593 case SENSOR_MT9M111
:
1594 case SENSOR_MT9V112
:
1595 i2c_r2(gspca_dev
, 0x20, &value2
);
1601 i2c_w2(gspca_dev
, 0x20, value2
);
1603 case SENSOR_HV7131R
:
1604 i2c_r1(gspca_dev
, 0x01, &value
);
1610 i2c_w1(gspca_dev
, 0x01, value
);
1616 static int set_exposure(struct gspca_dev
*gspca_dev
)
1618 struct sd
*sd
= (struct sd
*) gspca_dev
;
1619 u8 exp
[8] = {0x81, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1620 switch (sd
->sensor
) {
1628 exp
[3] = sd
->exposure
& 0xff;
1629 exp
[4] = sd
->exposure
>> 8;
1631 case SENSOR_MT9M001
:
1632 case SENSOR_MT9M111
:
1633 case SENSOR_MT9V112
:
1634 case SENSOR_MT9V111
:
1635 case SENSOR_MT9V011
:
1638 exp
[3] = sd
->exposure
>> 8;
1639 exp
[4] = sd
->exposure
& 0xff;
1641 case SENSOR_HV7131R
:
1644 exp
[3] = ((sd
->exposure
* 0xffffff) / 0xffff) >> 16;
1645 exp
[4] = ((sd
->exposure
* 0xffffff) / 0xffff) >> 8;
1646 exp
[5] = ((sd
->exposure
* 0xffffff) / 0xffff) & 0xff;
1649 i2c_w(gspca_dev
, exp
);
1653 static int set_gain(struct gspca_dev
*gspca_dev
)
1655 struct sd
*sd
= (struct sd
*) gspca_dev
;
1656 u8 gain
[8] = {0x81, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1657 switch (sd
->sensor
) {
1663 gain
[0] |= (2 << 4);
1664 gain
[3] = ov_gain
[sd
->gain
];
1666 case SENSOR_MT9V011
:
1667 case SENSOR_MT9V111
:
1668 gain
[0] |= (3 << 4);
1670 gain
[3] = micron1_gain
[sd
->gain
] >> 8;
1671 gain
[4] = micron1_gain
[sd
->gain
] & 0xff;
1673 case SENSOR_MT9V112
:
1674 case SENSOR_MT9M111
:
1675 gain
[0] |= (3 << 4);
1677 gain
[3] = micron1_gain
[sd
->gain
] >> 8;
1678 gain
[4] = micron1_gain
[sd
->gain
] & 0xff;
1680 case SENSOR_MT9M001
:
1681 gain
[0] |= (3 << 4);
1683 gain
[3] = micron2_gain
[sd
->gain
] >> 8;
1684 gain
[4] = micron2_gain
[sd
->gain
] & 0xff;
1686 case SENSOR_HV7131R
:
1687 gain
[0] |= (2 << 4);
1689 gain
[3] = hv7131r_gain
[sd
->gain
];
1692 i2c_w(gspca_dev
, gain
);
1696 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, s32 val
)
1698 struct sd
*sd
= (struct sd
*) gspca_dev
;
1700 sd
->brightness
= val
;
1701 if (gspca_dev
->streaming
)
1702 return set_cmatrix(gspca_dev
);
1706 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, s32
*val
)
1708 struct sd
*sd
= (struct sd
*) gspca_dev
;
1709 *val
= sd
->brightness
;
1714 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, s32 val
)
1716 struct sd
*sd
= (struct sd
*) gspca_dev
;
1719 if (gspca_dev
->streaming
)
1720 return set_cmatrix(gspca_dev
);
1724 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, s32
*val
)
1726 struct sd
*sd
= (struct sd
*) gspca_dev
;
1727 *val
= sd
->contrast
;
1731 static int sd_setsaturation(struct gspca_dev
*gspca_dev
, s32 val
)
1733 struct sd
*sd
= (struct sd
*) gspca_dev
;
1735 sd
->saturation
= val
;
1736 if (gspca_dev
->streaming
)
1737 return set_cmatrix(gspca_dev
);
1741 static int sd_getsaturation(struct gspca_dev
*gspca_dev
, s32
*val
)
1743 struct sd
*sd
= (struct sd
*) gspca_dev
;
1744 *val
= sd
->saturation
;
1748 static int sd_sethue(struct gspca_dev
*gspca_dev
, s32 val
)
1750 struct sd
*sd
= (struct sd
*) gspca_dev
;
1753 if (gspca_dev
->streaming
)
1754 return set_cmatrix(gspca_dev
);
1758 static int sd_gethue(struct gspca_dev
*gspca_dev
, s32
*val
)
1760 struct sd
*sd
= (struct sd
*) gspca_dev
;
1765 static int sd_setgamma(struct gspca_dev
*gspca_dev
, s32 val
)
1767 struct sd
*sd
= (struct sd
*) gspca_dev
;
1770 if (gspca_dev
->streaming
)
1771 return set_gamma(gspca_dev
);
1775 static int sd_getgamma(struct gspca_dev
*gspca_dev
, s32
*val
)
1777 struct sd
*sd
= (struct sd
*) gspca_dev
;
1782 static int sd_setredbalance(struct gspca_dev
*gspca_dev
, s32 val
)
1784 struct sd
*sd
= (struct sd
*) gspca_dev
;
1787 if (gspca_dev
->streaming
)
1788 return set_redblue(gspca_dev
);
1792 static int sd_getredbalance(struct gspca_dev
*gspca_dev
, s32
*val
)
1794 struct sd
*sd
= (struct sd
*) gspca_dev
;
1799 static int sd_setbluebalance(struct gspca_dev
*gspca_dev
, s32 val
)
1801 struct sd
*sd
= (struct sd
*) gspca_dev
;
1804 if (gspca_dev
->streaming
)
1805 return set_redblue(gspca_dev
);
1809 static int sd_getbluebalance(struct gspca_dev
*gspca_dev
, s32
*val
)
1811 struct sd
*sd
= (struct sd
*) gspca_dev
;
1816 static int sd_sethflip(struct gspca_dev
*gspca_dev
, s32 val
)
1818 struct sd
*sd
= (struct sd
*) gspca_dev
;
1821 if (gspca_dev
->streaming
)
1822 return set_hvflip(gspca_dev
);
1826 static int sd_gethflip(struct gspca_dev
*gspca_dev
, s32
*val
)
1828 struct sd
*sd
= (struct sd
*) gspca_dev
;
1833 static int sd_setvflip(struct gspca_dev
*gspca_dev
, s32 val
)
1835 struct sd
*sd
= (struct sd
*) gspca_dev
;
1838 if (gspca_dev
->streaming
)
1839 return set_hvflip(gspca_dev
);
1843 static int sd_getvflip(struct gspca_dev
*gspca_dev
, s32
*val
)
1845 struct sd
*sd
= (struct sd
*) gspca_dev
;
1850 static int sd_setexposure(struct gspca_dev
*gspca_dev
, s32 val
)
1852 struct sd
*sd
= (struct sd
*) gspca_dev
;
1855 if (gspca_dev
->streaming
)
1856 return set_exposure(gspca_dev
);
1860 static int sd_getexposure(struct gspca_dev
*gspca_dev
, s32
*val
)
1862 struct sd
*sd
= (struct sd
*) gspca_dev
;
1863 *val
= sd
->exposure
;
1867 static int sd_setgain(struct gspca_dev
*gspca_dev
, s32 val
)
1869 struct sd
*sd
= (struct sd
*) gspca_dev
;
1872 if (gspca_dev
->streaming
)
1873 return set_gain(gspca_dev
);
1877 static int sd_getgain(struct gspca_dev
*gspca_dev
, s32
*val
)
1879 struct sd
*sd
= (struct sd
*) gspca_dev
;
1884 static int sd_setautoexposure(struct gspca_dev
*gspca_dev
, s32 val
)
1886 struct sd
*sd
= (struct sd
*) gspca_dev
;
1887 sd
->auto_exposure
= val
;
1891 static int sd_getautoexposure(struct gspca_dev
*gspca_dev
, s32
*val
)
1893 struct sd
*sd
= (struct sd
*) gspca_dev
;
1894 *val
= sd
->auto_exposure
;
1898 #ifdef CONFIG_VIDEO_ADV_DEBUG
1899 static int sd_dbg_g_register(struct gspca_dev
*gspca_dev
,
1900 struct v4l2_dbg_register
*reg
)
1902 struct sd
*sd
= (struct sd
*) gspca_dev
;
1903 switch (reg
->match
.type
) {
1904 case V4L2_CHIP_MATCH_HOST
:
1905 if (reg
->match
.addr
!= 0)
1907 if (reg
->reg
< 0x1000 || reg
->reg
> 0x11ff)
1909 if (reg_r(gspca_dev
, reg
->reg
, 1) < 0)
1911 reg
->val
= gspca_dev
->usb_buf
[0];
1913 case V4L2_CHIP_MATCH_I2C_ADDR
:
1914 if (reg
->match
.addr
!= sd
->i2c_addr
)
1916 if (sd
->sensor
>= SENSOR_MT9V011
&&
1917 sd
->sensor
<= SENSOR_MT9M111
) {
1918 if (i2c_r2(gspca_dev
, reg
->reg
, (u16
*)®
->val
) < 0)
1921 if (i2c_r1(gspca_dev
, reg
->reg
, (u8
*)®
->val
) < 0)
1929 static int sd_dbg_s_register(struct gspca_dev
*gspca_dev
,
1930 struct v4l2_dbg_register
*reg
)
1932 struct sd
*sd
= (struct sd
*) gspca_dev
;
1933 switch (reg
->match
.type
) {
1934 case V4L2_CHIP_MATCH_HOST
:
1935 if (reg
->match
.addr
!= 0)
1937 if (reg
->reg
< 0x1000 || reg
->reg
> 0x11ff)
1939 if (reg_w1(gspca_dev
, reg
->reg
, reg
->val
) < 0)
1942 case V4L2_CHIP_MATCH_I2C_ADDR
:
1943 if (reg
->match
.addr
!= sd
->i2c_addr
)
1945 if (sd
->sensor
>= SENSOR_MT9V011
&&
1946 sd
->sensor
<= SENSOR_MT9M111
) {
1947 if (i2c_w2(gspca_dev
, reg
->reg
, reg
->val
) < 0)
1950 if (i2c_w1(gspca_dev
, reg
->reg
, reg
->val
) < 0)
1959 static int sd_chip_ident(struct gspca_dev
*gspca_dev
,
1960 struct v4l2_dbg_chip_ident
*chip
)
1962 struct sd
*sd
= (struct sd
*) gspca_dev
;
1964 switch (chip
->match
.type
) {
1965 case V4L2_CHIP_MATCH_HOST
:
1966 if (chip
->match
.addr
!= 0)
1969 chip
->ident
= V4L2_IDENT_SN9C20X
;
1971 case V4L2_CHIP_MATCH_I2C_ADDR
:
1972 if (chip
->match
.addr
!= sd
->i2c_addr
)
1975 chip
->ident
= i2c_ident
[sd
->sensor
];
1981 static int sd_config(struct gspca_dev
*gspca_dev
,
1982 const struct usb_device_id
*id
)
1984 struct sd
*sd
= (struct sd
*) gspca_dev
;
1987 cam
= &gspca_dev
->cam
;
1989 sd
->sensor
= (id
->driver_info
>> 8) & 0xff;
1990 sd
->i2c_addr
= id
->driver_info
& 0xff;
1992 switch (sd
->sensor
) {
1994 cam
->cam_mode
= sxga_mode
;
1995 cam
->nmodes
= ARRAY_SIZE(sxga_mode
);
1998 cam
->cam_mode
= vga_mode
;
1999 cam
->nmodes
= ARRAY_SIZE(vga_mode
);
2004 sd
->exposure_step
= 16;
2006 sd
->brightness
= BRIGHTNESS_DEFAULT
;
2007 sd
->contrast
= CONTRAST_DEFAULT
;
2008 sd
->saturation
= SATURATION_DEFAULT
;
2009 sd
->hue
= HUE_DEFAULT
;
2010 sd
->gamma
= GAMMA_DEFAULT
;
2011 sd
->red
= RED_DEFAULT
;
2012 sd
->blue
= BLUE_DEFAULT
;
2014 sd
->hflip
= HFLIP_DEFAULT
;
2015 sd
->vflip
= VFLIP_DEFAULT
;
2016 sd
->exposure
= EXPOSURE_DEFAULT
;
2017 sd
->gain
= GAIN_DEFAULT
;
2018 sd
->auto_exposure
= AUTO_EXPOSURE_DEFAULT
;
2022 #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
2023 sd
->input_gpio
= (id
->driver_info
>> 16) & 0xff;
2024 if (sn9c20x_input_init(gspca_dev
) < 0)
2030 static int sd_init(struct gspca_dev
*gspca_dev
)
2032 struct sd
*sd
= (struct sd
*) gspca_dev
;
2036 {0x80, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
2038 for (i
= 0; i
< ARRAY_SIZE(bridge_init
); i
++) {
2039 value
= bridge_init
[i
][1];
2040 if (reg_w(gspca_dev
, bridge_init
[i
][0], &value
, 1) < 0) {
2041 err("Device initialization failed");
2046 if (reg_w(gspca_dev
, 0x10c0, i2c_init
, 9) < 0) {
2047 err("Device initialization failed");
2051 switch (sd
->sensor
) {
2053 if (ov9650_init_sensor(gspca_dev
) < 0)
2055 info("OV9650 sensor detected");
2058 if (ov9655_init_sensor(gspca_dev
) < 0)
2060 info("OV9655 sensor detected");
2063 if (soi968_init_sensor(gspca_dev
) < 0)
2065 info("SOI968 sensor detected");
2068 if (ov7660_init_sensor(gspca_dev
) < 0)
2070 info("OV7660 sensor detected");
2073 if (ov7670_init_sensor(gspca_dev
) < 0)
2075 info("OV7670 sensor detected");
2077 case SENSOR_MT9VPRB
:
2078 if (mt9v_init_sensor(gspca_dev
) < 0)
2081 case SENSOR_MT9M111
:
2082 if (mt9m111_init_sensor(gspca_dev
) < 0)
2084 info("MT9M111 sensor detected");
2086 case SENSOR_MT9M001
:
2087 if (mt9m001_init_sensor(gspca_dev
) < 0)
2089 info("MT9M001 sensor detected");
2091 case SENSOR_HV7131R
:
2092 if (hv7131r_init_sensor(gspca_dev
) < 0)
2094 info("HV7131R sensor detected");
2097 info("Unsupported Sensor");
2104 static void configure_sensor_output(struct gspca_dev
*gspca_dev
, int mode
)
2106 struct sd
*sd
= (struct sd
*) gspca_dev
;
2108 switch (sd
->sensor
) {
2110 if (mode
& MODE_SXGA
) {
2111 i2c_w1(gspca_dev
, 0x17, 0x1b);
2112 i2c_w1(gspca_dev
, 0x18, 0xbc);
2113 i2c_w1(gspca_dev
, 0x19, 0x01);
2114 i2c_w1(gspca_dev
, 0x1a, 0x82);
2115 i2c_r1(gspca_dev
, 0x12, &value
);
2116 i2c_w1(gspca_dev
, 0x12, value
& 0x07);
2118 i2c_w1(gspca_dev
, 0x17, 0x24);
2119 i2c_w1(gspca_dev
, 0x18, 0xc5);
2120 i2c_w1(gspca_dev
, 0x19, 0x00);
2121 i2c_w1(gspca_dev
, 0x1a, 0x3c);
2122 i2c_r1(gspca_dev
, 0x12, &value
);
2123 i2c_w1(gspca_dev
, 0x12, (value
& 0x7) | 0x40);
2129 #define HW_WIN(mode, hstart, vstart) \
2130 ((const u8 []){hstart & 0xff, hstart >> 8, \
2131 vstart & 0xff, vstart >> 8, \
2132 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
2133 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
2135 #define CLR_WIN(width, height) \
2137 {0, width >> 2, 0, height >> 1,\
2138 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
2140 static int sd_start(struct gspca_dev
*gspca_dev
)
2142 struct sd
*sd
= (struct sd
*) gspca_dev
;
2143 int mode
= gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
;
2144 int width
= gspca_dev
->width
;
2145 int height
= gspca_dev
->height
;
2148 sd
->jpeg_hdr
= kmalloc(JPEG_HDR_SZ
, GFP_KERNEL
);
2149 if (sd
->jpeg_hdr
== NULL
)
2152 jpeg_define(sd
->jpeg_hdr
, height
, width
,
2154 jpeg_set_qual(sd
->jpeg_hdr
, sd
->quality
);
2156 if (mode
& MODE_RAW
)
2158 else if (mode
& MODE_JPEG
)
2163 switch (mode
& 0x0f) {
2166 info("Set 1280x1024");
2170 info("Set 640x480");
2174 info("Set 320x240");
2178 info("Set 160x120");
2182 configure_sensor_output(gspca_dev
, mode
);
2183 reg_w(gspca_dev
, 0x1100, sd
->jpeg_hdr
+ JPEG_QT0_OFFSET
, 64);
2184 reg_w(gspca_dev
, 0x1140, sd
->jpeg_hdr
+ JPEG_QT1_OFFSET
, 64);
2185 reg_w(gspca_dev
, 0x10fb, CLR_WIN(width
, height
), 5);
2186 reg_w(gspca_dev
, 0x1180, HW_WIN(mode
, sd
->hstart
, sd
->vstart
), 6);
2187 reg_w1(gspca_dev
, 0x1189, scale
);
2188 reg_w1(gspca_dev
, 0x10e0, fmt
);
2190 set_cmatrix(gspca_dev
);
2191 set_gamma(gspca_dev
);
2192 set_redblue(gspca_dev
);
2193 set_gain(gspca_dev
);
2194 set_exposure(gspca_dev
);
2195 set_hvflip(gspca_dev
);
2197 reg_r(gspca_dev
, 0x1061, 1);
2198 reg_w1(gspca_dev
, 0x1061, gspca_dev
->usb_buf
[0] | 0x02);
2202 static void sd_stopN(struct gspca_dev
*gspca_dev
)
2204 reg_r(gspca_dev
, 0x1061, 1);
2205 reg_w1(gspca_dev
, 0x1061, gspca_dev
->usb_buf
[0] & ~0x02);
2208 static void sd_stop0(struct gspca_dev
*gspca_dev
)
2210 struct sd
*sd
= (struct sd
*) gspca_dev
;
2211 kfree(sd
->jpeg_hdr
);
2214 static void do_autoexposure(struct gspca_dev
*gspca_dev
)
2216 struct sd
*sd
= (struct sd
*) gspca_dev
;
2217 int avg_lum
, new_exp
;
2219 if (!sd
->auto_exposure
)
2222 avg_lum
= atomic_read(&sd
->avg_lum
);
2225 * some hardcoded values are present
2226 * like those for maximal/minimal exposure
2227 * and exposure steps
2229 if (avg_lum
< MIN_AVG_LUM
) {
2230 if (sd
->exposure
> 0x1770)
2233 new_exp
= sd
->exposure
+ sd
->exposure_step
;
2234 if (new_exp
> 0x1770)
2238 sd
->exposure
= new_exp
;
2239 set_exposure(gspca_dev
);
2241 sd
->older_step
= sd
->old_step
;
2244 if (sd
->old_step
^ sd
->older_step
)
2245 sd
->exposure_step
/= 2;
2247 sd
->exposure_step
+= 2;
2249 if (avg_lum
> MAX_AVG_LUM
) {
2250 if (sd
->exposure
< 0x10)
2252 new_exp
= sd
->exposure
- sd
->exposure_step
;
2253 if (new_exp
> 0x1700)
2257 sd
->exposure
= new_exp
;
2258 set_exposure(gspca_dev
);
2259 sd
->older_step
= sd
->old_step
;
2262 if (sd
->old_step
^ sd
->older_step
)
2263 sd
->exposure_step
/= 2;
2265 sd
->exposure_step
+= 2;
2269 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
2270 struct gspca_frame
*frame
, /* target */
2271 u8
*data
, /* isoc packet */
2272 int len
) /* iso packet length */
2274 struct sd
*sd
= (struct sd
*) gspca_dev
;
2276 static unsigned char frame_header
[] =
2277 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2278 if (len
== 64 && memcmp(data
, frame_header
, 6) == 0) {
2279 avg_lum
= ((data
[35] >> 2) & 3) |
2282 avg_lum
+= ((data
[35] >> 4) & 3) |
2285 avg_lum
+= ((data
[35] >> 6) & 3) |
2288 avg_lum
+= (data
[36] & 3) |
2291 avg_lum
+= ((data
[36] >> 2) & 3) |
2294 avg_lum
+= ((data
[36] >> 4) & 3) |
2297 avg_lum
+= ((data
[36] >> 6) & 3) |
2300 avg_lum
+= ((data
[44] >> 4) & 3) |
2304 atomic_set(&sd
->avg_lum
, avg_lum
);
2305 gspca_frame_add(gspca_dev
, LAST_PACKET
,
2309 if (gspca_dev
->last_packet_type
== LAST_PACKET
) {
2310 if (gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
2312 gspca_frame_add(gspca_dev
, FIRST_PACKET
, frame
,
2313 sd
->jpeg_hdr
, JPEG_HDR_SZ
);
2314 gspca_frame_add(gspca_dev
, INTER_PACKET
, frame
,
2317 gspca_frame_add(gspca_dev
, FIRST_PACKET
, frame
,
2321 gspca_frame_add(gspca_dev
, INTER_PACKET
, frame
, data
, len
);
2325 /* sub-driver description */
2326 static const struct sd_desc sd_desc
= {
2327 .name
= MODULE_NAME
,
2329 .nctrls
= ARRAY_SIZE(sd_ctrls
),
2330 .config
= sd_config
,
2335 .pkt_scan
= sd_pkt_scan
,
2336 .dq_callback
= do_autoexposure
,
2337 #ifdef CONFIG_VIDEO_ADV_DEBUG
2338 .set_register
= sd_dbg_s_register
,
2339 .get_register
= sd_dbg_g_register
,
2341 .get_chip_ident
= sd_chip_ident
,
2344 #define SN9C20X(sensor, i2c_addr, button_mask) \
2345 .driver_info = (button_mask << 16) \
2346 | (SENSOR_ ## sensor << 8) \
2349 static const __devinitdata
struct usb_device_id device_table
[] = {
2350 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001
, 0x5d, 0)},
2351 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111
, 0x5d, 0)},
2352 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655
, 0x30, 0)},
2353 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968
, 0x30, 0x10)},
2354 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650
, 0x30, 0)},
2355 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650
, 0x30, 0)},
2356 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650
, 0x30, 0)},
2357 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670
, 0x21, 0)},
2358 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB
, 0x00, 0)},
2359 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660
, 0x21, 0)},
2360 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R
, 0x11, 0)},
2361 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650
, 0x30, 0)},
2362 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001
, 0x5d, 0)},
2363 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111
, 0x5d, 0)},
2364 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655
, 0x30, 0)},
2365 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968
, 0x30, 0)},
2366 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650
, 0x30, 0)},
2367 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670
, 0x21, 0)},
2368 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB
, 0x00, 0)},
2369 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655
, 0x30, 0)},
2370 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660
, 0x21, 0)},
2371 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R
, 0x11, 0)},
2372 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650
, 0x30, 0)},
2373 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660
, 0x21, 0)},
2374 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R
, 0x11, 0)},
2375 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R
, 0x11, 0)},
2376 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R
, 0x11, 0)},
2377 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R
, 0x11, 0)},
2378 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R
, 0x11, 0)},
2379 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111
, 0x5d, 0)},
2380 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111
, 0x5d, 0)},
2381 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111
, 0x5d, 0)},
2384 MODULE_DEVICE_TABLE(usb
, device_table
);
2386 /* -- device connect -- */
2387 static int sd_probe(struct usb_interface
*intf
,
2388 const struct usb_device_id
*id
)
2390 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
2394 static void sd_disconnect(struct usb_interface
*intf
)
2396 #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
2397 struct gspca_dev
*gspca_dev
= usb_get_intfdata(intf
);
2399 sn9c20x_input_cleanup(gspca_dev
);
2402 gspca_disconnect(intf
);
2405 static struct usb_driver sd_driver
= {
2406 .name
= MODULE_NAME
,
2407 .id_table
= device_table
,
2409 .disconnect
= sd_disconnect
,
2411 .suspend
= gspca_suspend
,
2412 .resume
= gspca_resume
,
2413 .reset_resume
= gspca_resume
,
2417 /* -- module insert / remove -- */
2418 static int __init
sd_mod_init(void)
2421 ret
= usb_register(&sd_driver
);
2427 static void __exit
sd_mod_exit(void)
2429 usb_deregister(&sd_driver
);
2430 info("deregistered");
2433 module_init(sd_mod_init
);
2434 module_exit(sd_mod_exit
);