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 | (1 << 4);
1156 row
[1] = sd
->i2c_addr
;
1163 if (i2c_w(gspca_dev
, row
) < 0)
1165 row
[0] = 0x81 | (1 << 4) | 0x02;
1167 if (i2c_w(gspca_dev
, row
) < 0)
1169 if (reg_r(gspca_dev
, 0x10c2, 5) < 0)
1171 *val
= gspca_dev
->usb_buf
[4];
1175 int i2c_r2(struct gspca_dev
*gspca_dev
, u8 reg
, u16
*val
)
1177 struct sd
*sd
= (struct sd
*) gspca_dev
;
1180 row
[0] = 0x81 | (1 << 4);
1181 row
[1] = sd
->i2c_addr
;
1188 if (i2c_w(gspca_dev
, row
) < 0)
1190 row
[0] = 0x81 | (2 << 4) | 0x02;
1192 if (i2c_w(gspca_dev
, row
) < 0)
1194 if (reg_r(gspca_dev
, 0x10c2, 5) < 0)
1196 *val
= (gspca_dev
->usb_buf
[3] << 8) | gspca_dev
->usb_buf
[4];
1200 static int ov9650_init_sensor(struct gspca_dev
*gspca_dev
)
1203 struct sd
*sd
= (struct sd
*) gspca_dev
;
1205 for (i
= 0; i
< ARRAY_SIZE(ov9650_init
); i
++) {
1206 if (i2c_w1(gspca_dev
, ov9650_init
[i
][0],
1207 ov9650_init
[i
][1]) < 0) {
1208 err("OV9650 sensor initialization failed");
1217 static int ov9655_init_sensor(struct gspca_dev
*gspca_dev
)
1220 struct sd
*sd
= (struct sd
*) gspca_dev
;
1222 for (i
= 0; i
< ARRAY_SIZE(ov9655_init
); i
++) {
1223 if (i2c_w1(gspca_dev
, ov9655_init
[i
][0],
1224 ov9655_init
[i
][1]) < 0) {
1225 err("OV9655 sensor initialization failed");
1229 /* disable hflip and vflip */
1230 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1236 static int soi968_init_sensor(struct gspca_dev
*gspca_dev
)
1239 struct sd
*sd
= (struct sd
*) gspca_dev
;
1241 for (i
= 0; i
< ARRAY_SIZE(soi968_init
); i
++) {
1242 if (i2c_w1(gspca_dev
, soi968_init
[i
][0],
1243 soi968_init
[i
][1]) < 0) {
1244 err("SOI968 sensor initialization failed");
1248 /* disable hflip and vflip */
1249 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1255 static int ov7660_init_sensor(struct gspca_dev
*gspca_dev
)
1258 struct sd
*sd
= (struct sd
*) gspca_dev
;
1260 for (i
= 0; i
< ARRAY_SIZE(ov7660_init
); i
++) {
1261 if (i2c_w1(gspca_dev
, ov7660_init
[i
][0],
1262 ov7660_init
[i
][1]) < 0) {
1263 err("OV7660 sensor initialization failed");
1267 /* disable hflip and vflip */
1268 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1274 static int ov7670_init_sensor(struct gspca_dev
*gspca_dev
)
1277 struct sd
*sd
= (struct sd
*) gspca_dev
;
1279 for (i
= 0; i
< ARRAY_SIZE(ov7670_init
); i
++) {
1280 if (i2c_w1(gspca_dev
, ov7670_init
[i
][0],
1281 ov7670_init
[i
][1]) < 0) {
1282 err("OV7670 sensor initialization failed");
1286 /* disable hflip and vflip */
1287 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1293 static int mt9v_init_sensor(struct gspca_dev
*gspca_dev
)
1295 struct sd
*sd
= (struct sd
*) gspca_dev
;
1300 sd
->i2c_addr
= 0x5d;
1301 ret
= i2c_r2(gspca_dev
, 0xff, &value
);
1302 if ((ret
== 0) && (value
== 0x8243)) {
1303 for (i
= 0; i
< ARRAY_SIZE(mt9v011_init
); i
++) {
1304 if (i2c_w2(gspca_dev
, mt9v011_init
[i
][0],
1305 mt9v011_init
[i
][1]) < 0) {
1306 err("MT9V011 sensor initialization failed");
1312 sd
->sensor
= SENSOR_MT9V011
;
1313 info("MT9V011 sensor detected");
1317 sd
->i2c_addr
= 0x5c;
1318 i2c_w2(gspca_dev
, 0x01, 0x0004);
1319 ret
= i2c_r2(gspca_dev
, 0xff, &value
);
1320 if ((ret
== 0) && (value
== 0x823a)) {
1321 for (i
= 0; i
< ARRAY_SIZE(mt9v111_init
); i
++) {
1322 if (i2c_w2(gspca_dev
, mt9v111_init
[i
][0],
1323 mt9v111_init
[i
][1]) < 0) {
1324 err("MT9V111 sensor initialization failed");
1330 sd
->sensor
= SENSOR_MT9V111
;
1331 info("MT9V111 sensor detected");
1335 sd
->i2c_addr
= 0x5d;
1336 ret
= i2c_w2(gspca_dev
, 0xf0, 0x0000);
1338 sd
->i2c_addr
= 0x48;
1339 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1341 ret
= i2c_r2(gspca_dev
, 0x00, &value
);
1342 if ((ret
== 0) && (value
== 0x1229)) {
1343 for (i
= 0; i
< ARRAY_SIZE(mt9v112_init
); i
++) {
1344 if (i2c_w2(gspca_dev
, mt9v112_init
[i
][0],
1345 mt9v112_init
[i
][1]) < 0) {
1346 err("MT9V112 sensor initialization failed");
1352 sd
->sensor
= SENSOR_MT9V112
;
1353 info("MT9V112 sensor detected");
1360 static int mt9m111_init_sensor(struct gspca_dev
*gspca_dev
)
1362 struct sd
*sd
= (struct sd
*) gspca_dev
;
1364 for (i
= 0; i
< ARRAY_SIZE(mt9m111_init
); i
++) {
1365 if (i2c_w2(gspca_dev
, mt9m111_init
[i
][0],
1366 mt9m111_init
[i
][1]) < 0) {
1367 err("MT9M111 sensor initialization failed");
1376 static int mt9m001_init_sensor(struct gspca_dev
*gspca_dev
)
1378 struct sd
*sd
= (struct sd
*) gspca_dev
;
1380 for (i
= 0; i
< ARRAY_SIZE(mt9m001_init
); i
++) {
1381 if (i2c_w2(gspca_dev
, mt9m001_init
[i
][0],
1382 mt9m001_init
[i
][1]) < 0) {
1383 err("MT9M001 sensor initialization failed");
1387 /* disable hflip and vflip */
1388 gspca_dev
->ctrl_dis
= (1 << HFLIP_IDX
) | (1 << VFLIP_IDX
);
1394 static int hv7131r_init_sensor(struct gspca_dev
*gspca_dev
)
1397 struct sd
*sd
= (struct sd
*) gspca_dev
;
1399 for (i
= 0; i
< ARRAY_SIZE(hv7131r_init
); i
++) {
1400 if (i2c_w1(gspca_dev
, hv7131r_init
[i
][0],
1401 hv7131r_init
[i
][1]) < 0) {
1402 err("HV7131R Sensor initialization failed");
1411 #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
1412 static int input_kthread(void *data
)
1414 struct gspca_dev
*gspca_dev
= (struct gspca_dev
*)data
;
1415 struct sd
*sd
= (struct sd
*) gspca_dev
;
1417 DECLARE_WAIT_QUEUE_HEAD(wait
);
1420 if (kthread_should_stop())
1423 if (reg_r(gspca_dev
, 0x1005, 1) < 0)
1426 input_report_key(sd
->input_dev
,
1428 gspca_dev
->usb_buf
[0] & sd
->input_gpio
);
1429 input_sync(sd
->input_dev
);
1431 wait_event_freezable_timeout(wait
,
1432 kthread_should_stop(),
1433 msecs_to_jiffies(100));
1439 static int sn9c20x_input_init(struct gspca_dev
*gspca_dev
)
1441 struct sd
*sd
= (struct sd
*) gspca_dev
;
1442 if (sd
->input_gpio
== 0)
1445 sd
->input_dev
= input_allocate_device();
1449 sd
->input_dev
->name
= "SN9C20X Webcam";
1451 sd
->input_dev
->phys
= kasprintf(GFP_KERNEL
, "usb-%s-%s",
1452 gspca_dev
->dev
->bus
->bus_name
,
1453 gspca_dev
->dev
->devpath
);
1455 if (!sd
->input_dev
->phys
)
1458 usb_to_input_id(gspca_dev
->dev
, &sd
->input_dev
->id
);
1459 sd
->input_dev
->dev
.parent
= &gspca_dev
->dev
->dev
;
1461 set_bit(EV_KEY
, sd
->input_dev
->evbit
);
1462 set_bit(KEY_CAMERA
, sd
->input_dev
->keybit
);
1464 if (input_register_device(sd
->input_dev
))
1467 sd
->input_task
= kthread_run(input_kthread
, gspca_dev
, "sn9c20x/%d",
1468 gspca_dev
->vdev
.minor
);
1470 if (IS_ERR(sd
->input_task
))
1476 static void sn9c20x_input_cleanup(struct gspca_dev
*gspca_dev
)
1478 struct sd
*sd
= (struct sd
*) gspca_dev
;
1479 if (sd
->input_task
!= NULL
&& !IS_ERR(sd
->input_task
))
1480 kthread_stop(sd
->input_task
);
1482 if (sd
->input_dev
!= NULL
) {
1483 input_unregister_device(sd
->input_dev
);
1484 kfree(sd
->input_dev
->phys
);
1485 input_free_device(sd
->input_dev
);
1486 sd
->input_dev
= NULL
;
1491 static int set_cmatrix(struct gspca_dev
*gspca_dev
)
1493 struct sd
*sd
= (struct sd
*) gspca_dev
;
1494 s32 hue_coord
, hue_index
= 180 + sd
->hue
;
1496 memset(cmatrix
, 0, 21);
1498 cmatrix
[2] = (sd
->contrast
* 0x25 / 0x100) + 0x26;
1499 cmatrix
[0] = 0x13 + (cmatrix
[2] - 0x26) * 0x13 / 0x25;
1500 cmatrix
[4] = 0x07 + (cmatrix
[2] - 0x26) * 0x07 / 0x25;
1501 cmatrix
[18] = sd
->brightness
- 0x80;
1503 hue_coord
= (hsv_red_x
[hue_index
] * sd
->saturation
) >> 8;
1504 cmatrix
[6] = (unsigned char)(hue_coord
& 0xff);
1505 cmatrix
[7] = (unsigned char)((hue_coord
>> 8) & 0x0f);
1507 hue_coord
= (hsv_red_y
[hue_index
] * sd
->saturation
) >> 8;
1508 cmatrix
[8] = (unsigned char)(hue_coord
& 0xff);
1509 cmatrix
[9] = (unsigned char)((hue_coord
>> 8) & 0x0f);
1511 hue_coord
= (hsv_green_x
[hue_index
] * sd
->saturation
) >> 8;
1512 cmatrix
[10] = (unsigned char)(hue_coord
& 0xff);
1513 cmatrix
[11] = (unsigned char)((hue_coord
>> 8) & 0x0f);
1515 hue_coord
= (hsv_green_y
[hue_index
] * sd
->saturation
) >> 8;
1516 cmatrix
[12] = (unsigned char)(hue_coord
& 0xff);
1517 cmatrix
[13] = (unsigned char)((hue_coord
>> 8) & 0x0f);
1519 hue_coord
= (hsv_blue_x
[hue_index
] * sd
->saturation
) >> 8;
1520 cmatrix
[14] = (unsigned char)(hue_coord
& 0xff);
1521 cmatrix
[15] = (unsigned char)((hue_coord
>> 8) & 0x0f);
1523 hue_coord
= (hsv_blue_y
[hue_index
] * sd
->saturation
) >> 8;
1524 cmatrix
[16] = (unsigned char)(hue_coord
& 0xff);
1525 cmatrix
[17] = (unsigned char)((hue_coord
>> 8) & 0x0f);
1527 return reg_w(gspca_dev
, 0x10e1, cmatrix
, 21);
1530 static int set_gamma(struct gspca_dev
*gspca_dev
)
1532 struct sd
*sd
= (struct sd
*) gspca_dev
;
1534 u8 gval
= sd
->gamma
* 0xb8 / 0x100;
1538 gamma
[1] = 0x13 + (gval
* (0xcb - 0x13) / 0xb8);
1539 gamma
[2] = 0x25 + (gval
* (0xee - 0x25) / 0xb8);
1540 gamma
[3] = 0x37 + (gval
* (0xfa - 0x37) / 0xb8);
1541 gamma
[4] = 0x45 + (gval
* (0xfc - 0x45) / 0xb8);
1542 gamma
[5] = 0x55 + (gval
* (0xfb - 0x55) / 0xb8);
1543 gamma
[6] = 0x65 + (gval
* (0xfc - 0x65) / 0xb8);
1544 gamma
[7] = 0x74 + (gval
* (0xfd - 0x74) / 0xb8);
1545 gamma
[8] = 0x83 + (gval
* (0xfe - 0x83) / 0xb8);
1546 gamma
[9] = 0x92 + (gval
* (0xfc - 0x92) / 0xb8);
1547 gamma
[10] = 0xa1 + (gval
* (0xfc - 0xa1) / 0xb8);
1548 gamma
[11] = 0xb0 + (gval
* (0xfc - 0xb0) / 0xb8);
1549 gamma
[12] = 0xbf + (gval
* (0xfb - 0xbf) / 0xb8);
1550 gamma
[13] = 0xce + (gval
* (0xfb - 0xce) / 0xb8);
1551 gamma
[14] = 0xdf + (gval
* (0xfd - 0xdf) / 0xb8);
1552 gamma
[15] = 0xea + (gval
* (0xf9 - 0xea) / 0xb8);
1555 return reg_w(gspca_dev
, 0x1190, gamma
, 17);
1558 static int set_redblue(struct gspca_dev
*gspca_dev
)
1560 struct sd
*sd
= (struct sd
*) gspca_dev
;
1561 reg_w1(gspca_dev
, 0x118c, sd
->red
);
1562 reg_w1(gspca_dev
, 0x118f, sd
->blue
);
1566 static int set_hvflip(struct gspca_dev
*gspca_dev
)
1570 struct sd
*sd
= (struct sd
*) gspca_dev
;
1571 switch (sd
->sensor
) {
1573 i2c_r1(gspca_dev
, 0x1e, &value
);
1582 i2c_w1(gspca_dev
, 0x1e, value
);
1583 i2c_w1(gspca_dev
, 0x3a, tslb
);
1585 case SENSOR_MT9V111
:
1586 case SENSOR_MT9V011
:
1587 i2c_r2(gspca_dev
, 0x20, &value2
);
1593 i2c_w2(gspca_dev
, 0x20, value2
);
1595 case SENSOR_MT9M111
:
1596 case SENSOR_MT9V112
:
1597 i2c_r2(gspca_dev
, 0x20, &value2
);
1603 i2c_w2(gspca_dev
, 0x20, value2
);
1605 case SENSOR_HV7131R
:
1606 i2c_r1(gspca_dev
, 0x01, &value
);
1612 i2c_w1(gspca_dev
, 0x01, value
);
1618 static int set_exposure(struct gspca_dev
*gspca_dev
)
1620 struct sd
*sd
= (struct sd
*) gspca_dev
;
1621 u8 exp
[8] = {0x81, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1622 switch (sd
->sensor
) {
1630 exp
[3] = sd
->exposure
& 0xff;
1631 exp
[4] = sd
->exposure
>> 8;
1633 case SENSOR_MT9M001
:
1634 case SENSOR_MT9M111
:
1635 case SENSOR_MT9V112
:
1636 case SENSOR_MT9V111
:
1637 case SENSOR_MT9V011
:
1640 exp
[3] = sd
->exposure
>> 8;
1641 exp
[4] = sd
->exposure
& 0xff;
1643 case SENSOR_HV7131R
:
1646 exp
[3] = ((sd
->exposure
* 0xffffff) / 0xffff) >> 16;
1647 exp
[4] = ((sd
->exposure
* 0xffffff) / 0xffff) >> 8;
1648 exp
[5] = ((sd
->exposure
* 0xffffff) / 0xffff) & 0xff;
1651 i2c_w(gspca_dev
, exp
);
1655 static int set_gain(struct gspca_dev
*gspca_dev
)
1657 struct sd
*sd
= (struct sd
*) gspca_dev
;
1658 u8 gain
[8] = {0x81, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1659 switch (sd
->sensor
) {
1665 gain
[0] |= (2 << 4);
1666 gain
[3] = ov_gain
[sd
->gain
];
1668 case SENSOR_MT9V011
:
1669 case SENSOR_MT9V111
:
1670 gain
[0] |= (3 << 4);
1672 gain
[3] = micron1_gain
[sd
->gain
] >> 8;
1673 gain
[4] = micron1_gain
[sd
->gain
] & 0xff;
1675 case SENSOR_MT9V112
:
1676 case SENSOR_MT9M111
:
1677 gain
[0] |= (3 << 4);
1679 gain
[3] = micron1_gain
[sd
->gain
] >> 8;
1680 gain
[4] = micron1_gain
[sd
->gain
] & 0xff;
1682 case SENSOR_MT9M001
:
1683 gain
[0] |= (3 << 4);
1685 gain
[3] = micron2_gain
[sd
->gain
] >> 8;
1686 gain
[4] = micron2_gain
[sd
->gain
] & 0xff;
1688 case SENSOR_HV7131R
:
1689 gain
[0] |= (2 << 4);
1691 gain
[3] = hv7131r_gain
[sd
->gain
];
1694 i2c_w(gspca_dev
, gain
);
1698 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, s32 val
)
1700 struct sd
*sd
= (struct sd
*) gspca_dev
;
1702 sd
->brightness
= val
;
1703 if (gspca_dev
->streaming
)
1704 return set_cmatrix(gspca_dev
);
1708 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, s32
*val
)
1710 struct sd
*sd
= (struct sd
*) gspca_dev
;
1711 *val
= sd
->brightness
;
1716 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, s32 val
)
1718 struct sd
*sd
= (struct sd
*) gspca_dev
;
1721 if (gspca_dev
->streaming
)
1722 return set_cmatrix(gspca_dev
);
1726 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, s32
*val
)
1728 struct sd
*sd
= (struct sd
*) gspca_dev
;
1729 *val
= sd
->contrast
;
1733 static int sd_setsaturation(struct gspca_dev
*gspca_dev
, s32 val
)
1735 struct sd
*sd
= (struct sd
*) gspca_dev
;
1737 sd
->saturation
= val
;
1738 if (gspca_dev
->streaming
)
1739 return set_cmatrix(gspca_dev
);
1743 static int sd_getsaturation(struct gspca_dev
*gspca_dev
, s32
*val
)
1745 struct sd
*sd
= (struct sd
*) gspca_dev
;
1746 *val
= sd
->saturation
;
1750 static int sd_sethue(struct gspca_dev
*gspca_dev
, s32 val
)
1752 struct sd
*sd
= (struct sd
*) gspca_dev
;
1755 if (gspca_dev
->streaming
)
1756 return set_cmatrix(gspca_dev
);
1760 static int sd_gethue(struct gspca_dev
*gspca_dev
, s32
*val
)
1762 struct sd
*sd
= (struct sd
*) gspca_dev
;
1767 static int sd_setgamma(struct gspca_dev
*gspca_dev
, s32 val
)
1769 struct sd
*sd
= (struct sd
*) gspca_dev
;
1772 if (gspca_dev
->streaming
)
1773 return set_gamma(gspca_dev
);
1777 static int sd_getgamma(struct gspca_dev
*gspca_dev
, s32
*val
)
1779 struct sd
*sd
= (struct sd
*) gspca_dev
;
1784 static int sd_setredbalance(struct gspca_dev
*gspca_dev
, s32 val
)
1786 struct sd
*sd
= (struct sd
*) gspca_dev
;
1789 if (gspca_dev
->streaming
)
1790 return set_redblue(gspca_dev
);
1794 static int sd_getredbalance(struct gspca_dev
*gspca_dev
, s32
*val
)
1796 struct sd
*sd
= (struct sd
*) gspca_dev
;
1801 static int sd_setbluebalance(struct gspca_dev
*gspca_dev
, s32 val
)
1803 struct sd
*sd
= (struct sd
*) gspca_dev
;
1806 if (gspca_dev
->streaming
)
1807 return set_redblue(gspca_dev
);
1811 static int sd_getbluebalance(struct gspca_dev
*gspca_dev
, s32
*val
)
1813 struct sd
*sd
= (struct sd
*) gspca_dev
;
1818 static int sd_sethflip(struct gspca_dev
*gspca_dev
, s32 val
)
1820 struct sd
*sd
= (struct sd
*) gspca_dev
;
1823 if (gspca_dev
->streaming
)
1824 return set_hvflip(gspca_dev
);
1828 static int sd_gethflip(struct gspca_dev
*gspca_dev
, s32
*val
)
1830 struct sd
*sd
= (struct sd
*) gspca_dev
;
1835 static int sd_setvflip(struct gspca_dev
*gspca_dev
, s32 val
)
1837 struct sd
*sd
= (struct sd
*) gspca_dev
;
1840 if (gspca_dev
->streaming
)
1841 return set_hvflip(gspca_dev
);
1845 static int sd_getvflip(struct gspca_dev
*gspca_dev
, s32
*val
)
1847 struct sd
*sd
= (struct sd
*) gspca_dev
;
1852 static int sd_setexposure(struct gspca_dev
*gspca_dev
, s32 val
)
1854 struct sd
*sd
= (struct sd
*) gspca_dev
;
1857 if (gspca_dev
->streaming
)
1858 return set_exposure(gspca_dev
);
1862 static int sd_getexposure(struct gspca_dev
*gspca_dev
, s32
*val
)
1864 struct sd
*sd
= (struct sd
*) gspca_dev
;
1865 *val
= sd
->exposure
;
1869 static int sd_setgain(struct gspca_dev
*gspca_dev
, s32 val
)
1871 struct sd
*sd
= (struct sd
*) gspca_dev
;
1874 if (gspca_dev
->streaming
)
1875 return set_gain(gspca_dev
);
1879 static int sd_getgain(struct gspca_dev
*gspca_dev
, s32
*val
)
1881 struct sd
*sd
= (struct sd
*) gspca_dev
;
1886 static int sd_setautoexposure(struct gspca_dev
*gspca_dev
, s32 val
)
1888 struct sd
*sd
= (struct sd
*) gspca_dev
;
1889 sd
->auto_exposure
= val
;
1893 static int sd_getautoexposure(struct gspca_dev
*gspca_dev
, s32
*val
)
1895 struct sd
*sd
= (struct sd
*) gspca_dev
;
1896 *val
= sd
->auto_exposure
;
1900 #ifdef CONFIG_VIDEO_ADV_DEBUG
1901 static int sd_dbg_g_register(struct gspca_dev
*gspca_dev
,
1902 struct v4l2_dbg_register
*reg
)
1904 struct sd
*sd
= (struct sd
*) gspca_dev
;
1905 switch (reg
->match
.type
) {
1906 case V4L2_CHIP_MATCH_HOST
:
1907 if (reg
->match
.addr
!= 0)
1909 if (reg
->reg
< 0x1000 || reg
->reg
> 0x11ff)
1911 if (reg_r(gspca_dev
, reg
->reg
, 1) < 0)
1913 reg
->val
= gspca_dev
->usb_buf
[0];
1915 case V4L2_CHIP_MATCH_I2C_ADDR
:
1916 if (reg
->match
.addr
!= sd
->i2c_addr
)
1918 if (sd
->sensor
>= SENSOR_MT9V011
&&
1919 sd
->sensor
<= SENSOR_MT9M111
) {
1920 if (i2c_r2(gspca_dev
, reg
->reg
, (u16
*)®
->val
) < 0)
1923 if (i2c_r1(gspca_dev
, reg
->reg
, (u8
*)®
->val
) < 0)
1931 static int sd_dbg_s_register(struct gspca_dev
*gspca_dev
,
1932 struct v4l2_dbg_register
*reg
)
1934 struct sd
*sd
= (struct sd
*) gspca_dev
;
1935 switch (reg
->match
.type
) {
1936 case V4L2_CHIP_MATCH_HOST
:
1937 if (reg
->match
.addr
!= 0)
1939 if (reg
->reg
< 0x1000 || reg
->reg
> 0x11ff)
1941 if (reg_w1(gspca_dev
, reg
->reg
, reg
->val
) < 0)
1944 case V4L2_CHIP_MATCH_I2C_ADDR
:
1945 if (reg
->match
.addr
!= sd
->i2c_addr
)
1947 if (sd
->sensor
>= SENSOR_MT9V011
&&
1948 sd
->sensor
<= SENSOR_MT9M111
) {
1949 if (i2c_w2(gspca_dev
, reg
->reg
, reg
->val
) < 0)
1952 if (i2c_w1(gspca_dev
, reg
->reg
, reg
->val
) < 0)
1961 static int sd_chip_ident(struct gspca_dev
*gspca_dev
,
1962 struct v4l2_dbg_chip_ident
*chip
)
1964 struct sd
*sd
= (struct sd
*) gspca_dev
;
1966 switch (chip
->match
.type
) {
1967 case V4L2_CHIP_MATCH_HOST
:
1968 if (chip
->match
.addr
!= 0)
1971 chip
->ident
= V4L2_IDENT_SN9C20X
;
1973 case V4L2_CHIP_MATCH_I2C_ADDR
:
1974 if (chip
->match
.addr
!= sd
->i2c_addr
)
1977 chip
->ident
= i2c_ident
[sd
->sensor
];
1983 static int sd_config(struct gspca_dev
*gspca_dev
,
1984 const struct usb_device_id
*id
)
1986 struct sd
*sd
= (struct sd
*) gspca_dev
;
1989 cam
= &gspca_dev
->cam
;
1991 sd
->sensor
= (id
->driver_info
>> 8) & 0xff;
1992 sd
->i2c_addr
= id
->driver_info
& 0xff;
1994 switch (sd
->sensor
) {
1996 cam
->cam_mode
= sxga_mode
;
1997 cam
->nmodes
= ARRAY_SIZE(sxga_mode
);
2000 cam
->cam_mode
= vga_mode
;
2001 cam
->nmodes
= ARRAY_SIZE(vga_mode
);
2006 sd
->exposure_step
= 16;
2008 sd
->brightness
= BRIGHTNESS_DEFAULT
;
2009 sd
->contrast
= CONTRAST_DEFAULT
;
2010 sd
->saturation
= SATURATION_DEFAULT
;
2011 sd
->hue
= HUE_DEFAULT
;
2012 sd
->gamma
= GAMMA_DEFAULT
;
2013 sd
->red
= RED_DEFAULT
;
2014 sd
->blue
= BLUE_DEFAULT
;
2016 sd
->hflip
= HFLIP_DEFAULT
;
2017 sd
->vflip
= VFLIP_DEFAULT
;
2018 sd
->exposure
= EXPOSURE_DEFAULT
;
2019 sd
->gain
= GAIN_DEFAULT
;
2020 sd
->auto_exposure
= AUTO_EXPOSURE_DEFAULT
;
2024 #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
2025 sd
->input_gpio
= (id
->driver_info
>> 16) & 0xff;
2026 if (sn9c20x_input_init(gspca_dev
) < 0)
2032 static int sd_init(struct gspca_dev
*gspca_dev
)
2034 struct sd
*sd
= (struct sd
*) gspca_dev
;
2038 {0x80, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
2040 for (i
= 0; i
< ARRAY_SIZE(bridge_init
); i
++) {
2041 value
= bridge_init
[i
][1];
2042 if (reg_w(gspca_dev
, bridge_init
[i
][0], &value
, 1) < 0) {
2043 err("Device initialization failed");
2048 if (reg_w(gspca_dev
, 0x10c0, i2c_init
, 9) < 0) {
2049 err("Device initialization failed");
2053 switch (sd
->sensor
) {
2055 if (ov9650_init_sensor(gspca_dev
) < 0)
2057 info("OV9650 sensor detected");
2060 if (ov9655_init_sensor(gspca_dev
) < 0)
2062 info("OV9655 sensor detected");
2065 if (soi968_init_sensor(gspca_dev
) < 0)
2067 info("SOI968 sensor detected");
2070 if (ov7660_init_sensor(gspca_dev
) < 0)
2072 info("OV7660 sensor detected");
2075 if (ov7670_init_sensor(gspca_dev
) < 0)
2077 info("OV7670 sensor detected");
2079 case SENSOR_MT9VPRB
:
2080 if (mt9v_init_sensor(gspca_dev
) < 0)
2083 case SENSOR_MT9M111
:
2084 if (mt9m111_init_sensor(gspca_dev
) < 0)
2086 info("MT9M111 sensor detected");
2088 case SENSOR_MT9M001
:
2089 if (mt9m001_init_sensor(gspca_dev
) < 0)
2091 info("MT9M001 sensor detected");
2093 case SENSOR_HV7131R
:
2094 if (hv7131r_init_sensor(gspca_dev
) < 0)
2096 info("HV7131R sensor detected");
2099 info("Unsupported Sensor");
2106 static void configure_sensor_output(struct gspca_dev
*gspca_dev
, int mode
)
2108 struct sd
*sd
= (struct sd
*) gspca_dev
;
2110 switch (sd
->sensor
) {
2112 if (mode
& MODE_SXGA
) {
2113 i2c_w1(gspca_dev
, 0x17, 0x1b);
2114 i2c_w1(gspca_dev
, 0x18, 0xbc);
2115 i2c_w1(gspca_dev
, 0x19, 0x01);
2116 i2c_w1(gspca_dev
, 0x1a, 0x82);
2117 i2c_r1(gspca_dev
, 0x12, &value
);
2118 i2c_w1(gspca_dev
, 0x12, value
& 0x07);
2120 i2c_w1(gspca_dev
, 0x17, 0x24);
2121 i2c_w1(gspca_dev
, 0x18, 0xc5);
2122 i2c_w1(gspca_dev
, 0x19, 0x00);
2123 i2c_w1(gspca_dev
, 0x1a, 0x3c);
2124 i2c_r1(gspca_dev
, 0x12, &value
);
2125 i2c_w1(gspca_dev
, 0x12, (value
& 0x7) | 0x40);
2131 #define HW_WIN(mode, hstart, vstart) \
2132 ((const u8 []){hstart & 0xff, hstart >> 8, \
2133 vstart & 0xff, vstart >> 8, \
2134 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
2135 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
2137 #define CLR_WIN(width, height) \
2139 {0, width >> 2, 0, height >> 1,\
2140 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
2142 static int sd_start(struct gspca_dev
*gspca_dev
)
2144 struct sd
*sd
= (struct sd
*) gspca_dev
;
2145 int mode
= gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
;
2146 int width
= gspca_dev
->width
;
2147 int height
= gspca_dev
->height
;
2150 sd
->jpeg_hdr
= kmalloc(JPEG_HDR_SZ
, GFP_KERNEL
);
2151 if (sd
->jpeg_hdr
== NULL
)
2154 jpeg_define(sd
->jpeg_hdr
, height
, width
,
2156 jpeg_set_qual(sd
->jpeg_hdr
, sd
->quality
);
2158 if (mode
& MODE_RAW
)
2160 else if (mode
& MODE_JPEG
)
2165 switch (mode
& 0x0f) {
2168 info("Set 1280x1024");
2172 info("Set 640x480");
2176 info("Set 320x240");
2180 info("Set 160x120");
2184 configure_sensor_output(gspca_dev
, mode
);
2185 reg_w(gspca_dev
, 0x1100, sd
->jpeg_hdr
+ JPEG_QT0_OFFSET
, 64);
2186 reg_w(gspca_dev
, 0x1140, sd
->jpeg_hdr
+ JPEG_QT1_OFFSET
, 64);
2187 reg_w(gspca_dev
, 0x10fb, CLR_WIN(width
, height
), 5);
2188 reg_w(gspca_dev
, 0x1180, HW_WIN(mode
, sd
->hstart
, sd
->vstart
), 6);
2189 reg_w1(gspca_dev
, 0x1189, scale
);
2190 reg_w1(gspca_dev
, 0x10e0, fmt
);
2192 set_cmatrix(gspca_dev
);
2193 set_gamma(gspca_dev
);
2194 set_redblue(gspca_dev
);
2195 set_gain(gspca_dev
);
2196 set_exposure(gspca_dev
);
2197 set_hvflip(gspca_dev
);
2199 reg_r(gspca_dev
, 0x1061, 1);
2200 reg_w1(gspca_dev
, 0x1061, gspca_dev
->usb_buf
[0] | 0x02);
2204 static void sd_stopN(struct gspca_dev
*gspca_dev
)
2206 reg_r(gspca_dev
, 0x1061, 1);
2207 reg_w1(gspca_dev
, 0x1061, gspca_dev
->usb_buf
[0] & ~0x02);
2210 static void sd_stop0(struct gspca_dev
*gspca_dev
)
2212 struct sd
*sd
= (struct sd
*) gspca_dev
;
2213 kfree(sd
->jpeg_hdr
);
2216 static void do_autoexposure(struct gspca_dev
*gspca_dev
)
2218 struct sd
*sd
= (struct sd
*) gspca_dev
;
2219 int avg_lum
, new_exp
;
2221 if (!sd
->auto_exposure
)
2224 avg_lum
= atomic_read(&sd
->avg_lum
);
2227 * some hardcoded values are present
2228 * like those for maximal/minimal exposure
2229 * and exposure steps
2231 if (avg_lum
< MIN_AVG_LUM
) {
2232 if (sd
->exposure
> 0x1770)
2235 new_exp
= sd
->exposure
+ sd
->exposure_step
;
2236 if (new_exp
> 0x1770)
2240 sd
->exposure
= new_exp
;
2241 set_exposure(gspca_dev
);
2243 sd
->older_step
= sd
->old_step
;
2246 if (sd
->old_step
^ sd
->older_step
)
2247 sd
->exposure_step
/= 2;
2249 sd
->exposure_step
+= 2;
2251 if (avg_lum
> MAX_AVG_LUM
) {
2252 if (sd
->exposure
< 0x10)
2254 new_exp
= sd
->exposure
- sd
->exposure_step
;
2255 if (new_exp
> 0x1700)
2259 sd
->exposure
= new_exp
;
2260 set_exposure(gspca_dev
);
2261 sd
->older_step
= sd
->old_step
;
2264 if (sd
->old_step
^ sd
->older_step
)
2265 sd
->exposure_step
/= 2;
2267 sd
->exposure_step
+= 2;
2271 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
2272 struct gspca_frame
*frame
, /* target */
2273 u8
*data
, /* isoc packet */
2274 int len
) /* iso packet length */
2276 struct sd
*sd
= (struct sd
*) gspca_dev
;
2278 static unsigned char frame_header
[] =
2279 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2280 if (len
== 64 && memcmp(data
, frame_header
, 6) == 0) {
2281 avg_lum
= ((data
[35] >> 2) & 3) |
2284 avg_lum
+= ((data
[35] >> 4) & 3) |
2287 avg_lum
+= ((data
[35] >> 6) & 3) |
2290 avg_lum
+= (data
[36] & 3) |
2293 avg_lum
+= ((data
[36] >> 2) & 3) |
2296 avg_lum
+= ((data
[36] >> 4) & 3) |
2299 avg_lum
+= ((data
[36] >> 6) & 3) |
2302 avg_lum
+= ((data
[44] >> 4) & 3) |
2306 atomic_set(&sd
->avg_lum
, avg_lum
);
2307 gspca_frame_add(gspca_dev
, LAST_PACKET
,
2311 if (gspca_dev
->last_packet_type
== LAST_PACKET
) {
2312 if (gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
2314 gspca_frame_add(gspca_dev
, FIRST_PACKET
, frame
,
2315 sd
->jpeg_hdr
, JPEG_HDR_SZ
);
2316 gspca_frame_add(gspca_dev
, INTER_PACKET
, frame
,
2319 gspca_frame_add(gspca_dev
, FIRST_PACKET
, frame
,
2323 gspca_frame_add(gspca_dev
, INTER_PACKET
, frame
, data
, len
);
2327 /* sub-driver description */
2328 static const struct sd_desc sd_desc
= {
2329 .name
= MODULE_NAME
,
2331 .nctrls
= ARRAY_SIZE(sd_ctrls
),
2332 .config
= sd_config
,
2337 .pkt_scan
= sd_pkt_scan
,
2338 .dq_callback
= do_autoexposure
,
2339 #ifdef CONFIG_VIDEO_ADV_DEBUG
2340 .set_register
= sd_dbg_s_register
,
2341 .get_register
= sd_dbg_g_register
,
2343 .get_chip_ident
= sd_chip_ident
,
2346 #define SN9C20X(sensor, i2c_addr, button_mask) \
2347 .driver_info = (button_mask << 16) \
2348 | (SENSOR_ ## sensor << 8) \
2351 static const __devinitdata
struct usb_device_id device_table
[] = {
2352 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001
, 0x5d, 0)},
2353 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111
, 0x5d, 0)},
2354 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655
, 0x30, 0)},
2355 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968
, 0x30, 0x10)},
2356 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650
, 0x30, 0)},
2357 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650
, 0x30, 0)},
2358 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650
, 0x30, 0)},
2359 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670
, 0x21, 0)},
2360 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB
, 0x00, 0)},
2361 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660
, 0x21, 0)},
2362 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R
, 0x11, 0)},
2363 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650
, 0x30, 0)},
2364 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001
, 0x5d, 0)},
2365 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111
, 0x5d, 0)},
2366 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655
, 0x30, 0)},
2367 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968
, 0x30, 0)},
2368 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650
, 0x30, 0)},
2369 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670
, 0x21, 0)},
2370 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB
, 0x00, 0)},
2371 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655
, 0x30, 0)},
2372 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660
, 0x21, 0)},
2373 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R
, 0x11, 0)},
2374 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650
, 0x30, 0)},
2375 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660
, 0x21, 0)},
2376 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R
, 0x11, 0)},
2377 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R
, 0x11, 0)},
2378 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R
, 0x11, 0)},
2379 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R
, 0x11, 0)},
2380 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R
, 0x11, 0)},
2381 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111
, 0x5d, 0)},
2382 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111
, 0x5d, 0)},
2383 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111
, 0x5d, 0)},
2386 MODULE_DEVICE_TABLE(usb
, device_table
);
2388 /* -- device connect -- */
2389 static int sd_probe(struct usb_interface
*intf
,
2390 const struct usb_device_id
*id
)
2392 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
2396 static void sd_disconnect(struct usb_interface
*intf
)
2398 #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
2399 struct gspca_dev
*gspca_dev
= usb_get_intfdata(intf
);
2401 sn9c20x_input_cleanup(gspca_dev
);
2404 gspca_disconnect(intf
);
2407 static struct usb_driver sd_driver
= {
2408 .name
= MODULE_NAME
,
2409 .id_table
= device_table
,
2411 .disconnect
= sd_disconnect
,
2413 .suspend
= gspca_suspend
,
2414 .resume
= gspca_resume
,
2415 .reset_resume
= gspca_resume
,
2419 /* -- module insert / remove -- */
2420 static int __init
sd_mod_init(void)
2423 ret
= usb_register(&sd_driver
);
2429 static void __exit
sd_mod_exit(void)
2431 usb_deregister(&sd_driver
);
2432 info("deregistered");
2435 module_init(sd_mod_init
);
2436 module_exit(sd_mod_exit
);