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
22 #include <linux/input.h>
23 #include <linux/slab.h>
29 #include <media/v4l2-chip-ident.h>
31 MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, "
32 "microdia project <microdia@googlegroups.com>");
33 MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
34 MODULE_LICENSE("GPL");
36 #define MODULE_NAME "sn9c20x"
39 #define MODE_JPEG 0x20
40 #define MODE_SXGA 0x80
42 #define SENSOR_OV9650 0
43 #define SENSOR_OV9655 1
44 #define SENSOR_SOI968 2
45 #define SENSOR_OV7660 3
46 #define SENSOR_OV7670 4
47 #define SENSOR_MT9V011 5
48 #define SENSOR_MT9V111 6
49 #define SENSOR_MT9V112 7
50 #define SENSOR_MT9M001 8
51 #define SENSOR_MT9M111 9
52 #define SENSOR_HV7131R 10
53 #define SENSOR_MT9VPRB 20
56 #define HAS_BUTTON 0x1
58 /* specific webcam descriptor */
60 struct gspca_dev gspca_dev;
62 #define MIN_AVG_LUM 80
63 #define MAX_AVG_LUM 130
104 static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val);
105 static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val);
106 static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val);
107 static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val);
108 static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val);
109 static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val);
110 static int sd_sethue(struct gspca_dev *gspca_dev, s32 val);
111 static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val);
112 static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val);
113 static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val);
114 static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val);
115 static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val);
116 static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val);
117 static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val);
118 static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val);
119 static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val);
120 static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val);
121 static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val);
122 static int sd_setgain(struct gspca_dev *gspca_dev, s32 val);
123 static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val);
124 static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val);
125 static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val);
126 static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val);
127 static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val);
129 static const struct ctrl sd_ctrls[] = {
131 #define BRIGHTNESS_IDX 0
133 .id = V4L2_CID_BRIGHTNESS,
134 .type = V4L2_CTRL_TYPE_INTEGER,
135 .name = "Brightness",
139 #define BRIGHTNESS_DEFAULT 0x7f
140 .default_value = BRIGHTNESS_DEFAULT,
142 .set = sd_setbrightness,
143 .get = sd_getbrightness,
146 #define CONTRAST_IDX 1
148 .id = V4L2_CID_CONTRAST,
149 .type = V4L2_CTRL_TYPE_INTEGER,
154 #define CONTRAST_DEFAULT 0x7f
155 .default_value = CONTRAST_DEFAULT,
157 .set = sd_setcontrast,
158 .get = sd_getcontrast,
161 #define SATURATION_IDX 2
163 .id = V4L2_CID_SATURATION,
164 .type = V4L2_CTRL_TYPE_INTEGER,
165 .name = "Saturation",
169 #define SATURATION_DEFAULT 0x7f
170 .default_value = SATURATION_DEFAULT,
172 .set = sd_setsaturation,
173 .get = sd_getsaturation,
179 .type = V4L2_CTRL_TYPE_INTEGER,
184 #define HUE_DEFAULT 0
185 .default_value = HUE_DEFAULT,
193 .id = V4L2_CID_GAMMA,
194 .type = V4L2_CTRL_TYPE_INTEGER,
199 #define GAMMA_DEFAULT 0x10
200 .default_value = GAMMA_DEFAULT,
208 .id = V4L2_CID_BLUE_BALANCE,
209 .type = V4L2_CTRL_TYPE_INTEGER,
210 .name = "Blue Balance",
214 #define BLUE_DEFAULT 0x28
215 .default_value = BLUE_DEFAULT,
217 .set = sd_setbluebalance,
218 .get = sd_getbluebalance,
223 .id = V4L2_CID_RED_BALANCE,
224 .type = V4L2_CTRL_TYPE_INTEGER,
225 .name = "Red Balance",
229 #define RED_DEFAULT 0x28
230 .default_value = RED_DEFAULT,
232 .set = sd_setredbalance,
233 .get = sd_getredbalance,
238 .id = V4L2_CID_HFLIP,
239 .type = V4L2_CTRL_TYPE_BOOLEAN,
240 .name = "Horizontal Flip",
244 #define HFLIP_DEFAULT 0
245 .default_value = HFLIP_DEFAULT,
253 .id = V4L2_CID_VFLIP,
254 .type = V4L2_CTRL_TYPE_BOOLEAN,
255 .name = "Vertical Flip",
259 #define VFLIP_DEFAULT 0
260 .default_value = VFLIP_DEFAULT,
266 #define EXPOSURE_IDX 9
268 .id = V4L2_CID_EXPOSURE,
269 .type = V4L2_CTRL_TYPE_INTEGER,
274 #define EXPOSURE_DEFAULT 0x33
275 .default_value = EXPOSURE_DEFAULT,
277 .set = sd_setexposure,
278 .get = sd_getexposure,
284 .type = V4L2_CTRL_TYPE_INTEGER,
289 #define GAIN_DEFAULT 0x00
290 .default_value = GAIN_DEFAULT,
296 #define AUTOGAIN_IDX 11
298 .id = V4L2_CID_AUTOGAIN,
299 .type = V4L2_CTRL_TYPE_BOOLEAN,
300 .name = "Auto Exposure",
304 #define AUTO_EXPOSURE_DEFAULT 1
305 .default_value = AUTO_EXPOSURE_DEFAULT,
307 .set = sd_setautoexposure,
308 .get = sd_getautoexposure,
312 static const struct v4l2_pix_format vga_mode[] = {
313 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
315 .sizeimage = 240 * 120,
316 .colorspace = V4L2_COLORSPACE_JPEG,
317 .priv = 0 | MODE_JPEG},
318 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
320 .sizeimage = 160 * 120,
321 .colorspace = V4L2_COLORSPACE_SRGB,
322 .priv = 0 | MODE_RAW},
323 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
325 .sizeimage = 240 * 120,
326 .colorspace = V4L2_COLORSPACE_SRGB,
328 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
330 .sizeimage = 480 * 240 ,
331 .colorspace = V4L2_COLORSPACE_JPEG,
332 .priv = 1 | MODE_JPEG},
333 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
335 .sizeimage = 320 * 240 ,
336 .colorspace = V4L2_COLORSPACE_SRGB,
337 .priv = 1 | MODE_RAW},
338 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
340 .sizeimage = 480 * 240 ,
341 .colorspace = V4L2_COLORSPACE_SRGB,
343 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
345 .sizeimage = 960 * 480,
346 .colorspace = V4L2_COLORSPACE_JPEG,
347 .priv = 2 | MODE_JPEG},
348 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
350 .sizeimage = 640 * 480,
351 .colorspace = V4L2_COLORSPACE_SRGB,
352 .priv = 2 | MODE_RAW},
353 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
355 .sizeimage = 960 * 480,
356 .colorspace = V4L2_COLORSPACE_SRGB,
360 static const struct v4l2_pix_format sxga_mode[] = {
361 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
363 .sizeimage = 240 * 120,
364 .colorspace = V4L2_COLORSPACE_JPEG,
365 .priv = 0 | MODE_JPEG},
366 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
368 .sizeimage = 160 * 120,
369 .colorspace = V4L2_COLORSPACE_SRGB,
370 .priv = 0 | MODE_RAW},
371 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
373 .sizeimage = 240 * 120,
374 .colorspace = V4L2_COLORSPACE_SRGB,
376 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
378 .sizeimage = 480 * 240 ,
379 .colorspace = V4L2_COLORSPACE_JPEG,
380 .priv = 1 | MODE_JPEG},
381 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
383 .sizeimage = 320 * 240 ,
384 .colorspace = V4L2_COLORSPACE_SRGB,
385 .priv = 1 | MODE_RAW},
386 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
388 .sizeimage = 480 * 240 ,
389 .colorspace = V4L2_COLORSPACE_SRGB,
391 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
393 .sizeimage = 960 * 480,
394 .colorspace = V4L2_COLORSPACE_JPEG,
395 .priv = 2 | MODE_JPEG},
396 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
398 .sizeimage = 640 * 480,
399 .colorspace = V4L2_COLORSPACE_SRGB,
400 .priv = 2 | MODE_RAW},
401 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
403 .sizeimage = 960 * 480,
404 .colorspace = V4L2_COLORSPACE_SRGB,
406 {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
407 .bytesperline = 1280,
408 .sizeimage = (1280 * 1024) + 64,
409 .colorspace = V4L2_COLORSPACE_SRGB,
410 .priv = 3 | MODE_RAW | MODE_SXGA},
413 static const s16 hsv_red_x[] = {
414 41, 44, 46, 48, 50, 52, 54, 56,
415 58, 60, 62, 64, 66, 68, 70, 72,
416 74, 76, 78, 80, 81, 83, 85, 87,
417 88, 90, 92, 93, 95, 97, 98, 100,
418 101, 102, 104, 105, 107, 108, 109, 110,
419 112, 113, 114, 115, 116, 117, 118, 119,
420 120, 121, 122, 123, 123, 124, 125, 125,
421 126, 127, 127, 128, 128, 129, 129, 129,
422 130, 130, 130, 130, 131, 131, 131, 131,
423 131, 131, 131, 131, 130, 130, 130, 130,
424 129, 129, 129, 128, 128, 127, 127, 126,
425 125, 125, 124, 123, 122, 122, 121, 120,
426 119, 118, 117, 116, 115, 114, 112, 111,
427 110, 109, 107, 106, 105, 103, 102, 101,
428 99, 98, 96, 94, 93, 91, 90, 88,
429 86, 84, 83, 81, 79, 77, 75, 74,
430 72, 70, 68, 66, 64, 62, 60, 58,
431 56, 54, 52, 49, 47, 45, 43, 41,
432 39, 36, 34, 32, 30, 28, 25, 23,
433 21, 19, 16, 14, 12, 9, 7, 5,
434 3, 0, -1, -3, -6, -8, -10, -12,
435 -15, -17, -19, -22, -24, -26, -28, -30,
436 -33, -35, -37, -39, -41, -44, -46, -48,
437 -50, -52, -54, -56, -58, -60, -62, -64,
438 -66, -68, -70, -72, -74, -76, -78, -80,
439 -81, -83, -85, -87, -88, -90, -92, -93,
440 -95, -97, -98, -100, -101, -102, -104, -105,
441 -107, -108, -109, -110, -112, -113, -114, -115,
442 -116, -117, -118, -119, -120, -121, -122, -123,
443 -123, -124, -125, -125, -126, -127, -127, -128,
444 -128, -128, -128, -128, -128, -128, -128, -128,
445 -128, -128, -128, -128, -128, -128, -128, -128,
446 -128, -128, -128, -128, -128, -128, -128, -128,
447 -128, -127, -127, -126, -125, -125, -124, -123,
448 -122, -122, -121, -120, -119, -118, -117, -116,
449 -115, -114, -112, -111, -110, -109, -107, -106,
450 -105, -103, -102, -101, -99, -98, -96, -94,
451 -93, -91, -90, -88, -86, -84, -83, -81,
452 -79, -77, -75, -74, -72, -70, -68, -66,
453 -64, -62, -60, -58, -56, -54, -52, -49,
454 -47, -45, -43, -41, -39, -36, -34, -32,
455 -30, -28, -25, -23, -21, -19, -16, -14,
456 -12, -9, -7, -5, -3, 0, 1, 3,
457 6, 8, 10, 12, 15, 17, 19, 22,
458 24, 26, 28, 30, 33, 35, 37, 39, 41
461 static const s16 hsv_red_y[] = {
462 82, 80, 78, 76, 74, 73, 71, 69,
463 67, 65, 63, 61, 58, 56, 54, 52,
464 50, 48, 46, 44, 41, 39, 37, 35,
465 32, 30, 28, 26, 23, 21, 19, 16,
466 14, 12, 10, 7, 5, 3, 0, -1,
467 -3, -6, -8, -10, -13, -15, -17, -19,
468 -22, -24, -26, -29, -31, -33, -35, -38,
469 -40, -42, -44, -46, -48, -51, -53, -55,
470 -57, -59, -61, -63, -65, -67, -69, -71,
471 -73, -75, -77, -79, -81, -82, -84, -86,
472 -88, -89, -91, -93, -94, -96, -98, -99,
473 -101, -102, -104, -105, -106, -108, -109, -110,
474 -112, -113, -114, -115, -116, -117, -119, -120,
475 -120, -121, -122, -123, -124, -125, -126, -126,
476 -127, -128, -128, -128, -128, -128, -128, -128,
477 -128, -128, -128, -128, -128, -128, -128, -128,
478 -128, -128, -128, -128, -128, -128, -128, -128,
479 -128, -128, -128, -128, -128, -128, -128, -128,
480 -127, -127, -126, -125, -125, -124, -123, -122,
481 -121, -120, -119, -118, -117, -116, -115, -114,
482 -113, -111, -110, -109, -107, -106, -105, -103,
483 -102, -100, -99, -97, -96, -94, -92, -91,
484 -89, -87, -85, -84, -82, -80, -78, -76,
485 -74, -73, -71, -69, -67, -65, -63, -61,
486 -58, -56, -54, -52, -50, -48, -46, -44,
487 -41, -39, -37, -35, -32, -30, -28, -26,
488 -23, -21, -19, -16, -14, -12, -10, -7,
489 -5, -3, 0, 1, 3, 6, 8, 10,
490 13, 15, 17, 19, 22, 24, 26, 29,
491 31, 33, 35, 38, 40, 42, 44, 46,
492 48, 51, 53, 55, 57, 59, 61, 63,
493 65, 67, 69, 71, 73, 75, 77, 79,
494 81, 82, 84, 86, 88, 89, 91, 93,
495 94, 96, 98, 99, 101, 102, 104, 105,
496 106, 108, 109, 110, 112, 113, 114, 115,
497 116, 117, 119, 120, 120, 121, 122, 123,
498 124, 125, 126, 126, 127, 128, 128, 129,
499 129, 130, 130, 131, 131, 131, 131, 132,
500 132, 132, 132, 132, 132, 132, 132, 132,
501 132, 132, 132, 131, 131, 131, 130, 130,
502 130, 129, 129, 128, 127, 127, 126, 125,
503 125, 124, 123, 122, 121, 120, 119, 118,
504 117, 116, 115, 114, 113, 111, 110, 109,
505 107, 106, 105, 103, 102, 100, 99, 97,
506 96, 94, 92, 91, 89, 87, 85, 84, 82
509 static const s16 hsv_green_x[] = {
510 -124, -124, -125, -125, -125, -125, -125, -125,
511 -125, -126, -126, -125, -125, -125, -125, -125,
512 -125, -124, -124, -124, -123, -123, -122, -122,
513 -121, -121, -120, -120, -119, -118, -117, -117,
514 -116, -115, -114, -113, -112, -111, -110, -109,
515 -108, -107, -105, -104, -103, -102, -100, -99,
516 -98, -96, -95, -93, -92, -91, -89, -87,
517 -86, -84, -83, -81, -79, -77, -76, -74,
518 -72, -70, -69, -67, -65, -63, -61, -59,
519 -57, -55, -53, -51, -49, -47, -45, -43,
520 -41, -39, -37, -35, -33, -30, -28, -26,
521 -24, -22, -20, -18, -15, -13, -11, -9,
522 -7, -4, -2, 0, 1, 3, 6, 8,
523 10, 12, 14, 17, 19, 21, 23, 25,
524 27, 29, 32, 34, 36, 38, 40, 42,
525 44, 46, 48, 50, 52, 54, 56, 58,
526 60, 62, 64, 66, 68, 70, 71, 73,
527 75, 77, 78, 80, 82, 83, 85, 87,
528 88, 90, 91, 93, 94, 96, 97, 98,
529 100, 101, 102, 104, 105, 106, 107, 108,
530 109, 111, 112, 113, 113, 114, 115, 116,
531 117, 118, 118, 119, 120, 120, 121, 122,
532 122, 123, 123, 124, 124, 124, 125, 125,
533 125, 125, 125, 125, 125, 126, 126, 125,
534 125, 125, 125, 125, 125, 124, 124, 124,
535 123, 123, 122, 122, 121, 121, 120, 120,
536 119, 118, 117, 117, 116, 115, 114, 113,
537 112, 111, 110, 109, 108, 107, 105, 104,
538 103, 102, 100, 99, 98, 96, 95, 93,
539 92, 91, 89, 87, 86, 84, 83, 81,
540 79, 77, 76, 74, 72, 70, 69, 67,
541 65, 63, 61, 59, 57, 55, 53, 51,
542 49, 47, 45, 43, 41, 39, 37, 35,
543 33, 30, 28, 26, 24, 22, 20, 18,
544 15, 13, 11, 9, 7, 4, 2, 0,
545 -1, -3, -6, -8, -10, -12, -14, -17,
546 -19, -21, -23, -25, -27, -29, -32, -34,
547 -36, -38, -40, -42, -44, -46, -48, -50,
548 -52, -54, -56, -58, -60, -62, -64, -66,
549 -68, -70, -71, -73, -75, -77, -78, -80,
550 -82, -83, -85, -87, -88, -90, -91, -93,
551 -94, -96, -97, -98, -100, -101, -102, -104,
552 -105, -106, -107, -108, -109, -111, -112, -113,
553 -113, -114, -115, -116, -117, -118, -118, -119,
554 -120, -120, -121, -122, -122, -123, -123, -124, -124
557 static const s16 hsv_green_y[] = {
558 -100, -99, -98, -97, -95, -94, -93, -91,
559 -90, -89, -87, -86, -84, -83, -81, -80,
560 -78, -76, -75, -73, -71, -70, -68, -66,
561 -64, -63, -61, -59, -57, -55, -53, -51,
562 -49, -48, -46, -44, -42, -40, -38, -36,
563 -34, -32, -30, -27, -25, -23, -21, -19,
564 -17, -15, -13, -11, -9, -7, -4, -2,
565 0, 1, 3, 5, 7, 9, 11, 14,
566 16, 18, 20, 22, 24, 26, 28, 30,
567 32, 34, 36, 38, 40, 42, 44, 46,
568 48, 50, 52, 54, 56, 58, 59, 61,
569 63, 65, 67, 68, 70, 72, 74, 75,
570 77, 78, 80, 82, 83, 85, 86, 88,
571 89, 90, 92, 93, 95, 96, 97, 98,
572 100, 101, 102, 103, 104, 105, 106, 107,
573 108, 109, 110, 111, 112, 112, 113, 114,
574 115, 115, 116, 116, 117, 117, 118, 118,
575 119, 119, 119, 120, 120, 120, 120, 120,
576 121, 121, 121, 121, 121, 121, 120, 120,
577 120, 120, 120, 119, 119, 119, 118, 118,
578 117, 117, 116, 116, 115, 114, 114, 113,
579 112, 111, 111, 110, 109, 108, 107, 106,
580 105, 104, 103, 102, 100, 99, 98, 97,
581 95, 94, 93, 91, 90, 89, 87, 86,
582 84, 83, 81, 80, 78, 76, 75, 73,
583 71, 70, 68, 66, 64, 63, 61, 59,
584 57, 55, 53, 51, 49, 48, 46, 44,
585 42, 40, 38, 36, 34, 32, 30, 27,
586 25, 23, 21, 19, 17, 15, 13, 11,
587 9, 7, 4, 2, 0, -1, -3, -5,
588 -7, -9, -11, -14, -16, -18, -20, -22,
589 -24, -26, -28, -30, -32, -34, -36, -38,
590 -40, -42, -44, -46, -48, -50, -52, -54,
591 -56, -58, -59, -61, -63, -65, -67, -68,
592 -70, -72, -74, -75, -77, -78, -80, -82,
593 -83, -85, -86, -88, -89, -90, -92, -93,
594 -95, -96, -97, -98, -100, -101, -102, -103,
595 -104, -105, -106, -107, -108, -109, -110, -111,
596 -112, -112, -113, -114, -115, -115, -116, -116,
597 -117, -117, -118, -118, -119, -119, -119, -120,
598 -120, -120, -120, -120, -121, -121, -121, -121,
599 -121, -121, -120, -120, -120, -120, -120, -119,
600 -119, -119, -118, -118, -117, -117, -116, -116,
601 -115, -114, -114, -113, -112, -111, -111, -110,
602 -109, -108, -107, -106, -105, -104, -103, -102, -100
605 static const s16 hsv_blue_x[] = {
606 112, 113, 114, 114, 115, 116, 117, 117,
607 118, 118, 119, 119, 120, 120, 120, 121,
608 121, 121, 122, 122, 122, 122, 122, 122,
609 122, 122, 122, 122, 122, 122, 121, 121,
610 121, 120, 120, 120, 119, 119, 118, 118,
611 117, 116, 116, 115, 114, 113, 113, 112,
612 111, 110, 109, 108, 107, 106, 105, 104,
613 103, 102, 100, 99, 98, 97, 95, 94,
614 93, 91, 90, 88, 87, 85, 84, 82,
615 80, 79, 77, 76, 74, 72, 70, 69,
616 67, 65, 63, 61, 60, 58, 56, 54,
617 52, 50, 48, 46, 44, 42, 40, 38,
618 36, 34, 32, 30, 28, 26, 24, 22,
619 19, 17, 15, 13, 11, 9, 7, 5,
620 2, 0, -1, -3, -5, -7, -9, -12,
621 -14, -16, -18, -20, -22, -24, -26, -28,
622 -31, -33, -35, -37, -39, -41, -43, -45,
623 -47, -49, -51, -53, -54, -56, -58, -60,
624 -62, -64, -66, -67, -69, -71, -73, -74,
625 -76, -78, -79, -81, -83, -84, -86, -87,
626 -89, -90, -92, -93, -94, -96, -97, -98,
627 -99, -101, -102, -103, -104, -105, -106, -107,
628 -108, -109, -110, -111, -112, -113, -114, -114,
629 -115, -116, -117, -117, -118, -118, -119, -119,
630 -120, -120, -120, -121, -121, -121, -122, -122,
631 -122, -122, -122, -122, -122, -122, -122, -122,
632 -122, -122, -121, -121, -121, -120, -120, -120,
633 -119, -119, -118, -118, -117, -116, -116, -115,
634 -114, -113, -113, -112, -111, -110, -109, -108,
635 -107, -106, -105, -104, -103, -102, -100, -99,
636 -98, -97, -95, -94, -93, -91, -90, -88,
637 -87, -85, -84, -82, -80, -79, -77, -76,
638 -74, -72, -70, -69, -67, -65, -63, -61,
639 -60, -58, -56, -54, -52, -50, -48, -46,
640 -44, -42, -40, -38, -36, -34, -32, -30,
641 -28, -26, -24, -22, -19, -17, -15, -13,
642 -11, -9, -7, -5, -2, 0, 1, 3,
643 5, 7, 9, 12, 14, 16, 18, 20,
644 22, 24, 26, 28, 31, 33, 35, 37,
645 39, 41, 43, 45, 47, 49, 51, 53,
646 54, 56, 58, 60, 62, 64, 66, 67,
647 69, 71, 73, 74, 76, 78, 79, 81,
648 83, 84, 86, 87, 89, 90, 92, 93,
649 94, 96, 97, 98, 99, 101, 102, 103,
650 104, 105, 106, 107, 108, 109, 110, 111, 112
653 static const s16 hsv_blue_y[] = {
654 -11, -13, -15, -17, -19, -21, -23, -25,
655 -27, -29, -31, -33, -35, -37, -39, -41,
656 -43, -45, -46, -48, -50, -52, -54, -55,
657 -57, -59, -61, -62, -64, -66, -67, -69,
658 -71, -72, -74, -75, -77, -78, -80, -81,
659 -83, -84, -86, -87, -88, -90, -91, -92,
660 -93, -95, -96, -97, -98, -99, -100, -101,
661 -102, -103, -104, -105, -106, -106, -107, -108,
662 -109, -109, -110, -111, -111, -112, -112, -113,
663 -113, -114, -114, -114, -115, -115, -115, -115,
664 -116, -116, -116, -116, -116, -116, -116, -116,
665 -116, -115, -115, -115, -115, -114, -114, -114,
666 -113, -113, -112, -112, -111, -111, -110, -110,
667 -109, -108, -108, -107, -106, -105, -104, -103,
668 -102, -101, -100, -99, -98, -97, -96, -95,
669 -94, -93, -91, -90, -89, -88, -86, -85,
670 -84, -82, -81, -79, -78, -76, -75, -73,
671 -71, -70, -68, -67, -65, -63, -62, -60,
672 -58, -56, -55, -53, -51, -49, -47, -45,
673 -44, -42, -40, -38, -36, -34, -32, -30,
674 -28, -26, -24, -22, -20, -18, -16, -14,
675 -12, -10, -8, -6, -4, -2, 0, 1,
676 3, 5, 7, 9, 11, 13, 15, 17,
677 19, 21, 23, 25, 27, 29, 31, 33,
678 35, 37, 39, 41, 43, 45, 46, 48,
679 50, 52, 54, 55, 57, 59, 61, 62,
680 64, 66, 67, 69, 71, 72, 74, 75,
681 77, 78, 80, 81, 83, 84, 86, 87,
682 88, 90, 91, 92, 93, 95, 96, 97,
683 98, 99, 100, 101, 102, 103, 104, 105,
684 106, 106, 107, 108, 109, 109, 110, 111,
685 111, 112, 112, 113, 113, 114, 114, 114,
686 115, 115, 115, 115, 116, 116, 116, 116,
687 116, 116, 116, 116, 116, 115, 115, 115,
688 115, 114, 114, 114, 113, 113, 112, 112,
689 111, 111, 110, 110, 109, 108, 108, 107,
690 106, 105, 104, 103, 102, 101, 100, 99,
691 98, 97, 96, 95, 94, 93, 91, 90,
692 89, 88, 86, 85, 84, 82, 81, 79,
693 78, 76, 75, 73, 71, 70, 68, 67,
694 65, 63, 62, 60, 58, 56, 55, 53,
695 51, 49, 47, 45, 44, 42, 40, 38,
696 36, 34, 32, 30, 28, 26, 24, 22,
697 20, 18, 16, 14, 12, 10, 8, 6,
698 4, 2, 0, -1, -3, -5, -7, -9, -11
701 static u16 i2c_ident[] = {
710 V4L2_IDENT_MT9M001C12ST,
715 static u16 bridge_init[][2] = {
716 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
717 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
718 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
719 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
720 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
721 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
722 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
723 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
724 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
725 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
726 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
727 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
728 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
729 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
730 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
731 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
732 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
733 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
734 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80}
737 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
738 static u8 ov_gain[] = {
739 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
740 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
741 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
742 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
743 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
744 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
745 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
749 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
750 static u16 micron1_gain[] = {
751 /* 1x 1.25x 1.5x 1.75x */
752 0x0020, 0x0028, 0x0030, 0x0038,
753 /* 2x 2.25x 2.5x 2.75x */
754 0x00a0, 0x00a4, 0x00a8, 0x00ac,
755 /* 3x 3.25x 3.5x 3.75x */
756 0x00b0, 0x00b4, 0x00b8, 0x00bc,
757 /* 4x 4.25x 4.5x 4.75x */
758 0x00c0, 0x00c4, 0x00c8, 0x00cc,
759 /* 5x 5.25x 5.5x 5.75x */
760 0x00d0, 0x00d4, 0x00d8, 0x00dc,
761 /* 6x 6.25x 6.5x 6.75x */
762 0x00e0, 0x00e4, 0x00e8, 0x00ec,
763 /* 7x 7.25x 7.5x 7.75x */
764 0x00f0, 0x00f4, 0x00f8, 0x00fc,
769 /* mt9m001 sensor uses a different gain formula then other micron sensors */
770 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
771 static u16 micron2_gain[] = {
772 /* 1x 1.25x 1.5x 1.75x */
773 0x0008, 0x000a, 0x000c, 0x000e,
774 /* 2x 2.25x 2.5x 2.75x */
775 0x0010, 0x0012, 0x0014, 0x0016,
776 /* 3x 3.25x 3.5x 3.75x */
777 0x0018, 0x001a, 0x001c, 0x001e,
778 /* 4x 4.25x 4.5x 4.75x */
779 0x0020, 0x0051, 0x0052, 0x0053,
780 /* 5x 5.25x 5.5x 5.75x */
781 0x0054, 0x0055, 0x0056, 0x0057,
782 /* 6x 6.25x 6.5x 6.75x */
783 0x0058, 0x0059, 0x005a, 0x005b,
784 /* 7x 7.25x 7.5x 7.75x */
785 0x005c, 0x005d, 0x005e, 0x005f,
790 /* Gain = .5 + bit[7:0] / 16 */
791 static u8 hv7131r_gain[] = {
792 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
793 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
794 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
795 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
796 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
797 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
798 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
802 static struct i2c_reg_u8 soi968_init[] = {
803 {0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f},
804 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
805 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
806 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
807 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
808 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
809 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
810 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
811 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
812 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
813 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
816 static struct i2c_reg_u8 ov7660_init[] = {
817 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
818 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
819 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
820 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
821 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6},
822 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
825 static struct i2c_reg_u8 ov7670_init[] = {
826 {0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
827 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
828 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
829 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
830 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
831 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
832 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
833 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
834 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
835 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
836 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
837 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
838 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
839 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
840 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
841 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
842 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
843 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
844 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
845 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
846 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
847 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
848 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
849 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
850 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
851 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
852 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
853 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
854 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
855 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
856 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
857 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
858 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
859 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
860 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
861 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
862 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
863 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
864 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
865 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
866 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
867 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
868 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
869 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
870 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
871 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
872 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
873 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
874 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
875 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
876 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
877 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
878 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
882 static struct i2c_reg_u8 ov9650_init[] = {
883 {0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78},
884 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
885 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
886 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
887 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
888 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
889 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
890 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
891 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
892 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
893 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
894 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
895 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
896 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
897 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
898 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
899 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
900 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
901 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
902 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
903 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
904 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
905 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
906 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
907 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
908 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
909 {0xaa, 0x92}, {0xab, 0x0a},
912 static struct i2c_reg_u8 ov9655_init[] = {
913 {0x12, 0x80}, {0x12, 0x01}, {0x0d, 0x00}, {0x0e, 0x61},
914 {0x11, 0x80}, {0x13, 0xba}, {0x14, 0x2e}, {0x16, 0x24},
915 {0x1e, 0x04}, {0x1e, 0x04}, {0x1e, 0x04}, {0x27, 0x08},
916 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x32, 0xbf},
917 {0x34, 0x3d}, {0x35, 0x00}, {0x36, 0xf8}, {0x38, 0x12},
918 {0x39, 0x57}, {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c},
919 {0x3d, 0x19}, {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40},
920 {0x42, 0x80}, {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a},
921 {0x48, 0x3c}, {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc},
922 {0x4d, 0xdc}, {0x4e, 0xdc}, {0x69, 0x02}, {0x6c, 0x04},
923 {0x6f, 0x9e}, {0x70, 0x05}, {0x71, 0x78}, {0x77, 0x02},
924 {0x8a, 0x23}, {0x8c, 0x0d}, {0x90, 0x7e}, {0x91, 0x7c},
925 {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68}, {0xa6, 0x60},
926 {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92}, {0xab, 0x04},
927 {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80}, {0xaf, 0x80},
928 {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00}, {0xb6, 0xaf},
929 {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44}, {0xbe, 0x3b},
930 {0xbf, 0x3a}, {0xc0, 0xe2}, {0xc1, 0xc8}, {0xc2, 0x01},
931 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
932 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x12, 0x61},
933 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
934 {0x03, 0x12}, {0x17, 0x14}, {0x18, 0x00}, {0x19, 0x01},
935 {0x1a, 0x3d}, {0x32, 0xbf}, {0x11, 0x80}, {0x2a, 0x10},
936 {0x2b, 0x0a}, {0x92, 0x00}, {0x93, 0x00}, {0x1e, 0x04},
937 {0x1e, 0x04}, {0x10, 0x7c}, {0x04, 0x03}, {0xa1, 0x00},
938 {0x2d, 0x00}, {0x2e, 0x00}, {0x00, 0x00}, {0x01, 0x80},
939 {0x02, 0x80}, {0x12, 0x61}, {0x36, 0xfa}, {0x8c, 0x8d},
940 {0xc0, 0xaa}, {0x69, 0x0a}, {0x03, 0x12}, {0x17, 0x14},
941 {0x18, 0x00}, {0x19, 0x01}, {0x1a, 0x3d}, {0x32, 0xbf},
942 {0x11, 0x80}, {0x2a, 0x10}, {0x2b, 0x0a}, {0x92, 0x00},
943 {0x93, 0x00}, {0x04, 0x01}, {0x10, 0x1f}, {0xa1, 0x00},
944 {0x00, 0x0a}, {0xa1, 0x00}, {0x10, 0x5d}, {0x04, 0x03},
945 {0x00, 0x01}, {0xa1, 0x00}, {0x10, 0x7c}, {0x04, 0x03},
946 {0x00, 0x03}, {0x00, 0x0a}, {0x00, 0x10}, {0x00, 0x13},
949 static struct i2c_reg_u16 mt9v112_init[] = {
950 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
951 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
952 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
953 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
954 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
955 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
956 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
957 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
958 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
959 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
960 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
961 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
962 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
963 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
964 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
965 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
968 static struct i2c_reg_u16 mt9v111_init[] = {
969 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
970 {0x01, 0x0001}, {0x02, 0x0016}, {0x03, 0x01e1},
971 {0x04, 0x0281}, {0x05, 0x0004}, {0x07, 0x3002},
972 {0x21, 0x0000}, {0x25, 0x4024}, {0x26, 0xff03},
973 {0x27, 0xff10}, {0x2b, 0x7828}, {0x2c, 0xb43c},
974 {0x2d, 0xf0a0}, {0x2e, 0x0c64}, {0x2f, 0x0064},
975 {0x67, 0x4010}, {0x06, 0x301e}, {0x08, 0x0480},
976 {0x01, 0x0004}, {0x02, 0x0016}, {0x03, 0x01e6},
977 {0x04, 0x0286}, {0x05, 0x0004}, {0x06, 0x0000},
978 {0x07, 0x3002}, {0x08, 0x0008}, {0x0c, 0x0000},
979 {0x0d, 0x0000}, {0x0e, 0x0000}, {0x0f, 0x0000},
980 {0x10, 0x0000}, {0x11, 0x0000}, {0x12, 0x00b0},
981 {0x13, 0x007c}, {0x14, 0x0000}, {0x15, 0x0000},
982 {0x16, 0x0000}, {0x17, 0x0000}, {0x18, 0x0000},
983 {0x19, 0x0000}, {0x1a, 0x0000}, {0x1b, 0x0000},
984 {0x1c, 0x0000}, {0x1d, 0x0000}, {0x30, 0x0000},
985 {0x30, 0x0005}, {0x31, 0x0000}, {0x02, 0x0016},
986 {0x03, 0x01e1}, {0x04, 0x0281}, {0x05, 0x0004},
987 {0x06, 0x0000}, {0x07, 0x3002}, {0x06, 0x002d},
988 {0x05, 0x0004}, {0x09, 0x0064}, {0x2b, 0x00a0},
989 {0x2c, 0x00a0}, {0x2d, 0x00a0}, {0x2e, 0x00a0},
990 {0x02, 0x0016}, {0x03, 0x01e1}, {0x04, 0x0281},
991 {0x05, 0x0004}, {0x06, 0x002d}, {0x07, 0x3002},
992 {0x0e, 0x0008}, {0x06, 0x002d}, {0x05, 0x0004},
995 static struct i2c_reg_u16 mt9v011_init[] = {
996 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
997 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
998 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
999 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
1000 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
1001 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
1002 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
1003 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
1004 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
1005 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
1006 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
1007 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
1008 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
1009 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
1010 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
1011 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
1012 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
1013 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
1014 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
1015 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
1016 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
1017 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1018 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
1019 {0x06, 0x0029}, {0x05, 0x0009},
1022 static struct i2c_reg_u16 mt9m001_init[] = {
1023 {0x0d, 0x0001}, {0x0d, 0x0000}, {0x01, 0x000e},
1024 {0x02, 0x0014}, {0x03, 0x03c1}, {0x04, 0x0501},
1025 {0x05, 0x0083}, {0x06, 0x0006}, {0x0d, 0x0002},
1026 {0x0a, 0x0000}, {0x0c, 0x0000}, {0x11, 0x0000},
1027 {0x1e, 0x8000}, {0x5f, 0x8904}, {0x60, 0x0000},
1028 {0x61, 0x0000}, {0x62, 0x0498}, {0x63, 0x0000},
1029 {0x64, 0x0000}, {0x20, 0x111d}, {0x06, 0x00f2},
1030 {0x05, 0x0013}, {0x09, 0x10f2}, {0x07, 0x0003},
1031 {0x2b, 0x002a}, {0x2d, 0x002a}, {0x2c, 0x002a},
1032 {0x2e, 0x0029}, {0x07, 0x0002},
1035 static struct i2c_reg_u16 mt9m111_init[] = {
1036 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
1037 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1038 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
1042 static struct i2c_reg_u8 hv7131r_init[] = {
1043 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
1044 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
1045 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
1046 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
1047 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
1048 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
1049 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
1050 {0x23, 0x09}, {0x01, 0x08},
1053 static int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
1055 struct usb_device *dev = gspca_dev->dev;
1057 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
1059 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1065 if (unlikely(result < 0 || result != length)) {
1066 err("Read register failed 0x%02X", reg);
1072 static int reg_w(struct gspca_dev *gspca_dev, u16 reg,
1073 const u8 *buffer, int length)
1075 struct usb_device *dev = gspca_dev->dev;
1077 memcpy(gspca_dev->usb_buf, buffer, length);
1078 result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1080 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1086 if (unlikely(result < 0 || result != length)) {
1087 err("Write register failed index 0x%02X", reg);
1093 static int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
1095 u8 data[1] = {value};
1096 return reg_w(gspca_dev, reg, data, 1);
1099 static int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
1102 reg_w(gspca_dev, 0x10c0, buffer, 8);
1103 for (i = 0; i < 5; i++) {
1104 reg_r(gspca_dev, 0x10c0, 1);
1105 if (gspca_dev->usb_buf[0] & 0x04) {
1106 if (gspca_dev->usb_buf[0] & 0x08)
1115 static int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1117 struct sd *sd = (struct sd *) gspca_dev;
1122 * from the point of view of the bridge, the length
1123 * includes the address
1125 row[0] = 0x81 | (2 << 4);
1126 row[1] = sd->i2c_addr;
1134 return i2c_w(gspca_dev, row);
1137 static int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1139 struct sd *sd = (struct sd *) gspca_dev;
1143 * from the point of view of the bridge, the length
1144 * includes the address
1146 row[0] = 0x81 | (3 << 4);
1147 row[1] = sd->i2c_addr;
1149 row[3] = (val >> 8) & 0xff;
1150 row[4] = val & 0xff;
1155 return i2c_w(gspca_dev, row);
1158 static int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1160 struct sd *sd = (struct sd *) gspca_dev;
1163 row[0] = 0x81 | (1 << 4);
1164 row[1] = sd->i2c_addr;
1171 if (i2c_w(gspca_dev, row) < 0)
1173 row[0] = 0x81 | (1 << 4) | 0x02;
1175 if (i2c_w(gspca_dev, row) < 0)
1177 if (reg_r(gspca_dev, 0x10c2, 5) < 0)
1179 *val = gspca_dev->usb_buf[4];
1183 static int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1185 struct sd *sd = (struct sd *) gspca_dev;
1188 row[0] = 0x81 | (1 << 4);
1189 row[1] = sd->i2c_addr;
1196 if (i2c_w(gspca_dev, row) < 0)
1198 row[0] = 0x81 | (2 << 4) | 0x02;
1200 if (i2c_w(gspca_dev, row) < 0)
1202 if (reg_r(gspca_dev, 0x10c2, 5) < 0)
1204 *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1208 static int ov9650_init_sensor(struct gspca_dev *gspca_dev)
1211 struct sd *sd = (struct sd *) gspca_dev;
1213 for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) {
1214 if (i2c_w1(gspca_dev, ov9650_init[i].reg,
1215 ov9650_init[i].val) < 0) {
1216 err("OV9650 sensor initialization failed");
1225 static int ov9655_init_sensor(struct gspca_dev *gspca_dev)
1228 struct sd *sd = (struct sd *) gspca_dev;
1230 for (i = 0; i < ARRAY_SIZE(ov9655_init); i++) {
1231 if (i2c_w1(gspca_dev, ov9655_init[i].reg,
1232 ov9655_init[i].val) < 0) {
1233 err("OV9655 sensor initialization failed");
1237 /* disable hflip and vflip */
1238 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1244 static int soi968_init_sensor(struct gspca_dev *gspca_dev)
1247 struct sd *sd = (struct sd *) gspca_dev;
1249 for (i = 0; i < ARRAY_SIZE(soi968_init); i++) {
1250 if (i2c_w1(gspca_dev, soi968_init[i].reg,
1251 soi968_init[i].val) < 0) {
1252 err("SOI968 sensor initialization failed");
1256 /* disable hflip and vflip */
1257 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << EXPOSURE_IDX);
1263 static int ov7660_init_sensor(struct gspca_dev *gspca_dev)
1266 struct sd *sd = (struct sd *) gspca_dev;
1268 for (i = 0; i < ARRAY_SIZE(ov7660_init); i++) {
1269 if (i2c_w1(gspca_dev, ov7660_init[i].reg,
1270 ov7660_init[i].val) < 0) {
1271 err("OV7660 sensor initialization failed");
1275 /* disable hflip and vflip */
1276 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1282 static int ov7670_init_sensor(struct gspca_dev *gspca_dev)
1285 struct sd *sd = (struct sd *) gspca_dev;
1287 for (i = 0; i < ARRAY_SIZE(ov7670_init); i++) {
1288 if (i2c_w1(gspca_dev, ov7670_init[i].reg,
1289 ov7670_init[i].val) < 0) {
1290 err("OV7670 sensor initialization failed");
1294 /* disable hflip and vflip */
1295 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1301 static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
1303 struct sd *sd = (struct sd *) gspca_dev;
1308 sd->i2c_addr = 0x5d;
1309 ret = i2c_r2(gspca_dev, 0xff, &value);
1310 if ((ret == 0) && (value == 0x8243)) {
1311 for (i = 0; i < ARRAY_SIZE(mt9v011_init); i++) {
1312 if (i2c_w2(gspca_dev, mt9v011_init[i].reg,
1313 mt9v011_init[i].val) < 0) {
1314 err("MT9V011 sensor initialization failed");
1320 sd->sensor = SENSOR_MT9V011;
1321 info("MT9V011 sensor detected");
1325 sd->i2c_addr = 0x5c;
1326 i2c_w2(gspca_dev, 0x01, 0x0004);
1327 ret = i2c_r2(gspca_dev, 0xff, &value);
1328 if ((ret == 0) && (value == 0x823a)) {
1329 for (i = 0; i < ARRAY_SIZE(mt9v111_init); i++) {
1330 if (i2c_w2(gspca_dev, mt9v111_init[i].reg,
1331 mt9v111_init[i].val) < 0) {
1332 err("MT9V111 sensor initialization failed");
1338 sd->sensor = SENSOR_MT9V111;
1339 info("MT9V111 sensor detected");
1343 sd->i2c_addr = 0x5d;
1344 ret = i2c_w2(gspca_dev, 0xf0, 0x0000);
1346 sd->i2c_addr = 0x48;
1347 i2c_w2(gspca_dev, 0xf0, 0x0000);
1349 ret = i2c_r2(gspca_dev, 0x00, &value);
1350 if ((ret == 0) && (value == 0x1229)) {
1351 for (i = 0; i < ARRAY_SIZE(mt9v112_init); i++) {
1352 if (i2c_w2(gspca_dev, mt9v112_init[i].reg,
1353 mt9v112_init[i].val) < 0) {
1354 err("MT9V112 sensor initialization failed");
1360 sd->sensor = SENSOR_MT9V112;
1361 info("MT9V112 sensor detected");
1368 static int mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1370 struct sd *sd = (struct sd *) gspca_dev;
1372 for (i = 0; i < ARRAY_SIZE(mt9m111_init); i++) {
1373 if (i2c_w2(gspca_dev, mt9m111_init[i].reg,
1374 mt9m111_init[i].val) < 0) {
1375 err("MT9M111 sensor initialization failed");
1379 gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | (1 << GAIN_IDX);
1385 static int mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1387 struct sd *sd = (struct sd *) gspca_dev;
1389 for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) {
1390 if (i2c_w2(gspca_dev, mt9m001_init[i].reg,
1391 mt9m001_init[i].val) < 0) {
1392 err("MT9M001 sensor initialization failed");
1396 /* disable hflip and vflip */
1397 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1403 static int hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1406 struct sd *sd = (struct sd *) gspca_dev;
1408 for (i = 0; i < ARRAY_SIZE(hv7131r_init); i++) {
1409 if (i2c_w1(gspca_dev, hv7131r_init[i].reg,
1410 hv7131r_init[i].val) < 0) {
1411 err("HV7131R Sensor initialization failed");
1420 static int set_cmatrix(struct gspca_dev *gspca_dev)
1422 struct sd *sd = (struct sd *) gspca_dev;
1423 s32 hue_coord, hue_index = 180 + sd->hue;
1426 memset(cmatrix, 0, sizeof cmatrix);
1427 cmatrix[2] = (sd->contrast * 0x25 / 0x100) + 0x26;
1428 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1429 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1430 cmatrix[18] = sd->brightness - 0x80;
1432 hue_coord = (hsv_red_x[hue_index] * sd->saturation) >> 8;
1433 cmatrix[6] = hue_coord;
1434 cmatrix[7] = (hue_coord >> 8) & 0x0f;
1436 hue_coord = (hsv_red_y[hue_index] * sd->saturation) >> 8;
1437 cmatrix[8] = hue_coord;
1438 cmatrix[9] = (hue_coord >> 8) & 0x0f;
1440 hue_coord = (hsv_green_x[hue_index] * sd->saturation) >> 8;
1441 cmatrix[10] = hue_coord;
1442 cmatrix[11] = (hue_coord >> 8) & 0x0f;
1444 hue_coord = (hsv_green_y[hue_index] * sd->saturation) >> 8;
1445 cmatrix[12] = hue_coord;
1446 cmatrix[13] = (hue_coord >> 8) & 0x0f;
1448 hue_coord = (hsv_blue_x[hue_index] * sd->saturation) >> 8;
1449 cmatrix[14] = hue_coord;
1450 cmatrix[15] = (hue_coord >> 8) & 0x0f;
1452 hue_coord = (hsv_blue_y[hue_index] * sd->saturation) >> 8;
1453 cmatrix[16] = hue_coord;
1454 cmatrix[17] = (hue_coord >> 8) & 0x0f;
1456 return reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1459 static int set_gamma(struct gspca_dev *gspca_dev)
1461 struct sd *sd = (struct sd *) gspca_dev;
1463 u8 gval = sd->gamma * 0xb8 / 0x100;
1467 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
1468 gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8);
1469 gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8);
1470 gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8);
1471 gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8);
1472 gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8);
1473 gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8);
1474 gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8);
1475 gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8);
1476 gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8);
1477 gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8);
1478 gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8);
1479 gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8);
1480 gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8);
1481 gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
1484 return reg_w(gspca_dev, 0x1190, gamma, 17);
1487 static int set_redblue(struct gspca_dev *gspca_dev)
1489 struct sd *sd = (struct sd *) gspca_dev;
1490 reg_w1(gspca_dev, 0x118c, sd->red);
1491 reg_w1(gspca_dev, 0x118f, sd->blue);
1495 static int set_hvflip(struct gspca_dev *gspca_dev)
1499 struct sd *sd = (struct sd *) gspca_dev;
1500 switch (sd->sensor) {
1502 i2c_r1(gspca_dev, 0x1e, &value);
1511 i2c_w1(gspca_dev, 0x1e, value);
1512 i2c_w1(gspca_dev, 0x3a, tslb);
1514 case SENSOR_MT9V111:
1515 case SENSOR_MT9V011:
1516 i2c_r2(gspca_dev, 0x20, &value2);
1522 i2c_w2(gspca_dev, 0x20, value2);
1524 case SENSOR_MT9M111:
1525 case SENSOR_MT9V112:
1526 i2c_r2(gspca_dev, 0x20, &value2);
1532 i2c_w2(gspca_dev, 0x20, value2);
1534 case SENSOR_HV7131R:
1535 i2c_r1(gspca_dev, 0x01, &value);
1541 i2c_w1(gspca_dev, 0x01, value);
1547 static int set_exposure(struct gspca_dev *gspca_dev)
1549 struct sd *sd = (struct sd *) gspca_dev;
1550 u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1551 switch (sd->sensor) {
1558 exp[3] = sd->exposure & 0xff;
1559 exp[4] = sd->exposure >> 8;
1561 case SENSOR_MT9M001:
1562 case SENSOR_MT9V112:
1563 case SENSOR_MT9V111:
1564 case SENSOR_MT9V011:
1567 exp[3] = sd->exposure >> 8;
1568 exp[4] = sd->exposure & 0xff;
1570 case SENSOR_HV7131R:
1573 exp[3] = (sd->exposure >> 5) & 0xff;
1574 exp[4] = (sd->exposure << 3) & 0xff;
1580 i2c_w(gspca_dev, exp);
1584 static int set_gain(struct gspca_dev *gspca_dev)
1586 struct sd *sd = (struct sd *) gspca_dev;
1587 u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1588 switch (sd->sensor) {
1594 gain[0] |= (2 << 4);
1595 gain[3] = ov_gain[sd->gain];
1597 case SENSOR_MT9V011:
1598 case SENSOR_MT9V111:
1599 gain[0] |= (3 << 4);
1601 gain[3] = micron1_gain[sd->gain] >> 8;
1602 gain[4] = micron1_gain[sd->gain] & 0xff;
1604 case SENSOR_MT9V112:
1605 gain[0] |= (3 << 4);
1607 gain[3] = micron1_gain[sd->gain] >> 8;
1608 gain[4] = micron1_gain[sd->gain] & 0xff;
1610 case SENSOR_MT9M001:
1611 gain[0] |= (3 << 4);
1613 gain[3] = micron2_gain[sd->gain] >> 8;
1614 gain[4] = micron2_gain[sd->gain] & 0xff;
1616 case SENSOR_HV7131R:
1617 gain[0] |= (2 << 4);
1619 gain[3] = hv7131r_gain[sd->gain];
1624 i2c_w(gspca_dev, gain);
1628 static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val)
1630 struct sd *sd = (struct sd *) gspca_dev;
1632 sd->brightness = val;
1633 if (gspca_dev->streaming)
1634 return set_cmatrix(gspca_dev);
1638 static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val)
1640 struct sd *sd = (struct sd *) gspca_dev;
1641 *val = sd->brightness;
1646 static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val)
1648 struct sd *sd = (struct sd *) gspca_dev;
1651 if (gspca_dev->streaming)
1652 return set_cmatrix(gspca_dev);
1656 static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val)
1658 struct sd *sd = (struct sd *) gspca_dev;
1659 *val = sd->contrast;
1663 static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val)
1665 struct sd *sd = (struct sd *) gspca_dev;
1667 sd->saturation = val;
1668 if (gspca_dev->streaming)
1669 return set_cmatrix(gspca_dev);
1673 static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val)
1675 struct sd *sd = (struct sd *) gspca_dev;
1676 *val = sd->saturation;
1680 static int sd_sethue(struct gspca_dev *gspca_dev, s32 val)
1682 struct sd *sd = (struct sd *) gspca_dev;
1685 if (gspca_dev->streaming)
1686 return set_cmatrix(gspca_dev);
1690 static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val)
1692 struct sd *sd = (struct sd *) gspca_dev;
1697 static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val)
1699 struct sd *sd = (struct sd *) gspca_dev;
1702 if (gspca_dev->streaming)
1703 return set_gamma(gspca_dev);
1707 static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val)
1709 struct sd *sd = (struct sd *) gspca_dev;
1714 static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val)
1716 struct sd *sd = (struct sd *) gspca_dev;
1719 if (gspca_dev->streaming)
1720 return set_redblue(gspca_dev);
1724 static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val)
1726 struct sd *sd = (struct sd *) gspca_dev;
1731 static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val)
1733 struct sd *sd = (struct sd *) gspca_dev;
1736 if (gspca_dev->streaming)
1737 return set_redblue(gspca_dev);
1741 static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val)
1743 struct sd *sd = (struct sd *) gspca_dev;
1748 static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val)
1750 struct sd *sd = (struct sd *) gspca_dev;
1753 if (gspca_dev->streaming)
1754 return set_hvflip(gspca_dev);
1758 static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val)
1760 struct sd *sd = (struct sd *) gspca_dev;
1765 static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val)
1767 struct sd *sd = (struct sd *) gspca_dev;
1770 if (gspca_dev->streaming)
1771 return set_hvflip(gspca_dev);
1775 static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val)
1777 struct sd *sd = (struct sd *) gspca_dev;
1782 static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val)
1784 struct sd *sd = (struct sd *) gspca_dev;
1787 if (gspca_dev->streaming)
1788 return set_exposure(gspca_dev);
1792 static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val)
1794 struct sd *sd = (struct sd *) gspca_dev;
1795 *val = sd->exposure;
1799 static int sd_setgain(struct gspca_dev *gspca_dev, s32 val)
1801 struct sd *sd = (struct sd *) gspca_dev;
1804 if (gspca_dev->streaming)
1805 return set_gain(gspca_dev);
1809 static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val)
1811 struct sd *sd = (struct sd *) gspca_dev;
1816 static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val)
1818 struct sd *sd = (struct sd *) gspca_dev;
1819 sd->auto_exposure = val;
1823 static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val)
1825 struct sd *sd = (struct sd *) gspca_dev;
1826 *val = sd->auto_exposure;
1830 #ifdef CONFIG_VIDEO_ADV_DEBUG
1831 static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1832 struct v4l2_dbg_register *reg)
1834 struct sd *sd = (struct sd *) gspca_dev;
1835 switch (reg->match.type) {
1836 case V4L2_CHIP_MATCH_HOST:
1837 if (reg->match.addr != 0)
1839 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1841 if (reg_r(gspca_dev, reg->reg, 1) < 0)
1843 reg->val = gspca_dev->usb_buf[0];
1845 case V4L2_CHIP_MATCH_I2C_ADDR:
1846 if (reg->match.addr != sd->i2c_addr)
1848 if (sd->sensor >= SENSOR_MT9V011 &&
1849 sd->sensor <= SENSOR_MT9M111) {
1850 if (i2c_r2(gspca_dev, reg->reg, (u16 *)®->val) < 0)
1853 if (i2c_r1(gspca_dev, reg->reg, (u8 *)®->val) < 0)
1861 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1862 struct v4l2_dbg_register *reg)
1864 struct sd *sd = (struct sd *) gspca_dev;
1865 switch (reg->match.type) {
1866 case V4L2_CHIP_MATCH_HOST:
1867 if (reg->match.addr != 0)
1869 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1871 if (reg_w1(gspca_dev, reg->reg, reg->val) < 0)
1874 case V4L2_CHIP_MATCH_I2C_ADDR:
1875 if (reg->match.addr != sd->i2c_addr)
1877 if (sd->sensor >= SENSOR_MT9V011 &&
1878 sd->sensor <= SENSOR_MT9M111) {
1879 if (i2c_w2(gspca_dev, reg->reg, reg->val) < 0)
1882 if (i2c_w1(gspca_dev, reg->reg, reg->val) < 0)
1891 static int sd_chip_ident(struct gspca_dev *gspca_dev,
1892 struct v4l2_dbg_chip_ident *chip)
1894 struct sd *sd = (struct sd *) gspca_dev;
1896 switch (chip->match.type) {
1897 case V4L2_CHIP_MATCH_HOST:
1898 if (chip->match.addr != 0)
1901 chip->ident = V4L2_IDENT_SN9C20X;
1903 case V4L2_CHIP_MATCH_I2C_ADDR:
1904 if (chip->match.addr != sd->i2c_addr)
1907 chip->ident = i2c_ident[sd->sensor];
1913 static int sd_config(struct gspca_dev *gspca_dev,
1914 const struct usb_device_id *id)
1916 struct sd *sd = (struct sd *) gspca_dev;
1919 cam = &gspca_dev->cam;
1921 sd->sensor = (id->driver_info >> 8) & 0xff;
1922 sd->i2c_addr = id->driver_info & 0xff;
1923 sd->flags = (id->driver_info >> 16) & 0xff;
1925 switch (sd->sensor) {
1926 case SENSOR_MT9M111:
1929 cam->cam_mode = sxga_mode;
1930 cam->nmodes = ARRAY_SIZE(sxga_mode);
1933 cam->cam_mode = vga_mode;
1934 cam->nmodes = ARRAY_SIZE(vga_mode);
1940 sd->exposure_step = 16;
1942 sd->brightness = BRIGHTNESS_DEFAULT;
1943 sd->contrast = CONTRAST_DEFAULT;
1944 sd->saturation = SATURATION_DEFAULT;
1945 sd->hue = HUE_DEFAULT;
1946 sd->gamma = GAMMA_DEFAULT;
1947 sd->red = RED_DEFAULT;
1948 sd->blue = BLUE_DEFAULT;
1950 sd->hflip = HFLIP_DEFAULT;
1951 sd->vflip = VFLIP_DEFAULT;
1952 sd->exposure = EXPOSURE_DEFAULT;
1953 sd->gain = GAIN_DEFAULT;
1954 sd->auto_exposure = AUTO_EXPOSURE_DEFAULT;
1961 static int sd_init(struct gspca_dev *gspca_dev)
1963 struct sd *sd = (struct sd *) gspca_dev;
1967 {0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
1969 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
1970 value = bridge_init[i][1];
1971 if (reg_w(gspca_dev, bridge_init[i][0], &value, 1) < 0) {
1972 err("Device initialization failed");
1977 if (reg_w(gspca_dev, 0x10c0, i2c_init, 9) < 0) {
1978 err("Device initialization failed");
1982 switch (sd->sensor) {
1984 if (ov9650_init_sensor(gspca_dev) < 0)
1986 info("OV9650 sensor detected");
1989 if (ov9655_init_sensor(gspca_dev) < 0)
1991 info("OV9655 sensor detected");
1994 if (soi968_init_sensor(gspca_dev) < 0)
1996 info("SOI968 sensor detected");
1999 if (ov7660_init_sensor(gspca_dev) < 0)
2001 info("OV7660 sensor detected");
2004 if (ov7670_init_sensor(gspca_dev) < 0)
2006 info("OV7670 sensor detected");
2008 case SENSOR_MT9VPRB:
2009 if (mt9v_init_sensor(gspca_dev) < 0)
2012 case SENSOR_MT9M111:
2013 if (mt9m111_init_sensor(gspca_dev) < 0)
2015 info("MT9M111 sensor detected");
2017 case SENSOR_MT9M001:
2018 if (mt9m001_init_sensor(gspca_dev) < 0)
2020 info("MT9M001 sensor detected");
2022 case SENSOR_HV7131R:
2023 if (hv7131r_init_sensor(gspca_dev) < 0)
2025 info("HV7131R sensor detected");
2028 info("Unsupported Sensor");
2035 static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
2037 struct sd *sd = (struct sd *) gspca_dev;
2039 switch (sd->sensor) {
2041 if (mode & MODE_SXGA) {
2042 i2c_w1(gspca_dev, 0x17, 0x1d);
2043 i2c_w1(gspca_dev, 0x18, 0xbd);
2044 i2c_w1(gspca_dev, 0x19, 0x01);
2045 i2c_w1(gspca_dev, 0x1a, 0x81);
2046 i2c_w1(gspca_dev, 0x12, 0x00);
2050 i2c_w1(gspca_dev, 0x17, 0x13);
2051 i2c_w1(gspca_dev, 0x18, 0x63);
2052 i2c_w1(gspca_dev, 0x19, 0x01);
2053 i2c_w1(gspca_dev, 0x1a, 0x79);
2054 i2c_w1(gspca_dev, 0x12, 0x40);
2060 if (mode & MODE_SXGA) {
2061 i2c_w1(gspca_dev, 0x17, 0x1b);
2062 i2c_w1(gspca_dev, 0x18, 0xbc);
2063 i2c_w1(gspca_dev, 0x19, 0x01);
2064 i2c_w1(gspca_dev, 0x1a, 0x82);
2065 i2c_r1(gspca_dev, 0x12, &value);
2066 i2c_w1(gspca_dev, 0x12, value & 0x07);
2068 i2c_w1(gspca_dev, 0x17, 0x24);
2069 i2c_w1(gspca_dev, 0x18, 0xc5);
2070 i2c_w1(gspca_dev, 0x19, 0x00);
2071 i2c_w1(gspca_dev, 0x1a, 0x3c);
2072 i2c_r1(gspca_dev, 0x12, &value);
2073 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
2076 case SENSOR_MT9M111:
2077 if (mode & MODE_SXGA) {
2078 i2c_w2(gspca_dev, 0xf0, 0x0002);
2079 i2c_w2(gspca_dev, 0xc8, 0x970b);
2080 i2c_w2(gspca_dev, 0xf0, 0x0000);
2082 i2c_w2(gspca_dev, 0xf0, 0x0002);
2083 i2c_w2(gspca_dev, 0xc8, 0x8000);
2084 i2c_w2(gspca_dev, 0xf0, 0x0000);
2090 #define HW_WIN(mode, hstart, vstart) \
2091 ((const u8 []){hstart, 0, vstart, 0, \
2092 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
2093 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
2095 #define CLR_WIN(width, height) \
2097 {0, width >> 2, 0, height >> 1,\
2098 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
2100 static int sd_start(struct gspca_dev *gspca_dev)
2102 struct sd *sd = (struct sd *) gspca_dev;
2103 int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
2104 int width = gspca_dev->width;
2105 int height = gspca_dev->height;
2108 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
2109 if (sd->jpeg_hdr == NULL)
2112 jpeg_define(sd->jpeg_hdr, height, width,
2114 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2116 if (mode & MODE_RAW)
2118 else if (mode & MODE_JPEG)
2123 switch (mode & 0x0f) {
2126 info("Set 1280x1024");
2130 info("Set 640x480");
2134 info("Set 320x240");
2138 info("Set 160x120");
2142 configure_sensor_output(gspca_dev, mode);
2143 reg_w(gspca_dev, 0x1100, sd->jpeg_hdr + JPEG_QT0_OFFSET, 64);
2144 reg_w(gspca_dev, 0x1140, sd->jpeg_hdr + JPEG_QT1_OFFSET, 64);
2145 reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2146 reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2147 reg_w1(gspca_dev, 0x1189, scale);
2148 reg_w1(gspca_dev, 0x10e0, fmt);
2150 set_cmatrix(gspca_dev);
2151 set_gamma(gspca_dev);
2152 set_redblue(gspca_dev);
2153 set_gain(gspca_dev);
2154 set_exposure(gspca_dev);
2155 set_hvflip(gspca_dev);
2157 reg_r(gspca_dev, 0x1061, 1);
2158 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] | 0x02);
2162 static void sd_stopN(struct gspca_dev *gspca_dev)
2164 reg_r(gspca_dev, 0x1061, 1);
2165 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] & ~0x02);
2168 static void sd_stop0(struct gspca_dev *gspca_dev)
2170 struct sd *sd = (struct sd *) gspca_dev;
2171 kfree(sd->jpeg_hdr);
2174 static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2176 struct sd *sd = (struct sd *) gspca_dev;
2180 * some hardcoded values are present
2181 * like those for maximal/minimal exposure
2182 * and exposure steps
2184 if (avg_lum < MIN_AVG_LUM) {
2185 if (sd->exposure > 0x1770)
2188 new_exp = sd->exposure + sd->exposure_step;
2189 if (new_exp > 0x1770)
2193 sd->exposure = new_exp;
2194 set_exposure(gspca_dev);
2196 sd->older_step = sd->old_step;
2199 if (sd->old_step ^ sd->older_step)
2200 sd->exposure_step /= 2;
2202 sd->exposure_step += 2;
2204 if (avg_lum > MAX_AVG_LUM) {
2205 if (sd->exposure < 0x10)
2207 new_exp = sd->exposure - sd->exposure_step;
2208 if (new_exp > 0x1700)
2212 sd->exposure = new_exp;
2213 set_exposure(gspca_dev);
2214 sd->older_step = sd->old_step;
2217 if (sd->old_step ^ sd->older_step)
2218 sd->exposure_step /= 2;
2220 sd->exposure_step += 2;
2224 static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2226 struct sd *sd = (struct sd *) gspca_dev;
2228 if (avg_lum < MIN_AVG_LUM) {
2229 if (sd->gain + 1 <= 28) {
2231 set_gain(gspca_dev);
2234 if (avg_lum > MAX_AVG_LUM) {
2237 set_gain(gspca_dev);
2242 static void sd_dqcallback(struct gspca_dev *gspca_dev)
2244 struct sd *sd = (struct sd *) gspca_dev;
2247 if (!sd->auto_exposure)
2250 avg_lum = atomic_read(&sd->avg_lum);
2251 if (sd->sensor == SENSOR_SOI968)
2252 do_autogain(gspca_dev, avg_lum);
2254 do_autoexposure(gspca_dev, avg_lum);
2258 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2259 u8 *data, /* interrupt packet */
2260 int len) /* interrupt packet length */
2262 struct sd *sd = (struct sd *) gspca_dev;
2264 if (sd->flags & HAS_BUTTON && len == 1) {
2265 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2266 input_sync(gspca_dev->input_dev);
2267 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2268 input_sync(gspca_dev->input_dev);
2275 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2276 u8 *data, /* isoc packet */
2277 int len) /* iso packet length */
2279 struct sd *sd = (struct sd *) gspca_dev;
2281 static u8 frame_header[] =
2282 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2283 if (len == 64 && memcmp(data, frame_header, 6) == 0) {
2284 avg_lum = ((data[35] >> 2) & 3) |
2287 avg_lum += ((data[35] >> 4) & 3) |
2290 avg_lum += ((data[35] >> 6) & 3) |
2293 avg_lum += (data[36] & 3) |
2296 avg_lum += ((data[36] >> 2) & 3) |
2299 avg_lum += ((data[36] >> 4) & 3) |
2302 avg_lum += ((data[36] >> 6) & 3) |
2305 avg_lum += ((data[44] >> 4) & 3) |
2309 atomic_set(&sd->avg_lum, avg_lum);
2310 gspca_frame_add(gspca_dev, LAST_PACKET,
2314 if (gspca_dev->last_packet_type == LAST_PACKET) {
2315 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv
2317 gspca_frame_add(gspca_dev, FIRST_PACKET,
2318 sd->jpeg_hdr, JPEG_HDR_SZ);
2319 gspca_frame_add(gspca_dev, INTER_PACKET,
2322 gspca_frame_add(gspca_dev, FIRST_PACKET,
2326 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2330 /* sub-driver description */
2331 static const struct sd_desc sd_desc = {
2332 .name = MODULE_NAME,
2334 .nctrls = ARRAY_SIZE(sd_ctrls),
2335 .config = sd_config,
2340 .pkt_scan = sd_pkt_scan,
2342 .int_pkt_scan = sd_int_pkt_scan,
2344 .dq_callback = sd_dqcallback,
2345 #ifdef CONFIG_VIDEO_ADV_DEBUG
2346 .set_register = sd_dbg_s_register,
2347 .get_register = sd_dbg_g_register,
2349 .get_chip_ident = sd_chip_ident,
2352 #define SN9C20X(sensor, i2c_addr, flags) \
2353 .driver_info = (flags << 16) \
2354 | (SENSOR_ ## sensor << 8) \
2357 static const __devinitdata struct usb_device_id device_table[] = {
2358 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2359 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
2360 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2361 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, HAS_BUTTON)},
2362 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30, 0)},
2363 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2364 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2365 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2366 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2367 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, 0)},
2368 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2369 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2370 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2371 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2372 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, HAS_BUTTON)},
2373 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2374 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2375 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2376 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2377 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, 0)},
2378 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, HAS_BUTTON)},
2379 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2380 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2381 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2382 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2383 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2384 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2385 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2386 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2387 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, HAS_BUTTON)},
2388 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2389 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2392 MODULE_DEVICE_TABLE(usb, device_table);
2394 /* -- device connect -- */
2395 static int sd_probe(struct usb_interface *intf,
2396 const struct usb_device_id *id)
2398 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2402 static struct usb_driver sd_driver = {
2403 .name = MODULE_NAME,
2404 .id_table = device_table,
2406 .disconnect = gspca_disconnect,
2408 .suspend = gspca_suspend,
2409 .resume = gspca_resume,
2410 .reset_resume = gspca_resume,
2414 /* -- module insert / remove -- */
2415 static int __init sd_mod_init(void)
2418 ret = usb_register(&sd_driver);
2424 static void __exit sd_mod_exit(void)
2426 usb_deregister(&sd_driver);
2427 info("deregistered");
2430 module_init(sd_mod_init);
2431 module_exit(sd_mod_exit);