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