2 * Sonix sn9c201 sn9c202 library
4 * Copyright (C) 2012 Jean-Francois Moine <http://moinejf.free.fr>
5 * Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com>
6 * Copyright (C) 2009 Brian Johnson <brijohn@gmail.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25 #include <linux/input.h>
30 #include <linux/dmi.h>
32 MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, "
33 "microdia project <microdia@googlegroups.com>");
34 MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
35 MODULE_LICENSE("GPL");
38 * Pixel format private data
40 #define SCALE_MASK 0x0f
41 #define SCALE_160x120 0
42 #define SCALE_320x240 1
43 #define SCALE_640x480 2
44 #define SCALE_1280x1024 3
46 #define MODE_JPEG 0x20
47 #define MODE_SXGA 0x80
49 #define SENSOR_OV9650 0
50 #define SENSOR_OV9655 1
51 #define SENSOR_SOI968 2
52 #define SENSOR_OV7660 3
53 #define SENSOR_OV7670 4
54 #define SENSOR_MT9V011 5
55 #define SENSOR_MT9V111 6
56 #define SENSOR_MT9V112 7
57 #define SENSOR_MT9M001 8
58 #define SENSOR_MT9M111 9
59 #define SENSOR_MT9M112 10
60 #define SENSOR_HV7131R 11
61 #define SENSOR_MT9VPRB 12
64 #define HAS_NO_BUTTON 0x1
65 #define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
66 #define FLIP_DETECT 0x4
68 /* specific webcam descriptor */
70 struct gspca_dev gspca_dev;
72 struct { /* color control cluster */
73 struct v4l2_ctrl *brightness;
74 struct v4l2_ctrl *contrast;
75 struct v4l2_ctrl *saturation;
76 struct v4l2_ctrl *hue;
78 struct { /* blue/red balance control cluster */
79 struct v4l2_ctrl *blue;
80 struct v4l2_ctrl *red;
82 struct { /* h/vflip control cluster */
83 struct v4l2_ctrl *hflip;
84 struct v4l2_ctrl *vflip;
86 struct v4l2_ctrl *gamma;
87 struct { /* autogain and exposure or gain control cluster */
88 struct v4l2_ctrl *autogain;
89 struct v4l2_ctrl *exposure;
90 struct v4l2_ctrl *gain;
92 struct v4l2_ctrl *jpegqual;
94 struct work_struct work;
96 u32 pktsz; /* (used by pkt_scan) */
99 u8 fmt; /* (used for JPEG QTAB update */
101 #define MIN_AVG_LUM 80
102 #define MAX_AVG_LUM 130
114 u8 jpeg_hdr[JPEG_HDR_SZ];
119 static void qual_upd(struct work_struct *work);
131 static const struct dmi_system_id flip_dmi_table[] = {
133 .ident = "MSI MS-1034",
135 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
136 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1034"),
137 DMI_MATCH(DMI_PRODUCT_VERSION, "0341")
141 .ident = "MSI MS-1039",
143 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
144 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1039"),
148 .ident = "MSI MS-1632",
150 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
151 DMI_MATCH(DMI_BOARD_NAME, "MS-1632")
155 .ident = "MSI MS-1633X",
157 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
158 DMI_MATCH(DMI_BOARD_NAME, "MS-1633X")
162 .ident = "MSI MS-1635X",
164 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
165 DMI_MATCH(DMI_BOARD_NAME, "MS-1635X")
169 .ident = "ASUSTeK W7J",
171 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
172 DMI_MATCH(DMI_BOARD_NAME, "W7J ")
178 static const struct v4l2_pix_format vga_mode[] = {
179 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
181 .sizeimage = 160 * 120 * 4 / 8 + 590,
182 .colorspace = V4L2_COLORSPACE_JPEG,
183 .priv = SCALE_160x120 | MODE_JPEG},
184 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
186 .sizeimage = 160 * 120,
187 .colorspace = V4L2_COLORSPACE_SRGB,
188 .priv = SCALE_160x120 | MODE_RAW},
189 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
191 .sizeimage = 240 * 120,
192 .colorspace = V4L2_COLORSPACE_SRGB,
193 .priv = SCALE_160x120},
194 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
196 .sizeimage = 320 * 240 * 4 / 8 + 590,
197 .colorspace = V4L2_COLORSPACE_JPEG,
198 .priv = SCALE_320x240 | MODE_JPEG},
199 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
201 .sizeimage = 320 * 240 ,
202 .colorspace = V4L2_COLORSPACE_SRGB,
203 .priv = SCALE_320x240 | MODE_RAW},
204 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
206 .sizeimage = 480 * 240 ,
207 .colorspace = V4L2_COLORSPACE_SRGB,
208 .priv = SCALE_320x240},
209 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
211 .sizeimage = 640 * 480 * 4 / 8 + 590,
212 .colorspace = V4L2_COLORSPACE_JPEG,
213 .priv = SCALE_640x480 | MODE_JPEG},
214 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
216 .sizeimage = 640 * 480,
217 .colorspace = V4L2_COLORSPACE_SRGB,
218 .priv = SCALE_640x480 | MODE_RAW},
219 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
221 .sizeimage = 960 * 480,
222 .colorspace = V4L2_COLORSPACE_SRGB,
223 .priv = SCALE_640x480},
226 static const struct v4l2_pix_format sxga_mode[] = {
227 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
229 .sizeimage = 160 * 120 * 4 / 8 + 590,
230 .colorspace = V4L2_COLORSPACE_JPEG,
231 .priv = SCALE_160x120 | MODE_JPEG},
232 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
234 .sizeimage = 160 * 120,
235 .colorspace = V4L2_COLORSPACE_SRGB,
236 .priv = SCALE_160x120 | MODE_RAW},
237 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
239 .sizeimage = 240 * 120,
240 .colorspace = V4L2_COLORSPACE_SRGB,
241 .priv = SCALE_160x120},
242 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
244 .sizeimage = 320 * 240 * 4 / 8 + 590,
245 .colorspace = V4L2_COLORSPACE_JPEG,
246 .priv = SCALE_320x240 | MODE_JPEG},
247 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
249 .sizeimage = 320 * 240 ,
250 .colorspace = V4L2_COLORSPACE_SRGB,
251 .priv = SCALE_320x240 | MODE_RAW},
252 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
254 .sizeimage = 480 * 240 ,
255 .colorspace = V4L2_COLORSPACE_SRGB,
256 .priv = SCALE_320x240},
257 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
259 .sizeimage = 640 * 480 * 4 / 8 + 590,
260 .colorspace = V4L2_COLORSPACE_JPEG,
261 .priv = SCALE_640x480 | MODE_JPEG},
262 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
264 .sizeimage = 640 * 480,
265 .colorspace = V4L2_COLORSPACE_SRGB,
266 .priv = SCALE_640x480 | MODE_RAW},
267 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
269 .sizeimage = 960 * 480,
270 .colorspace = V4L2_COLORSPACE_SRGB,
271 .priv = SCALE_640x480},
272 {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
273 .bytesperline = 1280,
274 .sizeimage = 1280 * 1024,
275 .colorspace = V4L2_COLORSPACE_SRGB,
276 .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
279 static const struct v4l2_pix_format mono_mode[] = {
280 {160, 120, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
282 .sizeimage = 160 * 120,
283 .colorspace = V4L2_COLORSPACE_SRGB,
284 .priv = SCALE_160x120 | MODE_RAW},
285 {320, 240, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
287 .sizeimage = 320 * 240 ,
288 .colorspace = V4L2_COLORSPACE_SRGB,
289 .priv = SCALE_320x240 | MODE_RAW},
290 {640, 480, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
292 .sizeimage = 640 * 480,
293 .colorspace = V4L2_COLORSPACE_SRGB,
294 .priv = SCALE_640x480 | MODE_RAW},
295 {1280, 1024, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
296 .bytesperline = 1280,
297 .sizeimage = 1280 * 1024,
298 .colorspace = V4L2_COLORSPACE_SRGB,
299 .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
302 static const s16 hsv_red_x[] = {
303 41, 44, 46, 48, 50, 52, 54, 56,
304 58, 60, 62, 64, 66, 68, 70, 72,
305 74, 76, 78, 80, 81, 83, 85, 87,
306 88, 90, 92, 93, 95, 97, 98, 100,
307 101, 102, 104, 105, 107, 108, 109, 110,
308 112, 113, 114, 115, 116, 117, 118, 119,
309 120, 121, 122, 123, 123, 124, 125, 125,
310 126, 127, 127, 128, 128, 129, 129, 129,
311 130, 130, 130, 130, 131, 131, 131, 131,
312 131, 131, 131, 131, 130, 130, 130, 130,
313 129, 129, 129, 128, 128, 127, 127, 126,
314 125, 125, 124, 123, 122, 122, 121, 120,
315 119, 118, 117, 116, 115, 114, 112, 111,
316 110, 109, 107, 106, 105, 103, 102, 101,
317 99, 98, 96, 94, 93, 91, 90, 88,
318 86, 84, 83, 81, 79, 77, 75, 74,
319 72, 70, 68, 66, 64, 62, 60, 58,
320 56, 54, 52, 49, 47, 45, 43, 41,
321 39, 36, 34, 32, 30, 28, 25, 23,
322 21, 19, 16, 14, 12, 9, 7, 5,
323 3, 0, -1, -3, -6, -8, -10, -12,
324 -15, -17, -19, -22, -24, -26, -28, -30,
325 -33, -35, -37, -39, -41, -44, -46, -48,
326 -50, -52, -54, -56, -58, -60, -62, -64,
327 -66, -68, -70, -72, -74, -76, -78, -80,
328 -81, -83, -85, -87, -88, -90, -92, -93,
329 -95, -97, -98, -100, -101, -102, -104, -105,
330 -107, -108, -109, -110, -112, -113, -114, -115,
331 -116, -117, -118, -119, -120, -121, -122, -123,
332 -123, -124, -125, -125, -126, -127, -127, -128,
333 -128, -128, -128, -128, -128, -128, -128, -128,
334 -128, -128, -128, -128, -128, -128, -128, -128,
335 -128, -128, -128, -128, -128, -128, -128, -128,
336 -128, -127, -127, -126, -125, -125, -124, -123,
337 -122, -122, -121, -120, -119, -118, -117, -116,
338 -115, -114, -112, -111, -110, -109, -107, -106,
339 -105, -103, -102, -101, -99, -98, -96, -94,
340 -93, -91, -90, -88, -86, -84, -83, -81,
341 -79, -77, -75, -74, -72, -70, -68, -66,
342 -64, -62, -60, -58, -56, -54, -52, -49,
343 -47, -45, -43, -41, -39, -36, -34, -32,
344 -30, -28, -25, -23, -21, -19, -16, -14,
345 -12, -9, -7, -5, -3, 0, 1, 3,
346 6, 8, 10, 12, 15, 17, 19, 22,
347 24, 26, 28, 30, 33, 35, 37, 39, 41
350 static const s16 hsv_red_y[] = {
351 82, 80, 78, 76, 74, 73, 71, 69,
352 67, 65, 63, 61, 58, 56, 54, 52,
353 50, 48, 46, 44, 41, 39, 37, 35,
354 32, 30, 28, 26, 23, 21, 19, 16,
355 14, 12, 10, 7, 5, 3, 0, -1,
356 -3, -6, -8, -10, -13, -15, -17, -19,
357 -22, -24, -26, -29, -31, -33, -35, -38,
358 -40, -42, -44, -46, -48, -51, -53, -55,
359 -57, -59, -61, -63, -65, -67, -69, -71,
360 -73, -75, -77, -79, -81, -82, -84, -86,
361 -88, -89, -91, -93, -94, -96, -98, -99,
362 -101, -102, -104, -105, -106, -108, -109, -110,
363 -112, -113, -114, -115, -116, -117, -119, -120,
364 -120, -121, -122, -123, -124, -125, -126, -126,
365 -127, -128, -128, -128, -128, -128, -128, -128,
366 -128, -128, -128, -128, -128, -128, -128, -128,
367 -128, -128, -128, -128, -128, -128, -128, -128,
368 -128, -128, -128, -128, -128, -128, -128, -128,
369 -127, -127, -126, -125, -125, -124, -123, -122,
370 -121, -120, -119, -118, -117, -116, -115, -114,
371 -113, -111, -110, -109, -107, -106, -105, -103,
372 -102, -100, -99, -97, -96, -94, -92, -91,
373 -89, -87, -85, -84, -82, -80, -78, -76,
374 -74, -73, -71, -69, -67, -65, -63, -61,
375 -58, -56, -54, -52, -50, -48, -46, -44,
376 -41, -39, -37, -35, -32, -30, -28, -26,
377 -23, -21, -19, -16, -14, -12, -10, -7,
378 -5, -3, 0, 1, 3, 6, 8, 10,
379 13, 15, 17, 19, 22, 24, 26, 29,
380 31, 33, 35, 38, 40, 42, 44, 46,
381 48, 51, 53, 55, 57, 59, 61, 63,
382 65, 67, 69, 71, 73, 75, 77, 79,
383 81, 82, 84, 86, 88, 89, 91, 93,
384 94, 96, 98, 99, 101, 102, 104, 105,
385 106, 108, 109, 110, 112, 113, 114, 115,
386 116, 117, 119, 120, 120, 121, 122, 123,
387 124, 125, 126, 126, 127, 128, 128, 129,
388 129, 130, 130, 131, 131, 131, 131, 132,
389 132, 132, 132, 132, 132, 132, 132, 132,
390 132, 132, 132, 131, 131, 131, 130, 130,
391 130, 129, 129, 128, 127, 127, 126, 125,
392 125, 124, 123, 122, 121, 120, 119, 118,
393 117, 116, 115, 114, 113, 111, 110, 109,
394 107, 106, 105, 103, 102, 100, 99, 97,
395 96, 94, 92, 91, 89, 87, 85, 84, 82
398 static const s16 hsv_green_x[] = {
399 -124, -124, -125, -125, -125, -125, -125, -125,
400 -125, -126, -126, -125, -125, -125, -125, -125,
401 -125, -124, -124, -124, -123, -123, -122, -122,
402 -121, -121, -120, -120, -119, -118, -117, -117,
403 -116, -115, -114, -113, -112, -111, -110, -109,
404 -108, -107, -105, -104, -103, -102, -100, -99,
405 -98, -96, -95, -93, -92, -91, -89, -87,
406 -86, -84, -83, -81, -79, -77, -76, -74,
407 -72, -70, -69, -67, -65, -63, -61, -59,
408 -57, -55, -53, -51, -49, -47, -45, -43,
409 -41, -39, -37, -35, -33, -30, -28, -26,
410 -24, -22, -20, -18, -15, -13, -11, -9,
411 -7, -4, -2, 0, 1, 3, 6, 8,
412 10, 12, 14, 17, 19, 21, 23, 25,
413 27, 29, 32, 34, 36, 38, 40, 42,
414 44, 46, 48, 50, 52, 54, 56, 58,
415 60, 62, 64, 66, 68, 70, 71, 73,
416 75, 77, 78, 80, 82, 83, 85, 87,
417 88, 90, 91, 93, 94, 96, 97, 98,
418 100, 101, 102, 104, 105, 106, 107, 108,
419 109, 111, 112, 113, 113, 114, 115, 116,
420 117, 118, 118, 119, 120, 120, 121, 122,
421 122, 123, 123, 124, 124, 124, 125, 125,
422 125, 125, 125, 125, 125, 126, 126, 125,
423 125, 125, 125, 125, 125, 124, 124, 124,
424 123, 123, 122, 122, 121, 121, 120, 120,
425 119, 118, 117, 117, 116, 115, 114, 113,
426 112, 111, 110, 109, 108, 107, 105, 104,
427 103, 102, 100, 99, 98, 96, 95, 93,
428 92, 91, 89, 87, 86, 84, 83, 81,
429 79, 77, 76, 74, 72, 70, 69, 67,
430 65, 63, 61, 59, 57, 55, 53, 51,
431 49, 47, 45, 43, 41, 39, 37, 35,
432 33, 30, 28, 26, 24, 22, 20, 18,
433 15, 13, 11, 9, 7, 4, 2, 0,
434 -1, -3, -6, -8, -10, -12, -14, -17,
435 -19, -21, -23, -25, -27, -29, -32, -34,
436 -36, -38, -40, -42, -44, -46, -48, -50,
437 -52, -54, -56, -58, -60, -62, -64, -66,
438 -68, -70, -71, -73, -75, -77, -78, -80,
439 -82, -83, -85, -87, -88, -90, -91, -93,
440 -94, -96, -97, -98, -100, -101, -102, -104,
441 -105, -106, -107, -108, -109, -111, -112, -113,
442 -113, -114, -115, -116, -117, -118, -118, -119,
443 -120, -120, -121, -122, -122, -123, -123, -124, -124
446 static const s16 hsv_green_y[] = {
447 -100, -99, -98, -97, -95, -94, -93, -91,
448 -90, -89, -87, -86, -84, -83, -81, -80,
449 -78, -76, -75, -73, -71, -70, -68, -66,
450 -64, -63, -61, -59, -57, -55, -53, -51,
451 -49, -48, -46, -44, -42, -40, -38, -36,
452 -34, -32, -30, -27, -25, -23, -21, -19,
453 -17, -15, -13, -11, -9, -7, -4, -2,
454 0, 1, 3, 5, 7, 9, 11, 14,
455 16, 18, 20, 22, 24, 26, 28, 30,
456 32, 34, 36, 38, 40, 42, 44, 46,
457 48, 50, 52, 54, 56, 58, 59, 61,
458 63, 65, 67, 68, 70, 72, 74, 75,
459 77, 78, 80, 82, 83, 85, 86, 88,
460 89, 90, 92, 93, 95, 96, 97, 98,
461 100, 101, 102, 103, 104, 105, 106, 107,
462 108, 109, 110, 111, 112, 112, 113, 114,
463 115, 115, 116, 116, 117, 117, 118, 118,
464 119, 119, 119, 120, 120, 120, 120, 120,
465 121, 121, 121, 121, 121, 121, 120, 120,
466 120, 120, 120, 119, 119, 119, 118, 118,
467 117, 117, 116, 116, 115, 114, 114, 113,
468 112, 111, 111, 110, 109, 108, 107, 106,
469 105, 104, 103, 102, 100, 99, 98, 97,
470 95, 94, 93, 91, 90, 89, 87, 86,
471 84, 83, 81, 80, 78, 76, 75, 73,
472 71, 70, 68, 66, 64, 63, 61, 59,
473 57, 55, 53, 51, 49, 48, 46, 44,
474 42, 40, 38, 36, 34, 32, 30, 27,
475 25, 23, 21, 19, 17, 15, 13, 11,
476 9, 7, 4, 2, 0, -1, -3, -5,
477 -7, -9, -11, -14, -16, -18, -20, -22,
478 -24, -26, -28, -30, -32, -34, -36, -38,
479 -40, -42, -44, -46, -48, -50, -52, -54,
480 -56, -58, -59, -61, -63, -65, -67, -68,
481 -70, -72, -74, -75, -77, -78, -80, -82,
482 -83, -85, -86, -88, -89, -90, -92, -93,
483 -95, -96, -97, -98, -100, -101, -102, -103,
484 -104, -105, -106, -107, -108, -109, -110, -111,
485 -112, -112, -113, -114, -115, -115, -116, -116,
486 -117, -117, -118, -118, -119, -119, -119, -120,
487 -120, -120, -120, -120, -121, -121, -121, -121,
488 -121, -121, -120, -120, -120, -120, -120, -119,
489 -119, -119, -118, -118, -117, -117, -116, -116,
490 -115, -114, -114, -113, -112, -111, -111, -110,
491 -109, -108, -107, -106, -105, -104, -103, -102, -100
494 static const s16 hsv_blue_x[] = {
495 112, 113, 114, 114, 115, 116, 117, 117,
496 118, 118, 119, 119, 120, 120, 120, 121,
497 121, 121, 122, 122, 122, 122, 122, 122,
498 122, 122, 122, 122, 122, 122, 121, 121,
499 121, 120, 120, 120, 119, 119, 118, 118,
500 117, 116, 116, 115, 114, 113, 113, 112,
501 111, 110, 109, 108, 107, 106, 105, 104,
502 103, 102, 100, 99, 98, 97, 95, 94,
503 93, 91, 90, 88, 87, 85, 84, 82,
504 80, 79, 77, 76, 74, 72, 70, 69,
505 67, 65, 63, 61, 60, 58, 56, 54,
506 52, 50, 48, 46, 44, 42, 40, 38,
507 36, 34, 32, 30, 28, 26, 24, 22,
508 19, 17, 15, 13, 11, 9, 7, 5,
509 2, 0, -1, -3, -5, -7, -9, -12,
510 -14, -16, -18, -20, -22, -24, -26, -28,
511 -31, -33, -35, -37, -39, -41, -43, -45,
512 -47, -49, -51, -53, -54, -56, -58, -60,
513 -62, -64, -66, -67, -69, -71, -73, -74,
514 -76, -78, -79, -81, -83, -84, -86, -87,
515 -89, -90, -92, -93, -94, -96, -97, -98,
516 -99, -101, -102, -103, -104, -105, -106, -107,
517 -108, -109, -110, -111, -112, -113, -114, -114,
518 -115, -116, -117, -117, -118, -118, -119, -119,
519 -120, -120, -120, -121, -121, -121, -122, -122,
520 -122, -122, -122, -122, -122, -122, -122, -122,
521 -122, -122, -121, -121, -121, -120, -120, -120,
522 -119, -119, -118, -118, -117, -116, -116, -115,
523 -114, -113, -113, -112, -111, -110, -109, -108,
524 -107, -106, -105, -104, -103, -102, -100, -99,
525 -98, -97, -95, -94, -93, -91, -90, -88,
526 -87, -85, -84, -82, -80, -79, -77, -76,
527 -74, -72, -70, -69, -67, -65, -63, -61,
528 -60, -58, -56, -54, -52, -50, -48, -46,
529 -44, -42, -40, -38, -36, -34, -32, -30,
530 -28, -26, -24, -22, -19, -17, -15, -13,
531 -11, -9, -7, -5, -2, 0, 1, 3,
532 5, 7, 9, 12, 14, 16, 18, 20,
533 22, 24, 26, 28, 31, 33, 35, 37,
534 39, 41, 43, 45, 47, 49, 51, 53,
535 54, 56, 58, 60, 62, 64, 66, 67,
536 69, 71, 73, 74, 76, 78, 79, 81,
537 83, 84, 86, 87, 89, 90, 92, 93,
538 94, 96, 97, 98, 99, 101, 102, 103,
539 104, 105, 106, 107, 108, 109, 110, 111, 112
542 static const s16 hsv_blue_y[] = {
543 -11, -13, -15, -17, -19, -21, -23, -25,
544 -27, -29, -31, -33, -35, -37, -39, -41,
545 -43, -45, -46, -48, -50, -52, -54, -55,
546 -57, -59, -61, -62, -64, -66, -67, -69,
547 -71, -72, -74, -75, -77, -78, -80, -81,
548 -83, -84, -86, -87, -88, -90, -91, -92,
549 -93, -95, -96, -97, -98, -99, -100, -101,
550 -102, -103, -104, -105, -106, -106, -107, -108,
551 -109, -109, -110, -111, -111, -112, -112, -113,
552 -113, -114, -114, -114, -115, -115, -115, -115,
553 -116, -116, -116, -116, -116, -116, -116, -116,
554 -116, -115, -115, -115, -115, -114, -114, -114,
555 -113, -113, -112, -112, -111, -111, -110, -110,
556 -109, -108, -108, -107, -106, -105, -104, -103,
557 -102, -101, -100, -99, -98, -97, -96, -95,
558 -94, -93, -91, -90, -89, -88, -86, -85,
559 -84, -82, -81, -79, -78, -76, -75, -73,
560 -71, -70, -68, -67, -65, -63, -62, -60,
561 -58, -56, -55, -53, -51, -49, -47, -45,
562 -44, -42, -40, -38, -36, -34, -32, -30,
563 -28, -26, -24, -22, -20, -18, -16, -14,
564 -12, -10, -8, -6, -4, -2, 0, 1,
565 3, 5, 7, 9, 11, 13, 15, 17,
566 19, 21, 23, 25, 27, 29, 31, 33,
567 35, 37, 39, 41, 43, 45, 46, 48,
568 50, 52, 54, 55, 57, 59, 61, 62,
569 64, 66, 67, 69, 71, 72, 74, 75,
570 77, 78, 80, 81, 83, 84, 86, 87,
571 88, 90, 91, 92, 93, 95, 96, 97,
572 98, 99, 100, 101, 102, 103, 104, 105,
573 106, 106, 107, 108, 109, 109, 110, 111,
574 111, 112, 112, 113, 113, 114, 114, 114,
575 115, 115, 115, 115, 116, 116, 116, 116,
576 116, 116, 116, 116, 116, 115, 115, 115,
577 115, 114, 114, 114, 113, 113, 112, 112,
578 111, 111, 110, 110, 109, 108, 108, 107,
579 106, 105, 104, 103, 102, 101, 100, 99,
580 98, 97, 96, 95, 94, 93, 91, 90,
581 89, 88, 86, 85, 84, 82, 81, 79,
582 78, 76, 75, 73, 71, 70, 68, 67,
583 65, 63, 62, 60, 58, 56, 55, 53,
584 51, 49, 47, 45, 44, 42, 40, 38,
585 36, 34, 32, 30, 28, 26, 24, 22,
586 20, 18, 16, 14, 12, 10, 8, 6,
587 4, 2, 0, -1, -3, -5, -7, -9, -11
590 static const u16 bridge_init[][2] = {
591 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
592 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
593 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
594 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
595 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
596 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
597 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
598 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
599 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
600 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
601 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
602 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
603 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
604 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
605 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
606 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
607 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
608 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
609 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
613 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
614 static const u8 ov_gain[] = {
615 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
616 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
617 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
618 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
619 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
620 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
621 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
625 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
626 static const u16 micron1_gain[] = {
627 /* 1x 1.25x 1.5x 1.75x */
628 0x0020, 0x0028, 0x0030, 0x0038,
629 /* 2x 2.25x 2.5x 2.75x */
630 0x00a0, 0x00a4, 0x00a8, 0x00ac,
631 /* 3x 3.25x 3.5x 3.75x */
632 0x00b0, 0x00b4, 0x00b8, 0x00bc,
633 /* 4x 4.25x 4.5x 4.75x */
634 0x00c0, 0x00c4, 0x00c8, 0x00cc,
635 /* 5x 5.25x 5.5x 5.75x */
636 0x00d0, 0x00d4, 0x00d8, 0x00dc,
637 /* 6x 6.25x 6.5x 6.75x */
638 0x00e0, 0x00e4, 0x00e8, 0x00ec,
639 /* 7x 7.25x 7.5x 7.75x */
640 0x00f0, 0x00f4, 0x00f8, 0x00fc,
645 /* mt9m001 sensor uses a different gain formula then other micron sensors */
646 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
647 static const u16 micron2_gain[] = {
648 /* 1x 1.25x 1.5x 1.75x */
649 0x0008, 0x000a, 0x000c, 0x000e,
650 /* 2x 2.25x 2.5x 2.75x */
651 0x0010, 0x0012, 0x0014, 0x0016,
652 /* 3x 3.25x 3.5x 3.75x */
653 0x0018, 0x001a, 0x001c, 0x001e,
654 /* 4x 4.25x 4.5x 4.75x */
655 0x0020, 0x0051, 0x0052, 0x0053,
656 /* 5x 5.25x 5.5x 5.75x */
657 0x0054, 0x0055, 0x0056, 0x0057,
658 /* 6x 6.25x 6.5x 6.75x */
659 0x0058, 0x0059, 0x005a, 0x005b,
660 /* 7x 7.25x 7.5x 7.75x */
661 0x005c, 0x005d, 0x005e, 0x005f,
666 /* Gain = .5 + bit[7:0] / 16 */
667 static const u8 hv7131r_gain[] = {
668 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
669 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
670 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
671 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
672 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
673 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
674 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
678 static const struct i2c_reg_u8 soi968_init[] = {
679 {0x0c, 0x00}, {0x0f, 0x1f},
680 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
681 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
682 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
683 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
684 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
685 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
686 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
687 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
688 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
689 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
692 static const struct i2c_reg_u8 ov7660_init[] = {
693 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
694 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
695 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
696 /* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using
697 0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
698 {0x17, 0x10}, {0x18, 0x61},
699 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
700 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0x00},
701 {0x2e, 0x00}, {0x01, 0x78}, {0x02, 0x50},
704 static const struct i2c_reg_u8 ov7670_init[] = {
705 {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
706 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
707 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
708 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
709 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
710 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
711 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
712 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
713 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
714 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
715 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
716 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
717 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
718 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
719 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
720 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
721 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
722 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
723 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
724 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
725 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
726 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
727 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
728 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
729 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
730 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
731 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
732 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
733 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
734 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
735 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
736 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
737 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
738 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
739 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
740 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
741 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
742 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
743 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
744 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
745 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
746 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
747 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
748 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
749 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
750 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
751 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
752 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
753 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
754 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
755 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
756 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
757 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
761 static const struct i2c_reg_u8 ov9650_init[] = {
762 {0x00, 0x00}, {0x01, 0x78},
763 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
764 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
765 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
766 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
767 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
768 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
769 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
770 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
771 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
772 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
773 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
774 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
775 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
776 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
777 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
778 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
779 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
780 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
781 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
782 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
783 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
784 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
785 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
786 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
787 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
788 {0xaa, 0x92}, {0xab, 0x0a},
791 static const struct i2c_reg_u8 ov9655_init[] = {
792 {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
793 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
794 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
795 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
796 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
797 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
798 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
799 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
800 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
801 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
802 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
803 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
804 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
805 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
806 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
807 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
808 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
809 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
810 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
811 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
812 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
813 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
814 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
815 {0x04, 0x03}, {0x00, 0x13},
818 static const struct i2c_reg_u16 mt9v112_init[] = {
819 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
820 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
821 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
822 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
823 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
824 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
825 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
826 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
827 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
828 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
829 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
830 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
831 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
832 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
833 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
834 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
837 static const struct i2c_reg_u16 mt9v111_init[] = {
838 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
839 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
840 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
841 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
842 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
843 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
844 {0x0e, 0x0008}, {0x20, 0x0000}
847 static const struct i2c_reg_u16 mt9v011_init[] = {
848 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
849 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
850 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
851 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
852 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
853 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
854 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
855 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
856 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
857 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
858 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
859 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
860 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
861 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
862 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
863 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
864 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
865 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
866 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
867 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
868 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
869 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
870 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
871 {0x06, 0x0029}, {0x05, 0x0009},
874 static const struct i2c_reg_u16 mt9m001_init[] = {
877 {0x04, 0x0500}, /* hres = 1280 */
878 {0x03, 0x0400}, /* vres = 1024 */
890 static const struct i2c_reg_u16 mt9m111_init[] = {
891 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
892 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
893 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
897 static const struct i2c_reg_u16 mt9m112_init[] = {
898 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
899 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
900 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
904 static const struct i2c_reg_u8 hv7131r_init[] = {
905 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
906 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
907 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
908 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
909 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
910 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
911 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
912 {0x23, 0x09}, {0x01, 0x08},
915 static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
917 struct usb_device *dev = gspca_dev->dev;
920 if (gspca_dev->usb_err < 0)
922 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
924 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
930 if (unlikely(result < 0 || result != length)) {
931 pr_err("Read register %02x failed %d\n", reg, result);
932 gspca_dev->usb_err = result;
934 * Make sure the buffer is zeroed to avoid uninitialized
937 memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
941 static void reg_w(struct gspca_dev *gspca_dev, u16 reg,
942 const u8 *buffer, int length)
944 struct usb_device *dev = gspca_dev->dev;
947 if (gspca_dev->usb_err < 0)
949 memcpy(gspca_dev->usb_buf, buffer, length);
950 result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
952 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
958 if (unlikely(result < 0 || result != length)) {
959 pr_err("Write register %02x failed %d\n", reg, result);
960 gspca_dev->usb_err = result;
964 static void reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
966 reg_w(gspca_dev, reg, &value, 1);
969 static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
973 reg_w(gspca_dev, 0x10c0, buffer, 8);
974 for (i = 0; i < 5; i++) {
975 reg_r(gspca_dev, 0x10c0, 1);
976 if (gspca_dev->usb_err < 0)
978 if (gspca_dev->usb_buf[0] & 0x04) {
979 if (gspca_dev->usb_buf[0] & 0x08) {
980 pr_err("i2c_w error\n");
981 gspca_dev->usb_err = -EIO;
987 pr_err("i2c_w reg %02x no response\n", buffer[2]);
988 /* gspca_dev->usb_err = -EIO; fixme: may occur */
991 static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
993 struct sd *sd = (struct sd *) gspca_dev;
997 * from the point of view of the bridge, the length
998 * includes the address
1000 row[0] = sd->i2c_intf | (2 << 4);
1001 row[1] = sd->i2c_addr;
1009 i2c_w(gspca_dev, row);
1012 static void i2c_w1_buf(struct gspca_dev *gspca_dev,
1013 const struct i2c_reg_u8 *buf, int sz)
1016 i2c_w1(gspca_dev, buf->reg, buf->val);
1021 static void i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1023 struct sd *sd = (struct sd *) gspca_dev;
1027 * from the point of view of the bridge, the length
1028 * includes the address
1030 row[0] = sd->i2c_intf | (3 << 4);
1031 row[1] = sd->i2c_addr;
1039 i2c_w(gspca_dev, row);
1042 static void i2c_w2_buf(struct gspca_dev *gspca_dev,
1043 const struct i2c_reg_u16 *buf, int sz)
1046 i2c_w2(gspca_dev, buf->reg, buf->val);
1051 static void i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1053 struct sd *sd = (struct sd *) gspca_dev;
1056 row[0] = sd->i2c_intf | (1 << 4);
1057 row[1] = sd->i2c_addr;
1064 i2c_w(gspca_dev, row);
1065 row[0] = sd->i2c_intf | (1 << 4) | 0x02;
1067 i2c_w(gspca_dev, row);
1068 reg_r(gspca_dev, 0x10c2, 5);
1069 *val = gspca_dev->usb_buf[4];
1072 static void i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1074 struct sd *sd = (struct sd *) gspca_dev;
1077 row[0] = sd->i2c_intf | (1 << 4);
1078 row[1] = sd->i2c_addr;
1085 i2c_w(gspca_dev, row);
1086 row[0] = sd->i2c_intf | (2 << 4) | 0x02;
1088 i2c_w(gspca_dev, row);
1089 reg_r(gspca_dev, 0x10c2, 5);
1090 *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1093 static void ov9650_init_sensor(struct gspca_dev *gspca_dev)
1096 struct sd *sd = (struct sd *) gspca_dev;
1098 i2c_r2(gspca_dev, 0x1c, &id);
1099 if (gspca_dev->usb_err < 0)
1103 pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id);
1104 gspca_dev->usb_err = -ENODEV;
1108 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1110 i2c_w1_buf(gspca_dev, ov9650_init, ARRAY_SIZE(ov9650_init));
1111 if (gspca_dev->usb_err < 0)
1112 pr_err("OV9650 sensor initialization failed\n");
1117 static void ov9655_init_sensor(struct gspca_dev *gspca_dev)
1119 struct sd *sd = (struct sd *) gspca_dev;
1121 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1123 i2c_w1_buf(gspca_dev, ov9655_init, ARRAY_SIZE(ov9655_init));
1124 if (gspca_dev->usb_err < 0)
1125 pr_err("OV9655 sensor initialization failed\n");
1131 static void soi968_init_sensor(struct gspca_dev *gspca_dev)
1133 struct sd *sd = (struct sd *) gspca_dev;
1135 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1137 i2c_w1_buf(gspca_dev, soi968_init, ARRAY_SIZE(soi968_init));
1138 if (gspca_dev->usb_err < 0)
1139 pr_err("SOI968 sensor initialization failed\n");
1145 static void ov7660_init_sensor(struct gspca_dev *gspca_dev)
1147 struct sd *sd = (struct sd *) gspca_dev;
1149 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1151 i2c_w1_buf(gspca_dev, ov7660_init, ARRAY_SIZE(ov7660_init));
1152 if (gspca_dev->usb_err < 0)
1153 pr_err("OV7660 sensor initialization failed\n");
1158 static void ov7670_init_sensor(struct gspca_dev *gspca_dev)
1160 struct sd *sd = (struct sd *) gspca_dev;
1162 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1164 i2c_w1_buf(gspca_dev, ov7670_init, ARRAY_SIZE(ov7670_init));
1165 if (gspca_dev->usb_err < 0)
1166 pr_err("OV7670 sensor initialization failed\n");
1172 static void mt9v_init_sensor(struct gspca_dev *gspca_dev)
1174 struct sd *sd = (struct sd *) gspca_dev;
1177 sd->i2c_addr = 0x5d;
1178 i2c_r2(gspca_dev, 0xff, &value);
1179 if (gspca_dev->usb_err >= 0
1180 && value == 0x8243) {
1181 i2c_w2_buf(gspca_dev, mt9v011_init, ARRAY_SIZE(mt9v011_init));
1182 if (gspca_dev->usb_err < 0) {
1183 pr_err("MT9V011 sensor initialization failed\n");
1188 sd->sensor = SENSOR_MT9V011;
1189 pr_info("MT9V011 sensor detected\n");
1193 gspca_dev->usb_err = 0;
1194 sd->i2c_addr = 0x5c;
1195 i2c_w2(gspca_dev, 0x01, 0x0004);
1196 i2c_r2(gspca_dev, 0xff, &value);
1197 if (gspca_dev->usb_err >= 0
1198 && value == 0x823a) {
1199 i2c_w2_buf(gspca_dev, mt9v111_init, ARRAY_SIZE(mt9v111_init));
1200 if (gspca_dev->usb_err < 0) {
1201 pr_err("MT9V111 sensor initialization failed\n");
1206 sd->sensor = SENSOR_MT9V111;
1207 pr_info("MT9V111 sensor detected\n");
1211 gspca_dev->usb_err = 0;
1212 sd->i2c_addr = 0x5d;
1213 i2c_w2(gspca_dev, 0xf0, 0x0000);
1214 if (gspca_dev->usb_err < 0) {
1215 gspca_dev->usb_err = 0;
1216 sd->i2c_addr = 0x48;
1217 i2c_w2(gspca_dev, 0xf0, 0x0000);
1219 i2c_r2(gspca_dev, 0x00, &value);
1220 if (gspca_dev->usb_err >= 0
1221 && value == 0x1229) {
1222 i2c_w2_buf(gspca_dev, mt9v112_init, ARRAY_SIZE(mt9v112_init));
1223 if (gspca_dev->usb_err < 0) {
1224 pr_err("MT9V112 sensor initialization failed\n");
1229 sd->sensor = SENSOR_MT9V112;
1230 pr_info("MT9V112 sensor detected\n");
1234 gspca_dev->usb_err = -ENODEV;
1237 static void mt9m112_init_sensor(struct gspca_dev *gspca_dev)
1239 struct sd *sd = (struct sd *) gspca_dev;
1241 i2c_w2_buf(gspca_dev, mt9m112_init, ARRAY_SIZE(mt9m112_init));
1242 if (gspca_dev->usb_err < 0)
1243 pr_err("MT9M112 sensor initialization failed\n");
1249 static void mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1251 struct sd *sd = (struct sd *) gspca_dev;
1253 i2c_w2_buf(gspca_dev, mt9m111_init, ARRAY_SIZE(mt9m111_init));
1254 if (gspca_dev->usb_err < 0)
1255 pr_err("MT9M111 sensor initialization failed\n");
1261 static void mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1263 struct sd *sd = (struct sd *) gspca_dev;
1266 i2c_r2(gspca_dev, 0x00, &id);
1267 if (gspca_dev->usb_err < 0)
1270 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
1274 pr_info("MT9M001 color sensor detected\n");
1277 pr_info("MT9M001 mono sensor detected\n");
1280 pr_err("No MT9M001 chip detected, ID = %x\n\n", id);
1281 gspca_dev->usb_err = -ENODEV;
1285 i2c_w2_buf(gspca_dev, mt9m001_init, ARRAY_SIZE(mt9m001_init));
1286 if (gspca_dev->usb_err < 0)
1287 pr_err("MT9M001 sensor initialization failed\n");
1293 static void hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1295 struct sd *sd = (struct sd *) gspca_dev;
1297 i2c_w1_buf(gspca_dev, hv7131r_init, ARRAY_SIZE(hv7131r_init));
1298 if (gspca_dev->usb_err < 0)
1299 pr_err("HV7131R Sensor initialization failed\n");
1305 static void set_cmatrix(struct gspca_dev *gspca_dev,
1306 s32 brightness, s32 contrast, s32 satur, s32 hue)
1308 s32 hue_coord, hue_index = 180 + hue;
1311 memset(cmatrix, 0, sizeof(cmatrix));
1312 cmatrix[2] = (contrast * 0x25 / 0x100) + 0x26;
1313 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1314 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1315 cmatrix[18] = brightness - 0x80;
1317 hue_coord = (hsv_red_x[hue_index] * satur) >> 8;
1318 cmatrix[6] = hue_coord;
1319 cmatrix[7] = (hue_coord >> 8) & 0x0f;
1321 hue_coord = (hsv_red_y[hue_index] * satur) >> 8;
1322 cmatrix[8] = hue_coord;
1323 cmatrix[9] = (hue_coord >> 8) & 0x0f;
1325 hue_coord = (hsv_green_x[hue_index] * satur) >> 8;
1326 cmatrix[10] = hue_coord;
1327 cmatrix[11] = (hue_coord >> 8) & 0x0f;
1329 hue_coord = (hsv_green_y[hue_index] * satur) >> 8;
1330 cmatrix[12] = hue_coord;
1331 cmatrix[13] = (hue_coord >> 8) & 0x0f;
1333 hue_coord = (hsv_blue_x[hue_index] * satur) >> 8;
1334 cmatrix[14] = hue_coord;
1335 cmatrix[15] = (hue_coord >> 8) & 0x0f;
1337 hue_coord = (hsv_blue_y[hue_index] * satur) >> 8;
1338 cmatrix[16] = hue_coord;
1339 cmatrix[17] = (hue_coord >> 8) & 0x0f;
1341 reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1344 static void set_gamma(struct gspca_dev *gspca_dev, s32 val)
1347 u8 gval = val * 0xb8 / 0x100;
1350 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
1351 gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8);
1352 gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8);
1353 gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8);
1354 gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8);
1355 gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8);
1356 gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8);
1357 gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8);
1358 gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8);
1359 gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8);
1360 gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8);
1361 gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8);
1362 gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8);
1363 gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8);
1364 gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
1367 reg_w(gspca_dev, 0x1190, gamma, 17);
1370 static void set_redblue(struct gspca_dev *gspca_dev, s32 blue, s32 red)
1372 reg_w1(gspca_dev, 0x118c, red);
1373 reg_w1(gspca_dev, 0x118f, blue);
1376 static void set_hvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip)
1380 struct sd *sd = (struct sd *) gspca_dev;
1382 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1387 switch (sd->sensor) {
1398 reg_w1(gspca_dev, 0x1182, sd->vstart);
1399 i2c_w1(gspca_dev, 0x1e, value);
1402 i2c_r1(gspca_dev, 0x1e, &value);
1411 i2c_w1(gspca_dev, 0x1e, value);
1412 i2c_w1(gspca_dev, 0x3a, tslb);
1414 case SENSOR_MT9V111:
1415 case SENSOR_MT9V011:
1416 i2c_r2(gspca_dev, 0x20, &value2);
1422 i2c_w2(gspca_dev, 0x20, value2);
1424 case SENSOR_MT9M112:
1425 case SENSOR_MT9M111:
1426 case SENSOR_MT9V112:
1427 i2c_r2(gspca_dev, 0x20, &value2);
1433 i2c_w2(gspca_dev, 0x20, value2);
1435 case SENSOR_HV7131R:
1436 i2c_r1(gspca_dev, 0x01, &value);
1442 i2c_w1(gspca_dev, 0x01, value);
1447 static void set_exposure(struct gspca_dev *gspca_dev, s32 expo)
1449 struct sd *sd = (struct sd *) gspca_dev;
1450 u8 exp[8] = {sd->i2c_intf, sd->i2c_addr,
1451 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1454 if (gspca_dev->streaming)
1457 switch (sd->sensor) {
1467 exp[2] = 0x10; /* AECH */
1468 exp[3] = expo2 >> 2;
1470 i2c_w(gspca_dev, exp);
1471 exp[2] = 0x04; /* COM1 */
1472 exp[3] = expo2 & 0x0003;
1474 i2c_w(gspca_dev, exp);
1478 exp[2] = 0x2d; /* ADVFL & ADVFH */
1482 case SENSOR_MT9M001:
1483 case SENSOR_MT9V112:
1484 case SENSOR_MT9V011:
1490 case SENSOR_HV7131R:
1500 i2c_w(gspca_dev, exp);
1503 static void set_gain(struct gspca_dev *gspca_dev, s32 g)
1505 struct sd *sd = (struct sd *) gspca_dev;
1506 u8 gain[8] = {sd->i2c_intf, sd->i2c_addr,
1507 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1509 if (gspca_dev->streaming)
1510 gain[7] = 0x15; /* or 1d ? */
1512 switch (sd->sensor) {
1518 gain[0] |= (2 << 4);
1519 gain[3] = ov_gain[g];
1521 case SENSOR_MT9V011:
1522 gain[0] |= (3 << 4);
1524 gain[3] = micron1_gain[g] >> 8;
1525 gain[4] = micron1_gain[g];
1527 case SENSOR_MT9V112:
1528 gain[0] |= (3 << 4);
1530 gain[3] = micron1_gain[g] >> 8;
1531 gain[4] = micron1_gain[g];
1533 case SENSOR_MT9M001:
1534 gain[0] |= (3 << 4);
1536 gain[3] = micron2_gain[g] >> 8;
1537 gain[4] = micron2_gain[g];
1539 case SENSOR_HV7131R:
1540 gain[0] |= (2 << 4);
1542 gain[3] = hv7131r_gain[g];
1547 i2c_w(gspca_dev, gain);
1550 static void set_quality(struct gspca_dev *gspca_dev, s32 val)
1552 struct sd *sd = (struct sd *) gspca_dev;
1554 jpeg_set_qual(sd->jpeg_hdr, val);
1555 reg_w1(gspca_dev, 0x1061, 0x01); /* stop transfer */
1556 reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20); /* write QTAB */
1557 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
1558 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
1559 reg_w1(gspca_dev, 0x1061, 0x03); /* restart transfer */
1560 reg_w1(gspca_dev, 0x10e0, sd->fmt);
1561 sd->fmt ^= 0x0c; /* invert QTAB use + write */
1562 reg_w1(gspca_dev, 0x10e0, sd->fmt);
1565 #ifdef CONFIG_VIDEO_ADV_DEBUG
1566 static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1567 struct v4l2_dbg_register *reg)
1569 struct sd *sd = (struct sd *) gspca_dev;
1572 switch (reg->match.addr) {
1574 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1576 reg_r(gspca_dev, reg->reg, 1);
1577 reg->val = gspca_dev->usb_buf[0];
1578 return gspca_dev->usb_err;
1580 if (sd->sensor >= SENSOR_MT9V011 &&
1581 sd->sensor <= SENSOR_MT9M112) {
1582 i2c_r2(gspca_dev, reg->reg, (u16 *) ®->val);
1585 i2c_r1(gspca_dev, reg->reg, (u8 *) ®->val);
1587 return gspca_dev->usb_err;
1592 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1593 const struct v4l2_dbg_register *reg)
1595 struct sd *sd = (struct sd *) gspca_dev;
1597 switch (reg->match.addr) {
1599 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1601 reg_w1(gspca_dev, reg->reg, reg->val);
1602 return gspca_dev->usb_err;
1604 if (sd->sensor >= SENSOR_MT9V011 &&
1605 sd->sensor <= SENSOR_MT9M112) {
1606 i2c_w2(gspca_dev, reg->reg, reg->val);
1608 i2c_w1(gspca_dev, reg->reg, reg->val);
1610 return gspca_dev->usb_err;
1615 static int sd_chip_info(struct gspca_dev *gspca_dev,
1616 struct v4l2_dbg_chip_info *chip)
1618 if (chip->match.addr > 1)
1620 if (chip->match.addr == 1)
1621 strlcpy(chip->name, "sensor", sizeof(chip->name));
1626 static int sd_config(struct gspca_dev *gspca_dev,
1627 const struct usb_device_id *id)
1629 struct sd *sd = (struct sd *) gspca_dev;
1632 cam = &gspca_dev->cam;
1633 cam->needs_full_bandwidth = 1;
1635 sd->sensor = id->driver_info >> 8;
1636 sd->i2c_addr = id->driver_info;
1637 sd->flags = id->driver_info >> 16;
1638 sd->i2c_intf = 0x80; /* i2c 100 Kb/s */
1640 switch (sd->sensor) {
1641 case SENSOR_MT9M112:
1642 case SENSOR_MT9M111:
1645 cam->cam_mode = sxga_mode;
1646 cam->nmodes = ARRAY_SIZE(sxga_mode);
1648 case SENSOR_MT9M001:
1649 cam->cam_mode = mono_mode;
1650 cam->nmodes = ARRAY_SIZE(mono_mode);
1652 case SENSOR_HV7131R:
1653 sd->i2c_intf = 0x81; /* i2c 400 Kb/s */
1656 cam->cam_mode = vga_mode;
1657 cam->nmodes = ARRAY_SIZE(vga_mode);
1663 sd->exposure_step = 16;
1665 INIT_WORK(&sd->work, qual_upd);
1670 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
1672 struct gspca_dev *gspca_dev =
1673 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
1674 struct sd *sd = (struct sd *)gspca_dev;
1676 gspca_dev->usb_err = 0;
1678 if (!gspca_dev->streaming)
1682 /* color control cluster */
1683 case V4L2_CID_BRIGHTNESS:
1684 set_cmatrix(gspca_dev, sd->brightness->val,
1685 sd->contrast->val, sd->saturation->val, sd->hue->val);
1687 case V4L2_CID_GAMMA:
1688 set_gamma(gspca_dev, ctrl->val);
1690 /* blue/red balance cluster */
1691 case V4L2_CID_BLUE_BALANCE:
1692 set_redblue(gspca_dev, sd->blue->val, sd->red->val);
1694 /* h/vflip cluster */
1695 case V4L2_CID_HFLIP:
1696 set_hvflip(gspca_dev, sd->hflip->val, sd->vflip->val);
1698 /* standalone exposure control */
1699 case V4L2_CID_EXPOSURE:
1700 set_exposure(gspca_dev, ctrl->val);
1702 /* standalone gain control */
1704 set_gain(gspca_dev, ctrl->val);
1706 /* autogain + exposure or gain control cluster */
1707 case V4L2_CID_AUTOGAIN:
1708 if (sd->sensor == SENSOR_SOI968)
1709 set_gain(gspca_dev, sd->gain->val);
1711 set_exposure(gspca_dev, sd->exposure->val);
1713 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1714 set_quality(gspca_dev, ctrl->val);
1717 return gspca_dev->usb_err;
1720 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1721 .s_ctrl = sd_s_ctrl,
1724 static int sd_init_controls(struct gspca_dev *gspca_dev)
1726 struct sd *sd = (struct sd *) gspca_dev;
1727 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1729 gspca_dev->vdev.ctrl_handler = hdl;
1730 v4l2_ctrl_handler_init(hdl, 13);
1732 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1733 V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
1734 sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1735 V4L2_CID_CONTRAST, 0, 255, 1, 127);
1736 sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1737 V4L2_CID_SATURATION, 0, 255, 1, 127);
1738 sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1739 V4L2_CID_HUE, -180, 180, 1, 0);
1741 sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1742 V4L2_CID_GAMMA, 0, 255, 1, 0x10);
1744 sd->blue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1745 V4L2_CID_BLUE_BALANCE, 0, 127, 1, 0x28);
1746 sd->red = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1747 V4L2_CID_RED_BALANCE, 0, 127, 1, 0x28);
1749 if (sd->sensor != SENSOR_OV9655 && sd->sensor != SENSOR_SOI968 &&
1750 sd->sensor != SENSOR_OV7670 && sd->sensor != SENSOR_MT9M001 &&
1751 sd->sensor != SENSOR_MT9VPRB) {
1752 sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1753 V4L2_CID_HFLIP, 0, 1, 1, 0);
1754 sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1755 V4L2_CID_VFLIP, 0, 1, 1, 0);
1758 if (sd->sensor != SENSOR_SOI968 && sd->sensor != SENSOR_MT9VPRB &&
1759 sd->sensor != SENSOR_MT9M112 && sd->sensor != SENSOR_MT9M111 &&
1760 sd->sensor != SENSOR_MT9V111)
1761 sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1762 V4L2_CID_EXPOSURE, 0, 0x1780, 1, 0x33);
1764 if (sd->sensor != SENSOR_MT9VPRB && sd->sensor != SENSOR_MT9M112 &&
1765 sd->sensor != SENSOR_MT9M111 && sd->sensor != SENSOR_MT9V111) {
1766 sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1767 V4L2_CID_GAIN, 0, 28, 1, 0);
1768 sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1769 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1772 sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1773 V4L2_CID_JPEG_COMPRESSION_QUALITY, 50, 90, 1, 80);
1775 pr_err("Could not initialize controls\n");
1779 v4l2_ctrl_cluster(4, &sd->brightness);
1780 v4l2_ctrl_cluster(2, &sd->blue);
1782 v4l2_ctrl_cluster(2, &sd->hflip);
1784 if (sd->sensor == SENSOR_SOI968)
1785 /* this sensor doesn't have the exposure control and
1786 autogain is clustered with gain instead. This works
1787 because sd->exposure == NULL. */
1788 v4l2_ctrl_auto_cluster(3, &sd->autogain, 0, false);
1790 /* Otherwise autogain is clustered with exposure. */
1791 v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false);
1796 static int sd_init(struct gspca_dev *gspca_dev)
1798 struct sd *sd = (struct sd *) gspca_dev;
1802 0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
1805 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
1806 value = bridge_init[i][1];
1807 reg_w(gspca_dev, bridge_init[i][0], &value, 1);
1808 if (gspca_dev->usb_err < 0) {
1809 pr_err("Device initialization failed\n");
1810 return gspca_dev->usb_err;
1814 if (sd->flags & LED_REVERSE)
1815 reg_w1(gspca_dev, 0x1006, 0x00);
1817 reg_w1(gspca_dev, 0x1006, 0x20);
1819 reg_w(gspca_dev, 0x10c0, i2c_init, 9);
1820 if (gspca_dev->usb_err < 0) {
1821 pr_err("Device initialization failed\n");
1822 return gspca_dev->usb_err;
1825 switch (sd->sensor) {
1827 ov9650_init_sensor(gspca_dev);
1828 if (gspca_dev->usb_err < 0)
1830 pr_info("OV9650 sensor detected\n");
1833 ov9655_init_sensor(gspca_dev);
1834 if (gspca_dev->usb_err < 0)
1836 pr_info("OV9655 sensor detected\n");
1839 soi968_init_sensor(gspca_dev);
1840 if (gspca_dev->usb_err < 0)
1842 pr_info("SOI968 sensor detected\n");
1845 ov7660_init_sensor(gspca_dev);
1846 if (gspca_dev->usb_err < 0)
1848 pr_info("OV7660 sensor detected\n");
1851 ov7670_init_sensor(gspca_dev);
1852 if (gspca_dev->usb_err < 0)
1854 pr_info("OV7670 sensor detected\n");
1856 case SENSOR_MT9VPRB:
1857 mt9v_init_sensor(gspca_dev);
1858 if (gspca_dev->usb_err < 0)
1860 pr_info("MT9VPRB sensor detected\n");
1862 case SENSOR_MT9M111:
1863 mt9m111_init_sensor(gspca_dev);
1864 if (gspca_dev->usb_err < 0)
1866 pr_info("MT9M111 sensor detected\n");
1868 case SENSOR_MT9M112:
1869 mt9m112_init_sensor(gspca_dev);
1870 if (gspca_dev->usb_err < 0)
1872 pr_info("MT9M112 sensor detected\n");
1874 case SENSOR_MT9M001:
1875 mt9m001_init_sensor(gspca_dev);
1876 if (gspca_dev->usb_err < 0)
1879 case SENSOR_HV7131R:
1880 hv7131r_init_sensor(gspca_dev);
1881 if (gspca_dev->usb_err < 0)
1883 pr_info("HV7131R sensor detected\n");
1886 pr_err("Unsupported sensor\n");
1887 gspca_dev->usb_err = -ENODEV;
1889 return gspca_dev->usb_err;
1892 static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
1894 struct sd *sd = (struct sd *) gspca_dev;
1897 switch (sd->sensor) {
1899 if (mode & MODE_SXGA) {
1900 i2c_w1(gspca_dev, 0x17, 0x1d);
1901 i2c_w1(gspca_dev, 0x18, 0xbd);
1902 i2c_w1(gspca_dev, 0x19, 0x01);
1903 i2c_w1(gspca_dev, 0x1a, 0x81);
1904 i2c_w1(gspca_dev, 0x12, 0x00);
1908 i2c_w1(gspca_dev, 0x17, 0x13);
1909 i2c_w1(gspca_dev, 0x18, 0x63);
1910 i2c_w1(gspca_dev, 0x19, 0x01);
1911 i2c_w1(gspca_dev, 0x1a, 0x79);
1912 i2c_w1(gspca_dev, 0x12, 0x40);
1918 if (mode & MODE_SXGA) {
1919 i2c_w1(gspca_dev, 0x17, 0x1b);
1920 i2c_w1(gspca_dev, 0x18, 0xbc);
1921 i2c_w1(gspca_dev, 0x19, 0x01);
1922 i2c_w1(gspca_dev, 0x1a, 0x82);
1923 i2c_r1(gspca_dev, 0x12, &value);
1924 i2c_w1(gspca_dev, 0x12, value & 0x07);
1926 i2c_w1(gspca_dev, 0x17, 0x24);
1927 i2c_w1(gspca_dev, 0x18, 0xc5);
1928 i2c_w1(gspca_dev, 0x19, 0x00);
1929 i2c_w1(gspca_dev, 0x1a, 0x3c);
1930 i2c_r1(gspca_dev, 0x12, &value);
1931 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
1934 case SENSOR_MT9M112:
1935 case SENSOR_MT9M111:
1936 if (mode & MODE_SXGA) {
1937 i2c_w2(gspca_dev, 0xf0, 0x0002);
1938 i2c_w2(gspca_dev, 0xc8, 0x970b);
1939 i2c_w2(gspca_dev, 0xf0, 0x0000);
1941 i2c_w2(gspca_dev, 0xf0, 0x0002);
1942 i2c_w2(gspca_dev, 0xc8, 0x8000);
1943 i2c_w2(gspca_dev, 0xf0, 0x0000);
1949 static int sd_isoc_init(struct gspca_dev *gspca_dev)
1951 struct usb_interface *intf;
1952 u32 flags = gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv;
1955 * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth
1956 * than our regular bandwidth calculations reserve, so we force the
1957 * use of a specific altsetting when using the SN9C20X_I420 fmt.
1959 if (!(flags & (MODE_RAW | MODE_JPEG))) {
1960 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
1962 if (intf->num_altsetting != 9) {
1963 pr_warn("sn9c20x camera with unknown number of alt "
1964 "settings (%d), please report!\n",
1965 intf->num_altsetting);
1966 gspca_dev->alt = intf->num_altsetting;
1970 switch (gspca_dev->pixfmt.width) {
1971 case 160: /* 160x120 */
1974 case 320: /* 320x240 */
1977 default: /* >= 640x480 */
1986 #define HW_WIN(mode, hstart, vstart) \
1987 ((const u8 []){hstart, 0, vstart, 0, \
1988 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
1989 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
1991 #define CLR_WIN(width, height) \
1993 {0, width >> 2, 0, height >> 1,\
1994 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
1996 static int sd_start(struct gspca_dev *gspca_dev)
1998 struct sd *sd = (struct sd *) gspca_dev;
1999 int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
2000 int width = gspca_dev->pixfmt.width;
2001 int height = gspca_dev->pixfmt.height;
2004 jpeg_define(sd->jpeg_hdr, height, width,
2006 jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual));
2008 if (mode & MODE_RAW)
2010 else if (mode & MODE_JPEG)
2013 fmt = 0x2f; /* YUV 420 */
2016 switch (mode & SCALE_MASK) {
2017 case SCALE_1280x1024:
2019 pr_info("Set 1280x1024\n");
2023 pr_info("Set 640x480\n");
2027 pr_info("Set 320x240\n");
2031 pr_info("Set 160x120\n");
2035 configure_sensor_output(gspca_dev, mode);
2036 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2037 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2038 reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2039 reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2040 reg_w1(gspca_dev, 0x1189, scale);
2041 reg_w1(gspca_dev, 0x10e0, fmt);
2043 set_cmatrix(gspca_dev, v4l2_ctrl_g_ctrl(sd->brightness),
2044 v4l2_ctrl_g_ctrl(sd->contrast),
2045 v4l2_ctrl_g_ctrl(sd->saturation),
2046 v4l2_ctrl_g_ctrl(sd->hue));
2047 set_gamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma));
2048 set_redblue(gspca_dev, v4l2_ctrl_g_ctrl(sd->blue),
2049 v4l2_ctrl_g_ctrl(sd->red));
2051 set_gain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain));
2053 set_exposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure));
2055 set_hvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip),
2056 v4l2_ctrl_g_ctrl(sd->vflip));
2058 reg_w1(gspca_dev, 0x1007, 0x20);
2059 reg_w1(gspca_dev, 0x1061, 0x03);
2061 /* if JPEG, prepare the compression quality update */
2062 if (mode & MODE_JPEG) {
2063 sd->pktsz = sd->npkt = 0;
2067 return gspca_dev->usb_err;
2070 static void sd_stopN(struct gspca_dev *gspca_dev)
2072 reg_w1(gspca_dev, 0x1007, 0x00);
2073 reg_w1(gspca_dev, 0x1061, 0x01);
2076 /* called on streamoff with alt==0 and on disconnect */
2077 /* the usb_lock is held at entry - restore on exit */
2078 static void sd_stop0(struct gspca_dev *gspca_dev)
2080 struct sd *sd = (struct sd *) gspca_dev;
2082 mutex_unlock(&gspca_dev->usb_lock);
2083 flush_work(&sd->work);
2084 mutex_lock(&gspca_dev->usb_lock);
2087 static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2089 struct sd *sd = (struct sd *) gspca_dev;
2090 s32 cur_exp = v4l2_ctrl_g_ctrl(sd->exposure);
2091 s32 max = sd->exposure->maximum - sd->exposure_step;
2092 s32 min = sd->exposure->minimum + sd->exposure_step;
2096 * some hardcoded values are present
2097 * like those for maximal/minimal exposure
2098 * and exposure steps
2100 if (avg_lum < MIN_AVG_LUM) {
2104 new_exp = cur_exp + sd->exposure_step;
2109 v4l2_ctrl_s_ctrl(sd->exposure, new_exp);
2111 sd->older_step = sd->old_step;
2114 if (sd->old_step ^ sd->older_step)
2115 sd->exposure_step /= 2;
2117 sd->exposure_step += 2;
2119 if (avg_lum > MAX_AVG_LUM) {
2122 new_exp = cur_exp - sd->exposure_step;
2127 v4l2_ctrl_s_ctrl(sd->exposure, new_exp);
2128 sd->older_step = sd->old_step;
2131 if (sd->old_step ^ sd->older_step)
2132 sd->exposure_step /= 2;
2134 sd->exposure_step += 2;
2138 static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2140 struct sd *sd = (struct sd *) gspca_dev;
2141 s32 cur_gain = v4l2_ctrl_g_ctrl(sd->gain);
2143 if (avg_lum < MIN_AVG_LUM && cur_gain < sd->gain->maximum)
2144 v4l2_ctrl_s_ctrl(sd->gain, cur_gain + 1);
2145 if (avg_lum > MAX_AVG_LUM && cur_gain > sd->gain->minimum)
2146 v4l2_ctrl_s_ctrl(sd->gain, cur_gain - 1);
2149 static void sd_dqcallback(struct gspca_dev *gspca_dev)
2151 struct sd *sd = (struct sd *) gspca_dev;
2154 if (sd->autogain == NULL || !v4l2_ctrl_g_ctrl(sd->autogain))
2157 avg_lum = atomic_read(&sd->avg_lum);
2158 if (sd->sensor == SENSOR_SOI968)
2159 do_autogain(gspca_dev, avg_lum);
2161 do_autoexposure(gspca_dev, avg_lum);
2164 /* JPEG quality update */
2165 /* This function is executed from a work queue. */
2166 static void qual_upd(struct work_struct *work)
2168 struct sd *sd = container_of(work, struct sd, work);
2169 struct gspca_dev *gspca_dev = &sd->gspca_dev;
2170 s32 qual = v4l2_ctrl_g_ctrl(sd->jpegqual);
2172 /* To protect gspca_dev->usb_buf and gspca_dev->usb_err */
2173 mutex_lock(&gspca_dev->usb_lock);
2174 PDEBUG(D_STREAM, "qual_upd %d%%", qual);
2175 gspca_dev->usb_err = 0;
2176 set_quality(gspca_dev, qual);
2177 mutex_unlock(&gspca_dev->usb_lock);
2180 #if IS_ENABLED(CONFIG_INPUT)
2181 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2182 u8 *data, /* interrupt packet */
2183 int len) /* interrupt packet length */
2185 struct sd *sd = (struct sd *) gspca_dev;
2187 if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
2188 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2189 input_sync(gspca_dev->input_dev);
2190 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2191 input_sync(gspca_dev->input_dev);
2198 /* check the JPEG compression */
2199 static void transfer_check(struct gspca_dev *gspca_dev,
2202 struct sd *sd = (struct sd *) gspca_dev;
2207 /* if USB error, discard the frame and decrease the quality */
2208 if (data[6] & 0x08) { /* USB FIFO full */
2209 gspca_dev->last_packet_type = DISCARD_PACKET;
2213 /* else, compute the filling rate and a new JPEG quality */
2214 r = (sd->pktsz * 100) /
2216 gspca_dev->urb[0]->iso_frame_desc[0].length);
2222 if (new_qual != 0) {
2223 sd->nchg += new_qual;
2224 if (sd->nchg < -6 || sd->nchg >= 12) {
2225 /* Note: we are in interrupt context, so we can't
2226 use v4l2_ctrl_g/s_ctrl here. Access the value
2227 directly instead. */
2228 s32 curqual = sd->jpegqual->cur.val;
2230 new_qual += curqual;
2231 if (new_qual < sd->jpegqual->minimum)
2232 new_qual = sd->jpegqual->minimum;
2233 else if (new_qual > sd->jpegqual->maximum)
2234 new_qual = sd->jpegqual->maximum;
2235 if (new_qual != curqual) {
2236 sd->jpegqual->cur.val = new_qual;
2237 schedule_work(&sd->work);
2243 sd->pktsz = sd->npkt = 0;
2246 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2247 u8 *data, /* isoc packet */
2248 int len) /* iso packet length */
2250 struct sd *sd = (struct sd *) gspca_dev;
2251 int avg_lum, is_jpeg;
2252 static const u8 frame_header[] = {
2253 0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96
2256 is_jpeg = (sd->fmt & 0x03) == 0;
2257 if (len >= 64 && memcmp(data, frame_header, 6) == 0) {
2258 avg_lum = ((data[35] >> 2) & 3) |
2261 avg_lum += ((data[35] >> 4) & 3) |
2264 avg_lum += ((data[35] >> 6) & 3) |
2267 avg_lum += (data[36] & 3) |
2270 avg_lum += ((data[36] >> 2) & 3) |
2273 avg_lum += ((data[36] >> 4) & 3) |
2276 avg_lum += ((data[36] >> 6) & 3) |
2279 avg_lum += ((data[44] >> 4) & 3) |
2283 atomic_set(&sd->avg_lum, avg_lum);
2286 transfer_check(gspca_dev, data);
2288 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2294 if (gspca_dev->last_packet_type == LAST_PACKET) {
2296 gspca_frame_add(gspca_dev, FIRST_PACKET,
2297 sd->jpeg_hdr, JPEG_HDR_SZ);
2298 gspca_frame_add(gspca_dev, INTER_PACKET,
2301 gspca_frame_add(gspca_dev, FIRST_PACKET,
2305 /* if JPEG, count the packets and their size */
2310 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2314 /* sub-driver description */
2315 static const struct sd_desc sd_desc = {
2316 .name = KBUILD_MODNAME,
2317 .config = sd_config,
2319 .init_controls = sd_init_controls,
2320 .isoc_init = sd_isoc_init,
2324 .pkt_scan = sd_pkt_scan,
2325 #if IS_ENABLED(CONFIG_INPUT)
2326 .int_pkt_scan = sd_int_pkt_scan,
2328 .dq_callback = sd_dqcallback,
2329 #ifdef CONFIG_VIDEO_ADV_DEBUG
2330 .set_register = sd_dbg_s_register,
2331 .get_register = sd_dbg_g_register,
2332 .get_chip_info = sd_chip_info,
2336 #define SN9C20X(sensor, i2c_addr, flags) \
2337 .driver_info = ((flags & 0xff) << 16) \
2338 | (SENSOR_ ## sensor << 8) \
2341 static const struct usb_device_id device_table[] = {
2342 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2343 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
2344 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2345 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
2346 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
2347 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
2348 (FLIP_DETECT | HAS_NO_BUTTON))},
2349 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2350 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2351 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2352 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2353 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, FLIP_DETECT)},
2354 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2355 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2356 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2357 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2358 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
2359 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
2360 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2361 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2362 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2363 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2364 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, LED_REVERSE)},
2365 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, LED_REVERSE)},
2366 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2367 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2368 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2369 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2370 {USB_DEVICE(0x0458, 0x7045), SN9C20X(MT9M112, 0x5d, LED_REVERSE)},
2371 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
2372 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
2373 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2374 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2375 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2376 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2377 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
2378 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2379 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2382 MODULE_DEVICE_TABLE(usb, device_table);
2384 /* -- device connect -- */
2385 static int sd_probe(struct usb_interface *intf,
2386 const struct usb_device_id *id)
2388 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2392 static struct usb_driver sd_driver = {
2393 .name = KBUILD_MODNAME,
2394 .id_table = device_table,
2396 .disconnect = gspca_disconnect,
2398 .suspend = gspca_suspend,
2399 .resume = gspca_resume,
2400 .reset_resume = gspca_resume,
2404 module_usb_driver(sd_driver);