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