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