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