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;
95 struct workqueue_struct *work_thread;
97 u32 pktsz; /* (used by pkt_scan) */
100 u8 fmt; /* (used for JPEG QTAB update */
102 #define MIN_AVG_LUM 80
103 #define MAX_AVG_LUM 130
115 u8 jpeg_hdr[JPEG_HDR_SZ];
120 static void qual_upd(struct work_struct *work);
132 static const struct dmi_system_id flip_dmi_table[] = {
134 .ident = "MSI MS-1034",
136 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
137 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1034"),
138 DMI_MATCH(DMI_PRODUCT_VERSION, "0341")
142 .ident = "MSI MS-1039",
144 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
145 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1039"),
149 .ident = "MSI MS-1632",
151 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
152 DMI_MATCH(DMI_BOARD_NAME, "MS-1632")
156 .ident = "MSI MS-1633X",
158 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
159 DMI_MATCH(DMI_BOARD_NAME, "MS-1633X")
163 .ident = "MSI MS-1635X",
165 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
166 DMI_MATCH(DMI_BOARD_NAME, "MS-1635X")
170 .ident = "ASUSTeK W7J",
172 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
173 DMI_MATCH(DMI_BOARD_NAME, "W7J ")
179 static const struct v4l2_pix_format vga_mode[] = {
180 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
182 .sizeimage = 160 * 120 * 4 / 8 + 590,
183 .colorspace = V4L2_COLORSPACE_JPEG,
184 .priv = SCALE_160x120 | MODE_JPEG},
185 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
187 .sizeimage = 160 * 120,
188 .colorspace = V4L2_COLORSPACE_SRGB,
189 .priv = SCALE_160x120 | MODE_RAW},
190 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
192 .sizeimage = 240 * 120,
193 .colorspace = V4L2_COLORSPACE_SRGB,
194 .priv = SCALE_160x120},
195 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
197 .sizeimage = 320 * 240 * 4 / 8 + 590,
198 .colorspace = V4L2_COLORSPACE_JPEG,
199 .priv = SCALE_320x240 | MODE_JPEG},
200 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
202 .sizeimage = 320 * 240 ,
203 .colorspace = V4L2_COLORSPACE_SRGB,
204 .priv = SCALE_320x240 | MODE_RAW},
205 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
207 .sizeimage = 480 * 240 ,
208 .colorspace = V4L2_COLORSPACE_SRGB,
209 .priv = SCALE_320x240},
210 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
212 .sizeimage = 640 * 480 * 4 / 8 + 590,
213 .colorspace = V4L2_COLORSPACE_JPEG,
214 .priv = SCALE_640x480 | MODE_JPEG},
215 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
217 .sizeimage = 640 * 480,
218 .colorspace = V4L2_COLORSPACE_SRGB,
219 .priv = SCALE_640x480 | MODE_RAW},
220 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
222 .sizeimage = 960 * 480,
223 .colorspace = V4L2_COLORSPACE_SRGB,
224 .priv = SCALE_640x480},
227 static const struct v4l2_pix_format sxga_mode[] = {
228 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
230 .sizeimage = 160 * 120 * 4 / 8 + 590,
231 .colorspace = V4L2_COLORSPACE_JPEG,
232 .priv = SCALE_160x120 | MODE_JPEG},
233 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
235 .sizeimage = 160 * 120,
236 .colorspace = V4L2_COLORSPACE_SRGB,
237 .priv = SCALE_160x120 | MODE_RAW},
238 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
240 .sizeimage = 240 * 120,
241 .colorspace = V4L2_COLORSPACE_SRGB,
242 .priv = SCALE_160x120},
243 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
245 .sizeimage = 320 * 240 * 4 / 8 + 590,
246 .colorspace = V4L2_COLORSPACE_JPEG,
247 .priv = SCALE_320x240 | MODE_JPEG},
248 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
250 .sizeimage = 320 * 240 ,
251 .colorspace = V4L2_COLORSPACE_SRGB,
252 .priv = SCALE_320x240 | MODE_RAW},
253 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
255 .sizeimage = 480 * 240 ,
256 .colorspace = V4L2_COLORSPACE_SRGB,
257 .priv = SCALE_320x240},
258 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
260 .sizeimage = 640 * 480 * 4 / 8 + 590,
261 .colorspace = V4L2_COLORSPACE_JPEG,
262 .priv = SCALE_640x480 | MODE_JPEG},
263 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
265 .sizeimage = 640 * 480,
266 .colorspace = V4L2_COLORSPACE_SRGB,
267 .priv = SCALE_640x480 | MODE_RAW},
268 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
270 .sizeimage = 960 * 480,
271 .colorspace = V4L2_COLORSPACE_SRGB,
272 .priv = SCALE_640x480},
273 {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
274 .bytesperline = 1280,
275 .sizeimage = 1280 * 1024,
276 .colorspace = V4L2_COLORSPACE_SRGB,
277 .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
280 static const struct v4l2_pix_format mono_mode[] = {
281 {160, 120, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
283 .sizeimage = 160 * 120,
284 .colorspace = V4L2_COLORSPACE_SRGB,
285 .priv = SCALE_160x120 | MODE_RAW},
286 {320, 240, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
288 .sizeimage = 320 * 240 ,
289 .colorspace = V4L2_COLORSPACE_SRGB,
290 .priv = SCALE_320x240 | MODE_RAW},
291 {640, 480, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
293 .sizeimage = 640 * 480,
294 .colorspace = V4L2_COLORSPACE_SRGB,
295 .priv = SCALE_640x480 | MODE_RAW},
296 {1280, 1024, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
297 .bytesperline = 1280,
298 .sizeimage = 1280 * 1024,
299 .colorspace = V4L2_COLORSPACE_SRGB,
300 .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
303 static const s16 hsv_red_x[] = {
304 41, 44, 46, 48, 50, 52, 54, 56,
305 58, 60, 62, 64, 66, 68, 70, 72,
306 74, 76, 78, 80, 81, 83, 85, 87,
307 88, 90, 92, 93, 95, 97, 98, 100,
308 101, 102, 104, 105, 107, 108, 109, 110,
309 112, 113, 114, 115, 116, 117, 118, 119,
310 120, 121, 122, 123, 123, 124, 125, 125,
311 126, 127, 127, 128, 128, 129, 129, 129,
312 130, 130, 130, 130, 131, 131, 131, 131,
313 131, 131, 131, 131, 130, 130, 130, 130,
314 129, 129, 129, 128, 128, 127, 127, 126,
315 125, 125, 124, 123, 122, 122, 121, 120,
316 119, 118, 117, 116, 115, 114, 112, 111,
317 110, 109, 107, 106, 105, 103, 102, 101,
318 99, 98, 96, 94, 93, 91, 90, 88,
319 86, 84, 83, 81, 79, 77, 75, 74,
320 72, 70, 68, 66, 64, 62, 60, 58,
321 56, 54, 52, 49, 47, 45, 43, 41,
322 39, 36, 34, 32, 30, 28, 25, 23,
323 21, 19, 16, 14, 12, 9, 7, 5,
324 3, 0, -1, -3, -6, -8, -10, -12,
325 -15, -17, -19, -22, -24, -26, -28, -30,
326 -33, -35, -37, -39, -41, -44, -46, -48,
327 -50, -52, -54, -56, -58, -60, -62, -64,
328 -66, -68, -70, -72, -74, -76, -78, -80,
329 -81, -83, -85, -87, -88, -90, -92, -93,
330 -95, -97, -98, -100, -101, -102, -104, -105,
331 -107, -108, -109, -110, -112, -113, -114, -115,
332 -116, -117, -118, -119, -120, -121, -122, -123,
333 -123, -124, -125, -125, -126, -127, -127, -128,
334 -128, -128, -128, -128, -128, -128, -128, -128,
335 -128, -128, -128, -128, -128, -128, -128, -128,
336 -128, -128, -128, -128, -128, -128, -128, -128,
337 -128, -127, -127, -126, -125, -125, -124, -123,
338 -122, -122, -121, -120, -119, -118, -117, -116,
339 -115, -114, -112, -111, -110, -109, -107, -106,
340 -105, -103, -102, -101, -99, -98, -96, -94,
341 -93, -91, -90, -88, -86, -84, -83, -81,
342 -79, -77, -75, -74, -72, -70, -68, -66,
343 -64, -62, -60, -58, -56, -54, -52, -49,
344 -47, -45, -43, -41, -39, -36, -34, -32,
345 -30, -28, -25, -23, -21, -19, -16, -14,
346 -12, -9, -7, -5, -3, 0, 1, 3,
347 6, 8, 10, 12, 15, 17, 19, 22,
348 24, 26, 28, 30, 33, 35, 37, 39, 41
351 static const s16 hsv_red_y[] = {
352 82, 80, 78, 76, 74, 73, 71, 69,
353 67, 65, 63, 61, 58, 56, 54, 52,
354 50, 48, 46, 44, 41, 39, 37, 35,
355 32, 30, 28, 26, 23, 21, 19, 16,
356 14, 12, 10, 7, 5, 3, 0, -1,
357 -3, -6, -8, -10, -13, -15, -17, -19,
358 -22, -24, -26, -29, -31, -33, -35, -38,
359 -40, -42, -44, -46, -48, -51, -53, -55,
360 -57, -59, -61, -63, -65, -67, -69, -71,
361 -73, -75, -77, -79, -81, -82, -84, -86,
362 -88, -89, -91, -93, -94, -96, -98, -99,
363 -101, -102, -104, -105, -106, -108, -109, -110,
364 -112, -113, -114, -115, -116, -117, -119, -120,
365 -120, -121, -122, -123, -124, -125, -126, -126,
366 -127, -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 -128, -128, -128, -128, -128, -128, -128, -128,
370 -127, -127, -126, -125, -125, -124, -123, -122,
371 -121, -120, -119, -118, -117, -116, -115, -114,
372 -113, -111, -110, -109, -107, -106, -105, -103,
373 -102, -100, -99, -97, -96, -94, -92, -91,
374 -89, -87, -85, -84, -82, -80, -78, -76,
375 -74, -73, -71, -69, -67, -65, -63, -61,
376 -58, -56, -54, -52, -50, -48, -46, -44,
377 -41, -39, -37, -35, -32, -30, -28, -26,
378 -23, -21, -19, -16, -14, -12, -10, -7,
379 -5, -3, 0, 1, 3, 6, 8, 10,
380 13, 15, 17, 19, 22, 24, 26, 29,
381 31, 33, 35, 38, 40, 42, 44, 46,
382 48, 51, 53, 55, 57, 59, 61, 63,
383 65, 67, 69, 71, 73, 75, 77, 79,
384 81, 82, 84, 86, 88, 89, 91, 93,
385 94, 96, 98, 99, 101, 102, 104, 105,
386 106, 108, 109, 110, 112, 113, 114, 115,
387 116, 117, 119, 120, 120, 121, 122, 123,
388 124, 125, 126, 126, 127, 128, 128, 129,
389 129, 130, 130, 131, 131, 131, 131, 132,
390 132, 132, 132, 132, 132, 132, 132, 132,
391 132, 132, 132, 131, 131, 131, 130, 130,
392 130, 129, 129, 128, 127, 127, 126, 125,
393 125, 124, 123, 122, 121, 120, 119, 118,
394 117, 116, 115, 114, 113, 111, 110, 109,
395 107, 106, 105, 103, 102, 100, 99, 97,
396 96, 94, 92, 91, 89, 87, 85, 84, 82
399 static const s16 hsv_green_x[] = {
400 -124, -124, -125, -125, -125, -125, -125, -125,
401 -125, -126, -126, -125, -125, -125, -125, -125,
402 -125, -124, -124, -124, -123, -123, -122, -122,
403 -121, -121, -120, -120, -119, -118, -117, -117,
404 -116, -115, -114, -113, -112, -111, -110, -109,
405 -108, -107, -105, -104, -103, -102, -100, -99,
406 -98, -96, -95, -93, -92, -91, -89, -87,
407 -86, -84, -83, -81, -79, -77, -76, -74,
408 -72, -70, -69, -67, -65, -63, -61, -59,
409 -57, -55, -53, -51, -49, -47, -45, -43,
410 -41, -39, -37, -35, -33, -30, -28, -26,
411 -24, -22, -20, -18, -15, -13, -11, -9,
412 -7, -4, -2, 0, 1, 3, 6, 8,
413 10, 12, 14, 17, 19, 21, 23, 25,
414 27, 29, 32, 34, 36, 38, 40, 42,
415 44, 46, 48, 50, 52, 54, 56, 58,
416 60, 62, 64, 66, 68, 70, 71, 73,
417 75, 77, 78, 80, 82, 83, 85, 87,
418 88, 90, 91, 93, 94, 96, 97, 98,
419 100, 101, 102, 104, 105, 106, 107, 108,
420 109, 111, 112, 113, 113, 114, 115, 116,
421 117, 118, 118, 119, 120, 120, 121, 122,
422 122, 123, 123, 124, 124, 124, 125, 125,
423 125, 125, 125, 125, 125, 126, 126, 125,
424 125, 125, 125, 125, 125, 124, 124, 124,
425 123, 123, 122, 122, 121, 121, 120, 120,
426 119, 118, 117, 117, 116, 115, 114, 113,
427 112, 111, 110, 109, 108, 107, 105, 104,
428 103, 102, 100, 99, 98, 96, 95, 93,
429 92, 91, 89, 87, 86, 84, 83, 81,
430 79, 77, 76, 74, 72, 70, 69, 67,
431 65, 63, 61, 59, 57, 55, 53, 51,
432 49, 47, 45, 43, 41, 39, 37, 35,
433 33, 30, 28, 26, 24, 22, 20, 18,
434 15, 13, 11, 9, 7, 4, 2, 0,
435 -1, -3, -6, -8, -10, -12, -14, -17,
436 -19, -21, -23, -25, -27, -29, -32, -34,
437 -36, -38, -40, -42, -44, -46, -48, -50,
438 -52, -54, -56, -58, -60, -62, -64, -66,
439 -68, -70, -71, -73, -75, -77, -78, -80,
440 -82, -83, -85, -87, -88, -90, -91, -93,
441 -94, -96, -97, -98, -100, -101, -102, -104,
442 -105, -106, -107, -108, -109, -111, -112, -113,
443 -113, -114, -115, -116, -117, -118, -118, -119,
444 -120, -120, -121, -122, -122, -123, -123, -124, -124
447 static const s16 hsv_green_y[] = {
448 -100, -99, -98, -97, -95, -94, -93, -91,
449 -90, -89, -87, -86, -84, -83, -81, -80,
450 -78, -76, -75, -73, -71, -70, -68, -66,
451 -64, -63, -61, -59, -57, -55, -53, -51,
452 -49, -48, -46, -44, -42, -40, -38, -36,
453 -34, -32, -30, -27, -25, -23, -21, -19,
454 -17, -15, -13, -11, -9, -7, -4, -2,
455 0, 1, 3, 5, 7, 9, 11, 14,
456 16, 18, 20, 22, 24, 26, 28, 30,
457 32, 34, 36, 38, 40, 42, 44, 46,
458 48, 50, 52, 54, 56, 58, 59, 61,
459 63, 65, 67, 68, 70, 72, 74, 75,
460 77, 78, 80, 82, 83, 85, 86, 88,
461 89, 90, 92, 93, 95, 96, 97, 98,
462 100, 101, 102, 103, 104, 105, 106, 107,
463 108, 109, 110, 111, 112, 112, 113, 114,
464 115, 115, 116, 116, 117, 117, 118, 118,
465 119, 119, 119, 120, 120, 120, 120, 120,
466 121, 121, 121, 121, 121, 121, 120, 120,
467 120, 120, 120, 119, 119, 119, 118, 118,
468 117, 117, 116, 116, 115, 114, 114, 113,
469 112, 111, 111, 110, 109, 108, 107, 106,
470 105, 104, 103, 102, 100, 99, 98, 97,
471 95, 94, 93, 91, 90, 89, 87, 86,
472 84, 83, 81, 80, 78, 76, 75, 73,
473 71, 70, 68, 66, 64, 63, 61, 59,
474 57, 55, 53, 51, 49, 48, 46, 44,
475 42, 40, 38, 36, 34, 32, 30, 27,
476 25, 23, 21, 19, 17, 15, 13, 11,
477 9, 7, 4, 2, 0, -1, -3, -5,
478 -7, -9, -11, -14, -16, -18, -20, -22,
479 -24, -26, -28, -30, -32, -34, -36, -38,
480 -40, -42, -44, -46, -48, -50, -52, -54,
481 -56, -58, -59, -61, -63, -65, -67, -68,
482 -70, -72, -74, -75, -77, -78, -80, -82,
483 -83, -85, -86, -88, -89, -90, -92, -93,
484 -95, -96, -97, -98, -100, -101, -102, -103,
485 -104, -105, -106, -107, -108, -109, -110, -111,
486 -112, -112, -113, -114, -115, -115, -116, -116,
487 -117, -117, -118, -118, -119, -119, -119, -120,
488 -120, -120, -120, -120, -121, -121, -121, -121,
489 -121, -121, -120, -120, -120, -120, -120, -119,
490 -119, -119, -118, -118, -117, -117, -116, -116,
491 -115, -114, -114, -113, -112, -111, -111, -110,
492 -109, -108, -107, -106, -105, -104, -103, -102, -100
495 static const s16 hsv_blue_x[] = {
496 112, 113, 114, 114, 115, 116, 117, 117,
497 118, 118, 119, 119, 120, 120, 120, 121,
498 121, 121, 122, 122, 122, 122, 122, 122,
499 122, 122, 122, 122, 122, 122, 121, 121,
500 121, 120, 120, 120, 119, 119, 118, 118,
501 117, 116, 116, 115, 114, 113, 113, 112,
502 111, 110, 109, 108, 107, 106, 105, 104,
503 103, 102, 100, 99, 98, 97, 95, 94,
504 93, 91, 90, 88, 87, 85, 84, 82,
505 80, 79, 77, 76, 74, 72, 70, 69,
506 67, 65, 63, 61, 60, 58, 56, 54,
507 52, 50, 48, 46, 44, 42, 40, 38,
508 36, 34, 32, 30, 28, 26, 24, 22,
509 19, 17, 15, 13, 11, 9, 7, 5,
510 2, 0, -1, -3, -5, -7, -9, -12,
511 -14, -16, -18, -20, -22, -24, -26, -28,
512 -31, -33, -35, -37, -39, -41, -43, -45,
513 -47, -49, -51, -53, -54, -56, -58, -60,
514 -62, -64, -66, -67, -69, -71, -73, -74,
515 -76, -78, -79, -81, -83, -84, -86, -87,
516 -89, -90, -92, -93, -94, -96, -97, -98,
517 -99, -101, -102, -103, -104, -105, -106, -107,
518 -108, -109, -110, -111, -112, -113, -114, -114,
519 -115, -116, -117, -117, -118, -118, -119, -119,
520 -120, -120, -120, -121, -121, -121, -122, -122,
521 -122, -122, -122, -122, -122, -122, -122, -122,
522 -122, -122, -121, -121, -121, -120, -120, -120,
523 -119, -119, -118, -118, -117, -116, -116, -115,
524 -114, -113, -113, -112, -111, -110, -109, -108,
525 -107, -106, -105, -104, -103, -102, -100, -99,
526 -98, -97, -95, -94, -93, -91, -90, -88,
527 -87, -85, -84, -82, -80, -79, -77, -76,
528 -74, -72, -70, -69, -67, -65, -63, -61,
529 -60, -58, -56, -54, -52, -50, -48, -46,
530 -44, -42, -40, -38, -36, -34, -32, -30,
531 -28, -26, -24, -22, -19, -17, -15, -13,
532 -11, -9, -7, -5, -2, 0, 1, 3,
533 5, 7, 9, 12, 14, 16, 18, 20,
534 22, 24, 26, 28, 31, 33, 35, 37,
535 39, 41, 43, 45, 47, 49, 51, 53,
536 54, 56, 58, 60, 62, 64, 66, 67,
537 69, 71, 73, 74, 76, 78, 79, 81,
538 83, 84, 86, 87, 89, 90, 92, 93,
539 94, 96, 97, 98, 99, 101, 102, 103,
540 104, 105, 106, 107, 108, 109, 110, 111, 112
543 static const s16 hsv_blue_y[] = {
544 -11, -13, -15, -17, -19, -21, -23, -25,
545 -27, -29, -31, -33, -35, -37, -39, -41,
546 -43, -45, -46, -48, -50, -52, -54, -55,
547 -57, -59, -61, -62, -64, -66, -67, -69,
548 -71, -72, -74, -75, -77, -78, -80, -81,
549 -83, -84, -86, -87, -88, -90, -91, -92,
550 -93, -95, -96, -97, -98, -99, -100, -101,
551 -102, -103, -104, -105, -106, -106, -107, -108,
552 -109, -109, -110, -111, -111, -112, -112, -113,
553 -113, -114, -114, -114, -115, -115, -115, -115,
554 -116, -116, -116, -116, -116, -116, -116, -116,
555 -116, -115, -115, -115, -115, -114, -114, -114,
556 -113, -113, -112, -112, -111, -111, -110, -110,
557 -109, -108, -108, -107, -106, -105, -104, -103,
558 -102, -101, -100, -99, -98, -97, -96, -95,
559 -94, -93, -91, -90, -89, -88, -86, -85,
560 -84, -82, -81, -79, -78, -76, -75, -73,
561 -71, -70, -68, -67, -65, -63, -62, -60,
562 -58, -56, -55, -53, -51, -49, -47, -45,
563 -44, -42, -40, -38, -36, -34, -32, -30,
564 -28, -26, -24, -22, -20, -18, -16, -14,
565 -12, -10, -8, -6, -4, -2, 0, 1,
566 3, 5, 7, 9, 11, 13, 15, 17,
567 19, 21, 23, 25, 27, 29, 31, 33,
568 35, 37, 39, 41, 43, 45, 46, 48,
569 50, 52, 54, 55, 57, 59, 61, 62,
570 64, 66, 67, 69, 71, 72, 74, 75,
571 77, 78, 80, 81, 83, 84, 86, 87,
572 88, 90, 91, 92, 93, 95, 96, 97,
573 98, 99, 100, 101, 102, 103, 104, 105,
574 106, 106, 107, 108, 109, 109, 110, 111,
575 111, 112, 112, 113, 113, 114, 114, 114,
576 115, 115, 115, 115, 116, 116, 116, 116,
577 116, 116, 116, 116, 116, 115, 115, 115,
578 115, 114, 114, 114, 113, 113, 112, 112,
579 111, 111, 110, 110, 109, 108, 108, 107,
580 106, 105, 104, 103, 102, 101, 100, 99,
581 98, 97, 96, 95, 94, 93, 91, 90,
582 89, 88, 86, 85, 84, 82, 81, 79,
583 78, 76, 75, 73, 71, 70, 68, 67,
584 65, 63, 62, 60, 58, 56, 55, 53,
585 51, 49, 47, 45, 44, 42, 40, 38,
586 36, 34, 32, 30, 28, 26, 24, 22,
587 20, 18, 16, 14, 12, 10, 8, 6,
588 4, 2, 0, -1, -3, -5, -7, -9, -11
591 static const u16 bridge_init[][2] = {
592 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
593 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
594 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
595 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
596 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
597 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
598 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
599 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
600 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
601 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
602 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
603 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
604 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
605 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
606 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
607 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
608 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
609 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
610 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
614 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
615 static const u8 ov_gain[] = {
616 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
617 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
618 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
619 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
620 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
621 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
622 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
626 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
627 static const u16 micron1_gain[] = {
628 /* 1x 1.25x 1.5x 1.75x */
629 0x0020, 0x0028, 0x0030, 0x0038,
630 /* 2x 2.25x 2.5x 2.75x */
631 0x00a0, 0x00a4, 0x00a8, 0x00ac,
632 /* 3x 3.25x 3.5x 3.75x */
633 0x00b0, 0x00b4, 0x00b8, 0x00bc,
634 /* 4x 4.25x 4.5x 4.75x */
635 0x00c0, 0x00c4, 0x00c8, 0x00cc,
636 /* 5x 5.25x 5.5x 5.75x */
637 0x00d0, 0x00d4, 0x00d8, 0x00dc,
638 /* 6x 6.25x 6.5x 6.75x */
639 0x00e0, 0x00e4, 0x00e8, 0x00ec,
640 /* 7x 7.25x 7.5x 7.75x */
641 0x00f0, 0x00f4, 0x00f8, 0x00fc,
646 /* mt9m001 sensor uses a different gain formula then other micron sensors */
647 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
648 static const u16 micron2_gain[] = {
649 /* 1x 1.25x 1.5x 1.75x */
650 0x0008, 0x000a, 0x000c, 0x000e,
651 /* 2x 2.25x 2.5x 2.75x */
652 0x0010, 0x0012, 0x0014, 0x0016,
653 /* 3x 3.25x 3.5x 3.75x */
654 0x0018, 0x001a, 0x001c, 0x001e,
655 /* 4x 4.25x 4.5x 4.75x */
656 0x0020, 0x0051, 0x0052, 0x0053,
657 /* 5x 5.25x 5.5x 5.75x */
658 0x0054, 0x0055, 0x0056, 0x0057,
659 /* 6x 6.25x 6.5x 6.75x */
660 0x0058, 0x0059, 0x005a, 0x005b,
661 /* 7x 7.25x 7.5x 7.75x */
662 0x005c, 0x005d, 0x005e, 0x005f,
667 /* Gain = .5 + bit[7:0] / 16 */
668 static const u8 hv7131r_gain[] = {
669 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
670 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
671 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
672 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
673 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
674 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
675 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
679 static const struct i2c_reg_u8 soi968_init[] = {
680 {0x0c, 0x00}, {0x0f, 0x1f},
681 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
682 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
683 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
684 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
685 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
686 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
687 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
688 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
689 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
690 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
693 static const struct i2c_reg_u8 ov7660_init[] = {
694 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
695 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
696 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
697 /* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using
698 0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
699 {0x17, 0x10}, {0x18, 0x61},
700 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
701 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0x00},
702 {0x2e, 0x00}, {0x01, 0x78}, {0x02, 0x50},
705 static const struct i2c_reg_u8 ov7670_init[] = {
706 {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
707 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
708 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
709 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
710 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
711 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
712 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
713 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
714 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
715 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
716 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
717 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
718 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
719 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
720 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
721 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
722 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
723 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
724 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
725 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
726 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
727 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
728 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
729 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
730 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
731 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
732 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
733 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
734 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
735 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
736 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
737 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
738 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
739 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
740 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
741 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
742 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
743 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
744 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
745 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
746 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
747 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
748 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
749 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
750 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
751 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
752 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
753 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
754 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
755 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
756 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
757 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
758 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
762 static const struct i2c_reg_u8 ov9650_init[] = {
763 {0x00, 0x00}, {0x01, 0x78},
764 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
765 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
766 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
767 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
768 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
769 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
770 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
771 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
772 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
773 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
774 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
775 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
776 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
777 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
778 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
779 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
780 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
781 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
782 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
783 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
784 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
785 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
786 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
787 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
788 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
789 {0xaa, 0x92}, {0xab, 0x0a},
792 static const struct i2c_reg_u8 ov9655_init[] = {
793 {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
794 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
795 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
796 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
797 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
798 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
799 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
800 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
801 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
802 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
803 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
804 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
805 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
806 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
807 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
808 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
809 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
810 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
811 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
812 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
813 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
814 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
815 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
816 {0x04, 0x03}, {0x00, 0x13},
819 static const struct i2c_reg_u16 mt9v112_init[] = {
820 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
821 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
822 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
823 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
824 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
825 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
826 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
827 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
828 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
829 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
830 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
831 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
832 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
833 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
834 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
835 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
838 static const struct i2c_reg_u16 mt9v111_init[] = {
839 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
840 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
841 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
842 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
843 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
844 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
845 {0x0e, 0x0008}, {0x20, 0x0000}
848 static const struct i2c_reg_u16 mt9v011_init[] = {
849 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
850 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
851 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
852 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
853 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
854 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
855 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
856 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
857 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
858 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
859 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
860 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
861 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
862 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
863 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
864 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
865 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
866 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
867 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
868 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
869 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
870 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
871 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
872 {0x06, 0x0029}, {0x05, 0x0009},
875 static const struct i2c_reg_u16 mt9m001_init[] = {
878 {0x04, 0x0500}, /* hres = 1280 */
879 {0x03, 0x0400}, /* vres = 1024 */
891 static const struct i2c_reg_u16 mt9m111_init[] = {
892 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
893 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
894 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
898 static const struct i2c_reg_u16 mt9m112_init[] = {
899 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
900 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
901 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
905 static const struct i2c_reg_u8 hv7131r_init[] = {
906 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
907 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
908 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
909 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
910 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
911 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
912 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
913 {0x23, 0x09}, {0x01, 0x08},
916 static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
918 struct usb_device *dev = gspca_dev->dev;
921 if (gspca_dev->usb_err < 0)
923 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
925 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
931 if (unlikely(result < 0 || result != length)) {
932 pr_err("Read register %02x failed %d\n", reg, result);
933 gspca_dev->usb_err = result;
935 * Make sure the buffer is zeroed to avoid uninitialized
938 memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
942 static void reg_w(struct gspca_dev *gspca_dev, u16 reg,
943 const u8 *buffer, int length)
945 struct usb_device *dev = gspca_dev->dev;
948 if (gspca_dev->usb_err < 0)
950 memcpy(gspca_dev->usb_buf, buffer, length);
951 result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
953 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
959 if (unlikely(result < 0 || result != length)) {
960 pr_err("Write register %02x failed %d\n", reg, result);
961 gspca_dev->usb_err = result;
965 static void reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
967 reg_w(gspca_dev, reg, &value, 1);
970 static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
974 reg_w(gspca_dev, 0x10c0, buffer, 8);
975 for (i = 0; i < 5; i++) {
976 reg_r(gspca_dev, 0x10c0, 1);
977 if (gspca_dev->usb_err < 0)
979 if (gspca_dev->usb_buf[0] & 0x04) {
980 if (gspca_dev->usb_buf[0] & 0x08) {
981 pr_err("i2c_w error\n");
982 gspca_dev->usb_err = -EIO;
988 pr_err("i2c_w reg %02x no response\n", buffer[2]);
989 /* gspca_dev->usb_err = -EIO; fixme: may occur */
992 static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
994 struct sd *sd = (struct sd *) gspca_dev;
998 * from the point of view of the bridge, the length
999 * includes the address
1001 row[0] = sd->i2c_intf | (2 << 4);
1002 row[1] = sd->i2c_addr;
1010 i2c_w(gspca_dev, row);
1013 static void i2c_w1_buf(struct gspca_dev *gspca_dev,
1014 const struct i2c_reg_u8 *buf, int sz)
1017 i2c_w1(gspca_dev, buf->reg, buf->val);
1022 static void i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1024 struct sd *sd = (struct sd *) gspca_dev;
1028 * from the point of view of the bridge, the length
1029 * includes the address
1031 row[0] = sd->i2c_intf | (3 << 4);
1032 row[1] = sd->i2c_addr;
1040 i2c_w(gspca_dev, row);
1043 static void i2c_w2_buf(struct gspca_dev *gspca_dev,
1044 const struct i2c_reg_u16 *buf, int sz)
1047 i2c_w2(gspca_dev, buf->reg, buf->val);
1052 static void i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1054 struct sd *sd = (struct sd *) gspca_dev;
1057 row[0] = sd->i2c_intf | (1 << 4);
1058 row[1] = sd->i2c_addr;
1065 i2c_w(gspca_dev, row);
1066 row[0] = sd->i2c_intf | (1 << 4) | 0x02;
1068 i2c_w(gspca_dev, row);
1069 reg_r(gspca_dev, 0x10c2, 5);
1070 *val = gspca_dev->usb_buf[4];
1073 static void i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1075 struct sd *sd = (struct sd *) gspca_dev;
1078 row[0] = sd->i2c_intf | (1 << 4);
1079 row[1] = sd->i2c_addr;
1086 i2c_w(gspca_dev, row);
1087 row[0] = sd->i2c_intf | (2 << 4) | 0x02;
1089 i2c_w(gspca_dev, row);
1090 reg_r(gspca_dev, 0x10c2, 5);
1091 *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1094 static void ov9650_init_sensor(struct gspca_dev *gspca_dev)
1097 struct sd *sd = (struct sd *) gspca_dev;
1099 i2c_r2(gspca_dev, 0x1c, &id);
1100 if (gspca_dev->usb_err < 0)
1104 pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id);
1105 gspca_dev->usb_err = -ENODEV;
1109 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1111 i2c_w1_buf(gspca_dev, ov9650_init, ARRAY_SIZE(ov9650_init));
1112 if (gspca_dev->usb_err < 0)
1113 pr_err("OV9650 sensor initialization failed\n");
1118 static void ov9655_init_sensor(struct gspca_dev *gspca_dev)
1120 struct sd *sd = (struct sd *) gspca_dev;
1122 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1124 i2c_w1_buf(gspca_dev, ov9655_init, ARRAY_SIZE(ov9655_init));
1125 if (gspca_dev->usb_err < 0)
1126 pr_err("OV9655 sensor initialization failed\n");
1132 static void soi968_init_sensor(struct gspca_dev *gspca_dev)
1134 struct sd *sd = (struct sd *) gspca_dev;
1136 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1138 i2c_w1_buf(gspca_dev, soi968_init, ARRAY_SIZE(soi968_init));
1139 if (gspca_dev->usb_err < 0)
1140 pr_err("SOI968 sensor initialization failed\n");
1146 static void ov7660_init_sensor(struct gspca_dev *gspca_dev)
1148 struct sd *sd = (struct sd *) gspca_dev;
1150 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1152 i2c_w1_buf(gspca_dev, ov7660_init, ARRAY_SIZE(ov7660_init));
1153 if (gspca_dev->usb_err < 0)
1154 pr_err("OV7660 sensor initialization failed\n");
1159 static void ov7670_init_sensor(struct gspca_dev *gspca_dev)
1161 struct sd *sd = (struct sd *) gspca_dev;
1163 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1165 i2c_w1_buf(gspca_dev, ov7670_init, ARRAY_SIZE(ov7670_init));
1166 if (gspca_dev->usb_err < 0)
1167 pr_err("OV7670 sensor initialization failed\n");
1173 static void mt9v_init_sensor(struct gspca_dev *gspca_dev)
1175 struct sd *sd = (struct sd *) gspca_dev;
1178 sd->i2c_addr = 0x5d;
1179 i2c_r2(gspca_dev, 0xff, &value);
1180 if (gspca_dev->usb_err >= 0
1181 && value == 0x8243) {
1182 i2c_w2_buf(gspca_dev, mt9v011_init, ARRAY_SIZE(mt9v011_init));
1183 if (gspca_dev->usb_err < 0) {
1184 pr_err("MT9V011 sensor initialization failed\n");
1189 sd->sensor = SENSOR_MT9V011;
1190 pr_info("MT9V011 sensor detected\n");
1194 gspca_dev->usb_err = 0;
1195 sd->i2c_addr = 0x5c;
1196 i2c_w2(gspca_dev, 0x01, 0x0004);
1197 i2c_r2(gspca_dev, 0xff, &value);
1198 if (gspca_dev->usb_err >= 0
1199 && value == 0x823a) {
1200 i2c_w2_buf(gspca_dev, mt9v111_init, ARRAY_SIZE(mt9v111_init));
1201 if (gspca_dev->usb_err < 0) {
1202 pr_err("MT9V111 sensor initialization failed\n");
1207 sd->sensor = SENSOR_MT9V111;
1208 pr_info("MT9V111 sensor detected\n");
1212 gspca_dev->usb_err = 0;
1213 sd->i2c_addr = 0x5d;
1214 i2c_w2(gspca_dev, 0xf0, 0x0000);
1215 if (gspca_dev->usb_err < 0) {
1216 gspca_dev->usb_err = 0;
1217 sd->i2c_addr = 0x48;
1218 i2c_w2(gspca_dev, 0xf0, 0x0000);
1220 i2c_r2(gspca_dev, 0x00, &value);
1221 if (gspca_dev->usb_err >= 0
1222 && value == 0x1229) {
1223 i2c_w2_buf(gspca_dev, mt9v112_init, ARRAY_SIZE(mt9v112_init));
1224 if (gspca_dev->usb_err < 0) {
1225 pr_err("MT9V112 sensor initialization failed\n");
1230 sd->sensor = SENSOR_MT9V112;
1231 pr_info("MT9V112 sensor detected\n");
1235 gspca_dev->usb_err = -ENODEV;
1238 static void mt9m112_init_sensor(struct gspca_dev *gspca_dev)
1240 struct sd *sd = (struct sd *) gspca_dev;
1242 i2c_w2_buf(gspca_dev, mt9m112_init, ARRAY_SIZE(mt9m112_init));
1243 if (gspca_dev->usb_err < 0)
1244 pr_err("MT9M112 sensor initialization failed\n");
1250 static void mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1252 struct sd *sd = (struct sd *) gspca_dev;
1254 i2c_w2_buf(gspca_dev, mt9m111_init, ARRAY_SIZE(mt9m111_init));
1255 if (gspca_dev->usb_err < 0)
1256 pr_err("MT9M111 sensor initialization failed\n");
1262 static void mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1264 struct sd *sd = (struct sd *) gspca_dev;
1267 i2c_r2(gspca_dev, 0x00, &id);
1268 if (gspca_dev->usb_err < 0)
1271 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
1275 pr_info("MT9M001 color sensor detected\n");
1278 pr_info("MT9M001 mono sensor detected\n");
1281 pr_err("No MT9M001 chip detected, ID = %x\n\n", id);
1282 gspca_dev->usb_err = -ENODEV;
1286 i2c_w2_buf(gspca_dev, mt9m001_init, ARRAY_SIZE(mt9m001_init));
1287 if (gspca_dev->usb_err < 0)
1288 pr_err("MT9M001 sensor initialization failed\n");
1294 static void hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1296 struct sd *sd = (struct sd *) gspca_dev;
1298 i2c_w1_buf(gspca_dev, hv7131r_init, ARRAY_SIZE(hv7131r_init));
1299 if (gspca_dev->usb_err < 0)
1300 pr_err("HV7131R Sensor initialization failed\n");
1306 static void set_cmatrix(struct gspca_dev *gspca_dev,
1307 s32 brightness, s32 contrast, s32 satur, s32 hue)
1309 s32 hue_coord, hue_index = 180 + hue;
1312 memset(cmatrix, 0, sizeof(cmatrix));
1313 cmatrix[2] = (contrast * 0x25 / 0x100) + 0x26;
1314 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1315 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1316 cmatrix[18] = brightness - 0x80;
1318 hue_coord = (hsv_red_x[hue_index] * satur) >> 8;
1319 cmatrix[6] = hue_coord;
1320 cmatrix[7] = (hue_coord >> 8) & 0x0f;
1322 hue_coord = (hsv_red_y[hue_index] * satur) >> 8;
1323 cmatrix[8] = hue_coord;
1324 cmatrix[9] = (hue_coord >> 8) & 0x0f;
1326 hue_coord = (hsv_green_x[hue_index] * satur) >> 8;
1327 cmatrix[10] = hue_coord;
1328 cmatrix[11] = (hue_coord >> 8) & 0x0f;
1330 hue_coord = (hsv_green_y[hue_index] * satur) >> 8;
1331 cmatrix[12] = hue_coord;
1332 cmatrix[13] = (hue_coord >> 8) & 0x0f;
1334 hue_coord = (hsv_blue_x[hue_index] * satur) >> 8;
1335 cmatrix[14] = hue_coord;
1336 cmatrix[15] = (hue_coord >> 8) & 0x0f;
1338 hue_coord = (hsv_blue_y[hue_index] * satur) >> 8;
1339 cmatrix[16] = hue_coord;
1340 cmatrix[17] = (hue_coord >> 8) & 0x0f;
1342 reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1345 static void set_gamma(struct gspca_dev *gspca_dev, s32 val)
1348 u8 gval = val * 0xb8 / 0x100;
1351 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
1352 gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8);
1353 gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8);
1354 gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8);
1355 gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8);
1356 gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8);
1357 gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8);
1358 gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8);
1359 gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8);
1360 gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8);
1361 gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8);
1362 gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8);
1363 gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8);
1364 gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8);
1365 gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
1368 reg_w(gspca_dev, 0x1190, gamma, 17);
1371 static void set_redblue(struct gspca_dev *gspca_dev, s32 blue, s32 red)
1373 reg_w1(gspca_dev, 0x118c, red);
1374 reg_w1(gspca_dev, 0x118f, blue);
1377 static void set_hvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip)
1381 struct sd *sd = (struct sd *) gspca_dev;
1383 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1388 switch (sd->sensor) {
1399 reg_w1(gspca_dev, 0x1182, sd->vstart);
1400 i2c_w1(gspca_dev, 0x1e, value);
1403 i2c_r1(gspca_dev, 0x1e, &value);
1412 i2c_w1(gspca_dev, 0x1e, value);
1413 i2c_w1(gspca_dev, 0x3a, tslb);
1415 case SENSOR_MT9V111:
1416 case SENSOR_MT9V011:
1417 i2c_r2(gspca_dev, 0x20, &value2);
1423 i2c_w2(gspca_dev, 0x20, value2);
1425 case SENSOR_MT9M112:
1426 case SENSOR_MT9M111:
1427 case SENSOR_MT9V112:
1428 i2c_r2(gspca_dev, 0x20, &value2);
1434 i2c_w2(gspca_dev, 0x20, value2);
1436 case SENSOR_HV7131R:
1437 i2c_r1(gspca_dev, 0x01, &value);
1443 i2c_w1(gspca_dev, 0x01, value);
1448 static void set_exposure(struct gspca_dev *gspca_dev, s32 expo)
1450 struct sd *sd = (struct sd *) gspca_dev;
1451 u8 exp[8] = {sd->i2c_intf, sd->i2c_addr,
1452 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1455 if (gspca_dev->streaming)
1458 switch (sd->sensor) {
1468 exp[2] = 0x10; /* AECH */
1469 exp[3] = expo2 >> 2;
1471 i2c_w(gspca_dev, exp);
1472 exp[2] = 0x04; /* COM1 */
1473 exp[3] = expo2 & 0x0003;
1475 i2c_w(gspca_dev, exp);
1479 exp[2] = 0x2d; /* ADVFL & ADVFH */
1483 case SENSOR_MT9M001:
1484 case SENSOR_MT9V112:
1485 case SENSOR_MT9V011:
1491 case SENSOR_HV7131R:
1501 i2c_w(gspca_dev, exp);
1504 static void set_gain(struct gspca_dev *gspca_dev, s32 g)
1506 struct sd *sd = (struct sd *) gspca_dev;
1507 u8 gain[8] = {sd->i2c_intf, sd->i2c_addr,
1508 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1510 if (gspca_dev->streaming)
1511 gain[7] = 0x15; /* or 1d ? */
1513 switch (sd->sensor) {
1519 gain[0] |= (2 << 4);
1520 gain[3] = ov_gain[g];
1522 case SENSOR_MT9V011:
1523 gain[0] |= (3 << 4);
1525 gain[3] = micron1_gain[g] >> 8;
1526 gain[4] = micron1_gain[g];
1528 case SENSOR_MT9V112:
1529 gain[0] |= (3 << 4);
1531 gain[3] = micron1_gain[g] >> 8;
1532 gain[4] = micron1_gain[g];
1534 case SENSOR_MT9M001:
1535 gain[0] |= (3 << 4);
1537 gain[3] = micron2_gain[g] >> 8;
1538 gain[4] = micron2_gain[g];
1540 case SENSOR_HV7131R:
1541 gain[0] |= (2 << 4);
1543 gain[3] = hv7131r_gain[g];
1548 i2c_w(gspca_dev, gain);
1551 static void set_quality(struct gspca_dev *gspca_dev, s32 val)
1553 struct sd *sd = (struct sd *) gspca_dev;
1555 jpeg_set_qual(sd->jpeg_hdr, val);
1556 reg_w1(gspca_dev, 0x1061, 0x01); /* stop transfer */
1557 reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20); /* write QTAB */
1558 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
1559 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
1560 reg_w1(gspca_dev, 0x1061, 0x03); /* restart transfer */
1561 reg_w1(gspca_dev, 0x10e0, sd->fmt);
1562 sd->fmt ^= 0x0c; /* invert QTAB use + write */
1563 reg_w1(gspca_dev, 0x10e0, sd->fmt);
1566 #ifdef CONFIG_VIDEO_ADV_DEBUG
1567 static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1568 struct v4l2_dbg_register *reg)
1570 struct sd *sd = (struct sd *) gspca_dev;
1573 switch (reg->match.addr) {
1575 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1577 reg_r(gspca_dev, reg->reg, 1);
1578 reg->val = gspca_dev->usb_buf[0];
1579 return gspca_dev->usb_err;
1581 if (sd->sensor >= SENSOR_MT9V011 &&
1582 sd->sensor <= SENSOR_MT9M112) {
1583 i2c_r2(gspca_dev, reg->reg, (u16 *) ®->val);
1586 i2c_r1(gspca_dev, reg->reg, (u8 *) ®->val);
1588 return gspca_dev->usb_err;
1593 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1594 const struct v4l2_dbg_register *reg)
1596 struct sd *sd = (struct sd *) gspca_dev;
1598 switch (reg->match.addr) {
1600 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1602 reg_w1(gspca_dev, reg->reg, reg->val);
1603 return gspca_dev->usb_err;
1605 if (sd->sensor >= SENSOR_MT9V011 &&
1606 sd->sensor <= SENSOR_MT9M112) {
1607 i2c_w2(gspca_dev, reg->reg, reg->val);
1609 i2c_w1(gspca_dev, reg->reg, reg->val);
1611 return gspca_dev->usb_err;
1616 static int sd_chip_info(struct gspca_dev *gspca_dev,
1617 struct v4l2_dbg_chip_info *chip)
1619 if (chip->match.addr > 1)
1621 if (chip->match.addr == 1)
1622 strlcpy(chip->name, "sensor", sizeof(chip->name));
1627 static int sd_config(struct gspca_dev *gspca_dev,
1628 const struct usb_device_id *id)
1630 struct sd *sd = (struct sd *) gspca_dev;
1633 cam = &gspca_dev->cam;
1634 cam->needs_full_bandwidth = 1;
1636 sd->sensor = id->driver_info >> 8;
1637 sd->i2c_addr = id->driver_info;
1638 sd->flags = id->driver_info >> 16;
1639 sd->i2c_intf = 0x80; /* i2c 100 Kb/s */
1641 switch (sd->sensor) {
1642 case SENSOR_MT9M112:
1643 case SENSOR_MT9M111:
1646 cam->cam_mode = sxga_mode;
1647 cam->nmodes = ARRAY_SIZE(sxga_mode);
1649 case SENSOR_MT9M001:
1650 cam->cam_mode = mono_mode;
1651 cam->nmodes = ARRAY_SIZE(mono_mode);
1653 case SENSOR_HV7131R:
1654 sd->i2c_intf = 0x81; /* i2c 400 Kb/s */
1657 cam->cam_mode = vga_mode;
1658 cam->nmodes = ARRAY_SIZE(vga_mode);
1664 sd->exposure_step = 16;
1666 INIT_WORK(&sd->work, qual_upd);
1671 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
1673 struct gspca_dev *gspca_dev =
1674 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
1675 struct sd *sd = (struct sd *)gspca_dev;
1677 gspca_dev->usb_err = 0;
1679 if (!gspca_dev->streaming)
1683 /* color control cluster */
1684 case V4L2_CID_BRIGHTNESS:
1685 set_cmatrix(gspca_dev, sd->brightness->val,
1686 sd->contrast->val, sd->saturation->val, sd->hue->val);
1688 case V4L2_CID_GAMMA:
1689 set_gamma(gspca_dev, ctrl->val);
1691 /* blue/red balance cluster */
1692 case V4L2_CID_BLUE_BALANCE:
1693 set_redblue(gspca_dev, sd->blue->val, sd->red->val);
1695 /* h/vflip cluster */
1696 case V4L2_CID_HFLIP:
1697 set_hvflip(gspca_dev, sd->hflip->val, sd->vflip->val);
1699 /* standalone exposure control */
1700 case V4L2_CID_EXPOSURE:
1701 set_exposure(gspca_dev, ctrl->val);
1703 /* standalone gain control */
1705 set_gain(gspca_dev, ctrl->val);
1707 /* autogain + exposure or gain control cluster */
1708 case V4L2_CID_AUTOGAIN:
1709 if (sd->sensor == SENSOR_SOI968)
1710 set_gain(gspca_dev, sd->gain->val);
1712 set_exposure(gspca_dev, sd->exposure->val);
1714 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1715 set_quality(gspca_dev, ctrl->val);
1718 return gspca_dev->usb_err;
1721 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1722 .s_ctrl = sd_s_ctrl,
1725 static int sd_init_controls(struct gspca_dev *gspca_dev)
1727 struct sd *sd = (struct sd *) gspca_dev;
1728 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1730 gspca_dev->vdev.ctrl_handler = hdl;
1731 v4l2_ctrl_handler_init(hdl, 13);
1733 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1734 V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
1735 sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1736 V4L2_CID_CONTRAST, 0, 255, 1, 127);
1737 sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1738 V4L2_CID_SATURATION, 0, 255, 1, 127);
1739 sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1740 V4L2_CID_HUE, -180, 180, 1, 0);
1742 sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1743 V4L2_CID_GAMMA, 0, 255, 1, 0x10);
1745 sd->blue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1746 V4L2_CID_BLUE_BALANCE, 0, 127, 1, 0x28);
1747 sd->red = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1748 V4L2_CID_RED_BALANCE, 0, 127, 1, 0x28);
1750 if (sd->sensor != SENSOR_OV9655 && sd->sensor != SENSOR_SOI968 &&
1751 sd->sensor != SENSOR_OV7670 && sd->sensor != SENSOR_MT9M001 &&
1752 sd->sensor != SENSOR_MT9VPRB) {
1753 sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1754 V4L2_CID_HFLIP, 0, 1, 1, 0);
1755 sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1756 V4L2_CID_VFLIP, 0, 1, 1, 0);
1759 if (sd->sensor != SENSOR_SOI968 && sd->sensor != SENSOR_MT9VPRB &&
1760 sd->sensor != SENSOR_MT9M112 && sd->sensor != SENSOR_MT9M111 &&
1761 sd->sensor != SENSOR_MT9V111)
1762 sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1763 V4L2_CID_EXPOSURE, 0, 0x1780, 1, 0x33);
1765 if (sd->sensor != SENSOR_MT9VPRB && sd->sensor != SENSOR_MT9M112 &&
1766 sd->sensor != SENSOR_MT9M111 && sd->sensor != SENSOR_MT9V111) {
1767 sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1768 V4L2_CID_GAIN, 0, 28, 1, 0);
1769 sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1770 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1773 sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1774 V4L2_CID_JPEG_COMPRESSION_QUALITY, 50, 90, 1, 80);
1776 pr_err("Could not initialize controls\n");
1780 v4l2_ctrl_cluster(4, &sd->brightness);
1781 v4l2_ctrl_cluster(2, &sd->blue);
1783 v4l2_ctrl_cluster(2, &sd->hflip);
1785 if (sd->sensor == SENSOR_SOI968)
1786 /* this sensor doesn't have the exposure control and
1787 autogain is clustered with gain instead. This works
1788 because sd->exposure == NULL. */
1789 v4l2_ctrl_auto_cluster(3, &sd->autogain, 0, false);
1791 /* Otherwise autogain is clustered with exposure. */
1792 v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false);
1797 static int sd_init(struct gspca_dev *gspca_dev)
1799 struct sd *sd = (struct sd *) gspca_dev;
1803 0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
1806 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
1807 value = bridge_init[i][1];
1808 reg_w(gspca_dev, bridge_init[i][0], &value, 1);
1809 if (gspca_dev->usb_err < 0) {
1810 pr_err("Device initialization failed\n");
1811 return gspca_dev->usb_err;
1815 if (sd->flags & LED_REVERSE)
1816 reg_w1(gspca_dev, 0x1006, 0x00);
1818 reg_w1(gspca_dev, 0x1006, 0x20);
1820 reg_w(gspca_dev, 0x10c0, i2c_init, 9);
1821 if (gspca_dev->usb_err < 0) {
1822 pr_err("Device initialization failed\n");
1823 return gspca_dev->usb_err;
1826 switch (sd->sensor) {
1828 ov9650_init_sensor(gspca_dev);
1829 if (gspca_dev->usb_err < 0)
1831 pr_info("OV9650 sensor detected\n");
1834 ov9655_init_sensor(gspca_dev);
1835 if (gspca_dev->usb_err < 0)
1837 pr_info("OV9655 sensor detected\n");
1840 soi968_init_sensor(gspca_dev);
1841 if (gspca_dev->usb_err < 0)
1843 pr_info("SOI968 sensor detected\n");
1846 ov7660_init_sensor(gspca_dev);
1847 if (gspca_dev->usb_err < 0)
1849 pr_info("OV7660 sensor detected\n");
1852 ov7670_init_sensor(gspca_dev);
1853 if (gspca_dev->usb_err < 0)
1855 pr_info("OV7670 sensor detected\n");
1857 case SENSOR_MT9VPRB:
1858 mt9v_init_sensor(gspca_dev);
1859 if (gspca_dev->usb_err < 0)
1861 pr_info("MT9VPRB sensor detected\n");
1863 case SENSOR_MT9M111:
1864 mt9m111_init_sensor(gspca_dev);
1865 if (gspca_dev->usb_err < 0)
1867 pr_info("MT9M111 sensor detected\n");
1869 case SENSOR_MT9M112:
1870 mt9m112_init_sensor(gspca_dev);
1871 if (gspca_dev->usb_err < 0)
1873 pr_info("MT9M112 sensor detected\n");
1875 case SENSOR_MT9M001:
1876 mt9m001_init_sensor(gspca_dev);
1877 if (gspca_dev->usb_err < 0)
1880 case SENSOR_HV7131R:
1881 hv7131r_init_sensor(gspca_dev);
1882 if (gspca_dev->usb_err < 0)
1884 pr_info("HV7131R sensor detected\n");
1887 pr_err("Unsupported sensor\n");
1888 gspca_dev->usb_err = -ENODEV;
1890 return gspca_dev->usb_err;
1893 static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
1895 struct sd *sd = (struct sd *) gspca_dev;
1898 switch (sd->sensor) {
1900 if (mode & MODE_SXGA) {
1901 i2c_w1(gspca_dev, 0x17, 0x1d);
1902 i2c_w1(gspca_dev, 0x18, 0xbd);
1903 i2c_w1(gspca_dev, 0x19, 0x01);
1904 i2c_w1(gspca_dev, 0x1a, 0x81);
1905 i2c_w1(gspca_dev, 0x12, 0x00);
1909 i2c_w1(gspca_dev, 0x17, 0x13);
1910 i2c_w1(gspca_dev, 0x18, 0x63);
1911 i2c_w1(gspca_dev, 0x19, 0x01);
1912 i2c_w1(gspca_dev, 0x1a, 0x79);
1913 i2c_w1(gspca_dev, 0x12, 0x40);
1919 if (mode & MODE_SXGA) {
1920 i2c_w1(gspca_dev, 0x17, 0x1b);
1921 i2c_w1(gspca_dev, 0x18, 0xbc);
1922 i2c_w1(gspca_dev, 0x19, 0x01);
1923 i2c_w1(gspca_dev, 0x1a, 0x82);
1924 i2c_r1(gspca_dev, 0x12, &value);
1925 i2c_w1(gspca_dev, 0x12, value & 0x07);
1927 i2c_w1(gspca_dev, 0x17, 0x24);
1928 i2c_w1(gspca_dev, 0x18, 0xc5);
1929 i2c_w1(gspca_dev, 0x19, 0x00);
1930 i2c_w1(gspca_dev, 0x1a, 0x3c);
1931 i2c_r1(gspca_dev, 0x12, &value);
1932 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
1935 case SENSOR_MT9M112:
1936 case SENSOR_MT9M111:
1937 if (mode & MODE_SXGA) {
1938 i2c_w2(gspca_dev, 0xf0, 0x0002);
1939 i2c_w2(gspca_dev, 0xc8, 0x970b);
1940 i2c_w2(gspca_dev, 0xf0, 0x0000);
1942 i2c_w2(gspca_dev, 0xf0, 0x0002);
1943 i2c_w2(gspca_dev, 0xc8, 0x8000);
1944 i2c_w2(gspca_dev, 0xf0, 0x0000);
1950 static int sd_isoc_init(struct gspca_dev *gspca_dev)
1952 struct usb_interface *intf;
1953 u32 flags = gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv;
1956 * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth
1957 * than our regular bandwidth calculations reserve, so we force the
1958 * use of a specific altsetting when using the SN9C20X_I420 fmt.
1960 if (!(flags & (MODE_RAW | MODE_JPEG))) {
1961 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
1963 if (intf->num_altsetting != 9) {
1964 pr_warn("sn9c20x camera with unknown number of alt "
1965 "settings (%d), please report!\n",
1966 intf->num_altsetting);
1967 gspca_dev->alt = intf->num_altsetting;
1971 switch (gspca_dev->pixfmt.width) {
1972 case 160: /* 160x120 */
1975 case 320: /* 320x240 */
1978 default: /* >= 640x480 */
1987 #define HW_WIN(mode, hstart, vstart) \
1988 ((const u8 []){hstart, 0, vstart, 0, \
1989 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
1990 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
1992 #define CLR_WIN(width, height) \
1994 {0, width >> 2, 0, height >> 1,\
1995 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
1997 static int sd_start(struct gspca_dev *gspca_dev)
1999 struct sd *sd = (struct sd *) gspca_dev;
2000 int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
2001 int width = gspca_dev->pixfmt.width;
2002 int height = gspca_dev->pixfmt.height;
2005 jpeg_define(sd->jpeg_hdr, height, width,
2007 jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual));
2009 if (mode & MODE_RAW)
2011 else if (mode & MODE_JPEG)
2014 fmt = 0x2f; /* YUV 420 */
2017 switch (mode & SCALE_MASK) {
2018 case SCALE_1280x1024:
2020 pr_info("Set 1280x1024\n");
2024 pr_info("Set 640x480\n");
2028 pr_info("Set 320x240\n");
2032 pr_info("Set 160x120\n");
2036 configure_sensor_output(gspca_dev, mode);
2037 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2038 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2039 reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2040 reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2041 reg_w1(gspca_dev, 0x1189, scale);
2042 reg_w1(gspca_dev, 0x10e0, fmt);
2044 set_cmatrix(gspca_dev, v4l2_ctrl_g_ctrl(sd->brightness),
2045 v4l2_ctrl_g_ctrl(sd->contrast),
2046 v4l2_ctrl_g_ctrl(sd->saturation),
2047 v4l2_ctrl_g_ctrl(sd->hue));
2048 set_gamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma));
2049 set_redblue(gspca_dev, v4l2_ctrl_g_ctrl(sd->blue),
2050 v4l2_ctrl_g_ctrl(sd->red));
2052 set_gain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain));
2054 set_exposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure));
2056 set_hvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip),
2057 v4l2_ctrl_g_ctrl(sd->vflip));
2059 reg_w1(gspca_dev, 0x1007, 0x20);
2060 reg_w1(gspca_dev, 0x1061, 0x03);
2062 /* if JPEG, prepare the compression quality update */
2063 if (mode & MODE_JPEG) {
2064 sd->pktsz = sd->npkt = 0;
2067 create_singlethread_workqueue(KBUILD_MODNAME);
2070 return gspca_dev->usb_err;
2073 static void sd_stopN(struct gspca_dev *gspca_dev)
2075 reg_w1(gspca_dev, 0x1007, 0x00);
2076 reg_w1(gspca_dev, 0x1061, 0x01);
2079 /* called on streamoff with alt==0 and on disconnect */
2080 /* the usb_lock is held at entry - restore on exit */
2081 static void sd_stop0(struct gspca_dev *gspca_dev)
2083 struct sd *sd = (struct sd *) gspca_dev;
2085 if (sd->work_thread != NULL) {
2086 mutex_unlock(&gspca_dev->usb_lock);
2087 destroy_workqueue(sd->work_thread);
2088 mutex_lock(&gspca_dev->usb_lock);
2089 sd->work_thread = NULL;
2093 static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2095 struct sd *sd = (struct sd *) gspca_dev;
2096 s32 cur_exp = v4l2_ctrl_g_ctrl(sd->exposure);
2097 s32 max = sd->exposure->maximum - sd->exposure_step;
2098 s32 min = sd->exposure->minimum + sd->exposure_step;
2102 * some hardcoded values are present
2103 * like those for maximal/minimal exposure
2104 * and exposure steps
2106 if (avg_lum < MIN_AVG_LUM) {
2110 new_exp = cur_exp + sd->exposure_step;
2115 v4l2_ctrl_s_ctrl(sd->exposure, new_exp);
2117 sd->older_step = sd->old_step;
2120 if (sd->old_step ^ sd->older_step)
2121 sd->exposure_step /= 2;
2123 sd->exposure_step += 2;
2125 if (avg_lum > MAX_AVG_LUM) {
2128 new_exp = cur_exp - sd->exposure_step;
2133 v4l2_ctrl_s_ctrl(sd->exposure, new_exp);
2134 sd->older_step = sd->old_step;
2137 if (sd->old_step ^ sd->older_step)
2138 sd->exposure_step /= 2;
2140 sd->exposure_step += 2;
2144 static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2146 struct sd *sd = (struct sd *) gspca_dev;
2147 s32 cur_gain = v4l2_ctrl_g_ctrl(sd->gain);
2149 if (avg_lum < MIN_AVG_LUM && cur_gain < sd->gain->maximum)
2150 v4l2_ctrl_s_ctrl(sd->gain, cur_gain + 1);
2151 if (avg_lum > MAX_AVG_LUM && cur_gain > sd->gain->minimum)
2152 v4l2_ctrl_s_ctrl(sd->gain, cur_gain - 1);
2155 static void sd_dqcallback(struct gspca_dev *gspca_dev)
2157 struct sd *sd = (struct sd *) gspca_dev;
2160 if (sd->autogain == NULL || !v4l2_ctrl_g_ctrl(sd->autogain))
2163 avg_lum = atomic_read(&sd->avg_lum);
2164 if (sd->sensor == SENSOR_SOI968)
2165 do_autogain(gspca_dev, avg_lum);
2167 do_autoexposure(gspca_dev, avg_lum);
2170 /* JPEG quality update */
2171 /* This function is executed from a work queue. */
2172 static void qual_upd(struct work_struct *work)
2174 struct sd *sd = container_of(work, struct sd, work);
2175 struct gspca_dev *gspca_dev = &sd->gspca_dev;
2176 s32 qual = v4l2_ctrl_g_ctrl(sd->jpegqual);
2178 /* To protect gspca_dev->usb_buf and gspca_dev->usb_err */
2179 mutex_lock(&gspca_dev->usb_lock);
2180 PDEBUG(D_STREAM, "qual_upd %d%%", qual);
2181 gspca_dev->usb_err = 0;
2182 set_quality(gspca_dev, qual);
2183 mutex_unlock(&gspca_dev->usb_lock);
2186 #if IS_ENABLED(CONFIG_INPUT)
2187 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2188 u8 *data, /* interrupt packet */
2189 int len) /* interrupt packet length */
2191 struct sd *sd = (struct sd *) gspca_dev;
2193 if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
2194 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2195 input_sync(gspca_dev->input_dev);
2196 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2197 input_sync(gspca_dev->input_dev);
2204 /* check the JPEG compression */
2205 static void transfer_check(struct gspca_dev *gspca_dev,
2208 struct sd *sd = (struct sd *) gspca_dev;
2213 /* if USB error, discard the frame and decrease the quality */
2214 if (data[6] & 0x08) { /* USB FIFO full */
2215 gspca_dev->last_packet_type = DISCARD_PACKET;
2219 /* else, compute the filling rate and a new JPEG quality */
2220 r = (sd->pktsz * 100) /
2222 gspca_dev->urb[0]->iso_frame_desc[0].length);
2228 if (new_qual != 0) {
2229 sd->nchg += new_qual;
2230 if (sd->nchg < -6 || sd->nchg >= 12) {
2231 /* Note: we are in interrupt context, so we can't
2232 use v4l2_ctrl_g/s_ctrl here. Access the value
2233 directly instead. */
2234 s32 curqual = sd->jpegqual->cur.val;
2236 new_qual += curqual;
2237 if (new_qual < sd->jpegqual->minimum)
2238 new_qual = sd->jpegqual->minimum;
2239 else if (new_qual > sd->jpegqual->maximum)
2240 new_qual = sd->jpegqual->maximum;
2241 if (new_qual != curqual) {
2242 sd->jpegqual->cur.val = new_qual;
2243 queue_work(sd->work_thread, &sd->work);
2249 sd->pktsz = sd->npkt = 0;
2252 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2253 u8 *data, /* isoc packet */
2254 int len) /* iso packet length */
2256 struct sd *sd = (struct sd *) gspca_dev;
2257 int avg_lum, is_jpeg;
2258 static const u8 frame_header[] = {
2259 0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96
2262 is_jpeg = (sd->fmt & 0x03) == 0;
2263 if (len >= 64 && memcmp(data, frame_header, 6) == 0) {
2264 avg_lum = ((data[35] >> 2) & 3) |
2267 avg_lum += ((data[35] >> 4) & 3) |
2270 avg_lum += ((data[35] >> 6) & 3) |
2273 avg_lum += (data[36] & 3) |
2276 avg_lum += ((data[36] >> 2) & 3) |
2279 avg_lum += ((data[36] >> 4) & 3) |
2282 avg_lum += ((data[36] >> 6) & 3) |
2285 avg_lum += ((data[44] >> 4) & 3) |
2289 atomic_set(&sd->avg_lum, avg_lum);
2292 transfer_check(gspca_dev, data);
2294 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2300 if (gspca_dev->last_packet_type == LAST_PACKET) {
2302 gspca_frame_add(gspca_dev, FIRST_PACKET,
2303 sd->jpeg_hdr, JPEG_HDR_SZ);
2304 gspca_frame_add(gspca_dev, INTER_PACKET,
2307 gspca_frame_add(gspca_dev, FIRST_PACKET,
2311 /* if JPEG, count the packets and their size */
2316 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2320 /* sub-driver description */
2321 static const struct sd_desc sd_desc = {
2322 .name = KBUILD_MODNAME,
2323 .config = sd_config,
2325 .init_controls = sd_init_controls,
2326 .isoc_init = sd_isoc_init,
2330 .pkt_scan = sd_pkt_scan,
2331 #if IS_ENABLED(CONFIG_INPUT)
2332 .int_pkt_scan = sd_int_pkt_scan,
2334 .dq_callback = sd_dqcallback,
2335 #ifdef CONFIG_VIDEO_ADV_DEBUG
2336 .set_register = sd_dbg_s_register,
2337 .get_register = sd_dbg_g_register,
2338 .get_chip_info = sd_chip_info,
2342 #define SN9C20X(sensor, i2c_addr, flags) \
2343 .driver_info = ((flags & 0xff) << 16) \
2344 | (SENSOR_ ## sensor << 8) \
2347 static const struct usb_device_id device_table[] = {
2348 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2349 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
2350 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2351 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
2352 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
2353 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
2354 (FLIP_DETECT | HAS_NO_BUTTON))},
2355 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2356 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2357 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2358 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2359 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, FLIP_DETECT)},
2360 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2361 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2362 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2363 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2364 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
2365 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
2366 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2367 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2368 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2369 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2370 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, LED_REVERSE)},
2371 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, LED_REVERSE)},
2372 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2373 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2374 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2375 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2376 {USB_DEVICE(0x0458, 0x7045), SN9C20X(MT9M112, 0x5d, LED_REVERSE)},
2377 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
2378 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
2379 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2380 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2381 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2382 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2383 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
2384 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2385 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2388 MODULE_DEVICE_TABLE(usb, device_table);
2390 /* -- device connect -- */
2391 static int sd_probe(struct usb_interface *intf,
2392 const struct usb_device_id *id)
2394 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2398 static struct usb_driver sd_driver = {
2399 .name = KBUILD_MODNAME,
2400 .id_table = device_table,
2402 .disconnect = gspca_disconnect,
2404 .suspend = gspca_suspend,
2405 .resume = gspca_resume,
2406 .reset_resume = gspca_resume,
2410 module_usb_driver(sd_driver);