V4L/DVB (12283): gspca - sn9c20x: New subdriver for sn9c201 and sn9c202 bridges.
[linux-2.6/mini2440.git] / drivers / media / video / gspca / sn9c20x.c
blob78ab26ceb90eb5453d66aa0b165d8193bf2d57cc
1 /*
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
9 * any later version.
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 #include "gspca.h"
22 #include "jpeg.h"
24 #include <media/v4l2-chip-ident.h>
25 #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
26 #include <linux/kthread.h>
27 #include <linux/freezer.h>
28 #include <linux/usb/input.h>
29 #include <linux/input.h>
30 #endif
32 MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, "
33 "microdia project <microdia@googlegroups.com>");
34 MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
35 MODULE_LICENSE("GPL");
37 #define MODULE_NAME "sn9c20x"
39 #define MODE_RAW 0x10
40 #define MODE_JPEG 0x20
41 #define MODE_SXGA 0x80
43 #define SENSOR_OV9650 0
44 #define SENSOR_OV9655 1
45 #define SENSOR_SOI968 2
46 #define SENSOR_OV7660 3
47 #define SENSOR_OV7670 4
48 #define SENSOR_MT9V011 5
49 #define SENSOR_MT9V111 6
50 #define SENSOR_MT9V112 7
51 #define SENSOR_MT9M001 8
52 #define SENSOR_MT9M111 9
53 #define SENSOR_HV7131R 10
54 #define SENSOR_MT9VPRB 20
56 /* specific webcam descriptor */
57 struct sd {
58 struct gspca_dev gspca_dev;
60 #define MIN_AVG_LUM 80
61 #define MAX_AVG_LUM 130
62 atomic_t avg_lum;
63 u8 old_step;
64 u8 older_step;
65 u8 exposure_step;
67 u8 brightness;
68 u8 contrast;
69 u8 saturation;
70 s16 hue;
71 u8 gamma;
72 u8 red;
73 u8 blue;
75 u8 hflip;
76 u8 vflip;
77 u8 gain;
78 u16 exposure;
79 u8 auto_exposure;
81 u8 i2c_addr;
82 u8 sensor;
83 u8 hstart;
84 u8 vstart;
86 u8 *jpeg_hdr;
87 u8 quality;
89 #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
90 struct input_dev *input_dev;
91 u8 input_gpio;
92 struct task_struct *input_task;
93 #endif
96 static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val);
97 static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val);
98 static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val);
99 static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val);
100 static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val);
101 static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val);
102 static int sd_sethue(struct gspca_dev *gspca_dev, s32 val);
103 static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val);
104 static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val);
105 static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val);
106 static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val);
107 static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val);
108 static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val);
109 static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val);
110 static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val);
111 static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val);
112 static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val);
113 static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val);
114 static int sd_setgain(struct gspca_dev *gspca_dev, s32 val);
115 static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val);
116 static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val);
117 static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val);
118 static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val);
119 static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val);
121 static struct ctrl sd_ctrls[] = {
123 #define BRIGHTNESS_IDX 0
125 .id = V4L2_CID_BRIGHTNESS,
126 .type = V4L2_CTRL_TYPE_INTEGER,
127 .name = "Brightness",
128 .minimum = 0,
129 .maximum = 0xff,
130 .step = 1,
131 #define BRIGHTNESS_DEFAULT 0x7f
132 .default_value = BRIGHTNESS_DEFAULT,
134 .set = sd_setbrightness,
135 .get = sd_getbrightness,
138 #define CONTRAST_IDX 1
140 .id = V4L2_CID_CONTRAST,
141 .type = V4L2_CTRL_TYPE_INTEGER,
142 .name = "Contrast",
143 .minimum = 0,
144 .maximum = 0xff,
145 .step = 1,
146 #define CONTRAST_DEFAULT 0x7f
147 .default_value = CONTRAST_DEFAULT,
149 .set = sd_setcontrast,
150 .get = sd_getcontrast,
153 #define SATURATION_IDX 2
155 .id = V4L2_CID_SATURATION,
156 .type = V4L2_CTRL_TYPE_INTEGER,
157 .name = "Saturation",
158 .minimum = 0,
159 .maximum = 0xff,
160 .step = 1,
161 #define SATURATION_DEFAULT 0x7f
162 .default_value = SATURATION_DEFAULT,
164 .set = sd_setsaturation,
165 .get = sd_getsaturation,
168 #define HUE_IDX 3
170 .id = V4L2_CID_HUE,
171 .type = V4L2_CTRL_TYPE_INTEGER,
172 .name = "Hue",
173 .minimum = -180,
174 .maximum = 180,
175 .step = 1,
176 #define HUE_DEFAULT 0
177 .default_value = HUE_DEFAULT,
179 .set = sd_sethue,
180 .get = sd_gethue,
183 #define GAMMA_IDX 4
185 .id = V4L2_CID_GAMMA,
186 .type = V4L2_CTRL_TYPE_INTEGER,
187 .name = "Gamma",
188 .minimum = 0,
189 .maximum = 0xff,
190 .step = 1,
191 #define GAMMA_DEFAULT 0x10
192 .default_value = GAMMA_DEFAULT,
194 .set = sd_setgamma,
195 .get = sd_getgamma,
198 #define BLUE_IDX 5
200 .id = V4L2_CID_BLUE_BALANCE,
201 .type = V4L2_CTRL_TYPE_INTEGER,
202 .name = "Blue Balance",
203 .minimum = 0,
204 .maximum = 0x7f,
205 .step = 1,
206 #define BLUE_DEFAULT 0x28
207 .default_value = BLUE_DEFAULT,
209 .set = sd_setbluebalance,
210 .get = sd_getbluebalance,
213 #define RED_IDX 6
215 .id = V4L2_CID_RED_BALANCE,
216 .type = V4L2_CTRL_TYPE_INTEGER,
217 .name = "Red Balance",
218 .minimum = 0,
219 .maximum = 0x7f,
220 .step = 1,
221 #define RED_DEFAULT 0x28
222 .default_value = RED_DEFAULT,
224 .set = sd_setredbalance,
225 .get = sd_getredbalance,
228 #define HFLIP_IDX 7
230 .id = V4L2_CID_HFLIP,
231 .type = V4L2_CTRL_TYPE_BOOLEAN,
232 .name = "Horizontal Flip",
233 .minimum = 0,
234 .maximum = 1,
235 .step = 1,
236 #define HFLIP_DEFAULT 0
237 .default_value = HFLIP_DEFAULT,
239 .set = sd_sethflip,
240 .get = sd_gethflip,
243 #define VFLIP_IDX 8
245 .id = V4L2_CID_VFLIP,
246 .type = V4L2_CTRL_TYPE_BOOLEAN,
247 .name = "Vertical Flip",
248 .minimum = 0,
249 .maximum = 1,
250 .step = 1,
251 #define VFLIP_DEFAULT 0
252 .default_value = VFLIP_DEFAULT,
254 .set = sd_setvflip,
255 .get = sd_getvflip,
258 #define EXPOSURE_IDX 9
260 .id = V4L2_CID_EXPOSURE,
261 .type = V4L2_CTRL_TYPE_INTEGER,
262 .name = "Exposure",
263 .minimum = 0,
264 .maximum = 0x1780,
265 .step = 1,
266 #define EXPOSURE_DEFAULT 0x33
267 .default_value = EXPOSURE_DEFAULT,
269 .set = sd_setexposure,
270 .get = sd_getexposure,
273 #define GAIN_IDX 10
275 .id = V4L2_CID_GAIN,
276 .type = V4L2_CTRL_TYPE_INTEGER,
277 .name = "Gain",
278 .minimum = 0,
279 .maximum = 28,
280 .step = 1,
281 #define GAIN_DEFAULT 0x00
282 .default_value = GAIN_DEFAULT,
284 .set = sd_setgain,
285 .get = sd_getgain,
288 #define AUTOGAIN_IDX 11
290 .id = V4L2_CID_AUTOGAIN,
291 .type = V4L2_CTRL_TYPE_BOOLEAN,
292 .name = "Auto Exposure",
293 .minimum = 0,
294 .maximum = 1,
295 .step = 1,
296 #define AUTO_EXPOSURE_DEFAULT 1
297 .default_value = AUTO_EXPOSURE_DEFAULT,
299 .set = sd_setautoexposure,
300 .get = sd_getautoexposure,
304 static const struct v4l2_pix_format vga_mode[] = {
305 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
306 .bytesperline = 240,
307 .sizeimage = 240 * 120,
308 .colorspace = V4L2_COLORSPACE_JPEG,
309 .priv = 0 | MODE_JPEG},
310 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
311 .bytesperline = 160,
312 .sizeimage = 160 * 120,
313 .colorspace = V4L2_COLORSPACE_SRGB,
314 .priv = 0 | MODE_RAW},
315 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
316 .bytesperline = 240,
317 .sizeimage = 240 * 120,
318 .colorspace = V4L2_COLORSPACE_SRGB,
319 .priv = 0},
320 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
321 .bytesperline = 480,
322 .sizeimage = 480 * 240 ,
323 .colorspace = V4L2_COLORSPACE_JPEG,
324 .priv = 1 | MODE_JPEG},
325 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
326 .bytesperline = 320,
327 .sizeimage = 320 * 240 ,
328 .colorspace = V4L2_COLORSPACE_SRGB,
329 .priv = 1 | MODE_RAW},
330 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
331 .bytesperline = 480,
332 .sizeimage = 480 * 240 ,
333 .colorspace = V4L2_COLORSPACE_SRGB,
334 .priv = 1},
335 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
336 .bytesperline = 960,
337 .sizeimage = 960 * 480,
338 .colorspace = V4L2_COLORSPACE_JPEG,
339 .priv = 2 | MODE_JPEG},
340 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
341 .bytesperline = 640,
342 .sizeimage = 640 * 480,
343 .colorspace = V4L2_COLORSPACE_SRGB,
344 .priv = 2 | MODE_RAW},
345 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
346 .bytesperline = 960,
347 .sizeimage = 960 * 480,
348 .colorspace = V4L2_COLORSPACE_SRGB,
349 .priv = 2},
352 static const struct v4l2_pix_format sxga_mode[] = {
353 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
354 .bytesperline = 240,
355 .sizeimage = 240 * 120,
356 .colorspace = V4L2_COLORSPACE_JPEG,
357 .priv = 0 | MODE_JPEG},
358 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
359 .bytesperline = 160,
360 .sizeimage = 160 * 120,
361 .colorspace = V4L2_COLORSPACE_SRGB,
362 .priv = 0 | MODE_RAW},
363 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
364 .bytesperline = 240,
365 .sizeimage = 240 * 120,
366 .colorspace = V4L2_COLORSPACE_SRGB,
367 .priv = 0},
368 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
369 .bytesperline = 480,
370 .sizeimage = 480 * 240 ,
371 .colorspace = V4L2_COLORSPACE_JPEG,
372 .priv = 1 | MODE_JPEG},
373 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
374 .bytesperline = 320,
375 .sizeimage = 320 * 240 ,
376 .colorspace = V4L2_COLORSPACE_SRGB,
377 .priv = 1 | MODE_RAW},
378 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
379 .bytesperline = 480,
380 .sizeimage = 480 * 240 ,
381 .colorspace = V4L2_COLORSPACE_SRGB,
382 .priv = 1},
383 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
384 .bytesperline = 960,
385 .sizeimage = 960 * 480,
386 .colorspace = V4L2_COLORSPACE_JPEG,
387 .priv = 2 | MODE_JPEG},
388 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
389 .bytesperline = 640,
390 .sizeimage = 640 * 480,
391 .colorspace = V4L2_COLORSPACE_SRGB,
392 .priv = 2 | MODE_RAW},
393 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
394 .bytesperline = 960,
395 .sizeimage = 960 * 480,
396 .colorspace = V4L2_COLORSPACE_SRGB,
397 .priv = 2},
398 {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
399 .bytesperline = 1280,
400 .sizeimage = (1280 * 1024) + 64,
401 .colorspace = V4L2_COLORSPACE_SRGB,
402 .priv = 3 | MODE_RAW | MODE_SXGA},
405 static const int hsv_red_x[] = {
406 41, 44, 46, 48, 50, 52, 54, 56,
407 58, 60, 62, 64, 66, 68, 70, 72,
408 74, 76, 78, 80, 81, 83, 85, 87,
409 88, 90, 92, 93, 95, 97, 98, 100,
410 101, 102, 104, 105, 107, 108, 109, 110,
411 112, 113, 114, 115, 116, 117, 118, 119,
412 120, 121, 122, 123, 123, 124, 125, 125,
413 126, 127, 127, 128, 128, 129, 129, 129,
414 130, 130, 130, 130, 131, 131, 131, 131,
415 131, 131, 131, 131, 130, 130, 130, 130,
416 129, 129, 129, 128, 128, 127, 127, 126,
417 125, 125, 124, 123, 122, 122, 121, 120,
418 119, 118, 117, 116, 115, 114, 112, 111,
419 110, 109, 107, 106, 105, 103, 102, 101,
420 99, 98, 96, 94, 93, 91, 90, 88,
421 86, 84, 83, 81, 79, 77, 75, 74,
422 72, 70, 68, 66, 64, 62, 60, 58,
423 56, 54, 52, 49, 47, 45, 43, 41,
424 39, 36, 34, 32, 30, 28, 25, 23,
425 21, 19, 16, 14, 12, 9, 7, 5,
426 3, 0, -1, -3, -6, -8, -10, -12,
427 -15, -17, -19, -22, -24, -26, -28, -30,
428 -33, -35, -37, -39, -41, -44, -46, -48,
429 -50, -52, -54, -56, -58, -60, -62, -64,
430 -66, -68, -70, -72, -74, -76, -78, -80,
431 -81, -83, -85, -87, -88, -90, -92, -93,
432 -95, -97, -98, -100, -101, -102, -104, -105,
433 -107, -108, -109, -110, -112, -113, -114, -115,
434 -116, -117, -118, -119, -120, -121, -122, -123,
435 -123, -124, -125, -125, -126, -127, -127, -128,
436 -128, -128, -128, -128, -128, -128, -128, -128,
437 -128, -128, -128, -128, -128, -128, -128, -128,
438 -128, -128, -128, -128, -128, -128, -128, -128,
439 -128, -127, -127, -126, -125, -125, -124, -123,
440 -122, -122, -121, -120, -119, -118, -117, -116,
441 -115, -114, -112, -111, -110, -109, -107, -106,
442 -105, -103, -102, -101, -99, -98, -96, -94,
443 -93, -91, -90, -88, -86, -84, -83, -81,
444 -79, -77, -75, -74, -72, -70, -68, -66,
445 -64, -62, -60, -58, -56, -54, -52, -49,
446 -47, -45, -43, -41, -39, -36, -34, -32,
447 -30, -28, -25, -23, -21, -19, -16, -14,
448 -12, -9, -7, -5, -3, 0, 1, 3,
449 6, 8, 10, 12, 15, 17, 19, 22,
450 24, 26, 28, 30, 33, 35, 37, 39, 41
453 static const int hsv_red_y[] = {
454 82, 80, 78, 76, 74, 73, 71, 69,
455 67, 65, 63, 61, 58, 56, 54, 52,
456 50, 48, 46, 44, 41, 39, 37, 35,
457 32, 30, 28, 26, 23, 21, 19, 16,
458 14, 12, 10, 7, 5, 3, 0, -1,
459 -3, -6, -8, -10, -13, -15, -17, -19,
460 -22, -24, -26, -29, -31, -33, -35, -38,
461 -40, -42, -44, -46, -48, -51, -53, -55,
462 -57, -59, -61, -63, -65, -67, -69, -71,
463 -73, -75, -77, -79, -81, -82, -84, -86,
464 -88, -89, -91, -93, -94, -96, -98, -99,
465 -101, -102, -104, -105, -106, -108, -109, -110,
466 -112, -113, -114, -115, -116, -117, -119, -120,
467 -120, -121, -122, -123, -124, -125, -126, -126,
468 -127, -128, -128, -128, -128, -128, -128, -128,
469 -128, -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 -127, -127, -126, -125, -125, -124, -123, -122,
473 -121, -120, -119, -118, -117, -116, -115, -114,
474 -113, -111, -110, -109, -107, -106, -105, -103,
475 -102, -100, -99, -97, -96, -94, -92, -91,
476 -89, -87, -85, -84, -82, -80, -78, -76,
477 -74, -73, -71, -69, -67, -65, -63, -61,
478 -58, -56, -54, -52, -50, -48, -46, -44,
479 -41, -39, -37, -35, -32, -30, -28, -26,
480 -23, -21, -19, -16, -14, -12, -10, -7,
481 -5, -3, 0, 1, 3, 6, 8, 10,
482 13, 15, 17, 19, 22, 24, 26, 29,
483 31, 33, 35, 38, 40, 42, 44, 46,
484 48, 51, 53, 55, 57, 59, 61, 63,
485 65, 67, 69, 71, 73, 75, 77, 79,
486 81, 82, 84, 86, 88, 89, 91, 93,
487 94, 96, 98, 99, 101, 102, 104, 105,
488 106, 108, 109, 110, 112, 113, 114, 115,
489 116, 117, 119, 120, 120, 121, 122, 123,
490 124, 125, 126, 126, 127, 128, 128, 129,
491 129, 130, 130, 131, 131, 131, 131, 132,
492 132, 132, 132, 132, 132, 132, 132, 132,
493 132, 132, 132, 131, 131, 131, 130, 130,
494 130, 129, 129, 128, 127, 127, 126, 125,
495 125, 124, 123, 122, 121, 120, 119, 118,
496 117, 116, 115, 114, 113, 111, 110, 109,
497 107, 106, 105, 103, 102, 100, 99, 97,
498 96, 94, 92, 91, 89, 87, 85, 84, 82
501 static const int hsv_green_x[] = {
502 -124, -124, -125, -125, -125, -125, -125, -125,
503 -125, -126, -126, -125, -125, -125, -125, -125,
504 -125, -124, -124, -124, -123, -123, -122, -122,
505 -121, -121, -120, -120, -119, -118, -117, -117,
506 -116, -115, -114, -113, -112, -111, -110, -109,
507 -108, -107, -105, -104, -103, -102, -100, -99,
508 -98, -96, -95, -93, -92, -91, -89, -87,
509 -86, -84, -83, -81, -79, -77, -76, -74,
510 -72, -70, -69, -67, -65, -63, -61, -59,
511 -57, -55, -53, -51, -49, -47, -45, -43,
512 -41, -39, -37, -35, -33, -30, -28, -26,
513 -24, -22, -20, -18, -15, -13, -11, -9,
514 -7, -4, -2, 0, 1, 3, 6, 8,
515 10, 12, 14, 17, 19, 21, 23, 25,
516 27, 29, 32, 34, 36, 38, 40, 42,
517 44, 46, 48, 50, 52, 54, 56, 58,
518 60, 62, 64, 66, 68, 70, 71, 73,
519 75, 77, 78, 80, 82, 83, 85, 87,
520 88, 90, 91, 93, 94, 96, 97, 98,
521 100, 101, 102, 104, 105, 106, 107, 108,
522 109, 111, 112, 113, 113, 114, 115, 116,
523 117, 118, 118, 119, 120, 120, 121, 122,
524 122, 123, 123, 124, 124, 124, 125, 125,
525 125, 125, 125, 125, 125, 126, 126, 125,
526 125, 125, 125, 125, 125, 124, 124, 124,
527 123, 123, 122, 122, 121, 121, 120, 120,
528 119, 118, 117, 117, 116, 115, 114, 113,
529 112, 111, 110, 109, 108, 107, 105, 104,
530 103, 102, 100, 99, 98, 96, 95, 93,
531 92, 91, 89, 87, 86, 84, 83, 81,
532 79, 77, 76, 74, 72, 70, 69, 67,
533 65, 63, 61, 59, 57, 55, 53, 51,
534 49, 47, 45, 43, 41, 39, 37, 35,
535 33, 30, 28, 26, 24, 22, 20, 18,
536 15, 13, 11, 9, 7, 4, 2, 0,
537 -1, -3, -6, -8, -10, -12, -14, -17,
538 -19, -21, -23, -25, -27, -29, -32, -34,
539 -36, -38, -40, -42, -44, -46, -48, -50,
540 -52, -54, -56, -58, -60, -62, -64, -66,
541 -68, -70, -71, -73, -75, -77, -78, -80,
542 -82, -83, -85, -87, -88, -90, -91, -93,
543 -94, -96, -97, -98, -100, -101, -102, -104,
544 -105, -106, -107, -108, -109, -111, -112, -113,
545 -113, -114, -115, -116, -117, -118, -118, -119,
546 -120, -120, -121, -122, -122, -123, -123, -124, -124
549 static const int hsv_green_y[] = {
550 -100, -99, -98, -97, -95, -94, -93, -91,
551 -90, -89, -87, -86, -84, -83, -81, -80,
552 -78, -76, -75, -73, -71, -70, -68, -66,
553 -64, -63, -61, -59, -57, -55, -53, -51,
554 -49, -48, -46, -44, -42, -40, -38, -36,
555 -34, -32, -30, -27, -25, -23, -21, -19,
556 -17, -15, -13, -11, -9, -7, -4, -2,
557 0, 1, 3, 5, 7, 9, 11, 14,
558 16, 18, 20, 22, 24, 26, 28, 30,
559 32, 34, 36, 38, 40, 42, 44, 46,
560 48, 50, 52, 54, 56, 58, 59, 61,
561 63, 65, 67, 68, 70, 72, 74, 75,
562 77, 78, 80, 82, 83, 85, 86, 88,
563 89, 90, 92, 93, 95, 96, 97, 98,
564 100, 101, 102, 103, 104, 105, 106, 107,
565 108, 109, 110, 111, 112, 112, 113, 114,
566 115, 115, 116, 116, 117, 117, 118, 118,
567 119, 119, 119, 120, 120, 120, 120, 120,
568 121, 121, 121, 121, 121, 121, 120, 120,
569 120, 120, 120, 119, 119, 119, 118, 118,
570 117, 117, 116, 116, 115, 114, 114, 113,
571 112, 111, 111, 110, 109, 108, 107, 106,
572 105, 104, 103, 102, 100, 99, 98, 97,
573 95, 94, 93, 91, 90, 89, 87, 86,
574 84, 83, 81, 80, 78, 76, 75, 73,
575 71, 70, 68, 66, 64, 63, 61, 59,
576 57, 55, 53, 51, 49, 48, 46, 44,
577 42, 40, 38, 36, 34, 32, 30, 27,
578 25, 23, 21, 19, 17, 15, 13, 11,
579 9, 7, 4, 2, 0, -1, -3, -5,
580 -7, -9, -11, -14, -16, -18, -20, -22,
581 -24, -26, -28, -30, -32, -34, -36, -38,
582 -40, -42, -44, -46, -48, -50, -52, -54,
583 -56, -58, -59, -61, -63, -65, -67, -68,
584 -70, -72, -74, -75, -77, -78, -80, -82,
585 -83, -85, -86, -88, -89, -90, -92, -93,
586 -95, -96, -97, -98, -100, -101, -102, -103,
587 -104, -105, -106, -107, -108, -109, -110, -111,
588 -112, -112, -113, -114, -115, -115, -116, -116,
589 -117, -117, -118, -118, -119, -119, -119, -120,
590 -120, -120, -120, -120, -121, -121, -121, -121,
591 -121, -121, -120, -120, -120, -120, -120, -119,
592 -119, -119, -118, -118, -117, -117, -116, -116,
593 -115, -114, -114, -113, -112, -111, -111, -110,
594 -109, -108, -107, -106, -105, -104, -103, -102, -100
597 static const int hsv_blue_x[] = {
598 112, 113, 114, 114, 115, 116, 117, 117,
599 118, 118, 119, 119, 120, 120, 120, 121,
600 121, 121, 122, 122, 122, 122, 122, 122,
601 122, 122, 122, 122, 122, 122, 121, 121,
602 121, 120, 120, 120, 119, 119, 118, 118,
603 117, 116, 116, 115, 114, 113, 113, 112,
604 111, 110, 109, 108, 107, 106, 105, 104,
605 103, 102, 100, 99, 98, 97, 95, 94,
606 93, 91, 90, 88, 87, 85, 84, 82,
607 80, 79, 77, 76, 74, 72, 70, 69,
608 67, 65, 63, 61, 60, 58, 56, 54,
609 52, 50, 48, 46, 44, 42, 40, 38,
610 36, 34, 32, 30, 28, 26, 24, 22,
611 19, 17, 15, 13, 11, 9, 7, 5,
612 2, 0, -1, -3, -5, -7, -9, -12,
613 -14, -16, -18, -20, -22, -24, -26, -28,
614 -31, -33, -35, -37, -39, -41, -43, -45,
615 -47, -49, -51, -53, -54, -56, -58, -60,
616 -62, -64, -66, -67, -69, -71, -73, -74,
617 -76, -78, -79, -81, -83, -84, -86, -87,
618 -89, -90, -92, -93, -94, -96, -97, -98,
619 -99, -101, -102, -103, -104, -105, -106, -107,
620 -108, -109, -110, -111, -112, -113, -114, -114,
621 -115, -116, -117, -117, -118, -118, -119, -119,
622 -120, -120, -120, -121, -121, -121, -122, -122,
623 -122, -122, -122, -122, -122, -122, -122, -122,
624 -122, -122, -121, -121, -121, -120, -120, -120,
625 -119, -119, -118, -118, -117, -116, -116, -115,
626 -114, -113, -113, -112, -111, -110, -109, -108,
627 -107, -106, -105, -104, -103, -102, -100, -99,
628 -98, -97, -95, -94, -93, -91, -90, -88,
629 -87, -85, -84, -82, -80, -79, -77, -76,
630 -74, -72, -70, -69, -67, -65, -63, -61,
631 -60, -58, -56, -54, -52, -50, -48, -46,
632 -44, -42, -40, -38, -36, -34, -32, -30,
633 -28, -26, -24, -22, -19, -17, -15, -13,
634 -11, -9, -7, -5, -2, 0, 1, 3,
635 5, 7, 9, 12, 14, 16, 18, 20,
636 22, 24, 26, 28, 31, 33, 35, 37,
637 39, 41, 43, 45, 47, 49, 51, 53,
638 54, 56, 58, 60, 62, 64, 66, 67,
639 69, 71, 73, 74, 76, 78, 79, 81,
640 83, 84, 86, 87, 89, 90, 92, 93,
641 94, 96, 97, 98, 99, 101, 102, 103,
642 104, 105, 106, 107, 108, 109, 110, 111, 112
645 static const int hsv_blue_y[] = {
646 -11, -13, -15, -17, -19, -21, -23, -25,
647 -27, -29, -31, -33, -35, -37, -39, -41,
648 -43, -45, -46, -48, -50, -52, -54, -55,
649 -57, -59, -61, -62, -64, -66, -67, -69,
650 -71, -72, -74, -75, -77, -78, -80, -81,
651 -83, -84, -86, -87, -88, -90, -91, -92,
652 -93, -95, -96, -97, -98, -99, -100, -101,
653 -102, -103, -104, -105, -106, -106, -107, -108,
654 -109, -109, -110, -111, -111, -112, -112, -113,
655 -113, -114, -114, -114, -115, -115, -115, -115,
656 -116, -116, -116, -116, -116, -116, -116, -116,
657 -116, -115, -115, -115, -115, -114, -114, -114,
658 -113, -113, -112, -112, -111, -111, -110, -110,
659 -109, -108, -108, -107, -106, -105, -104, -103,
660 -102, -101, -100, -99, -98, -97, -96, -95,
661 -94, -93, -91, -90, -89, -88, -86, -85,
662 -84, -82, -81, -79, -78, -76, -75, -73,
663 -71, -70, -68, -67, -65, -63, -62, -60,
664 -58, -56, -55, -53, -51, -49, -47, -45,
665 -44, -42, -40, -38, -36, -34, -32, -30,
666 -28, -26, -24, -22, -20, -18, -16, -14,
667 -12, -10, -8, -6, -4, -2, 0, 1,
668 3, 5, 7, 9, 11, 13, 15, 17,
669 19, 21, 23, 25, 27, 29, 31, 33,
670 35, 37, 39, 41, 43, 45, 46, 48,
671 50, 52, 54, 55, 57, 59, 61, 62,
672 64, 66, 67, 69, 71, 72, 74, 75,
673 77, 78, 80, 81, 83, 84, 86, 87,
674 88, 90, 91, 92, 93, 95, 96, 97,
675 98, 99, 100, 101, 102, 103, 104, 105,
676 106, 106, 107, 108, 109, 109, 110, 111,
677 111, 112, 112, 113, 113, 114, 114, 114,
678 115, 115, 115, 115, 116, 116, 116, 116,
679 116, 116, 116, 116, 116, 115, 115, 115,
680 115, 114, 114, 114, 113, 113, 112, 112,
681 111, 111, 110, 110, 109, 108, 108, 107,
682 106, 105, 104, 103, 102, 101, 100, 99,
683 98, 97, 96, 95, 94, 93, 91, 90,
684 89, 88, 86, 85, 84, 82, 81, 79,
685 78, 76, 75, 73, 71, 70, 68, 67,
686 65, 63, 62, 60, 58, 56, 55, 53,
687 51, 49, 47, 45, 44, 42, 40, 38,
688 36, 34, 32, 30, 28, 26, 24, 22,
689 20, 18, 16, 14, 12, 10, 8, 6,
690 4, 2, 0, -1, -3, -5, -7, -9, -11
693 static u16 i2c_ident[] = {
694 V4L2_IDENT_OV9650,
695 V4L2_IDENT_OV9655,
696 V4L2_IDENT_SOI968,
697 V4L2_IDENT_OV7660,
698 V4L2_IDENT_OV7670,
699 V4L2_IDENT_MT9V011,
700 V4L2_IDENT_MT9V111,
701 V4L2_IDENT_MT9V112,
702 V4L2_IDENT_MT9M001C12ST,
703 V4L2_IDENT_MT9M111,
704 V4L2_IDENT_HV7131R,
707 static u16 bridge_init[][2] = {
708 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
709 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
710 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
711 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
712 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
713 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
714 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
715 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
716 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
717 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
718 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
719 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
720 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
721 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
722 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
723 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
724 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
725 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
726 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80}
729 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
730 static u8 ov_gain[] = {
731 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
732 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
733 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
734 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
735 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
736 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
737 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
738 0x70 /* 8x */
741 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
742 static u16 micron1_gain[] = {
743 /* 1x 1.25x 1.5x 1.75x */
744 0x0020, 0x0028, 0x0030, 0x0038,
745 /* 2x 2.25x 2.5x 2.75x */
746 0x00a0, 0x00a4, 0x00a8, 0x00ac,
747 /* 3x 3.25x 3.5x 3.75x */
748 0x00b0, 0x00b4, 0x00b8, 0x00bc,
749 /* 4x 4.25x 4.5x 4.75x */
750 0x00c0, 0x00c4, 0x00c8, 0x00cc,
751 /* 5x 5.25x 5.5x 5.75x */
752 0x00d0, 0x00d4, 0x00d8, 0x00dc,
753 /* 6x 6.25x 6.5x 6.75x */
754 0x00e0, 0x00e4, 0x00e8, 0x00ec,
755 /* 7x 7.25x 7.5x 7.75x */
756 0x00f0, 0x00f4, 0x00f8, 0x00fc,
757 /* 8x */
758 0x01c0
761 /* mt9m001 sensor uses a different gain formula then other micron sensors */
762 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
763 static u16 micron2_gain[] = {
764 /* 1x 1.25x 1.5x 1.75x */
765 0x0008, 0x000a, 0x000c, 0x000e,
766 /* 2x 2.25x 2.5x 2.75x */
767 0x0010, 0x0012, 0x0014, 0x0016,
768 /* 3x 3.25x 3.5x 3.75x */
769 0x0018, 0x001a, 0x001c, 0x001e,
770 /* 4x 4.25x 4.5x 4.75x */
771 0x0020, 0x0051, 0x0052, 0x0053,
772 /* 5x 5.25x 5.5x 5.75x */
773 0x0054, 0x0055, 0x0056, 0x0057,
774 /* 6x 6.25x 6.5x 6.75x */
775 0x0058, 0x0059, 0x005a, 0x005b,
776 /* 7x 7.25x 7.5x 7.75x */
777 0x005c, 0x005d, 0x005e, 0x005f,
778 /* 8x */
779 0x0060
782 /* Gain = .5 + bit[7:0] / 16 */
783 static u8 hv7131r_gain[] = {
784 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
785 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
786 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
787 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
788 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
789 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
790 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
791 0x78 /* 8x */
794 static u8 soi968_init[][2] = {
795 {0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f},
796 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
797 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
798 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
799 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
800 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
801 {0x13, 0x8a}, {0x12, 0x40}, {0x17, 0x13},
802 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
803 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
804 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
805 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
808 static u8 ov7660_init[][2] = {
809 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
810 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
811 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
812 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
813 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6},
814 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
817 static u8 ov7670_init[][2] = {
818 {0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
819 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
820 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
821 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
822 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
823 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
824 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
825 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
826 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
827 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
828 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
829 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
830 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
831 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
832 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
833 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
834 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
835 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
836 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
837 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
838 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
839 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
840 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
841 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
842 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
843 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
844 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
845 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
846 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
847 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
848 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
849 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
850 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
851 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
852 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
853 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
854 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
855 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
856 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
857 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
858 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
859 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
860 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
861 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
862 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
863 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
864 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
865 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
866 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
867 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
868 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
869 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
870 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
871 {0x93, 0x00},
874 static u8 ov9650_init[][2] = {
875 {0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78},
876 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
877 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
878 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
879 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
880 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
881 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
882 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
883 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
884 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
885 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
886 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
887 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
888 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
889 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
890 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
891 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
892 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
893 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
894 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
895 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
896 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
897 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
898 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
899 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
900 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
901 {0xaa, 0x92}, {0xab, 0x0a},
904 static u8 ov9655_init[][2] = {
905 {0x12, 0x80}, {0x12, 0x01}, {0x0d, 0x00}, {0x0e, 0x61},
906 {0x11, 0x80}, {0x13, 0xba}, {0x14, 0x2e}, {0x16, 0x24},
907 {0x1e, 0x04}, {0x1e, 0x04}, {0x1e, 0x04}, {0x27, 0x08},
908 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x32, 0xbf},
909 {0x34, 0x3d}, {0x35, 0x00}, {0x36, 0xf8}, {0x38, 0x12},
910 {0x39, 0x57}, {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c},
911 {0x3d, 0x19}, {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40},
912 {0x42, 0x80}, {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a},
913 {0x48, 0x3c}, {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc},
914 {0x4d, 0xdc}, {0x4e, 0xdc}, {0x69, 0x02}, {0x6c, 0x04},
915 {0x6f, 0x9e}, {0x70, 0x05}, {0x71, 0x78}, {0x77, 0x02},
916 {0x8a, 0x23}, {0x8c, 0x0d}, {0x90, 0x7e}, {0x91, 0x7c},
917 {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68}, {0xa6, 0x60},
918 {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92}, {0xab, 0x04},
919 {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80}, {0xaf, 0x80},
920 {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00}, {0xb6, 0xaf},
921 {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44}, {0xbe, 0x3b},
922 {0xbf, 0x3a}, {0xc0, 0xe2}, {0xc1, 0xc8}, {0xc2, 0x01},
923 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
924 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x12, 0x61},
925 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
926 {0x03, 0x12}, {0x17, 0x14}, {0x18, 0x00}, {0x19, 0x01},
927 {0x1a, 0x3d}, {0x32, 0xbf}, {0x11, 0x80}, {0x2a, 0x10},
928 {0x2b, 0x0a}, {0x92, 0x00}, {0x93, 0x00}, {0x1e, 0x04},
929 {0x1e, 0x04}, {0x10, 0x7c}, {0x04, 0x03}, {0xa1, 0x00},
930 {0x2d, 0x00}, {0x2e, 0x00}, {0x00, 0x00}, {0x01, 0x80},
931 {0x02, 0x80}, {0x12, 0x61}, {0x36, 0xfa}, {0x8c, 0x8d},
932 {0xc0, 0xaa}, {0x69, 0x0a}, {0x03, 0x12}, {0x17, 0x14},
933 {0x18, 0x00}, {0x19, 0x01}, {0x1a, 0x3d}, {0x32, 0xbf},
934 {0x11, 0x80}, {0x2a, 0x10}, {0x2b, 0x0a}, {0x92, 0x00},
935 {0x93, 0x00}, {0x04, 0x01}, {0x10, 0x1f}, {0xa1, 0x00},
936 {0x00, 0x0a}, {0xa1, 0x00}, {0x10, 0x5d}, {0x04, 0x03},
937 {0x00, 0x01}, {0xa1, 0x00}, {0x10, 0x7c}, {0x04, 0x03},
938 {0x00, 0x03}, {0x00, 0x0a}, {0x00, 0x10}, {0x00, 0x13},
941 static u16 mt9v112_init[][2] = {
942 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
943 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
944 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
945 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
946 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
947 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
948 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
949 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
950 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
951 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
952 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
953 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
954 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
955 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
956 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
957 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
960 static u16 mt9v111_init[][2] = {
961 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
962 {0x01, 0x0001}, {0x02, 0x0016}, {0x03, 0x01e1},
963 {0x04, 0x0281}, {0x05, 0x0004}, {0x07, 0x3002},
964 {0x21, 0x0000}, {0x25, 0x4024}, {0x26, 0xff03},
965 {0x27, 0xff10}, {0x2b, 0x7828}, {0x2c, 0xb43c},
966 {0x2d, 0xf0a0}, {0x2e, 0x0c64}, {0x2f, 0x0064},
967 {0x67, 0x4010}, {0x06, 0x301e}, {0x08, 0x0480},
968 {0x01, 0x0004}, {0x02, 0x0016}, {0x03, 0x01e6},
969 {0x04, 0x0286}, {0x05, 0x0004}, {0x06, 0x0000},
970 {0x07, 0x3002}, {0x08, 0x0008}, {0x0c, 0x0000},
971 {0x0d, 0x0000}, {0x0e, 0x0000}, {0x0f, 0x0000},
972 {0x10, 0x0000}, {0x11, 0x0000}, {0x12, 0x00b0},
973 {0x13, 0x007c}, {0x14, 0x0000}, {0x15, 0x0000},
974 {0x16, 0x0000}, {0x17, 0x0000}, {0x18, 0x0000},
975 {0x19, 0x0000}, {0x1a, 0x0000}, {0x1b, 0x0000},
976 {0x1c, 0x0000}, {0x1d, 0x0000}, {0x30, 0x0000},
977 {0x30, 0x0005}, {0x31, 0x0000}, {0x02, 0x0016},
978 {0x03, 0x01e1}, {0x04, 0x0281}, {0x05, 0x0004},
979 {0x06, 0x0000}, {0x07, 0x3002}, {0x06, 0x002d},
980 {0x05, 0x0004}, {0x09, 0x0064}, {0x2b, 0x00a0},
981 {0x2c, 0x00a0}, {0x2d, 0x00a0}, {0x2e, 0x00a0},
982 {0x02, 0x0016}, {0x03, 0x01e1}, {0x04, 0x0281},
983 {0x05, 0x0004}, {0x06, 0x002d}, {0x07, 0x3002},
984 {0x0e, 0x0008}, {0x06, 0x002d}, {0x05, 0x0004},
987 static u16 mt9v011_init[][2] = {
988 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
989 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
990 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
991 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
992 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
993 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
994 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
995 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
996 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
997 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
998 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
999 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
1000 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
1001 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
1002 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
1003 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
1004 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
1005 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
1006 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
1007 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
1008 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
1009 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
1010 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
1011 {0x06, 0x0029}, {0x05, 0x0009},
1014 static u16 mt9m001_init[][2] = {
1015 {0x0d, 0x0001}, {0x0d, 0x0000}, {0x01, 0x000e},
1016 {0x02, 0x0014}, {0x03, 0x03c1}, {0x04, 0x0501},
1017 {0x05, 0x0083}, {0x06, 0x0006}, {0x0d, 0x0002},
1018 {0x0a, 0x0000}, {0x0c, 0x0000}, {0x11, 0x0000},
1019 {0x1e, 0x8000}, {0x5f, 0x8904}, {0x60, 0x0000},
1020 {0x61, 0x0000}, {0x62, 0x0498}, {0x63, 0x0000},
1021 {0x64, 0x0000}, {0x20, 0x111d}, {0x06, 0x00f2},
1022 {0x05, 0x0013}, {0x09, 0x10f2}, {0x07, 0x0003},
1023 {0x2b, 0x002a}, {0x2d, 0x002a}, {0x2c, 0x002a},
1024 {0x2e, 0x0029}, {0x07, 0x0002},
1027 static u16 mt9m111_init[][2] = {
1028 {0xf0, 0x0000}, {0x0d, 0x0008}, {0x0d, 0x0009},
1029 {0x0d, 0x0008}, {0xf0, 0x0001}, {0x3a, 0x4300},
1030 {0x9b, 0x4300}, {0xa1, 0x0280}, {0xa4, 0x0200},
1031 {0x06, 0x308e}, {0xf0, 0x0000},
1034 static u8 hv7131r_init[][2] = {
1035 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
1036 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
1037 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
1038 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
1039 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
1040 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
1041 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
1042 {0x23, 0x09}, {0x01, 0x08},
1045 int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
1047 struct usb_device *dev = gspca_dev->dev;
1048 int result;
1049 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
1050 0x00,
1051 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1052 reg,
1053 0x00,
1054 gspca_dev->usb_buf,
1055 length,
1056 500);
1057 if (unlikely(result < 0 || result != length)) {
1058 err("Read register failed 0x%02X", reg);
1059 return -EIO;
1061 return 0;
1064 int reg_w(struct gspca_dev *gspca_dev, u16 reg, const u8 *buffer, int length)
1066 struct usb_device *dev = gspca_dev->dev;
1067 int result;
1068 memcpy(gspca_dev->usb_buf, buffer, length);
1069 result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1070 0x08,
1071 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1072 reg,
1073 0x00,
1074 gspca_dev->usb_buf,
1075 length,
1076 500);
1077 if (unlikely(result < 0 || result != length)) {
1078 err("Write register failed index 0x%02X", reg);
1079 return -EIO;
1081 return 0;
1084 int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
1086 u8 data[1] = {value};
1087 return reg_w(gspca_dev, reg, data, 1);
1090 int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
1092 int i;
1093 reg_w(gspca_dev, 0x10c0, buffer, 8);
1094 for (i = 0; i < 5; i++) {
1095 reg_r(gspca_dev, 0x10c0, 1);
1096 if (gspca_dev->usb_buf[0] & 0x04) {
1097 if (gspca_dev->usb_buf[0] & 0x08)
1098 return -1;
1099 return 0;
1101 msleep(1);
1103 return -1;
1106 int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1108 struct sd *sd = (struct sd *) gspca_dev;
1110 u8 row[8];
1113 * from the point of view of the bridge, the length
1114 * includes the address
1116 row[0] = 0x81 | (2 << 4);
1117 row[1] = sd->i2c_addr;
1118 row[2] = reg;
1119 row[3] = val;
1120 row[4] = 0x00;
1121 row[5] = 0x00;
1122 row[6] = 0x00;
1123 row[7] = 0x10;
1125 return i2c_w(gspca_dev, row);
1128 int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1130 struct sd *sd = (struct sd *) gspca_dev;
1131 u8 row[8];
1134 * from the point of view of the bridge, the length
1135 * includes the address
1137 row[0] = 0x81 | (3 << 4);
1138 row[1] = sd->i2c_addr;
1139 row[2] = reg;
1140 row[3] = (val >> 8) & 0xff;
1141 row[4] = val & 0xff;
1142 row[5] = 0x00;
1143 row[6] = 0x00;
1144 row[7] = 0x10;
1146 return i2c_w(gspca_dev, row);
1149 int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1151 struct sd *sd = (struct sd *) gspca_dev;
1152 u8 row[8];
1154 row[0] = 0x81 | 0x10;
1155 row[1] = sd->i2c_addr;
1156 row[2] = reg;
1157 row[3] = 0;
1158 row[4] = 0;
1159 row[5] = 0;
1160 row[6] = 0;
1161 row[7] = 0x10;
1162 reg_w(gspca_dev, 0x10c0, row, 8);
1163 msleep(1);
1164 row[0] = 0x81 | (2 << 4) | 0x02;
1165 row[2] = 0;
1166 reg_w(gspca_dev, 0x10c0, row, 8);
1167 msleep(1);
1168 reg_r(gspca_dev, 0x10c2, 5);
1169 *val = gspca_dev->usb_buf[3];
1170 return 0;
1173 int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1175 struct sd *sd = (struct sd *) gspca_dev;
1176 u8 row[8];
1178 row[0] = 0x81 | 0x10;
1179 row[1] = sd->i2c_addr;
1180 row[2] = reg;
1181 row[3] = 0;
1182 row[4] = 0;
1183 row[5] = 0;
1184 row[6] = 0;
1185 row[7] = 0x10;
1186 reg_w(gspca_dev, 0x10c0, row, 8);
1187 msleep(1);
1188 row[0] = 0x81 | (3 << 4) | 0x02;
1189 row[2] = 0;
1190 reg_w(gspca_dev, 0x10c0, row, 8);
1191 msleep(1);
1192 reg_r(gspca_dev, 0x10c2, 5);
1193 *val = (gspca_dev->usb_buf[2] << 8) | gspca_dev->usb_buf[3];
1194 return 0;
1197 static int ov9650_init_sensor(struct gspca_dev *gspca_dev)
1199 int i;
1200 struct sd *sd = (struct sd *) gspca_dev;
1202 for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) {
1203 if (i2c_w1(gspca_dev, ov9650_init[i][0],
1204 ov9650_init[i][1]) < 0) {
1205 err("OV9650 sensor initialization failed");
1206 return -ENODEV;
1209 sd->hstart = 1;
1210 sd->vstart = 7;
1211 return 0;
1214 static int ov9655_init_sensor(struct gspca_dev *gspca_dev)
1216 int i;
1217 struct sd *sd = (struct sd *) gspca_dev;
1219 for (i = 0; i < ARRAY_SIZE(ov9655_init); i++) {
1220 if (i2c_w1(gspca_dev, ov9655_init[i][0],
1221 ov9655_init[i][1]) < 0) {
1222 err("OV9655 sensor initialization failed");
1223 return -ENODEV;
1226 /* disable hflip and vflip */
1227 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1228 sd->hstart = 0;
1229 sd->vstart = 7;
1230 return 0;
1233 static int soi968_init_sensor(struct gspca_dev *gspca_dev)
1235 int i;
1236 struct sd *sd = (struct sd *) gspca_dev;
1238 for (i = 0; i < ARRAY_SIZE(soi968_init); i++) {
1239 if (i2c_w1(gspca_dev, soi968_init[i][0],
1240 soi968_init[i][1]) < 0) {
1241 err("SOI968 sensor initialization failed");
1242 return -ENODEV;
1245 /* disable hflip and vflip */
1246 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1247 sd->hstart = 60;
1248 sd->vstart = 11;
1249 return 0;
1252 static int ov7660_init_sensor(struct gspca_dev *gspca_dev)
1254 int i;
1255 struct sd *sd = (struct sd *) gspca_dev;
1257 for (i = 0; i < ARRAY_SIZE(ov7660_init); i++) {
1258 if (i2c_w1(gspca_dev, ov7660_init[i][0],
1259 ov7660_init[i][1]) < 0) {
1260 err("OV7660 sensor initialization failed");
1261 return -ENODEV;
1264 /* disable hflip and vflip */
1265 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1266 sd->hstart = 1;
1267 sd->vstart = 1;
1268 return 0;
1271 static int ov7670_init_sensor(struct gspca_dev *gspca_dev)
1273 int i;
1274 struct sd *sd = (struct sd *) gspca_dev;
1276 for (i = 0; i < ARRAY_SIZE(ov7670_init); i++) {
1277 if (i2c_w1(gspca_dev, ov7670_init[i][0],
1278 ov7670_init[i][1]) < 0) {
1279 err("OV7670 sensor initialization failed");
1280 return -ENODEV;
1283 /* disable hflip and vflip */
1284 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1285 sd->hstart = 0;
1286 sd->vstart = 1;
1287 return 0;
1290 static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
1292 struct sd *sd = (struct sd *) gspca_dev;
1293 int i;
1294 u16 value;
1295 int ret;
1297 sd->i2c_addr = 0x5d;
1298 ret = i2c_r2(gspca_dev, 0xff, &value);
1299 if ((ret == 0) && (value == 0x8243)) {
1300 for (i = 0; i < ARRAY_SIZE(mt9v011_init); i++) {
1301 if (i2c_w2(gspca_dev, mt9v011_init[i][0],
1302 mt9v011_init[i][1]) < 0) {
1303 err("MT9V011 sensor initialization failed");
1304 return -ENODEV;
1307 sd->hstart = 2;
1308 sd->vstart = 2;
1309 sd->sensor = SENSOR_MT9V011;
1310 info("MT9V011 sensor detected");
1311 return 0;
1314 sd->i2c_addr = 0x5c;
1315 i2c_w2(gspca_dev, 0x01, 0x0004);
1316 ret = i2c_r2(gspca_dev, 0xff, &value);
1317 if ((ret == 0) && (value == 0x823a)) {
1318 for (i = 0; i < ARRAY_SIZE(mt9v111_init); i++) {
1319 if (i2c_w2(gspca_dev, mt9v111_init[i][0],
1320 mt9v111_init[i][1]) < 0) {
1321 err("MT9V111 sensor initialization failed");
1322 return -ENODEV;
1325 sd->hstart = 2;
1326 sd->vstart = 2;
1327 sd->sensor = SENSOR_MT9V111;
1328 info("MT9V111 sensor detected");
1329 return 0;
1332 sd->i2c_addr = 0x5d;
1333 ret = i2c_w2(gspca_dev, 0xf0, 0x0000);
1334 if (ret < 0) {
1335 sd->i2c_addr = 0x48;
1336 i2c_w2(gspca_dev, 0xf0, 0x0000);
1338 ret = i2c_r2(gspca_dev, 0x00, &value);
1339 if ((ret == 0) && (value == 0x1229)) {
1340 for (i = 0; i < ARRAY_SIZE(mt9v112_init); i++) {
1341 if (i2c_w2(gspca_dev, mt9v112_init[i][0],
1342 mt9v112_init[i][1]) < 0) {
1343 err("MT9V112 sensor initialization failed");
1344 return -ENODEV;
1347 sd->hstart = 6;
1348 sd->vstart = 2;
1349 sd->sensor = SENSOR_MT9V112;
1350 info("MT9V112 sensor detected");
1351 return 0;
1354 return -ENODEV;
1357 static int mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1359 struct sd *sd = (struct sd *) gspca_dev;
1360 int i;
1361 for (i = 0; i < ARRAY_SIZE(mt9m111_init); i++) {
1362 if (i2c_w2(gspca_dev, mt9m111_init[i][0],
1363 mt9m111_init[i][1]) < 0) {
1364 err("MT9M111 sensor initialization failed");
1365 return -ENODEV;
1368 sd->hstart = 0;
1369 sd->vstart = 2;
1370 return 0;
1373 static int mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1375 struct sd *sd = (struct sd *) gspca_dev;
1376 int i;
1377 for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) {
1378 if (i2c_w2(gspca_dev, mt9m001_init[i][0],
1379 mt9m001_init[i][1]) < 0) {
1380 err("MT9M001 sensor initialization failed");
1381 return -ENODEV;
1384 /* disable hflip and vflip */
1385 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
1386 sd->hstart = 2;
1387 sd->vstart = 2;
1388 return 0;
1391 static int hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1393 int i;
1394 struct sd *sd = (struct sd *) gspca_dev;
1396 for (i = 0; i < ARRAY_SIZE(hv7131r_init); i++) {
1397 if (i2c_w1(gspca_dev, hv7131r_init[i][0],
1398 hv7131r_init[i][1]) < 0) {
1399 err("HV7131R Sensor initialization failed");
1400 return -ENODEV;
1403 sd->hstart = 0;
1404 sd->vstart = 1;
1405 return 0;
1408 #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
1409 static int input_kthread(void *data)
1411 struct gspca_dev *gspca_dev = (struct gspca_dev *)data;
1412 struct sd *sd = (struct sd *) gspca_dev;
1414 DECLARE_WAIT_QUEUE_HEAD(wait);
1415 set_freezable();
1416 for (;;) {
1417 if (kthread_should_stop())
1418 break;
1420 if (reg_r(gspca_dev, 0x1005, 1) < 0)
1421 continue;
1423 input_report_key(sd->input_dev,
1424 KEY_CAMERA,
1425 gspca_dev->usb_buf[0] & sd->input_gpio);
1426 input_sync(sd->input_dev);
1428 wait_event_freezable_timeout(wait,
1429 kthread_should_stop(),
1430 msecs_to_jiffies(100));
1432 return 0;
1436 static int sn9c20x_input_init(struct gspca_dev *gspca_dev)
1438 struct sd *sd = (struct sd *) gspca_dev;
1439 if (sd->input_gpio == 0)
1440 return 0;
1442 sd->input_dev = input_allocate_device();
1443 if (!sd->input_dev)
1444 return -ENOMEM;
1446 sd->input_dev->name = "SN9C20X Webcam";
1448 sd->input_dev->phys = kasprintf(GFP_KERNEL, "usb-%s-%s",
1449 gspca_dev->dev->bus->bus_name,
1450 gspca_dev->dev->devpath);
1452 if (!sd->input_dev->phys)
1453 return -ENOMEM;
1455 usb_to_input_id(gspca_dev->dev, &sd->input_dev->id);
1456 sd->input_dev->dev.parent = &gspca_dev->dev->dev;
1458 set_bit(EV_KEY, sd->input_dev->evbit);
1459 set_bit(KEY_CAMERA, sd->input_dev->keybit);
1461 if (input_register_device(sd->input_dev))
1462 return -EINVAL;
1464 sd->input_task = kthread_run(input_kthread, gspca_dev, "sn9c20x/%d",
1465 gspca_dev->vdev.minor);
1467 if (IS_ERR(sd->input_task))
1468 return -EINVAL;
1470 return 0;
1473 static void sn9c20x_input_cleanup(struct gspca_dev *gspca_dev)
1475 struct sd *sd = (struct sd *) gspca_dev;
1476 if (sd->input_task != NULL && !IS_ERR(sd->input_task))
1477 kthread_stop(sd->input_task);
1479 if (sd->input_dev != NULL) {
1480 input_unregister_device(sd->input_dev);
1481 kfree(sd->input_dev->phys);
1482 input_free_device(sd->input_dev);
1483 sd->input_dev = NULL;
1486 #endif
1488 static int set_cmatrix(struct gspca_dev *gspca_dev)
1490 struct sd *sd = (struct sd *) gspca_dev;
1491 s32 hue_coord, hue_index = 180 + sd->hue;
1492 u8 cmatrix[21];
1493 memset(cmatrix, 0, 21);
1495 cmatrix[2] = (sd->contrast * 0x25 / 0x100) + 0x26;
1496 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1497 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1498 cmatrix[18] = sd->brightness - 0x80;
1500 hue_coord = (hsv_red_x[hue_index] * sd->saturation) >> 8;
1501 cmatrix[6] = (unsigned char)(hue_coord & 0xff);
1502 cmatrix[7] = (unsigned char)((hue_coord >> 8) & 0x0f);
1504 hue_coord = (hsv_red_y[hue_index] * sd->saturation) >> 8;
1505 cmatrix[8] = (unsigned char)(hue_coord & 0xff);
1506 cmatrix[9] = (unsigned char)((hue_coord >> 8) & 0x0f);
1508 hue_coord = (hsv_green_x[hue_index] * sd->saturation) >> 8;
1509 cmatrix[10] = (unsigned char)(hue_coord & 0xff);
1510 cmatrix[11] = (unsigned char)((hue_coord >> 8) & 0x0f);
1512 hue_coord = (hsv_green_y[hue_index] * sd->saturation) >> 8;
1513 cmatrix[12] = (unsigned char)(hue_coord & 0xff);
1514 cmatrix[13] = (unsigned char)((hue_coord >> 8) & 0x0f);
1516 hue_coord = (hsv_blue_x[hue_index] * sd->saturation) >> 8;
1517 cmatrix[14] = (unsigned char)(hue_coord & 0xff);
1518 cmatrix[15] = (unsigned char)((hue_coord >> 8) & 0x0f);
1520 hue_coord = (hsv_blue_y[hue_index] * sd->saturation) >> 8;
1521 cmatrix[16] = (unsigned char)(hue_coord & 0xff);
1522 cmatrix[17] = (unsigned char)((hue_coord >> 8) & 0x0f);
1524 return reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1527 static int set_gamma(struct gspca_dev *gspca_dev)
1529 struct sd *sd = (struct sd *) gspca_dev;
1530 u8 gamma[17];
1531 u8 gval = sd->gamma * 0xb8 / 0x100;
1534 gamma[0] = 0x0a;
1535 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
1536 gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8);
1537 gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8);
1538 gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8);
1539 gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8);
1540 gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8);
1541 gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8);
1542 gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8);
1543 gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8);
1544 gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8);
1545 gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8);
1546 gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8);
1547 gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8);
1548 gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8);
1549 gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
1550 gamma[16] = 0xf5;
1552 return reg_w(gspca_dev, 0x1190, gamma, 17);
1555 static int set_redblue(struct gspca_dev *gspca_dev)
1557 struct sd *sd = (struct sd *) gspca_dev;
1558 reg_w1(gspca_dev, 0x118c, sd->red);
1559 reg_w1(gspca_dev, 0x118f, sd->blue);
1560 return 0;
1563 static int set_hvflip(struct gspca_dev *gspca_dev)
1565 u8 value, tslb;
1566 u16 value2;
1567 struct sd *sd = (struct sd *) gspca_dev;
1568 switch (sd->sensor) {
1569 case SENSOR_OV9650:
1570 i2c_r1(gspca_dev, 0x1e, &value);
1571 value &= ~0x30;
1572 tslb = 0x01;
1573 if (sd->hflip)
1574 value |= 0x20;
1575 if (sd->vflip) {
1576 value |= 0x10;
1577 tslb = 0x49;
1579 i2c_w1(gspca_dev, 0x1e, value);
1580 i2c_w1(gspca_dev, 0x3a, tslb);
1581 break;
1582 case SENSOR_MT9V111:
1583 case SENSOR_MT9V011:
1584 i2c_r2(gspca_dev, 0x20, &value2);
1585 value2 &= ~0xc0a0;
1586 if (sd->hflip)
1587 value2 |= 0x8080;
1588 if (sd->vflip)
1589 value2 |= 0x4020;
1590 i2c_w2(gspca_dev, 0x20, value2);
1591 break;
1592 case SENSOR_MT9M111:
1593 case SENSOR_MT9V112:
1594 i2c_r2(gspca_dev, 0x20, &value2);
1595 value2 &= ~0x0003;
1596 if (sd->hflip)
1597 value2 |= 0x0002;
1598 if (sd->vflip)
1599 value2 |= 0x0001;
1600 i2c_w2(gspca_dev, 0x20, value2);
1601 break;
1602 case SENSOR_HV7131R:
1603 i2c_r1(gspca_dev, 0x01, &value);
1604 value &= ~0x03;
1605 if (sd->vflip)
1606 value |= 0x01;
1607 if (sd->hflip)
1608 value |= 0x02;
1609 i2c_w1(gspca_dev, 0x01, value);
1610 break;
1612 return 0;
1615 static int set_exposure(struct gspca_dev *gspca_dev)
1617 struct sd *sd = (struct sd *) gspca_dev;
1618 u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1619 switch (sd->sensor) {
1620 case SENSOR_OV7660:
1621 case SENSOR_OV7670:
1622 case SENSOR_SOI968:
1623 case SENSOR_OV9655:
1624 case SENSOR_OV9650:
1625 exp[0] |= (3 << 4);
1626 exp[2] = 0x2d;
1627 exp[3] = sd->exposure & 0xff;
1628 exp[4] = sd->exposure >> 8;
1629 break;
1630 case SENSOR_MT9M001:
1631 case SENSOR_MT9M111:
1632 case SENSOR_MT9V112:
1633 case SENSOR_MT9V111:
1634 case SENSOR_MT9V011:
1635 exp[0] |= (3 << 4);
1636 exp[2] = 0x09;
1637 exp[3] = sd->exposure >> 8;
1638 exp[4] = sd->exposure & 0xff;
1639 break;
1640 case SENSOR_HV7131R:
1641 exp[0] |= (4 << 4);
1642 exp[2] = 0x25;
1643 exp[3] = ((sd->exposure * 0xffffff) / 0xffff) >> 16;
1644 exp[4] = ((sd->exposure * 0xffffff) / 0xffff) >> 8;
1645 exp[5] = ((sd->exposure * 0xffffff) / 0xffff) & 0xff;
1646 break;
1648 i2c_w(gspca_dev, exp);
1649 return 0;
1652 static int set_gain(struct gspca_dev *gspca_dev)
1654 struct sd *sd = (struct sd *) gspca_dev;
1655 u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1656 switch (sd->sensor) {
1657 case SENSOR_OV7660:
1658 case SENSOR_OV7670:
1659 case SENSOR_SOI968:
1660 case SENSOR_OV9655:
1661 case SENSOR_OV9650:
1662 gain[0] |= (2 << 4);
1663 gain[3] = ov_gain[sd->gain];
1664 break;
1665 case SENSOR_MT9V011:
1666 case SENSOR_MT9V111:
1667 gain[0] |= (3 << 4);
1668 gain[2] = 0x35;
1669 gain[3] = micron1_gain[sd->gain] >> 8;
1670 gain[4] = micron1_gain[sd->gain] & 0xff;
1671 break;
1672 case SENSOR_MT9V112:
1673 case SENSOR_MT9M111:
1674 gain[0] |= (3 << 4);
1675 gain[2] = 0x2f;
1676 gain[3] = micron1_gain[sd->gain] >> 8;
1677 gain[4] = micron1_gain[sd->gain] & 0xff;
1678 break;
1679 case SENSOR_MT9M001:
1680 gain[0] |= (3 << 4);
1681 gain[2] = 0x2f;
1682 gain[3] = micron2_gain[sd->gain] >> 8;
1683 gain[4] = micron2_gain[sd->gain] & 0xff;
1684 break;
1685 case SENSOR_HV7131R:
1686 gain[0] |= (2 << 4);
1687 gain[2] = 0x30;
1688 gain[3] = hv7131r_gain[sd->gain];
1689 break;
1691 i2c_w(gspca_dev, gain);
1692 return 0;
1695 static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val)
1697 struct sd *sd = (struct sd *) gspca_dev;
1699 sd->brightness = val;
1700 if (gspca_dev->streaming)
1701 return set_cmatrix(gspca_dev);
1702 return 0;
1705 static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val)
1707 struct sd *sd = (struct sd *) gspca_dev;
1708 *val = sd->brightness;
1709 return 0;
1713 static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val)
1715 struct sd *sd = (struct sd *) gspca_dev;
1717 sd->contrast = val;
1718 if (gspca_dev->streaming)
1719 return set_cmatrix(gspca_dev);
1720 return 0;
1723 static int sd_getcontrast(struct gspca_dev *gspca_dev, s32 *val)
1725 struct sd *sd = (struct sd *) gspca_dev;
1726 *val = sd->contrast;
1727 return 0;
1730 static int sd_setsaturation(struct gspca_dev *gspca_dev, s32 val)
1732 struct sd *sd = (struct sd *) gspca_dev;
1734 sd->saturation = val;
1735 if (gspca_dev->streaming)
1736 return set_cmatrix(gspca_dev);
1737 return 0;
1740 static int sd_getsaturation(struct gspca_dev *gspca_dev, s32 *val)
1742 struct sd *sd = (struct sd *) gspca_dev;
1743 *val = sd->saturation;
1744 return 0;
1747 static int sd_sethue(struct gspca_dev *gspca_dev, s32 val)
1749 struct sd *sd = (struct sd *) gspca_dev;
1751 sd->hue = val;
1752 if (gspca_dev->streaming)
1753 return set_cmatrix(gspca_dev);
1754 return 0;
1757 static int sd_gethue(struct gspca_dev *gspca_dev, s32 *val)
1759 struct sd *sd = (struct sd *) gspca_dev;
1760 *val = sd->hue;
1761 return 0;
1764 static int sd_setgamma(struct gspca_dev *gspca_dev, s32 val)
1766 struct sd *sd = (struct sd *) gspca_dev;
1768 sd->gamma = val;
1769 if (gspca_dev->streaming)
1770 return set_gamma(gspca_dev);
1771 return 0;
1774 static int sd_getgamma(struct gspca_dev *gspca_dev, s32 *val)
1776 struct sd *sd = (struct sd *) gspca_dev;
1777 *val = sd->gamma;
1778 return 0;
1781 static int sd_setredbalance(struct gspca_dev *gspca_dev, s32 val)
1783 struct sd *sd = (struct sd *) gspca_dev;
1785 sd->red = val;
1786 if (gspca_dev->streaming)
1787 return set_redblue(gspca_dev);
1788 return 0;
1791 static int sd_getredbalance(struct gspca_dev *gspca_dev, s32 *val)
1793 struct sd *sd = (struct sd *) gspca_dev;
1794 *val = sd->red;
1795 return 0;
1798 static int sd_setbluebalance(struct gspca_dev *gspca_dev, s32 val)
1800 struct sd *sd = (struct sd *) gspca_dev;
1802 sd->blue = val;
1803 if (gspca_dev->streaming)
1804 return set_redblue(gspca_dev);
1805 return 0;
1808 static int sd_getbluebalance(struct gspca_dev *gspca_dev, s32 *val)
1810 struct sd *sd = (struct sd *) gspca_dev;
1811 *val = sd->blue;
1812 return 0;
1815 static int sd_sethflip(struct gspca_dev *gspca_dev, s32 val)
1817 struct sd *sd = (struct sd *) gspca_dev;
1819 sd->hflip = val;
1820 if (gspca_dev->streaming)
1821 return set_hvflip(gspca_dev);
1822 return 0;
1825 static int sd_gethflip(struct gspca_dev *gspca_dev, s32 *val)
1827 struct sd *sd = (struct sd *) gspca_dev;
1828 *val = sd->hflip;
1829 return 0;
1832 static int sd_setvflip(struct gspca_dev *gspca_dev, s32 val)
1834 struct sd *sd = (struct sd *) gspca_dev;
1836 sd->vflip = val;
1837 if (gspca_dev->streaming)
1838 return set_hvflip(gspca_dev);
1839 return 0;
1842 static int sd_getvflip(struct gspca_dev *gspca_dev, s32 *val)
1844 struct sd *sd = (struct sd *) gspca_dev;
1845 *val = sd->vflip;
1846 return 0;
1849 static int sd_setexposure(struct gspca_dev *gspca_dev, s32 val)
1851 struct sd *sd = (struct sd *) gspca_dev;
1853 sd->exposure = val;
1854 if (gspca_dev->streaming)
1855 return set_exposure(gspca_dev);
1856 return 0;
1859 static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val)
1861 struct sd *sd = (struct sd *) gspca_dev;
1862 *val = sd->exposure;
1863 return 0;
1866 static int sd_setgain(struct gspca_dev *gspca_dev, s32 val)
1868 struct sd *sd = (struct sd *) gspca_dev;
1870 sd->gain = val;
1871 if (gspca_dev->streaming)
1872 return set_gain(gspca_dev);
1873 return 0;
1876 static int sd_getgain(struct gspca_dev *gspca_dev, s32 *val)
1878 struct sd *sd = (struct sd *) gspca_dev;
1879 *val = sd->gain;
1880 return 0;
1883 static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val)
1885 struct sd *sd = (struct sd *) gspca_dev;
1886 sd->auto_exposure = val;
1887 return 0;
1890 static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val)
1892 struct sd *sd = (struct sd *) gspca_dev;
1893 *val = sd->auto_exposure;
1894 return 0;
1897 #ifdef CONFIG_VIDEO_ADV_DEBUG
1898 static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1899 struct v4l2_dbg_register *reg)
1901 struct sd *sd = (struct sd *) gspca_dev;
1902 switch (reg->match.type) {
1903 case V4L2_CHIP_MATCH_HOST:
1904 if (reg->match.addr != 0)
1905 return -EINVAL;
1906 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1907 return -EINVAL;
1908 if (reg_r(gspca_dev, reg->reg, 1) < 0)
1909 return -EINVAL;
1910 reg->val = gspca_dev->usb_buf[0];
1911 return 0;
1912 case V4L2_CHIP_MATCH_I2C_ADDR:
1913 if (reg->match.addr != sd->i2c_addr)
1914 return -EINVAL;
1915 if (sd->sensor >= SENSOR_MT9V011 &&
1916 sd->sensor <= SENSOR_MT9M111) {
1917 if (i2c_r2(gspca_dev, reg->reg, (u16 *)&reg->val) < 0)
1918 return -EINVAL;
1919 } else {
1920 if (i2c_r1(gspca_dev, reg->reg, (u8 *)&reg->val) < 0)
1921 return -EINVAL;
1923 return 0;
1925 return -EINVAL;
1928 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1929 struct v4l2_dbg_register *reg)
1931 struct sd *sd = (struct sd *) gspca_dev;
1932 switch (reg->match.type) {
1933 case V4L2_CHIP_MATCH_HOST:
1934 if (reg->match.addr != 0)
1935 return -EINVAL;
1936 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1937 return -EINVAL;
1938 if (reg_w1(gspca_dev, reg->reg, reg->val) < 0)
1939 return -EINVAL;
1940 return 0;
1941 case V4L2_CHIP_MATCH_I2C_ADDR:
1942 if (reg->match.addr != sd->i2c_addr)
1943 return -EINVAL;
1944 if (sd->sensor >= SENSOR_MT9V011 &&
1945 sd->sensor <= SENSOR_MT9M111) {
1946 if (i2c_w2(gspca_dev, reg->reg, reg->val) < 0)
1947 return -EINVAL;
1948 } else {
1949 if (i2c_w1(gspca_dev, reg->reg, reg->val) < 0)
1950 return -EINVAL;
1952 return 0;
1954 return -EINVAL;
1956 #endif
1958 static int sd_chip_ident(struct gspca_dev *gspca_dev,
1959 struct v4l2_dbg_chip_ident *chip)
1961 struct sd *sd = (struct sd *) gspca_dev;
1963 switch (chip->match.type) {
1964 case V4L2_CHIP_MATCH_HOST:
1965 if (chip->match.addr != 0)
1966 return -EINVAL;
1967 chip->revision = 0;
1968 chip->ident = V4L2_IDENT_SN9C20X;
1969 return 0;
1970 case V4L2_CHIP_MATCH_I2C_ADDR:
1971 if (chip->match.addr != sd->i2c_addr)
1972 return -EINVAL;
1973 chip->revision = 0;
1974 chip->ident = i2c_ident[sd->sensor];
1975 return 0;
1977 return -EINVAL;
1980 static int sd_config(struct gspca_dev *gspca_dev,
1981 const struct usb_device_id *id)
1983 struct sd *sd = (struct sd *) gspca_dev;
1984 struct cam *cam;
1986 cam = &gspca_dev->cam;
1988 sd->sensor = (id->driver_info >> 8) & 0xff;
1989 sd->i2c_addr = id->driver_info & 0xff;
1991 switch (sd->sensor) {
1992 case SENSOR_OV9650:
1993 cam->cam_mode = sxga_mode;
1994 cam->nmodes = ARRAY_SIZE(sxga_mode);
1995 break;
1996 default:
1997 cam->cam_mode = vga_mode;
1998 cam->nmodes = ARRAY_SIZE(vga_mode);
2001 sd->old_step = 0;
2002 sd->older_step = 0;
2003 sd->exposure_step = 16;
2005 sd->brightness = BRIGHTNESS_DEFAULT;
2006 sd->contrast = CONTRAST_DEFAULT;
2007 sd->saturation = SATURATION_DEFAULT;
2008 sd->hue = HUE_DEFAULT;
2009 sd->gamma = GAMMA_DEFAULT;
2010 sd->red = RED_DEFAULT;
2011 sd->blue = BLUE_DEFAULT;
2013 sd->hflip = HFLIP_DEFAULT;
2014 sd->vflip = VFLIP_DEFAULT;
2015 sd->exposure = EXPOSURE_DEFAULT;
2016 sd->gain = GAIN_DEFAULT;
2017 sd->auto_exposure = AUTO_EXPOSURE_DEFAULT;
2019 sd->quality = 95;
2021 #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
2022 sd->input_gpio = (id->driver_info >> 16) & 0xff;
2023 if (sn9c20x_input_init(gspca_dev) < 0)
2024 return -ENODEV;
2025 #endif
2026 return 0;
2029 static int sd_init(struct gspca_dev *gspca_dev)
2031 struct sd *sd = (struct sd *) gspca_dev;
2032 int i;
2033 u8 value;
2034 u8 i2c_init[9] =
2035 {0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
2037 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
2038 value = bridge_init[i][1];
2039 if (reg_w(gspca_dev, bridge_init[i][0], &value, 1) < 0) {
2040 err("Device initialization failed");
2041 return -ENODEV;
2045 if (reg_w(gspca_dev, 0x10c0, i2c_init, 9) < 0) {
2046 err("Device initialization failed");
2047 return -ENODEV;
2050 switch (sd->sensor) {
2051 case SENSOR_OV9650:
2052 if (ov9650_init_sensor(gspca_dev) < 0)
2053 return -ENODEV;
2054 info("OV9650 sensor detected");
2055 break;
2056 case SENSOR_OV9655:
2057 if (ov9655_init_sensor(gspca_dev) < 0)
2058 return -ENODEV;
2059 info("OV9655 sensor detected");
2060 break;
2061 case SENSOR_SOI968:
2062 if (soi968_init_sensor(gspca_dev) < 0)
2063 return -ENODEV;
2064 info("SOI968 sensor detected");
2065 break;
2066 case SENSOR_OV7660:
2067 if (ov7660_init_sensor(gspca_dev) < 0)
2068 return -ENODEV;
2069 info("OV7660 sensor detected");
2070 break;
2071 case SENSOR_OV7670:
2072 if (ov7670_init_sensor(gspca_dev) < 0)
2073 return -ENODEV;
2074 info("OV7670 sensor detected");
2075 break;
2076 case SENSOR_MT9VPRB:
2077 if (mt9v_init_sensor(gspca_dev) < 0)
2078 return -ENODEV;
2079 break;
2080 case SENSOR_MT9M111:
2081 if (mt9m111_init_sensor(gspca_dev) < 0)
2082 return -ENODEV;
2083 info("MT9M111 sensor detected");
2084 break;
2085 case SENSOR_MT9M001:
2086 if (mt9m001_init_sensor(gspca_dev) < 0)
2087 return -ENODEV;
2088 info("MT9M001 sensor detected");
2089 break;
2090 case SENSOR_HV7131R:
2091 if (hv7131r_init_sensor(gspca_dev) < 0)
2092 return -ENODEV;
2093 info("HV7131R sensor detected");
2094 break;
2095 default:
2096 info("Unsupported Sensor");
2097 return -ENODEV;
2100 return 0;
2103 static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
2105 struct sd *sd = (struct sd *) gspca_dev;
2106 u8 value;
2107 switch (sd->sensor) {
2108 case SENSOR_OV9650:
2109 if (mode & MODE_SXGA) {
2110 i2c_w1(gspca_dev, 0x17, 0x1b);
2111 i2c_w1(gspca_dev, 0x18, 0xbc);
2112 i2c_w1(gspca_dev, 0x19, 0x01);
2113 i2c_w1(gspca_dev, 0x1a, 0x82);
2114 i2c_r1(gspca_dev, 0x12, &value);
2115 i2c_w1(gspca_dev, 0x12, value & 0x07);
2116 } else {
2117 i2c_w1(gspca_dev, 0x17, 0x24);
2118 i2c_w1(gspca_dev, 0x18, 0xc5);
2119 i2c_w1(gspca_dev, 0x19, 0x00);
2120 i2c_w1(gspca_dev, 0x1a, 0x3c);
2121 i2c_r1(gspca_dev, 0x12, &value);
2122 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
2124 break;
2128 #define HW_WIN(mode, hstart, vstart) \
2129 ((const u8 []){hstart & 0xff, hstart >> 8, \
2130 vstart & 0xff, vstart >> 8, \
2131 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
2132 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
2134 #define CLR_WIN(width, height) \
2135 ((const u8 [])\
2136 {0, width >> 2, 0, height >> 1,\
2137 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
2139 static int sd_start(struct gspca_dev *gspca_dev)
2141 struct sd *sd = (struct sd *) gspca_dev;
2142 int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
2143 int width = gspca_dev->width;
2144 int height = gspca_dev->height;
2145 u8 fmt, scale = 0;
2147 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
2148 if (sd->jpeg_hdr == NULL)
2149 return -ENOMEM;
2151 jpeg_define(sd->jpeg_hdr, height, width,
2152 0x21);
2153 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2155 if (mode & MODE_RAW)
2156 fmt = 0x2d;
2157 else if (mode & MODE_JPEG)
2158 fmt = 0x2c;
2159 else
2160 fmt = 0x2f;
2162 switch (mode & 0x0f) {
2163 case 3:
2164 scale = 0xc0;
2165 info("Set 1280x1024");
2166 break;
2167 case 2:
2168 scale = 0x80;
2169 info("Set 640x480");
2170 break;
2171 case 1:
2172 scale = 0x90;
2173 info("Set 320x240");
2174 break;
2175 case 0:
2176 scale = 0xa0;
2177 info("Set 160x120");
2178 break;
2181 configure_sensor_output(gspca_dev, mode);
2182 reg_w(gspca_dev, 0x1100, sd->jpeg_hdr + JPEG_QT0_OFFSET, 64);
2183 reg_w(gspca_dev, 0x1140, sd->jpeg_hdr + JPEG_QT1_OFFSET, 64);
2184 reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2185 reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2186 reg_w1(gspca_dev, 0x1189, scale);
2187 reg_w1(gspca_dev, 0x10e0, fmt);
2189 set_cmatrix(gspca_dev);
2190 set_gamma(gspca_dev);
2191 set_redblue(gspca_dev);
2192 set_gain(gspca_dev);
2193 set_exposure(gspca_dev);
2194 set_hvflip(gspca_dev);
2196 reg_r(gspca_dev, 0x1061, 1);
2197 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] | 0x02);
2198 return 0;
2201 static void sd_stopN(struct gspca_dev *gspca_dev)
2203 reg_r(gspca_dev, 0x1061, 1);
2204 reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] & ~0x02);
2207 static void sd_stop0(struct gspca_dev *gspca_dev)
2209 struct sd *sd = (struct sd *) gspca_dev;
2210 kfree(sd->jpeg_hdr);
2213 static void do_autoexposure(struct gspca_dev *gspca_dev)
2215 struct sd *sd = (struct sd *) gspca_dev;
2216 int avg_lum, new_exp;
2218 if (!sd->auto_exposure)
2219 return;
2221 avg_lum = atomic_read(&sd->avg_lum);
2224 * some hardcoded values are present
2225 * like those for maximal/minimal exposure
2226 * and exposure steps
2228 if (avg_lum < MIN_AVG_LUM) {
2229 if (sd->exposure > 0x1770)
2230 return;
2232 new_exp = sd->exposure + sd->exposure_step;
2233 if (new_exp > 0x1770)
2234 new_exp = 0x1770;
2235 if (new_exp < 0x10)
2236 new_exp = 0x10;
2237 sd->exposure = new_exp;
2238 set_exposure(gspca_dev);
2240 sd->older_step = sd->old_step;
2241 sd->old_step = 1;
2243 if (sd->old_step ^ sd->older_step)
2244 sd->exposure_step /= 2;
2245 else
2246 sd->exposure_step += 2;
2248 if (avg_lum > MAX_AVG_LUM) {
2249 if (sd->exposure < 0x10)
2250 return;
2251 new_exp = sd->exposure - sd->exposure_step;
2252 if (new_exp > 0x1700)
2253 new_exp = 0x1770;
2254 if (new_exp < 0x10)
2255 new_exp = 0x10;
2256 sd->exposure = new_exp;
2257 set_exposure(gspca_dev);
2258 sd->older_step = sd->old_step;
2259 sd->old_step = 0;
2261 if (sd->old_step ^ sd->older_step)
2262 sd->exposure_step /= 2;
2263 else
2264 sd->exposure_step += 2;
2268 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2269 struct gspca_frame *frame, /* target */
2270 u8 *data, /* isoc packet */
2271 int len) /* iso packet length */
2273 struct sd *sd = (struct sd *) gspca_dev;
2274 int avg_lum;
2275 static unsigned char frame_header[] =
2276 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2277 if (len == 64 && memcmp(data, frame_header, 6) == 0) {
2278 avg_lum = ((data[35] >> 2) & 3) |
2279 (data[20] << 2) |
2280 (data[19] << 10);
2281 avg_lum += ((data[35] >> 4) & 3) |
2282 (data[22] << 2) |
2283 (data[21] << 10);
2284 avg_lum += ((data[35] >> 6) & 3) |
2285 (data[24] << 2) |
2286 (data[23] << 10);
2287 avg_lum += (data[36] & 3) |
2288 (data[26] << 2) |
2289 (data[25] << 10);
2290 avg_lum += ((data[36] >> 2) & 3) |
2291 (data[28] << 2) |
2292 (data[27] << 10);
2293 avg_lum += ((data[36] >> 4) & 3) |
2294 (data[30] << 2) |
2295 (data[29] << 10);
2296 avg_lum += ((data[36] >> 6) & 3) |
2297 (data[32] << 2) |
2298 (data[31] << 10);
2299 avg_lum += ((data[44] >> 4) & 3) |
2300 (data[34] << 2) |
2301 (data[33] << 10);
2302 avg_lum >>= 9;
2303 atomic_set(&sd->avg_lum, avg_lum);
2304 gspca_frame_add(gspca_dev, LAST_PACKET,
2305 frame, data, len);
2306 return;
2308 if (gspca_dev->last_packet_type == LAST_PACKET) {
2309 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv
2310 & MODE_JPEG) {
2311 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
2312 sd->jpeg_hdr, JPEG_HDR_SZ);
2313 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
2314 data, len);
2315 } else {
2316 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
2317 data, len);
2319 } else {
2320 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
2324 /* sub-driver description */
2325 static const struct sd_desc sd_desc = {
2326 .name = MODULE_NAME,
2327 .ctrls = sd_ctrls,
2328 .nctrls = ARRAY_SIZE(sd_ctrls),
2329 .config = sd_config,
2330 .init = sd_init,
2331 .start = sd_start,
2332 .stopN = sd_stopN,
2333 .stop0 = sd_stop0,
2334 .pkt_scan = sd_pkt_scan,
2335 .dq_callback = do_autoexposure,
2336 #ifdef CONFIG_VIDEO_ADV_DEBUG
2337 .set_register = sd_dbg_s_register,
2338 .get_register = sd_dbg_g_register,
2339 #endif
2340 .get_chip_ident = sd_chip_ident,
2343 #define SN9C20X(sensor, i2c_addr, button_mask) \
2344 .driver_info = (button_mask << 16) \
2345 | (SENSOR_ ## sensor << 8) \
2346 | (i2c_addr)
2348 static const __devinitdata struct usb_device_id device_table[] = {
2349 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2350 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
2351 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2352 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, 0x10)},
2353 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30, 0)},
2354 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2355 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2356 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2357 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2358 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, 0)},
2359 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2360 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2361 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2362 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2363 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
2364 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2365 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2366 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2367 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2368 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, 0)},
2369 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, 0)},
2370 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2371 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2372 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2373 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2374 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2375 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2376 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2377 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2378 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
2379 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2380 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2383 MODULE_DEVICE_TABLE(usb, device_table);
2385 /* -- device connect -- */
2386 static int sd_probe(struct usb_interface *intf,
2387 const struct usb_device_id *id)
2389 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2390 THIS_MODULE);
2393 static void sd_disconnect(struct usb_interface *intf)
2395 #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV
2396 struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
2398 sn9c20x_input_cleanup(gspca_dev);
2399 #endif
2401 gspca_disconnect(intf);
2404 static struct usb_driver sd_driver = {
2405 .name = MODULE_NAME,
2406 .id_table = device_table,
2407 .probe = sd_probe,
2408 .disconnect = sd_disconnect,
2409 #ifdef CONFIG_PM
2410 .suspend = gspca_suspend,
2411 .resume = gspca_resume,
2412 .reset_resume = gspca_resume,
2413 #endif
2416 /* -- module insert / remove -- */
2417 static int __init sd_mod_init(void)
2419 int ret;
2420 ret = usb_register(&sd_driver);
2421 if (ret < 0)
2422 return ret;
2423 info("registered");
2424 return 0;
2426 static void __exit sd_mod_exit(void)
2428 usb_deregister(&sd_driver);
2429 info("deregistered");
2432 module_init(sd_mod_init);
2433 module_exit(sd_mod_exit);