xref: /linux/drivers/media/usb/gspca/sn9c20x.c (revision 2a2dfc869d3345ccdd91322b023f4b0da84acbe7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *	Sonix sn9c201 sn9c202 library
4  *
5  * Copyright (C) 2012 Jean-Francois Moine <http://moinejf.free.fr>
6  *	Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com>
7  *	Copyright (C) 2009 Brian Johnson <brijohn@gmail.com>
8  */
9 
10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11 
12 #include <linux/input.h>
13 
14 #include "gspca.h"
15 #include "jpeg.h"
16 
17 #include <linux/dmi.h>
18 
19 MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, microdia project <microdia@googlegroups.com>");
20 MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
21 MODULE_LICENSE("GPL");
22 
23 /*
24  * Pixel format private data
25  */
26 #define SCALE_MASK	0x0f
27 #define SCALE_160x120	0
28 #define SCALE_320x240	1
29 #define SCALE_640x480	2
30 #define SCALE_1280x1024	3
31 #define MODE_RAW	0x10
32 #define MODE_JPEG	0x20
33 #define MODE_SXGA	0x80
34 
35 #define SENSOR_OV9650	0
36 #define SENSOR_OV9655	1
37 #define SENSOR_SOI968	2
38 #define SENSOR_OV7660	3
39 #define SENSOR_OV7670	4
40 #define SENSOR_MT9V011	5
41 #define SENSOR_MT9V111	6
42 #define SENSOR_MT9V112	7
43 #define SENSOR_MT9M001	8
44 #define SENSOR_MT9M111	9
45 #define SENSOR_MT9M112  10
46 #define SENSOR_HV7131R	11
47 #define SENSOR_MT9VPRB	12
48 
49 /* camera flags */
50 #define HAS_NO_BUTTON	0x1
51 #define LED_REVERSE	0x2 /* some cameras unset gpio to turn on leds */
52 #define FLIP_DETECT	0x4
53 #define HAS_LED_TORCH	0x8
54 
55 /* specific webcam descriptor */
56 struct sd {
57 	struct gspca_dev gspca_dev;
58 
59 	struct { /* color control cluster */
60 		struct v4l2_ctrl *brightness;
61 		struct v4l2_ctrl *contrast;
62 		struct v4l2_ctrl *saturation;
63 		struct v4l2_ctrl *hue;
64 	};
65 	struct { /* blue/red balance control cluster */
66 		struct v4l2_ctrl *blue;
67 		struct v4l2_ctrl *red;
68 	};
69 	struct { /* h/vflip control cluster */
70 		struct v4l2_ctrl *hflip;
71 		struct v4l2_ctrl *vflip;
72 	};
73 	struct v4l2_ctrl *gamma;
74 	struct { /* autogain and exposure or gain control cluster */
75 		struct v4l2_ctrl *autogain;
76 		struct v4l2_ctrl *exposure;
77 		struct v4l2_ctrl *gain;
78 	};
79 	struct v4l2_ctrl *jpegqual;
80 
81 	struct v4l2_ctrl *led_mode;
82 
83 	struct work_struct work;
84 
85 	u32 pktsz;			/* (used by pkt_scan) */
86 	u16 npkt;
87 	s8 nchg;
88 	u8 fmt;				/* (used for JPEG QTAB update */
89 
90 #define MIN_AVG_LUM 80
91 #define MAX_AVG_LUM 130
92 	atomic_t avg_lum;
93 	u8 old_step;
94 	u8 older_step;
95 	u8 exposure_step;
96 
97 	u8 i2c_addr;
98 	u8 i2c_intf;
99 	u8 sensor;
100 	u8 hstart;
101 	u8 vstart;
102 
103 	u8 jpeg_hdr[JPEG_HDR_SZ];
104 
105 	u8 flags;
106 };
107 
108 static void qual_upd(struct work_struct *work);
109 
110 struct i2c_reg_u8 {
111 	u8 reg;
112 	u8 val;
113 };
114 
115 struct i2c_reg_u16 {
116 	u8 reg;
117 	u16 val;
118 };
119 
120 static const struct dmi_system_id flip_dmi_table[] = {
121 	{
122 		.ident = "MSI MS-1034",
123 		.matches = {
124 			DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
125 			DMI_MATCH(DMI_PRODUCT_NAME, "MS-1034"),
126 			DMI_MATCH(DMI_PRODUCT_VERSION, "0341")
127 		}
128 	},
129 	{
130 		.ident = "MSI MS-1039",
131 		.matches = {
132 			DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
133 			DMI_MATCH(DMI_PRODUCT_NAME, "MS-1039"),
134 		}
135 	},
136 	{
137 		.ident = "MSI MS-1632",
138 		.matches = {
139 			DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
140 			DMI_MATCH(DMI_BOARD_NAME, "MS-1632")
141 		}
142 	},
143 	{
144 		.ident = "MSI MS-1633X",
145 		.matches = {
146 			DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
147 			DMI_MATCH(DMI_BOARD_NAME, "MS-1633X")
148 		}
149 	},
150 	{
151 		.ident = "MSI MS-1635X",
152 		.matches = {
153 			DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
154 			DMI_MATCH(DMI_BOARD_NAME, "MS-1635X")
155 		}
156 	},
157 	{
158 		.ident = "ASUSTeK W7J",
159 		.matches = {
160 			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
161 			DMI_MATCH(DMI_BOARD_NAME, "W7J       ")
162 		}
163 	},
164 	{}
165 };
166 
167 static const struct v4l2_pix_format vga_mode[] = {
168 	{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
169 		.bytesperline = 160,
170 		.sizeimage = 160 * 120 * 4 / 8 + 590,
171 		.colorspace = V4L2_COLORSPACE_JPEG,
172 		.priv = SCALE_160x120 | MODE_JPEG},
173 	{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
174 		.bytesperline = 160,
175 		.sizeimage = 160 * 120,
176 		.colorspace = V4L2_COLORSPACE_SRGB,
177 		.priv = SCALE_160x120 | MODE_RAW},
178 	{160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
179 		.bytesperline = 160,
180 		.sizeimage = 240 * 120,
181 		.colorspace = V4L2_COLORSPACE_SRGB,
182 		.priv = SCALE_160x120},
183 	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
184 		.bytesperline = 320,
185 		.sizeimage = 320 * 240 * 4 / 8 + 590,
186 		.colorspace = V4L2_COLORSPACE_JPEG,
187 		.priv = SCALE_320x240 | MODE_JPEG},
188 	{320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
189 		.bytesperline = 320,
190 		.sizeimage = 320 * 240 ,
191 		.colorspace = V4L2_COLORSPACE_SRGB,
192 		.priv = SCALE_320x240 | MODE_RAW},
193 	{320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
194 		.bytesperline = 320,
195 		.sizeimage = 480 * 240 ,
196 		.colorspace = V4L2_COLORSPACE_SRGB,
197 		.priv = SCALE_320x240},
198 	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
199 		.bytesperline = 640,
200 		.sizeimage = 640 * 480 * 4 / 8 + 590,
201 		.colorspace = V4L2_COLORSPACE_JPEG,
202 		.priv = SCALE_640x480 | MODE_JPEG},
203 	{640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
204 		.bytesperline = 640,
205 		.sizeimage = 640 * 480,
206 		.colorspace = V4L2_COLORSPACE_SRGB,
207 		.priv = SCALE_640x480 | MODE_RAW},
208 	{640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
209 		.bytesperline = 640,
210 		.sizeimage = 960 * 480,
211 		.colorspace = V4L2_COLORSPACE_SRGB,
212 		.priv = SCALE_640x480},
213 };
214 
215 static const struct v4l2_pix_format sxga_mode[] = {
216 	{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
217 		.bytesperline = 160,
218 		.sizeimage = 160 * 120 * 4 / 8 + 590,
219 		.colorspace = V4L2_COLORSPACE_JPEG,
220 		.priv = SCALE_160x120 | MODE_JPEG},
221 	{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
222 		.bytesperline = 160,
223 		.sizeimage = 160 * 120,
224 		.colorspace = V4L2_COLORSPACE_SRGB,
225 		.priv = SCALE_160x120 | MODE_RAW},
226 	{160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
227 		.bytesperline = 160,
228 		.sizeimage = 240 * 120,
229 		.colorspace = V4L2_COLORSPACE_SRGB,
230 		.priv = SCALE_160x120},
231 	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
232 		.bytesperline = 320,
233 		.sizeimage = 320 * 240 * 4 / 8 + 590,
234 		.colorspace = V4L2_COLORSPACE_JPEG,
235 		.priv = SCALE_320x240 | MODE_JPEG},
236 	{320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
237 		.bytesperline = 320,
238 		.sizeimage = 320 * 240 ,
239 		.colorspace = V4L2_COLORSPACE_SRGB,
240 		.priv = SCALE_320x240 | MODE_RAW},
241 	{320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
242 		.bytesperline = 320,
243 		.sizeimage = 480 * 240 ,
244 		.colorspace = V4L2_COLORSPACE_SRGB,
245 		.priv = SCALE_320x240},
246 	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
247 		.bytesperline = 640,
248 		.sizeimage = 640 * 480 * 4 / 8 + 590,
249 		.colorspace = V4L2_COLORSPACE_JPEG,
250 		.priv = SCALE_640x480 | MODE_JPEG},
251 	{640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
252 		.bytesperline = 640,
253 		.sizeimage = 640 * 480,
254 		.colorspace = V4L2_COLORSPACE_SRGB,
255 		.priv = SCALE_640x480 | MODE_RAW},
256 	{640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
257 		.bytesperline = 640,
258 		.sizeimage = 960 * 480,
259 		.colorspace = V4L2_COLORSPACE_SRGB,
260 		.priv = SCALE_640x480},
261 	{1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
262 		.bytesperline = 1280,
263 		.sizeimage = 1280 * 1024,
264 		.colorspace = V4L2_COLORSPACE_SRGB,
265 		.priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
266 };
267 
268 static const struct v4l2_pix_format mono_mode[] = {
269 	{160, 120, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
270 		.bytesperline = 160,
271 		.sizeimage = 160 * 120,
272 		.colorspace = V4L2_COLORSPACE_SRGB,
273 		.priv = SCALE_160x120 | MODE_RAW},
274 	{320, 240, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
275 		.bytesperline = 320,
276 		.sizeimage = 320 * 240 ,
277 		.colorspace = V4L2_COLORSPACE_SRGB,
278 		.priv = SCALE_320x240 | MODE_RAW},
279 	{640, 480, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
280 		.bytesperline = 640,
281 		.sizeimage = 640 * 480,
282 		.colorspace = V4L2_COLORSPACE_SRGB,
283 		.priv = SCALE_640x480 | MODE_RAW},
284 	{1280, 1024, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
285 		.bytesperline = 1280,
286 		.sizeimage = 1280 * 1024,
287 		.colorspace = V4L2_COLORSPACE_SRGB,
288 		.priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
289 };
290 
291 static const s16 hsv_red_x[] = {
292 	41,  44,  46,  48,  50,  52,  54,  56,
293 	58,  60,  62,  64,  66,  68,  70,  72,
294 	74,  76,  78,  80,  81,  83,  85,  87,
295 	88,  90,  92,  93,  95,  97,  98, 100,
296 	101, 102, 104, 105, 107, 108, 109, 110,
297 	112, 113, 114, 115, 116, 117, 118, 119,
298 	120, 121, 122, 123, 123, 124, 125, 125,
299 	126, 127, 127, 128, 128, 129, 129, 129,
300 	130, 130, 130, 130, 131, 131, 131, 131,
301 	131, 131, 131, 131, 130, 130, 130, 130,
302 	129, 129, 129, 128, 128, 127, 127, 126,
303 	125, 125, 124, 123, 122, 122, 121, 120,
304 	119, 118, 117, 116, 115, 114, 112, 111,
305 	110, 109, 107, 106, 105, 103, 102, 101,
306 	99,  98,  96,  94,  93,  91,  90,  88,
307 	86,  84,  83,  81,  79,  77,  75,  74,
308 	72,  70,  68,  66,  64,  62,  60,  58,
309 	56,  54,  52,  49,  47,  45,  43,  41,
310 	39,  36,  34,  32,  30,  28,  25,  23,
311 	21,  19,  16,  14,  12,   9,   7,   5,
312 	3,   0,  -1,  -3,  -6,  -8, -10, -12,
313 	-15, -17, -19, -22, -24, -26, -28, -30,
314 	-33, -35, -37, -39, -41, -44, -46, -48,
315 	-50, -52, -54, -56, -58, -60, -62, -64,
316 	-66, -68, -70, -72, -74, -76, -78, -80,
317 	-81, -83, -85, -87, -88, -90, -92, -93,
318 	-95, -97, -98, -100, -101, -102, -104, -105,
319 	-107, -108, -109, -110, -112, -113, -114, -115,
320 	-116, -117, -118, -119, -120, -121, -122, -123,
321 	-123, -124, -125, -125, -126, -127, -127, -128,
322 	-128, -128, -128, -128, -128, -128, -128, -128,
323 	-128, -128, -128, -128, -128, -128, -128, -128,
324 	-128, -128, -128, -128, -128, -128, -128, -128,
325 	-128, -127, -127, -126, -125, -125, -124, -123,
326 	-122, -122, -121, -120, -119, -118, -117, -116,
327 	-115, -114, -112, -111, -110, -109, -107, -106,
328 	-105, -103, -102, -101, -99, -98, -96, -94,
329 	-93, -91, -90, -88, -86, -84, -83, -81,
330 	-79, -77, -75, -74, -72, -70, -68, -66,
331 	-64, -62, -60, -58, -56, -54, -52, -49,
332 	-47, -45, -43, -41, -39, -36, -34, -32,
333 	-30, -28, -25, -23, -21, -19, -16, -14,
334 	-12,  -9,  -7,  -5,  -3,   0,   1,   3,
335 	6,   8,  10,  12,  15,  17,  19,  22,
336 	24,  26,  28,  30,  33,  35,  37,  39, 41
337 };
338 
339 static const s16 hsv_red_y[] = {
340 	82,  80,  78,  76,  74,  73,  71,  69,
341 	67,  65,  63,  61,  58,  56,  54,  52,
342 	50,  48,  46,  44,  41,  39,  37,  35,
343 	32,  30,  28,  26,  23,  21,  19,  16,
344 	14,  12,  10,   7,   5,   3,   0,  -1,
345 	-3,  -6,  -8, -10, -13, -15, -17, -19,
346 	-22, -24, -26, -29, -31, -33, -35, -38,
347 	-40, -42, -44, -46, -48, -51, -53, -55,
348 	-57, -59, -61, -63, -65, -67, -69, -71,
349 	-73, -75, -77, -79, -81, -82, -84, -86,
350 	-88, -89, -91, -93, -94, -96, -98, -99,
351 	-101, -102, -104, -105, -106, -108, -109, -110,
352 	-112, -113, -114, -115, -116, -117, -119, -120,
353 	-120, -121, -122, -123, -124, -125, -126, -126,
354 	-127, -128, -128, -128, -128, -128, -128, -128,
355 	-128, -128, -128, -128, -128, -128, -128, -128,
356 	-128, -128, -128, -128, -128, -128, -128, -128,
357 	-128, -128, -128, -128, -128, -128, -128, -128,
358 	-127, -127, -126, -125, -125, -124, -123, -122,
359 	-121, -120, -119, -118, -117, -116, -115, -114,
360 	-113, -111, -110, -109, -107, -106, -105, -103,
361 	-102, -100, -99, -97, -96, -94, -92, -91,
362 	-89, -87, -85, -84, -82, -80, -78, -76,
363 	-74, -73, -71, -69, -67, -65, -63, -61,
364 	-58, -56, -54, -52, -50, -48, -46, -44,
365 	-41, -39, -37, -35, -32, -30, -28, -26,
366 	-23, -21, -19, -16, -14, -12, -10,  -7,
367 	-5,  -3,   0,   1,   3,   6,   8,  10,
368 	13,  15,  17,  19,  22,  24,  26,  29,
369 	31,  33,  35,  38,  40,  42,  44,  46,
370 	48,  51,  53,  55,  57,  59,  61,  63,
371 	65,  67,  69,  71,  73,  75,  77,  79,
372 	81,  82,  84,  86,  88,  89,  91,  93,
373 	94,  96,  98,  99, 101, 102, 104, 105,
374 	106, 108, 109, 110, 112, 113, 114, 115,
375 	116, 117, 119, 120, 120, 121, 122, 123,
376 	124, 125, 126, 126, 127, 128, 128, 129,
377 	129, 130, 130, 131, 131, 131, 131, 132,
378 	132, 132, 132, 132, 132, 132, 132, 132,
379 	132, 132, 132, 131, 131, 131, 130, 130,
380 	130, 129, 129, 128, 127, 127, 126, 125,
381 	125, 124, 123, 122, 121, 120, 119, 118,
382 	117, 116, 115, 114, 113, 111, 110, 109,
383 	107, 106, 105, 103, 102, 100,  99,  97,
384 	96, 94, 92, 91, 89, 87, 85, 84, 82
385 };
386 
387 static const s16 hsv_green_x[] = {
388 	-124, -124, -125, -125, -125, -125, -125, -125,
389 	-125, -126, -126, -125, -125, -125, -125, -125,
390 	-125, -124, -124, -124, -123, -123, -122, -122,
391 	-121, -121, -120, -120, -119, -118, -117, -117,
392 	-116, -115, -114, -113, -112, -111, -110, -109,
393 	-108, -107, -105, -104, -103, -102, -100, -99,
394 	-98, -96, -95, -93, -92, -91, -89, -87,
395 	-86, -84, -83, -81, -79, -77, -76, -74,
396 	-72, -70, -69, -67, -65, -63, -61, -59,
397 	-57, -55, -53, -51, -49, -47, -45, -43,
398 	-41, -39, -37, -35, -33, -30, -28, -26,
399 	-24, -22, -20, -18, -15, -13, -11,  -9,
400 	-7,  -4,  -2,   0,   1,   3,   6,   8,
401 	10,  12,  14,  17,  19,  21,  23,  25,
402 	27,  29,  32,  34,  36,  38,  40,  42,
403 	44,  46,  48,  50,  52,  54,  56,  58,
404 	60,  62,  64,  66,  68,  70,  71,  73,
405 	75,  77,  78,  80,  82,  83,  85,  87,
406 	88,  90,  91,  93,  94,  96,  97,  98,
407 	100, 101, 102, 104, 105, 106, 107, 108,
408 	109, 111, 112, 113, 113, 114, 115, 116,
409 	117, 118, 118, 119, 120, 120, 121, 122,
410 	122, 123, 123, 124, 124, 124, 125, 125,
411 	125, 125, 125, 125, 125, 126, 126, 125,
412 	125, 125, 125, 125, 125, 124, 124, 124,
413 	123, 123, 122, 122, 121, 121, 120, 120,
414 	119, 118, 117, 117, 116, 115, 114, 113,
415 	112, 111, 110, 109, 108, 107, 105, 104,
416 	103, 102, 100,  99,  98,  96,  95,  93,
417 	92,  91,  89,  87,  86,  84,  83,  81,
418 	79,  77,  76,  74,  72,  70,  69,  67,
419 	65,  63,  61,  59,  57,  55,  53,  51,
420 	49,  47,  45,  43,  41,  39,  37,  35,
421 	33,  30,  28,  26,  24,  22,  20,  18,
422 	15,  13,  11,   9,   7,   4,   2,   0,
423 	-1,  -3,  -6,  -8, -10, -12, -14, -17,
424 	-19, -21, -23, -25, -27, -29, -32, -34,
425 	-36, -38, -40, -42, -44, -46, -48, -50,
426 	-52, -54, -56, -58, -60, -62, -64, -66,
427 	-68, -70, -71, -73, -75, -77, -78, -80,
428 	-82, -83, -85, -87, -88, -90, -91, -93,
429 	-94, -96, -97, -98, -100, -101, -102, -104,
430 	-105, -106, -107, -108, -109, -111, -112, -113,
431 	-113, -114, -115, -116, -117, -118, -118, -119,
432 	-120, -120, -121, -122, -122, -123, -123, -124, -124
433 };
434 
435 static const s16 hsv_green_y[] = {
436 	-100, -99, -98, -97, -95, -94, -93, -91,
437 	-90, -89, -87, -86, -84, -83, -81, -80,
438 	-78, -76, -75, -73, -71, -70, -68, -66,
439 	-64, -63, -61, -59, -57, -55, -53, -51,
440 	-49, -48, -46, -44, -42, -40, -38, -36,
441 	-34, -32, -30, -27, -25, -23, -21, -19,
442 	-17, -15, -13, -11,  -9,  -7,  -4,  -2,
443 	0,   1,   3,   5,   7,   9,  11,  14,
444 	16,  18,  20,  22,  24,  26,  28,  30,
445 	32,  34,  36,  38,  40,  42,  44,  46,
446 	48,  50,  52,  54,  56,  58,  59,  61,
447 	63,  65,  67,  68,  70,  72,  74,  75,
448 	77,  78,  80,  82,  83,  85,  86,  88,
449 	89,  90,  92,  93,  95,  96,  97,  98,
450 	100, 101, 102, 103, 104, 105, 106, 107,
451 	108, 109, 110, 111, 112, 112, 113, 114,
452 	115, 115, 116, 116, 117, 117, 118, 118,
453 	119, 119, 119, 120, 120, 120, 120, 120,
454 	121, 121, 121, 121, 121, 121, 120, 120,
455 	120, 120, 120, 119, 119, 119, 118, 118,
456 	117, 117, 116, 116, 115, 114, 114, 113,
457 	112, 111, 111, 110, 109, 108, 107, 106,
458 	105, 104, 103, 102, 100,  99,  98,  97,
459 	95,  94,  93,  91,  90,  89,  87,  86,
460 	84,  83,  81,  80,  78,  76,  75,  73,
461 	71,  70,  68,  66,  64,  63,  61,  59,
462 	57,  55,  53,  51,  49,  48,  46,  44,
463 	42,  40,  38,  36,  34,  32,  30,  27,
464 	25,  23,  21,  19,  17,  15,  13,  11,
465 	9,   7,   4,   2,   0,  -1,  -3,  -5,
466 	-7,  -9, -11, -14, -16, -18, -20, -22,
467 	-24, -26, -28, -30, -32, -34, -36, -38,
468 	-40, -42, -44, -46, -48, -50, -52, -54,
469 	-56, -58, -59, -61, -63, -65, -67, -68,
470 	-70, -72, -74, -75, -77, -78, -80, -82,
471 	-83, -85, -86, -88, -89, -90, -92, -93,
472 	-95, -96, -97, -98, -100, -101, -102, -103,
473 	-104, -105, -106, -107, -108, -109, -110, -111,
474 	-112, -112, -113, -114, -115, -115, -116, -116,
475 	-117, -117, -118, -118, -119, -119, -119, -120,
476 	-120, -120, -120, -120, -121, -121, -121, -121,
477 	-121, -121, -120, -120, -120, -120, -120, -119,
478 	-119, -119, -118, -118, -117, -117, -116, -116,
479 	-115, -114, -114, -113, -112, -111, -111, -110,
480 	-109, -108, -107, -106, -105, -104, -103, -102, -100
481 };
482 
483 static const s16 hsv_blue_x[] = {
484 	112, 113, 114, 114, 115, 116, 117, 117,
485 	118, 118, 119, 119, 120, 120, 120, 121,
486 	121, 121, 122, 122, 122, 122, 122, 122,
487 	122, 122, 122, 122, 122, 122, 121, 121,
488 	121, 120, 120, 120, 119, 119, 118, 118,
489 	117, 116, 116, 115, 114, 113, 113, 112,
490 	111, 110, 109, 108, 107, 106, 105, 104,
491 	103, 102, 100,  99,  98,  97,  95,  94,
492 	93,  91,  90,  88,  87,  85,  84,  82,
493 	80,  79,  77,  76,  74,  72,  70,  69,
494 	67,  65,  63,  61,  60,  58,  56,  54,
495 	52,  50,  48,  46,  44,  42,  40,  38,
496 	36,  34,  32,  30,  28,  26,  24,  22,
497 	19,  17,  15,  13,  11,   9,   7,   5,
498 	2,   0,  -1,  -3,  -5,  -7,  -9, -12,
499 	-14, -16, -18, -20, -22, -24, -26, -28,
500 	-31, -33, -35, -37, -39, -41, -43, -45,
501 	-47, -49, -51, -53, -54, -56, -58, -60,
502 	-62, -64, -66, -67, -69, -71, -73, -74,
503 	-76, -78, -79, -81, -83, -84, -86, -87,
504 	-89, -90, -92, -93, -94, -96, -97, -98,
505 	-99, -101, -102, -103, -104, -105, -106, -107,
506 	-108, -109, -110, -111, -112, -113, -114, -114,
507 	-115, -116, -117, -117, -118, -118, -119, -119,
508 	-120, -120, -120, -121, -121, -121, -122, -122,
509 	-122, -122, -122, -122, -122, -122, -122, -122,
510 	-122, -122, -121, -121, -121, -120, -120, -120,
511 	-119, -119, -118, -118, -117, -116, -116, -115,
512 	-114, -113, -113, -112, -111, -110, -109, -108,
513 	-107, -106, -105, -104, -103, -102, -100, -99,
514 	-98, -97, -95, -94, -93, -91, -90, -88,
515 	-87, -85, -84, -82, -80, -79, -77, -76,
516 	-74, -72, -70, -69, -67, -65, -63, -61,
517 	-60, -58, -56, -54, -52, -50, -48, -46,
518 	-44, -42, -40, -38, -36, -34, -32, -30,
519 	-28, -26, -24, -22, -19, -17, -15, -13,
520 	-11,  -9,  -7,  -5,  -2,   0,   1,   3,
521 	5,   7,   9,  12,  14,  16,  18,  20,
522 	22,  24,  26,  28,  31,  33,  35,  37,
523 	39,  41,  43,  45,  47,  49,  51,  53,
524 	54,  56,  58,  60,  62,  64,  66,  67,
525 	69,  71,  73,  74,  76,  78,  79,  81,
526 	83,  84,  86,  87,  89,  90,  92,  93,
527 	94,  96,  97,  98,  99, 101, 102, 103,
528 	104, 105, 106, 107, 108, 109, 110, 111, 112
529 };
530 
531 static const s16 hsv_blue_y[] = {
532 	-11, -13, -15, -17, -19, -21, -23, -25,
533 	-27, -29, -31, -33, -35, -37, -39, -41,
534 	-43, -45, -46, -48, -50, -52, -54, -55,
535 	-57, -59, -61, -62, -64, -66, -67, -69,
536 	-71, -72, -74, -75, -77, -78, -80, -81,
537 	-83, -84, -86, -87, -88, -90, -91, -92,
538 	-93, -95, -96, -97, -98, -99, -100, -101,
539 	-102, -103, -104, -105, -106, -106, -107, -108,
540 	-109, -109, -110, -111, -111, -112, -112, -113,
541 	-113, -114, -114, -114, -115, -115, -115, -115,
542 	-116, -116, -116, -116, -116, -116, -116, -116,
543 	-116, -115, -115, -115, -115, -114, -114, -114,
544 	-113, -113, -112, -112, -111, -111, -110, -110,
545 	-109, -108, -108, -107, -106, -105, -104, -103,
546 	-102, -101, -100, -99, -98, -97, -96, -95,
547 	-94, -93, -91, -90, -89, -88, -86, -85,
548 	-84, -82, -81, -79, -78, -76, -75, -73,
549 	-71, -70, -68, -67, -65, -63, -62, -60,
550 	-58, -56, -55, -53, -51, -49, -47, -45,
551 	-44, -42, -40, -38, -36, -34, -32, -30,
552 	-28, -26, -24, -22, -20, -18, -16, -14,
553 	-12, -10,  -8,  -6,  -4,  -2,   0,   1,
554 	3,   5,   7,   9,  11,  13,  15,  17,
555 	19,  21,  23,  25,  27,  29,  31,  33,
556 	35,  37,  39,  41,  43,  45,  46,  48,
557 	50,  52,  54,  55,  57,  59,  61,  62,
558 	64,  66,  67,  69,  71,  72,  74,  75,
559 	77,  78,  80,  81,  83,  84,  86,  87,
560 	88,  90,  91,  92,  93,  95,  96,  97,
561 	98,  99, 100, 101, 102, 103, 104, 105,
562 	106, 106, 107, 108, 109, 109, 110, 111,
563 	111, 112, 112, 113, 113, 114, 114, 114,
564 	115, 115, 115, 115, 116, 116, 116, 116,
565 	116, 116, 116, 116, 116, 115, 115, 115,
566 	115, 114, 114, 114, 113, 113, 112, 112,
567 	111, 111, 110, 110, 109, 108, 108, 107,
568 	106, 105, 104, 103, 102, 101, 100,  99,
569 	98,  97,  96,  95,  94,  93,  91,  90,
570 	89,  88,  86,  85,  84,  82,  81,  79,
571 	78,  76,  75,  73,  71,  70,  68,  67,
572 	65,  63,  62,  60,  58,  56,  55,  53,
573 	51,  49,  47,  45,  44,  42,  40,  38,
574 	36,  34,  32,  30,  28,  26,  24,  22,
575 	20,  18,  16,  14,  12,  10,   8,   6,
576 	4,   2,   0,  -1,  -3,  -5,  -7,  -9, -11
577 };
578 
579 static const u16 bridge_init[][2] = {
580 	{0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
581 	{0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
582 	{0x1068, 0x30}, {0x1069, 0x20},	{0x106a, 0x10},
583 	{0x106b, 0x08},	{0x1188, 0x87},	{0x11a1, 0x00},
584 	{0x11a2, 0x00},	{0x11a3, 0x6a},	{0x11a4, 0x50},
585 	{0x11ab, 0x00},	{0x11ac, 0x00},	{0x11ad, 0x50},
586 	{0x11ae, 0x3c},	{0x118a, 0x04},	{0x0395, 0x04},
587 	{0x11b8, 0x3a},	{0x118b, 0x0e},	{0x10f7, 0x05},
588 	{0x10f8, 0x14},	{0x10fa, 0xff},	{0x10f9, 0x00},
589 	{0x11ba, 0x0a},	{0x11a5, 0x2d},	{0x11a6, 0x2d},
590 	{0x11a7, 0x3a},	{0x11a8, 0x05},	{0x11a9, 0x04},
591 	{0x11aa, 0x3f},	{0x11af, 0x28},	{0x11b0, 0xd8},
592 	{0x11b1, 0x14},	{0x11b2, 0xec},	{0x11b3, 0x32},
593 	{0x11b4, 0xdd},	{0x11b5, 0x32},	{0x11b6, 0xdd},
594 	{0x10e0, 0x2c},	{0x11bc, 0x40},	{0x11bd, 0x01},
595 	{0x11be, 0xf0},	{0x11bf, 0x00},	{0x118c, 0x1f},
596 	{0x118d, 0x1f},	{0x118e, 0x1f},	{0x118f, 0x1f},
597 	{0x1180, 0x01},	{0x1181, 0x00},	{0x1182, 0x01},
598 	{0x1183, 0x00},	{0x1184, 0x50},	{0x1185, 0x80},
599 	{0x1007, 0x00}
600 };
601 
602 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
603 static const u8 ov_gain[] = {
604 	0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
605 	0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
606 	0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
607 	0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
608 	0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
609 	0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
610 	0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
611 	0x70 /* 8x */
612 };
613 
614 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
615 static const u16 micron1_gain[] = {
616 	/* 1x   1.25x   1.5x    1.75x */
617 	0x0020, 0x0028, 0x0030, 0x0038,
618 	/* 2x   2.25x   2.5x    2.75x */
619 	0x00a0, 0x00a4, 0x00a8, 0x00ac,
620 	/* 3x   3.25x   3.5x    3.75x */
621 	0x00b0, 0x00b4, 0x00b8, 0x00bc,
622 	/* 4x   4.25x   4.5x    4.75x */
623 	0x00c0, 0x00c4, 0x00c8, 0x00cc,
624 	/* 5x   5.25x   5.5x    5.75x */
625 	0x00d0, 0x00d4, 0x00d8, 0x00dc,
626 	/* 6x   6.25x   6.5x    6.75x */
627 	0x00e0, 0x00e4, 0x00e8, 0x00ec,
628 	/* 7x   7.25x   7.5x    7.75x */
629 	0x00f0, 0x00f4, 0x00f8, 0x00fc,
630 	/* 8x */
631 	0x01c0
632 };
633 
634 /* mt9m001 sensor uses a different gain formula then other micron sensors */
635 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
636 static const u16 micron2_gain[] = {
637 	/* 1x   1.25x   1.5x    1.75x */
638 	0x0008, 0x000a, 0x000c, 0x000e,
639 	/* 2x   2.25x   2.5x    2.75x */
640 	0x0010, 0x0012, 0x0014, 0x0016,
641 	/* 3x   3.25x   3.5x    3.75x */
642 	0x0018, 0x001a, 0x001c, 0x001e,
643 	/* 4x   4.25x   4.5x    4.75x */
644 	0x0020, 0x0051, 0x0052, 0x0053,
645 	/* 5x   5.25x   5.5x    5.75x */
646 	0x0054, 0x0055, 0x0056, 0x0057,
647 	/* 6x   6.25x   6.5x    6.75x */
648 	0x0058, 0x0059, 0x005a, 0x005b,
649 	/* 7x   7.25x   7.5x    7.75x */
650 	0x005c, 0x005d, 0x005e, 0x005f,
651 	/* 8x */
652 	0x0060
653 };
654 
655 /* Gain = .5 + bit[7:0] / 16 */
656 static const u8 hv7131r_gain[] = {
657 	0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
658 	0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
659 	0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
660 	0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
661 	0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
662 	0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
663 	0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
664 	0x78 /* 8x */
665 };
666 
667 static const struct i2c_reg_u8 soi968_init[] = {
668 	{0x0c, 0x00}, {0x0f, 0x1f},
669 	{0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
670 	{0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
671 	{0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
672 	{0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
673 	{0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
674 	{0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
675 	{0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
676 	{0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
677 	{0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
678 	{0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
679 };
680 
681 static const struct i2c_reg_u8 ov7660_init[] = {
682 	{0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
683 	{0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
684 	{0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
685 	/* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using
686 	   0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
687 	{0x17, 0x10}, {0x18, 0x61},
688 	{0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
689 	{0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0x00},
690 	{0x2e, 0x00}, {0x01, 0x78}, {0x02, 0x50},
691 };
692 
693 static const struct i2c_reg_u8 ov7670_init[] = {
694 	{0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
695 	{0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
696 	{0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
697 	{0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
698 	{0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
699 	{0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
700 	{0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
701 	{0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
702 	{0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
703 	{0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
704 	{0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
705 	{0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
706 	{0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
707 	{0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
708 	{0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
709 	{0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
710 	{0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
711 	{0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
712 	{0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
713 	{0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
714 	{0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
715 	{0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
716 	{0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
717 	{0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
718 	{0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
719 	{0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
720 	{0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
721 	{0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
722 	{0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
723 	{0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
724 	{0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
725 	{0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
726 	{0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
727 	{0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
728 	{0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
729 	{0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
730 	{0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
731 	{0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
732 	{0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
733 	{0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
734 	{0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
735 	{0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
736 	{0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
737 	{0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
738 	{0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
739 	{0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
740 	{0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
741 	{0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
742 	{0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
743 	{0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
744 	{0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
745 	{0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
746 	{0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
747 	{0x93, 0x00},
748 };
749 
750 static const struct i2c_reg_u8 ov9650_init[] = {
751 	{0x00, 0x00}, {0x01, 0x78},
752 	{0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
753 	{0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
754 	{0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
755 	{0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
756 	{0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
757 	{0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
758 	{0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
759 	{0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
760 	{0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
761 	{0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
762 	{0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
763 	{0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
764 	{0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
765 	{0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
766 	{0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
767 	{0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
768 	{0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
769 	{0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
770 	{0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
771 	{0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
772 	{0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
773 	{0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
774 	{0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
775 	{0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
776 	{0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
777 	{0xaa, 0x92}, {0xab, 0x0a},
778 };
779 
780 static const struct i2c_reg_u8 ov9655_init[] = {
781 	{0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
782 	{0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
783 	{0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
784 	{0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
785 	{0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
786 	{0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
787 	{0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
788 	{0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
789 	{0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
790 	{0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
791 	{0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
792 	{0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
793 	{0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
794 	{0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
795 	{0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
796 	{0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
797 	{0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
798 	{0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
799 	{0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
800 	{0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
801 	{0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
802 	{0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
803 	{0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
804 	{0x04, 0x03}, {0x00, 0x13},
805 };
806 
807 static const struct i2c_reg_u16 mt9v112_init[] = {
808 	{0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
809 	{0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
810 	{0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
811 	{0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
812 	{0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
813 	{0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
814 	{0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
815 	{0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
816 	{0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
817 	{0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
818 	{0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
819 	{0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
820 	{0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
821 	{0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
822 	{0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
823 	{0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
824 };
825 
826 static const struct i2c_reg_u16 mt9v111_init[] = {
827 	{0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
828 	{0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
829 	{0x2e, 0x0c64},	{0x2f, 0x0064}, {0x06, 0x600e},
830 	{0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
831 	{0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
832 	{0x06, 0x002d},	{0x07, 0x3002}, {0x08, 0x0008},
833 	{0x0e, 0x0008}, {0x20, 0x0000}
834 };
835 
836 static const struct i2c_reg_u16 mt9v011_init[] = {
837 	{0x07, 0x0002},	{0x0d, 0x0001},	{0x0d, 0x0000},
838 	{0x01, 0x0008},	{0x02, 0x0016},	{0x03, 0x01e1},
839 	{0x04, 0x0281},	{0x05, 0x0083},	{0x06, 0x0006},
840 	{0x0d, 0x0002}, {0x0a, 0x0000},	{0x0b, 0x0000},
841 	{0x0c, 0x0000},	{0x0d, 0x0000},	{0x0e, 0x0000},
842 	{0x0f, 0x0000},	{0x10, 0x0000},	{0x11, 0x0000},
843 	{0x12, 0x0000},	{0x13, 0x0000},	{0x14, 0x0000},
844 	{0x15, 0x0000},	{0x16, 0x0000},	{0x17, 0x0000},
845 	{0x18, 0x0000},	{0x19, 0x0000},	{0x1a, 0x0000},
846 	{0x1b, 0x0000},	{0x1c, 0x0000},	{0x1d, 0x0000},
847 	{0x32, 0x0000},	{0x20, 0x1101},	{0x21, 0x0000},
848 	{0x22, 0x0000},	{0x23, 0x0000},	{0x24, 0x0000},
849 	{0x25, 0x0000},	{0x26, 0x0000},	{0x27, 0x0024},
850 	{0x2f, 0xf7b0},	{0x30, 0x0005},	{0x31, 0x0000},
851 	{0x32, 0x0000},	{0x33, 0x0000},	{0x34, 0x0100},
852 	{0x3d, 0x068f},	{0x40, 0x01e0},	{0x41, 0x00d1},
853 	{0x44, 0x0082},	{0x5a, 0x0000},	{0x5b, 0x0000},
854 	{0x5c, 0x0000},	{0x5d, 0x0000},	{0x5e, 0x0000},
855 	{0x5f, 0xa31d},	{0x62, 0x0611},	{0x0a, 0x0000},
856 	{0x06, 0x0029},	{0x05, 0x0009},	{0x20, 0x1101},
857 	{0x20, 0x1101},	{0x09, 0x0064},	{0x07, 0x0003},
858 	{0x2b, 0x0033},	{0x2c, 0x00a0},	{0x2d, 0x00a0},
859 	{0x2e, 0x0033},	{0x07, 0x0002},	{0x06, 0x0000},
860 	{0x06, 0x0029},	{0x05, 0x0009},
861 };
862 
863 static const struct i2c_reg_u16 mt9m001_init[] = {
864 	{0x0d, 0x0001},
865 	{0x0d, 0x0000},
866 	{0x04, 0x0500},		/* hres = 1280 */
867 	{0x03, 0x0400},		/* vres = 1024 */
868 	{0x20, 0x1100},
869 	{0x06, 0x0010},
870 	{0x2b, 0x0024},
871 	{0x2e, 0x0024},
872 	{0x35, 0x0024},
873 	{0x2d, 0x0020},
874 	{0x2c, 0x0020},
875 	{0x09, 0x0ad4},
876 	{0x35, 0x0057},
877 };
878 
879 static const struct i2c_reg_u16 mt9m111_init[] = {
880 	{0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
881 	{0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
882 	{0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
883 	{0xf0, 0x0000},
884 };
885 
886 static const struct i2c_reg_u16 mt9m112_init[] = {
887 	{0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
888 	{0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
889 	{0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
890 	{0xf0, 0x0000},
891 };
892 
893 static const struct i2c_reg_u8 hv7131r_init[] = {
894 	{0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
895 	{0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
896 	{0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
897 	{0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
898 	{0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
899 	{0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
900 	{0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
901 	{0x23, 0x09}, {0x01, 0x08},
902 };
903 
904 static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
905 {
906 	struct usb_device *dev = gspca_dev->dev;
907 	int result;
908 
909 	if (gspca_dev->usb_err < 0)
910 		return;
911 	result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
912 			0x00,
913 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
914 			reg,
915 			0x00,
916 			gspca_dev->usb_buf,
917 			length,
918 			500);
919 	if (unlikely(result < 0 || result != length)) {
920 		pr_err("Read register %02x failed %d\n", reg, result);
921 		gspca_dev->usb_err = result;
922 		/*
923 		 * Make sure the buffer is zeroed to avoid uninitialized
924 		 * values.
925 		 */
926 		memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
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_led_mode(struct gspca_dev *gspca_dev, s32 val)
1540 {
1541 	reg_w1(gspca_dev, 0x1007, 0x60);
1542 	reg_w1(gspca_dev, 0x1006, val ? 0x40 : 0x00);
1543 }
1544 
1545 static void set_quality(struct gspca_dev *gspca_dev, s32 val)
1546 {
1547 	struct sd *sd = (struct sd *) gspca_dev;
1548 
1549 	jpeg_set_qual(sd->jpeg_hdr, val);
1550 	reg_w1(gspca_dev, 0x1061, 0x01);	/* stop transfer */
1551 	reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20); /* write QTAB */
1552 	reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
1553 	reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
1554 	reg_w1(gspca_dev, 0x1061, 0x03);	/* restart transfer */
1555 	reg_w1(gspca_dev, 0x10e0, sd->fmt);
1556 	sd->fmt ^= 0x0c;			/* invert QTAB use + write */
1557 	reg_w1(gspca_dev, 0x10e0, sd->fmt);
1558 }
1559 
1560 #ifdef CONFIG_VIDEO_ADV_DEBUG
1561 static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1562 			struct v4l2_dbg_register *reg)
1563 {
1564 	struct sd *sd = (struct sd *) gspca_dev;
1565 
1566 	reg->size = 1;
1567 	switch (reg->match.addr) {
1568 	case 0:
1569 		if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1570 			return -EINVAL;
1571 		reg_r(gspca_dev, reg->reg, 1);
1572 		reg->val = gspca_dev->usb_buf[0];
1573 		return gspca_dev->usb_err;
1574 	case 1:
1575 		if (sd->sensor >= SENSOR_MT9V011 &&
1576 		    sd->sensor <= SENSOR_MT9M112) {
1577 			i2c_r2(gspca_dev, reg->reg, (u16 *) &reg->val);
1578 			reg->size = 2;
1579 		} else {
1580 			i2c_r1(gspca_dev, reg->reg, (u8 *) &reg->val);
1581 		}
1582 		return gspca_dev->usb_err;
1583 	}
1584 	return -EINVAL;
1585 }
1586 
1587 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1588 			const struct v4l2_dbg_register *reg)
1589 {
1590 	struct sd *sd = (struct sd *) gspca_dev;
1591 
1592 	switch (reg->match.addr) {
1593 	case 0:
1594 		if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1595 			return -EINVAL;
1596 		reg_w1(gspca_dev, reg->reg, reg->val);
1597 		return gspca_dev->usb_err;
1598 	case 1:
1599 		if (sd->sensor >= SENSOR_MT9V011 &&
1600 		    sd->sensor <= SENSOR_MT9M112) {
1601 			i2c_w2(gspca_dev, reg->reg, reg->val);
1602 		} else {
1603 			i2c_w1(gspca_dev, reg->reg, reg->val);
1604 		}
1605 		return gspca_dev->usb_err;
1606 	}
1607 	return -EINVAL;
1608 }
1609 
1610 static int sd_chip_info(struct gspca_dev *gspca_dev,
1611 			struct v4l2_dbg_chip_info *chip)
1612 {
1613 	if (chip->match.addr > 1)
1614 		return -EINVAL;
1615 	if (chip->match.addr == 1)
1616 		strscpy(chip->name, "sensor", sizeof(chip->name));
1617 	return 0;
1618 }
1619 #endif
1620 
1621 static int sd_config(struct gspca_dev *gspca_dev,
1622 			const struct usb_device_id *id)
1623 {
1624 	struct sd *sd = (struct sd *) gspca_dev;
1625 	struct cam *cam;
1626 
1627 	cam = &gspca_dev->cam;
1628 	cam->needs_full_bandwidth = 1;
1629 
1630 	sd->sensor = id->driver_info >> 8;
1631 	sd->i2c_addr = id->driver_info;
1632 	sd->flags = id->driver_info >> 16;
1633 	sd->i2c_intf = 0x80;			/* i2c 100 Kb/s */
1634 
1635 	switch (sd->sensor) {
1636 	case SENSOR_MT9M112:
1637 	case SENSOR_MT9M111:
1638 	case SENSOR_OV9650:
1639 	case SENSOR_SOI968:
1640 		cam->cam_mode = sxga_mode;
1641 		cam->nmodes = ARRAY_SIZE(sxga_mode);
1642 		break;
1643 	case SENSOR_MT9M001:
1644 		cam->cam_mode = mono_mode;
1645 		cam->nmodes = ARRAY_SIZE(mono_mode);
1646 		break;
1647 	case SENSOR_HV7131R:
1648 		sd->i2c_intf = 0x81;			/* i2c 400 Kb/s */
1649 		fallthrough;
1650 	default:
1651 		cam->cam_mode = vga_mode;
1652 		cam->nmodes = ARRAY_SIZE(vga_mode);
1653 		break;
1654 	}
1655 
1656 	sd->old_step = 0;
1657 	sd->older_step = 0;
1658 	sd->exposure_step = 16;
1659 
1660 	INIT_WORK(&sd->work, qual_upd);
1661 
1662 	return 0;
1663 }
1664 
1665 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
1666 {
1667 	struct gspca_dev *gspca_dev =
1668 		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
1669 	struct sd *sd = (struct sd *)gspca_dev;
1670 
1671 	gspca_dev->usb_err = 0;
1672 
1673 	if (!gspca_dev->streaming)
1674 		return 0;
1675 
1676 	switch (ctrl->id) {
1677 	/* color control cluster */
1678 	case V4L2_CID_BRIGHTNESS:
1679 		set_cmatrix(gspca_dev, sd->brightness->val,
1680 			sd->contrast->val, sd->saturation->val, sd->hue->val);
1681 		break;
1682 	case V4L2_CID_GAMMA:
1683 		set_gamma(gspca_dev, ctrl->val);
1684 		break;
1685 	/* blue/red balance cluster */
1686 	case V4L2_CID_BLUE_BALANCE:
1687 		set_redblue(gspca_dev, sd->blue->val, sd->red->val);
1688 		break;
1689 	/* h/vflip cluster */
1690 	case V4L2_CID_HFLIP:
1691 		set_hvflip(gspca_dev, sd->hflip->val, sd->vflip->val);
1692 		break;
1693 	/* standalone exposure control */
1694 	case V4L2_CID_EXPOSURE:
1695 		set_exposure(gspca_dev, ctrl->val);
1696 		break;
1697 	/* standalone gain control */
1698 	case V4L2_CID_GAIN:
1699 		set_gain(gspca_dev, ctrl->val);
1700 		break;
1701 	/* autogain + exposure or gain control cluster */
1702 	case V4L2_CID_AUTOGAIN:
1703 		if (sd->sensor == SENSOR_SOI968)
1704 			set_gain(gspca_dev, sd->gain->val);
1705 		else
1706 			set_exposure(gspca_dev, sd->exposure->val);
1707 		break;
1708 	case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1709 		set_quality(gspca_dev, ctrl->val);
1710 		break;
1711 	case V4L2_CID_FLASH_LED_MODE:
1712 		set_led_mode(gspca_dev, ctrl->val);
1713 		break;
1714 	}
1715 	return gspca_dev->usb_err;
1716 }
1717 
1718 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1719 	.s_ctrl = sd_s_ctrl,
1720 };
1721 
1722 static int sd_init_controls(struct gspca_dev *gspca_dev)
1723 {
1724 	struct sd *sd = (struct sd *) gspca_dev;
1725 	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1726 
1727 	gspca_dev->vdev.ctrl_handler = hdl;
1728 	v4l2_ctrl_handler_init(hdl, 13);
1729 
1730 	sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1731 			V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
1732 	sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1733 			V4L2_CID_CONTRAST, 0, 255, 1, 127);
1734 	sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1735 			V4L2_CID_SATURATION, 0, 255, 1, 127);
1736 	sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1737 			V4L2_CID_HUE, -180, 180, 1, 0);
1738 
1739 	sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1740 			V4L2_CID_GAMMA, 0, 255, 1, 0x10);
1741 
1742 	sd->blue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1743 			V4L2_CID_BLUE_BALANCE, 0, 127, 1, 0x28);
1744 	sd->red = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1745 			V4L2_CID_RED_BALANCE, 0, 127, 1, 0x28);
1746 
1747 	if (sd->sensor != SENSOR_OV9655 && sd->sensor != SENSOR_SOI968 &&
1748 	    sd->sensor != SENSOR_OV7670 && sd->sensor != SENSOR_MT9M001 &&
1749 	    sd->sensor != SENSOR_MT9VPRB) {
1750 		sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1751 			V4L2_CID_HFLIP, 0, 1, 1, 0);
1752 		sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1753 			V4L2_CID_VFLIP, 0, 1, 1, 0);
1754 	}
1755 
1756 	if (sd->sensor != SENSOR_SOI968 && sd->sensor != SENSOR_MT9VPRB &&
1757 	    sd->sensor != SENSOR_MT9M112 && sd->sensor != SENSOR_MT9M111 &&
1758 	    sd->sensor != SENSOR_MT9V111)
1759 		sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1760 			V4L2_CID_EXPOSURE, 0, 0x1780, 1, 0x33);
1761 
1762 	if (sd->sensor != SENSOR_MT9VPRB && sd->sensor != SENSOR_MT9M112 &&
1763 	    sd->sensor != SENSOR_MT9M111 && sd->sensor != SENSOR_MT9V111) {
1764 		sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1765 			V4L2_CID_GAIN, 0, 28, 1, 0);
1766 		sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1767 			V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1768 	}
1769 
1770 	sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1771 			V4L2_CID_JPEG_COMPRESSION_QUALITY, 50, 90, 1, 80);
1772 
1773 	if (sd->flags & HAS_LED_TORCH)
1774 		sd->led_mode = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
1775 				V4L2_CID_FLASH_LED_MODE, V4L2_FLASH_LED_MODE_TORCH,
1776 				~0x5, V4L2_FLASH_LED_MODE_NONE);
1777 
1778 	if (hdl->error) {
1779 		pr_err("Could not initialize controls\n");
1780 		return hdl->error;
1781 	}
1782 
1783 	v4l2_ctrl_cluster(4, &sd->brightness);
1784 	v4l2_ctrl_cluster(2, &sd->blue);
1785 	if (sd->hflip)
1786 		v4l2_ctrl_cluster(2, &sd->hflip);
1787 	if (sd->autogain) {
1788 		if (sd->sensor == SENSOR_SOI968)
1789 			/* this sensor doesn't have the exposure control and
1790 			   autogain is clustered with gain instead. This works
1791 			   because sd->exposure == NULL. */
1792 			v4l2_ctrl_auto_cluster(3, &sd->autogain, 0, false);
1793 		else
1794 			/* Otherwise autogain is clustered with exposure. */
1795 			v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false);
1796 	}
1797 	return 0;
1798 }
1799 
1800 static int sd_init(struct gspca_dev *gspca_dev)
1801 {
1802 	struct sd *sd = (struct sd *) gspca_dev;
1803 	int i;
1804 	u8 value;
1805 	u8 i2c_init[9] = {
1806 		0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
1807 	};
1808 
1809 	for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
1810 		value = bridge_init[i][1];
1811 		reg_w(gspca_dev, bridge_init[i][0], &value, 1);
1812 		if (gspca_dev->usb_err < 0) {
1813 			pr_err("Device initialization failed\n");
1814 			return gspca_dev->usb_err;
1815 		}
1816 	}
1817 
1818 	if (sd->flags & LED_REVERSE)
1819 		reg_w1(gspca_dev, 0x1006, 0x00);
1820 	else
1821 		reg_w1(gspca_dev, 0x1006, 0x20);
1822 
1823 	reg_w(gspca_dev, 0x10c0, i2c_init, 9);
1824 	if (gspca_dev->usb_err < 0) {
1825 		pr_err("Device initialization failed\n");
1826 		return gspca_dev->usb_err;
1827 	}
1828 
1829 	switch (sd->sensor) {
1830 	case SENSOR_OV9650:
1831 		ov9650_init_sensor(gspca_dev);
1832 		if (gspca_dev->usb_err < 0)
1833 			break;
1834 		pr_info("OV9650 sensor detected\n");
1835 		break;
1836 	case SENSOR_OV9655:
1837 		ov9655_init_sensor(gspca_dev);
1838 		if (gspca_dev->usb_err < 0)
1839 			break;
1840 		pr_info("OV9655 sensor detected\n");
1841 		break;
1842 	case SENSOR_SOI968:
1843 		soi968_init_sensor(gspca_dev);
1844 		if (gspca_dev->usb_err < 0)
1845 			break;
1846 		pr_info("SOI968 sensor detected\n");
1847 		break;
1848 	case SENSOR_OV7660:
1849 		ov7660_init_sensor(gspca_dev);
1850 		if (gspca_dev->usb_err < 0)
1851 			break;
1852 		pr_info("OV7660 sensor detected\n");
1853 		break;
1854 	case SENSOR_OV7670:
1855 		ov7670_init_sensor(gspca_dev);
1856 		if (gspca_dev->usb_err < 0)
1857 			break;
1858 		pr_info("OV7670 sensor detected\n");
1859 		break;
1860 	case SENSOR_MT9VPRB:
1861 		mt9v_init_sensor(gspca_dev);
1862 		if (gspca_dev->usb_err < 0)
1863 			break;
1864 		pr_info("MT9VPRB sensor detected\n");
1865 		break;
1866 	case SENSOR_MT9M111:
1867 		mt9m111_init_sensor(gspca_dev);
1868 		if (gspca_dev->usb_err < 0)
1869 			break;
1870 		pr_info("MT9M111 sensor detected\n");
1871 		break;
1872 	case SENSOR_MT9M112:
1873 		mt9m112_init_sensor(gspca_dev);
1874 		if (gspca_dev->usb_err < 0)
1875 			break;
1876 		pr_info("MT9M112 sensor detected\n");
1877 		break;
1878 	case SENSOR_MT9M001:
1879 		mt9m001_init_sensor(gspca_dev);
1880 		if (gspca_dev->usb_err < 0)
1881 			break;
1882 		break;
1883 	case SENSOR_HV7131R:
1884 		hv7131r_init_sensor(gspca_dev);
1885 		if (gspca_dev->usb_err < 0)
1886 			break;
1887 		pr_info("HV7131R sensor detected\n");
1888 		break;
1889 	default:
1890 		pr_err("Unsupported sensor\n");
1891 		gspca_dev->usb_err = -ENODEV;
1892 	}
1893 	return gspca_dev->usb_err;
1894 }
1895 
1896 static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
1897 {
1898 	struct sd *sd = (struct sd *) gspca_dev;
1899 	u8 value;
1900 
1901 	switch (sd->sensor) {
1902 	case SENSOR_SOI968:
1903 		if (mode & MODE_SXGA) {
1904 			i2c_w1(gspca_dev, 0x17, 0x1d);
1905 			i2c_w1(gspca_dev, 0x18, 0xbd);
1906 			i2c_w1(gspca_dev, 0x19, 0x01);
1907 			i2c_w1(gspca_dev, 0x1a, 0x81);
1908 			i2c_w1(gspca_dev, 0x12, 0x00);
1909 			sd->hstart = 140;
1910 			sd->vstart = 19;
1911 		} else {
1912 			i2c_w1(gspca_dev, 0x17, 0x13);
1913 			i2c_w1(gspca_dev, 0x18, 0x63);
1914 			i2c_w1(gspca_dev, 0x19, 0x01);
1915 			i2c_w1(gspca_dev, 0x1a, 0x79);
1916 			i2c_w1(gspca_dev, 0x12, 0x40);
1917 			sd->hstart = 60;
1918 			sd->vstart = 11;
1919 		}
1920 		break;
1921 	case SENSOR_OV9650:
1922 		if (mode & MODE_SXGA) {
1923 			i2c_w1(gspca_dev, 0x17, 0x1b);
1924 			i2c_w1(gspca_dev, 0x18, 0xbc);
1925 			i2c_w1(gspca_dev, 0x19, 0x01);
1926 			i2c_w1(gspca_dev, 0x1a, 0x82);
1927 			i2c_r1(gspca_dev, 0x12, &value);
1928 			i2c_w1(gspca_dev, 0x12, value & 0x07);
1929 		} else {
1930 			i2c_w1(gspca_dev, 0x17, 0x24);
1931 			i2c_w1(gspca_dev, 0x18, 0xc5);
1932 			i2c_w1(gspca_dev, 0x19, 0x00);
1933 			i2c_w1(gspca_dev, 0x1a, 0x3c);
1934 			i2c_r1(gspca_dev, 0x12, &value);
1935 			i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
1936 		}
1937 		break;
1938 	case SENSOR_MT9M112:
1939 	case SENSOR_MT9M111:
1940 		if (mode & MODE_SXGA) {
1941 			i2c_w2(gspca_dev, 0xf0, 0x0002);
1942 			i2c_w2(gspca_dev, 0xc8, 0x970b);
1943 			i2c_w2(gspca_dev, 0xf0, 0x0000);
1944 		} else {
1945 			i2c_w2(gspca_dev, 0xf0, 0x0002);
1946 			i2c_w2(gspca_dev, 0xc8, 0x8000);
1947 			i2c_w2(gspca_dev, 0xf0, 0x0000);
1948 		}
1949 		break;
1950 	}
1951 }
1952 
1953 static int sd_isoc_init(struct gspca_dev *gspca_dev)
1954 {
1955 	struct usb_interface *intf;
1956 	u32 flags = gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv;
1957 
1958 	/*
1959 	 * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth
1960 	 * than our regular bandwidth calculations reserve, so we force the
1961 	 * use of a specific altsetting when using the SN9C20X_I420 fmt.
1962 	 */
1963 	if (!(flags & (MODE_RAW | MODE_JPEG))) {
1964 		intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
1965 
1966 		if (intf->num_altsetting != 9) {
1967 			pr_warn("sn9c20x camera with unknown number of alt settings (%d), please report!\n",
1968 				intf->num_altsetting);
1969 			gspca_dev->alt = intf->num_altsetting;
1970 			return 0;
1971 		}
1972 
1973 		switch (gspca_dev->pixfmt.width) {
1974 		case 160: /* 160x120 */
1975 			gspca_dev->alt = 2;
1976 			break;
1977 		case 320: /* 320x240 */
1978 			gspca_dev->alt = 6;
1979 			break;
1980 		default:  /* >= 640x480 */
1981 			gspca_dev->alt = 9;
1982 			break;
1983 		}
1984 	}
1985 
1986 	return 0;
1987 }
1988 
1989 #define HW_WIN(mode, hstart, vstart) \
1990 ((const u8 []){hstart, 0, vstart, 0, \
1991 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
1992 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
1993 
1994 #define CLR_WIN(width, height) \
1995 ((const u8 [])\
1996 {0, width >> 2, 0, height >> 1,\
1997 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
1998 
1999 static int sd_start(struct gspca_dev *gspca_dev)
2000 {
2001 	struct sd *sd = (struct sd *) gspca_dev;
2002 	int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
2003 	int width = gspca_dev->pixfmt.width;
2004 	int height = gspca_dev->pixfmt.height;
2005 	u8 fmt, scale = 0;
2006 
2007 	jpeg_define(sd->jpeg_hdr, height, width,
2008 			0x21);
2009 	jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual));
2010 
2011 	if (mode & MODE_RAW)
2012 		fmt = 0x2d;
2013 	else if (mode & MODE_JPEG)
2014 		fmt = 0x24;
2015 	else
2016 		fmt = 0x2f;	/* YUV 420 */
2017 	sd->fmt = fmt;
2018 
2019 	switch (mode & SCALE_MASK) {
2020 	case SCALE_1280x1024:
2021 		scale = 0xc0;
2022 		pr_info("Set 1280x1024\n");
2023 		break;
2024 	case SCALE_640x480:
2025 		scale = 0x80;
2026 		pr_info("Set 640x480\n");
2027 		break;
2028 	case SCALE_320x240:
2029 		scale = 0x90;
2030 		pr_info("Set 320x240\n");
2031 		break;
2032 	case SCALE_160x120:
2033 		scale = 0xa0;
2034 		pr_info("Set 160x120\n");
2035 		break;
2036 	}
2037 
2038 	configure_sensor_output(gspca_dev, mode);
2039 	reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2040 	reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2041 	reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2042 	reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2043 	reg_w1(gspca_dev, 0x1189, scale);
2044 	reg_w1(gspca_dev, 0x10e0, fmt);
2045 
2046 	set_cmatrix(gspca_dev, v4l2_ctrl_g_ctrl(sd->brightness),
2047 			v4l2_ctrl_g_ctrl(sd->contrast),
2048 			v4l2_ctrl_g_ctrl(sd->saturation),
2049 			v4l2_ctrl_g_ctrl(sd->hue));
2050 	set_gamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma));
2051 	set_redblue(gspca_dev, v4l2_ctrl_g_ctrl(sd->blue),
2052 			v4l2_ctrl_g_ctrl(sd->red));
2053 	if (sd->gain)
2054 		set_gain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain));
2055 	if (sd->exposure)
2056 		set_exposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure));
2057 	if (sd->hflip)
2058 		set_hvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip),
2059 				v4l2_ctrl_g_ctrl(sd->vflip));
2060 
2061 	reg_w1(gspca_dev, 0x1007, 0x20);
2062 	reg_w1(gspca_dev, 0x1061, 0x03);
2063 
2064 	/* if JPEG, prepare the compression quality update */
2065 	if (mode & MODE_JPEG) {
2066 		sd->pktsz = sd->npkt = 0;
2067 		sd->nchg = 0;
2068 	}
2069 	if (sd->led_mode)
2070 		v4l2_ctrl_s_ctrl(sd->led_mode, 0);
2071 
2072 	return gspca_dev->usb_err;
2073 }
2074 
2075 static void sd_stopN(struct gspca_dev *gspca_dev)
2076 {
2077 	reg_w1(gspca_dev, 0x1007, 0x00);
2078 	reg_w1(gspca_dev, 0x1061, 0x01);
2079 }
2080 
2081 /* called on streamoff with alt==0 and on disconnect */
2082 /* the usb_lock is held at entry - restore on exit */
2083 static void sd_stop0(struct gspca_dev *gspca_dev)
2084 {
2085 	struct sd *sd = (struct sd *) gspca_dev;
2086 
2087 	mutex_unlock(&gspca_dev->usb_lock);
2088 	flush_work(&sd->work);
2089 	mutex_lock(&gspca_dev->usb_lock);
2090 }
2091 
2092 static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2093 {
2094 	struct sd *sd = (struct sd *) gspca_dev;
2095 	s32 cur_exp = v4l2_ctrl_g_ctrl(sd->exposure);
2096 	s32 max = sd->exposure->maximum - sd->exposure_step;
2097 	s32 min = sd->exposure->minimum + sd->exposure_step;
2098 	s16 new_exp;
2099 
2100 	/*
2101 	 * some hardcoded values are present
2102 	 * like those for maximal/minimal exposure
2103 	 * and exposure steps
2104 	 */
2105 	if (avg_lum < MIN_AVG_LUM) {
2106 		if (cur_exp > max)
2107 			return;
2108 
2109 		new_exp = cur_exp + sd->exposure_step;
2110 		if (new_exp > max)
2111 			new_exp = max;
2112 		if (new_exp < min)
2113 			new_exp = min;
2114 		v4l2_ctrl_s_ctrl(sd->exposure, new_exp);
2115 
2116 		sd->older_step = sd->old_step;
2117 		sd->old_step = 1;
2118 
2119 		if (sd->old_step ^ sd->older_step)
2120 			sd->exposure_step /= 2;
2121 		else
2122 			sd->exposure_step += 2;
2123 	}
2124 	if (avg_lum > MAX_AVG_LUM) {
2125 		if (cur_exp < min)
2126 			return;
2127 		new_exp = cur_exp - sd->exposure_step;
2128 		if (new_exp > max)
2129 			new_exp = max;
2130 		if (new_exp < min)
2131 			new_exp = min;
2132 		v4l2_ctrl_s_ctrl(sd->exposure, new_exp);
2133 		sd->older_step = sd->old_step;
2134 		sd->old_step = 0;
2135 
2136 		if (sd->old_step ^ sd->older_step)
2137 			sd->exposure_step /= 2;
2138 		else
2139 			sd->exposure_step += 2;
2140 	}
2141 }
2142 
2143 static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2144 {
2145 	struct sd *sd = (struct sd *) gspca_dev;
2146 	s32 cur_gain = v4l2_ctrl_g_ctrl(sd->gain);
2147 
2148 	if (avg_lum < MIN_AVG_LUM && cur_gain < sd->gain->maximum)
2149 		v4l2_ctrl_s_ctrl(sd->gain, cur_gain + 1);
2150 	if (avg_lum > MAX_AVG_LUM && cur_gain > sd->gain->minimum)
2151 		v4l2_ctrl_s_ctrl(sd->gain, cur_gain - 1);
2152 }
2153 
2154 static void sd_dqcallback(struct gspca_dev *gspca_dev)
2155 {
2156 	struct sd *sd = (struct sd *) gspca_dev;
2157 	int avg_lum;
2158 
2159 	if (sd->autogain == NULL || !v4l2_ctrl_g_ctrl(sd->autogain))
2160 		return;
2161 
2162 	avg_lum = atomic_read(&sd->avg_lum);
2163 	if (sd->sensor == SENSOR_SOI968)
2164 		do_autogain(gspca_dev, avg_lum);
2165 	else
2166 		do_autoexposure(gspca_dev, avg_lum);
2167 }
2168 
2169 /* JPEG quality update */
2170 /* This function is executed from a work queue. */
2171 static void qual_upd(struct work_struct *work)
2172 {
2173 	struct sd *sd = container_of(work, struct sd, work);
2174 	struct gspca_dev *gspca_dev = &sd->gspca_dev;
2175 	s32 qual = v4l2_ctrl_g_ctrl(sd->jpegqual);
2176 
2177 	/* To protect gspca_dev->usb_buf and gspca_dev->usb_err */
2178 	mutex_lock(&gspca_dev->usb_lock);
2179 	gspca_dbg(gspca_dev, D_STREAM, "qual_upd %d%%\n", qual);
2180 	gspca_dev->usb_err = 0;
2181 	set_quality(gspca_dev, qual);
2182 	mutex_unlock(&gspca_dev->usb_lock);
2183 }
2184 
2185 #if IS_ENABLED(CONFIG_INPUT)
2186 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2187 			u8 *data,		/* interrupt packet */
2188 			int len)		/* interrupt packet length */
2189 {
2190 	struct sd *sd = (struct sd *) gspca_dev;
2191 
2192 	if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
2193 		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2194 		input_sync(gspca_dev->input_dev);
2195 		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2196 		input_sync(gspca_dev->input_dev);
2197 		return 0;
2198 	}
2199 	return -EINVAL;
2200 }
2201 #endif
2202 
2203 /* check the JPEG compression */
2204 static void transfer_check(struct gspca_dev *gspca_dev,
2205 			u8 *data)
2206 {
2207 	struct sd *sd = (struct sd *) gspca_dev;
2208 	int new_qual, r;
2209 
2210 	new_qual = 0;
2211 
2212 	/* if USB error, discard the frame and decrease the quality */
2213 	if (data[6] & 0x08) {				/* USB FIFO full */
2214 		gspca_dev->last_packet_type = DISCARD_PACKET;
2215 		new_qual = -5;
2216 	} else {
2217 
2218 		/* else, compute the filling rate and a new JPEG quality */
2219 		r = (sd->pktsz * 100) /
2220 			(sd->npkt *
2221 				gspca_dev->urb[0]->iso_frame_desc[0].length);
2222 		if (r >= 85)
2223 			new_qual = -3;
2224 		else if (r < 75)
2225 			new_qual = 2;
2226 	}
2227 	if (new_qual != 0) {
2228 		sd->nchg += new_qual;
2229 		if (sd->nchg < -6 || sd->nchg >= 12) {
2230 			/* Note: we are in interrupt context, so we can't
2231 			   use v4l2_ctrl_g/s_ctrl here. Access the value
2232 			   directly instead. */
2233 			s32 curqual = sd->jpegqual->cur.val;
2234 			sd->nchg = 0;
2235 			new_qual += curqual;
2236 			if (new_qual < sd->jpegqual->minimum)
2237 				new_qual = sd->jpegqual->minimum;
2238 			else if (new_qual > sd->jpegqual->maximum)
2239 				new_qual = sd->jpegqual->maximum;
2240 			if (new_qual != curqual) {
2241 				sd->jpegqual->cur.val = new_qual;
2242 				schedule_work(&sd->work);
2243 			}
2244 		}
2245 	} else {
2246 		sd->nchg = 0;
2247 	}
2248 	sd->pktsz = sd->npkt = 0;
2249 }
2250 
2251 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2252 			u8 *data,			/* isoc packet */
2253 			int len)			/* iso packet length */
2254 {
2255 	struct sd *sd = (struct sd *) gspca_dev;
2256 	int avg_lum, is_jpeg;
2257 	static const u8 frame_header[] = {
2258 		0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96
2259 	};
2260 
2261 	is_jpeg = (sd->fmt & 0x03) == 0;
2262 	if (len >= 64 && memcmp(data, frame_header, 6) == 0) {
2263 		avg_lum = ((data[35] >> 2) & 3) |
2264 			   (data[20] << 2) |
2265 			   (data[19] << 10);
2266 		avg_lum += ((data[35] >> 4) & 3) |
2267 			    (data[22] << 2) |
2268 			    (data[21] << 10);
2269 		avg_lum += ((data[35] >> 6) & 3) |
2270 			    (data[24] << 2) |
2271 			    (data[23] << 10);
2272 		avg_lum += (data[36] & 3) |
2273 			   (data[26] << 2) |
2274 			   (data[25] << 10);
2275 		avg_lum += ((data[36] >> 2) & 3) |
2276 			    (data[28] << 2) |
2277 			    (data[27] << 10);
2278 		avg_lum += ((data[36] >> 4) & 3) |
2279 			    (data[30] << 2) |
2280 			    (data[29] << 10);
2281 		avg_lum += ((data[36] >> 6) & 3) |
2282 			    (data[32] << 2) |
2283 			    (data[31] << 10);
2284 		avg_lum += ((data[44] >> 4) & 3) |
2285 			    (data[34] << 2) |
2286 			    (data[33] << 10);
2287 		avg_lum >>= 9;
2288 		atomic_set(&sd->avg_lum, avg_lum);
2289 
2290 		if (is_jpeg)
2291 			transfer_check(gspca_dev, data);
2292 
2293 		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2294 		len -= 64;
2295 		if (len == 0)
2296 			return;
2297 		data += 64;
2298 	}
2299 	if (gspca_dev->last_packet_type == LAST_PACKET) {
2300 		if (is_jpeg) {
2301 			gspca_frame_add(gspca_dev, FIRST_PACKET,
2302 				sd->jpeg_hdr, JPEG_HDR_SZ);
2303 			gspca_frame_add(gspca_dev, INTER_PACKET,
2304 				data, len);
2305 		} else {
2306 			gspca_frame_add(gspca_dev, FIRST_PACKET,
2307 				data, len);
2308 		}
2309 	} else {
2310 		/* if JPEG, count the packets and their size */
2311 		if (is_jpeg) {
2312 			sd->npkt++;
2313 			sd->pktsz += len;
2314 		}
2315 		gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2316 	}
2317 }
2318 
2319 /* sub-driver description */
2320 static const struct sd_desc sd_desc = {
2321 	.name = KBUILD_MODNAME,
2322 	.config = sd_config,
2323 	.init = sd_init,
2324 	.init_controls = sd_init_controls,
2325 	.isoc_init = sd_isoc_init,
2326 	.start = sd_start,
2327 	.stopN = sd_stopN,
2328 	.stop0 = sd_stop0,
2329 	.pkt_scan = sd_pkt_scan,
2330 #if IS_ENABLED(CONFIG_INPUT)
2331 	.int_pkt_scan = sd_int_pkt_scan,
2332 #endif
2333 	.dq_callback = sd_dqcallback,
2334 #ifdef CONFIG_VIDEO_ADV_DEBUG
2335 	.set_register = sd_dbg_s_register,
2336 	.get_register = sd_dbg_g_register,
2337 	.get_chip_info = sd_chip_info,
2338 #endif
2339 };
2340 
2341 #define SN9C20X(sensor, i2c_addr, flags) \
2342 	.driver_info =  ((flags & 0xff) << 16) \
2343 			| (SENSOR_ ## sensor << 8) \
2344 			| (i2c_addr)
2345 
2346 static const struct usb_device_id device_table[] = {
2347 	{USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2348 	{USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, HAS_LED_TORCH)},
2349 	{USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2350 	{USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
2351 	{USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
2352 	{USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
2353 					     (FLIP_DETECT | HAS_NO_BUTTON))},
2354 	{USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2355 	{USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2356 	{USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2357 	{USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2358 	{USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, FLIP_DETECT)},
2359 	{USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2360 	{USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2361 	{USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2362 	{USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2363 	{USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
2364 	{USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
2365 	{USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2366 	{USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2367 	{USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2368 	{USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2369 	{USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, LED_REVERSE)},
2370 	{USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, LED_REVERSE)},
2371 	{USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2372 	{USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2373 	{USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2374 	{USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2375 	{USB_DEVICE(0x0458, 0x7045), SN9C20X(MT9M112, 0x5d, LED_REVERSE)},
2376 	{USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
2377 	{USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
2378 	{USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2379 	{USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2380 	{USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2381 	{USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2382 	{USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
2383 	{USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2384 	{USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2385 	{}
2386 };
2387 MODULE_DEVICE_TABLE(usb, device_table);
2388 
2389 /* -- device connect -- */
2390 static int sd_probe(struct usb_interface *intf,
2391 		    const struct usb_device_id *id)
2392 {
2393 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2394 				THIS_MODULE);
2395 }
2396 
2397 static struct usb_driver sd_driver = {
2398 	.name = KBUILD_MODNAME,
2399 	.id_table = device_table,
2400 	.probe = sd_probe,
2401 	.disconnect = gspca_disconnect,
2402 #ifdef CONFIG_PM
2403 	.suspend = gspca_suspend,
2404 	.resume = gspca_resume,
2405 	.reset_resume = gspca_resume,
2406 #endif
2407 };
2408 
2409 module_usb_driver(sd_driver);
2410