1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Sonix sn9c201 sn9c202 library
5 * Copyright (C) 2012 Jean-Francois Moine <http://moinejf.free.fr>
6 * Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com>
7 * Copyright (C) 2009 Brian Johnson <brijohn@gmail.com>
10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12 #include <linux/input.h>
17 #include <linux/dmi.h>
19 MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, microdia project <microdia@googlegroups.com>");
20 MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
21 MODULE_LICENSE("GPL");
24 * Pixel format private data
26 #define SCALE_MASK 0x0f
27 #define SCALE_160x120 0
28 #define SCALE_320x240 1
29 #define SCALE_640x480 2
30 #define SCALE_1280x1024 3
32 #define MODE_JPEG 0x20
33 #define MODE_SXGA 0x80
35 #define SENSOR_OV9650 0
36 #define SENSOR_OV9655 1
37 #define SENSOR_SOI968 2
38 #define SENSOR_OV7660 3
39 #define SENSOR_OV7670 4
40 #define SENSOR_MT9V011 5
41 #define SENSOR_MT9V111 6
42 #define SENSOR_MT9V112 7
43 #define SENSOR_MT9M001 8
44 #define SENSOR_MT9M111 9
45 #define SENSOR_MT9M112 10
46 #define SENSOR_HV7131R 11
47 #define SENSOR_MT9VPRB 12
50 #define HAS_NO_BUTTON 0x1
51 #define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
52 #define FLIP_DETECT 0x4
53 #define HAS_LED_TORCH 0x8
55 /* specific webcam descriptor */
57 struct gspca_dev gspca_dev;
59 struct { /* color control cluster */
60 struct v4l2_ctrl *brightness;
61 struct v4l2_ctrl *contrast;
62 struct v4l2_ctrl *saturation;
63 struct v4l2_ctrl *hue;
65 struct { /* blue/red balance control cluster */
66 struct v4l2_ctrl *blue;
67 struct v4l2_ctrl *red;
69 struct { /* h/vflip control cluster */
70 struct v4l2_ctrl *hflip;
71 struct v4l2_ctrl *vflip;
73 struct v4l2_ctrl *gamma;
74 struct { /* autogain and exposure or gain control cluster */
75 struct v4l2_ctrl *autogain;
76 struct v4l2_ctrl *exposure;
77 struct v4l2_ctrl *gain;
79 struct v4l2_ctrl *jpegqual;
81 struct v4l2_ctrl *led_mode;
83 struct work_struct work;
85 u32 pktsz; /* (used by pkt_scan) */
88 u8 fmt; /* (used for JPEG QTAB update */
90 #define MIN_AVG_LUM 80
91 #define MAX_AVG_LUM 130
103 u8 jpeg_hdr[JPEG_HDR_SZ];
108 static void qual_upd(struct work_struct *work);
120 static const struct dmi_system_id flip_dmi_table[] = {
122 .ident = "MSI MS-1034",
124 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
125 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1034"),
126 DMI_MATCH(DMI_PRODUCT_VERSION, "0341")
130 .ident = "MSI MS-1039",
132 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
133 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1039"),
137 .ident = "MSI MS-1632",
139 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
140 DMI_MATCH(DMI_BOARD_NAME, "MS-1632")
144 .ident = "MSI MS-1633X",
146 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
147 DMI_MATCH(DMI_BOARD_NAME, "MS-1633X")
151 .ident = "MSI MS-1635X",
153 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
154 DMI_MATCH(DMI_BOARD_NAME, "MS-1635X")
158 .ident = "ASUSTeK W7J",
160 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
161 DMI_MATCH(DMI_BOARD_NAME, "W7J ")
167 static const struct v4l2_pix_format vga_mode[] = {
168 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
170 .sizeimage = 160 * 120 * 4 / 8 + 590,
171 .colorspace = V4L2_COLORSPACE_JPEG,
172 .priv = SCALE_160x120 | MODE_JPEG},
173 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
175 .sizeimage = 160 * 120,
176 .colorspace = V4L2_COLORSPACE_SRGB,
177 .priv = SCALE_160x120 | MODE_RAW},
178 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
180 .sizeimage = 240 * 120,
181 .colorspace = V4L2_COLORSPACE_SRGB,
182 .priv = SCALE_160x120},
183 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
185 .sizeimage = 320 * 240 * 4 / 8 + 590,
186 .colorspace = V4L2_COLORSPACE_JPEG,
187 .priv = SCALE_320x240 | MODE_JPEG},
188 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
190 .sizeimage = 320 * 240 ,
191 .colorspace = V4L2_COLORSPACE_SRGB,
192 .priv = SCALE_320x240 | MODE_RAW},
193 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
195 .sizeimage = 480 * 240 ,
196 .colorspace = V4L2_COLORSPACE_SRGB,
197 .priv = SCALE_320x240},
198 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
200 .sizeimage = 640 * 480 * 4 / 8 + 590,
201 .colorspace = V4L2_COLORSPACE_JPEG,
202 .priv = SCALE_640x480 | MODE_JPEG},
203 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
205 .sizeimage = 640 * 480,
206 .colorspace = V4L2_COLORSPACE_SRGB,
207 .priv = SCALE_640x480 | MODE_RAW},
208 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
210 .sizeimage = 960 * 480,
211 .colorspace = V4L2_COLORSPACE_SRGB,
212 .priv = SCALE_640x480},
215 static const struct v4l2_pix_format sxga_mode[] = {
216 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
218 .sizeimage = 160 * 120 * 4 / 8 + 590,
219 .colorspace = V4L2_COLORSPACE_JPEG,
220 .priv = SCALE_160x120 | MODE_JPEG},
221 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
223 .sizeimage = 160 * 120,
224 .colorspace = V4L2_COLORSPACE_SRGB,
225 .priv = SCALE_160x120 | MODE_RAW},
226 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
228 .sizeimage = 240 * 120,
229 .colorspace = V4L2_COLORSPACE_SRGB,
230 .priv = SCALE_160x120},
231 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
233 .sizeimage = 320 * 240 * 4 / 8 + 590,
234 .colorspace = V4L2_COLORSPACE_JPEG,
235 .priv = SCALE_320x240 | MODE_JPEG},
236 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
238 .sizeimage = 320 * 240 ,
239 .colorspace = V4L2_COLORSPACE_SRGB,
240 .priv = SCALE_320x240 | MODE_RAW},
241 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
243 .sizeimage = 480 * 240 ,
244 .colorspace = V4L2_COLORSPACE_SRGB,
245 .priv = SCALE_320x240},
246 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
248 .sizeimage = 640 * 480 * 4 / 8 + 590,
249 .colorspace = V4L2_COLORSPACE_JPEG,
250 .priv = SCALE_640x480 | MODE_JPEG},
251 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
253 .sizeimage = 640 * 480,
254 .colorspace = V4L2_COLORSPACE_SRGB,
255 .priv = SCALE_640x480 | MODE_RAW},
256 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
258 .sizeimage = 960 * 480,
259 .colorspace = V4L2_COLORSPACE_SRGB,
260 .priv = SCALE_640x480},
261 {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
262 .bytesperline = 1280,
263 .sizeimage = 1280 * 1024,
264 .colorspace = V4L2_COLORSPACE_SRGB,
265 .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
268 static const struct v4l2_pix_format mono_mode[] = {
269 {160, 120, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
271 .sizeimage = 160 * 120,
272 .colorspace = V4L2_COLORSPACE_SRGB,
273 .priv = SCALE_160x120 | MODE_RAW},
274 {320, 240, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
276 .sizeimage = 320 * 240 ,
277 .colorspace = V4L2_COLORSPACE_SRGB,
278 .priv = SCALE_320x240 | MODE_RAW},
279 {640, 480, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
281 .sizeimage = 640 * 480,
282 .colorspace = V4L2_COLORSPACE_SRGB,
283 .priv = SCALE_640x480 | MODE_RAW},
284 {1280, 1024, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
285 .bytesperline = 1280,
286 .sizeimage = 1280 * 1024,
287 .colorspace = V4L2_COLORSPACE_SRGB,
288 .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
291 static const s16 hsv_red_x[] = {
292 41, 44, 46, 48, 50, 52, 54, 56,
293 58, 60, 62, 64, 66, 68, 70, 72,
294 74, 76, 78, 80, 81, 83, 85, 87,
295 88, 90, 92, 93, 95, 97, 98, 100,
296 101, 102, 104, 105, 107, 108, 109, 110,
297 112, 113, 114, 115, 116, 117, 118, 119,
298 120, 121, 122, 123, 123, 124, 125, 125,
299 126, 127, 127, 128, 128, 129, 129, 129,
300 130, 130, 130, 130, 131, 131, 131, 131,
301 131, 131, 131, 131, 130, 130, 130, 130,
302 129, 129, 129, 128, 128, 127, 127, 126,
303 125, 125, 124, 123, 122, 122, 121, 120,
304 119, 118, 117, 116, 115, 114, 112, 111,
305 110, 109, 107, 106, 105, 103, 102, 101,
306 99, 98, 96, 94, 93, 91, 90, 88,
307 86, 84, 83, 81, 79, 77, 75, 74,
308 72, 70, 68, 66, 64, 62, 60, 58,
309 56, 54, 52, 49, 47, 45, 43, 41,
310 39, 36, 34, 32, 30, 28, 25, 23,
311 21, 19, 16, 14, 12, 9, 7, 5,
312 3, 0, -1, -3, -6, -8, -10, -12,
313 -15, -17, -19, -22, -24, -26, -28, -30,
314 -33, -35, -37, -39, -41, -44, -46, -48,
315 -50, -52, -54, -56, -58, -60, -62, -64,
316 -66, -68, -70, -72, -74, -76, -78, -80,
317 -81, -83, -85, -87, -88, -90, -92, -93,
318 -95, -97, -98, -100, -101, -102, -104, -105,
319 -107, -108, -109, -110, -112, -113, -114, -115,
320 -116, -117, -118, -119, -120, -121, -122, -123,
321 -123, -124, -125, -125, -126, -127, -127, -128,
322 -128, -128, -128, -128, -128, -128, -128, -128,
323 -128, -128, -128, -128, -128, -128, -128, -128,
324 -128, -128, -128, -128, -128, -128, -128, -128,
325 -128, -127, -127, -126, -125, -125, -124, -123,
326 -122, -122, -121, -120, -119, -118, -117, -116,
327 -115, -114, -112, -111, -110, -109, -107, -106,
328 -105, -103, -102, -101, -99, -98, -96, -94,
329 -93, -91, -90, -88, -86, -84, -83, -81,
330 -79, -77, -75, -74, -72, -70, -68, -66,
331 -64, -62, -60, -58, -56, -54, -52, -49,
332 -47, -45, -43, -41, -39, -36, -34, -32,
333 -30, -28, -25, -23, -21, -19, -16, -14,
334 -12, -9, -7, -5, -3, 0, 1, 3,
335 6, 8, 10, 12, 15, 17, 19, 22,
336 24, 26, 28, 30, 33, 35, 37, 39, 41
339 static const s16 hsv_red_y[] = {
340 82, 80, 78, 76, 74, 73, 71, 69,
341 67, 65, 63, 61, 58, 56, 54, 52,
342 50, 48, 46, 44, 41, 39, 37, 35,
343 32, 30, 28, 26, 23, 21, 19, 16,
344 14, 12, 10, 7, 5, 3, 0, -1,
345 -3, -6, -8, -10, -13, -15, -17, -19,
346 -22, -24, -26, -29, -31, -33, -35, -38,
347 -40, -42, -44, -46, -48, -51, -53, -55,
348 -57, -59, -61, -63, -65, -67, -69, -71,
349 -73, -75, -77, -79, -81, -82, -84, -86,
350 -88, -89, -91, -93, -94, -96, -98, -99,
351 -101, -102, -104, -105, -106, -108, -109, -110,
352 -112, -113, -114, -115, -116, -117, -119, -120,
353 -120, -121, -122, -123, -124, -125, -126, -126,
354 -127, -128, -128, -128, -128, -128, -128, -128,
355 -128, -128, -128, -128, -128, -128, -128, -128,
356 -128, -128, -128, -128, -128, -128, -128, -128,
357 -128, -128, -128, -128, -128, -128, -128, -128,
358 -127, -127, -126, -125, -125, -124, -123, -122,
359 -121, -120, -119, -118, -117, -116, -115, -114,
360 -113, -111, -110, -109, -107, -106, -105, -103,
361 -102, -100, -99, -97, -96, -94, -92, -91,
362 -89, -87, -85, -84, -82, -80, -78, -76,
363 -74, -73, -71, -69, -67, -65, -63, -61,
364 -58, -56, -54, -52, -50, -48, -46, -44,
365 -41, -39, -37, -35, -32, -30, -28, -26,
366 -23, -21, -19, -16, -14, -12, -10, -7,
367 -5, -3, 0, 1, 3, 6, 8, 10,
368 13, 15, 17, 19, 22, 24, 26, 29,
369 31, 33, 35, 38, 40, 42, 44, 46,
370 48, 51, 53, 55, 57, 59, 61, 63,
371 65, 67, 69, 71, 73, 75, 77, 79,
372 81, 82, 84, 86, 88, 89, 91, 93,
373 94, 96, 98, 99, 101, 102, 104, 105,
374 106, 108, 109, 110, 112, 113, 114, 115,
375 116, 117, 119, 120, 120, 121, 122, 123,
376 124, 125, 126, 126, 127, 128, 128, 129,
377 129, 130, 130, 131, 131, 131, 131, 132,
378 132, 132, 132, 132, 132, 132, 132, 132,
379 132, 132, 132, 131, 131, 131, 130, 130,
380 130, 129, 129, 128, 127, 127, 126, 125,
381 125, 124, 123, 122, 121, 120, 119, 118,
382 117, 116, 115, 114, 113, 111, 110, 109,
383 107, 106, 105, 103, 102, 100, 99, 97,
384 96, 94, 92, 91, 89, 87, 85, 84, 82
387 static const s16 hsv_green_x[] = {
388 -124, -124, -125, -125, -125, -125, -125, -125,
389 -125, -126, -126, -125, -125, -125, -125, -125,
390 -125, -124, -124, -124, -123, -123, -122, -122,
391 -121, -121, -120, -120, -119, -118, -117, -117,
392 -116, -115, -114, -113, -112, -111, -110, -109,
393 -108, -107, -105, -104, -103, -102, -100, -99,
394 -98, -96, -95, -93, -92, -91, -89, -87,
395 -86, -84, -83, -81, -79, -77, -76, -74,
396 -72, -70, -69, -67, -65, -63, -61, -59,
397 -57, -55, -53, -51, -49, -47, -45, -43,
398 -41, -39, -37, -35, -33, -30, -28, -26,
399 -24, -22, -20, -18, -15, -13, -11, -9,
400 -7, -4, -2, 0, 1, 3, 6, 8,
401 10, 12, 14, 17, 19, 21, 23, 25,
402 27, 29, 32, 34, 36, 38, 40, 42,
403 44, 46, 48, 50, 52, 54, 56, 58,
404 60, 62, 64, 66, 68, 70, 71, 73,
405 75, 77, 78, 80, 82, 83, 85, 87,
406 88, 90, 91, 93, 94, 96, 97, 98,
407 100, 101, 102, 104, 105, 106, 107, 108,
408 109, 111, 112, 113, 113, 114, 115, 116,
409 117, 118, 118, 119, 120, 120, 121, 122,
410 122, 123, 123, 124, 124, 124, 125, 125,
411 125, 125, 125, 125, 125, 126, 126, 125,
412 125, 125, 125, 125, 125, 124, 124, 124,
413 123, 123, 122, 122, 121, 121, 120, 120,
414 119, 118, 117, 117, 116, 115, 114, 113,
415 112, 111, 110, 109, 108, 107, 105, 104,
416 103, 102, 100, 99, 98, 96, 95, 93,
417 92, 91, 89, 87, 86, 84, 83, 81,
418 79, 77, 76, 74, 72, 70, 69, 67,
419 65, 63, 61, 59, 57, 55, 53, 51,
420 49, 47, 45, 43, 41, 39, 37, 35,
421 33, 30, 28, 26, 24, 22, 20, 18,
422 15, 13, 11, 9, 7, 4, 2, 0,
423 -1, -3, -6, -8, -10, -12, -14, -17,
424 -19, -21, -23, -25, -27, -29, -32, -34,
425 -36, -38, -40, -42, -44, -46, -48, -50,
426 -52, -54, -56, -58, -60, -62, -64, -66,
427 -68, -70, -71, -73, -75, -77, -78, -80,
428 -82, -83, -85, -87, -88, -90, -91, -93,
429 -94, -96, -97, -98, -100, -101, -102, -104,
430 -105, -106, -107, -108, -109, -111, -112, -113,
431 -113, -114, -115, -116, -117, -118, -118, -119,
432 -120, -120, -121, -122, -122, -123, -123, -124, -124
435 static const s16 hsv_green_y[] = {
436 -100, -99, -98, -97, -95, -94, -93, -91,
437 -90, -89, -87, -86, -84, -83, -81, -80,
438 -78, -76, -75, -73, -71, -70, -68, -66,
439 -64, -63, -61, -59, -57, -55, -53, -51,
440 -49, -48, -46, -44, -42, -40, -38, -36,
441 -34, -32, -30, -27, -25, -23, -21, -19,
442 -17, -15, -13, -11, -9, -7, -4, -2,
443 0, 1, 3, 5, 7, 9, 11, 14,
444 16, 18, 20, 22, 24, 26, 28, 30,
445 32, 34, 36, 38, 40, 42, 44, 46,
446 48, 50, 52, 54, 56, 58, 59, 61,
447 63, 65, 67, 68, 70, 72, 74, 75,
448 77, 78, 80, 82, 83, 85, 86, 88,
449 89, 90, 92, 93, 95, 96, 97, 98,
450 100, 101, 102, 103, 104, 105, 106, 107,
451 108, 109, 110, 111, 112, 112, 113, 114,
452 115, 115, 116, 116, 117, 117, 118, 118,
453 119, 119, 119, 120, 120, 120, 120, 120,
454 121, 121, 121, 121, 121, 121, 120, 120,
455 120, 120, 120, 119, 119, 119, 118, 118,
456 117, 117, 116, 116, 115, 114, 114, 113,
457 112, 111, 111, 110, 109, 108, 107, 106,
458 105, 104, 103, 102, 100, 99, 98, 97,
459 95, 94, 93, 91, 90, 89, 87, 86,
460 84, 83, 81, 80, 78, 76, 75, 73,
461 71, 70, 68, 66, 64, 63, 61, 59,
462 57, 55, 53, 51, 49, 48, 46, 44,
463 42, 40, 38, 36, 34, 32, 30, 27,
464 25, 23, 21, 19, 17, 15, 13, 11,
465 9, 7, 4, 2, 0, -1, -3, -5,
466 -7, -9, -11, -14, -16, -18, -20, -22,
467 -24, -26, -28, -30, -32, -34, -36, -38,
468 -40, -42, -44, -46, -48, -50, -52, -54,
469 -56, -58, -59, -61, -63, -65, -67, -68,
470 -70, -72, -74, -75, -77, -78, -80, -82,
471 -83, -85, -86, -88, -89, -90, -92, -93,
472 -95, -96, -97, -98, -100, -101, -102, -103,
473 -104, -105, -106, -107, -108, -109, -110, -111,
474 -112, -112, -113, -114, -115, -115, -116, -116,
475 -117, -117, -118, -118, -119, -119, -119, -120,
476 -120, -120, -120, -120, -121, -121, -121, -121,
477 -121, -121, -120, -120, -120, -120, -120, -119,
478 -119, -119, -118, -118, -117, -117, -116, -116,
479 -115, -114, -114, -113, -112, -111, -111, -110,
480 -109, -108, -107, -106, -105, -104, -103, -102, -100
483 static const s16 hsv_blue_x[] = {
484 112, 113, 114, 114, 115, 116, 117, 117,
485 118, 118, 119, 119, 120, 120, 120, 121,
486 121, 121, 122, 122, 122, 122, 122, 122,
487 122, 122, 122, 122, 122, 122, 121, 121,
488 121, 120, 120, 120, 119, 119, 118, 118,
489 117, 116, 116, 115, 114, 113, 113, 112,
490 111, 110, 109, 108, 107, 106, 105, 104,
491 103, 102, 100, 99, 98, 97, 95, 94,
492 93, 91, 90, 88, 87, 85, 84, 82,
493 80, 79, 77, 76, 74, 72, 70, 69,
494 67, 65, 63, 61, 60, 58, 56, 54,
495 52, 50, 48, 46, 44, 42, 40, 38,
496 36, 34, 32, 30, 28, 26, 24, 22,
497 19, 17, 15, 13, 11, 9, 7, 5,
498 2, 0, -1, -3, -5, -7, -9, -12,
499 -14, -16, -18, -20, -22, -24, -26, -28,
500 -31, -33, -35, -37, -39, -41, -43, -45,
501 -47, -49, -51, -53, -54, -56, -58, -60,
502 -62, -64, -66, -67, -69, -71, -73, -74,
503 -76, -78, -79, -81, -83, -84, -86, -87,
504 -89, -90, -92, -93, -94, -96, -97, -98,
505 -99, -101, -102, -103, -104, -105, -106, -107,
506 -108, -109, -110, -111, -112, -113, -114, -114,
507 -115, -116, -117, -117, -118, -118, -119, -119,
508 -120, -120, -120, -121, -121, -121, -122, -122,
509 -122, -122, -122, -122, -122, -122, -122, -122,
510 -122, -122, -121, -121, -121, -120, -120, -120,
511 -119, -119, -118, -118, -117, -116, -116, -115,
512 -114, -113, -113, -112, -111, -110, -109, -108,
513 -107, -106, -105, -104, -103, -102, -100, -99,
514 -98, -97, -95, -94, -93, -91, -90, -88,
515 -87, -85, -84, -82, -80, -79, -77, -76,
516 -74, -72, -70, -69, -67, -65, -63, -61,
517 -60, -58, -56, -54, -52, -50, -48, -46,
518 -44, -42, -40, -38, -36, -34, -32, -30,
519 -28, -26, -24, -22, -19, -17, -15, -13,
520 -11, -9, -7, -5, -2, 0, 1, 3,
521 5, 7, 9, 12, 14, 16, 18, 20,
522 22, 24, 26, 28, 31, 33, 35, 37,
523 39, 41, 43, 45, 47, 49, 51, 53,
524 54, 56, 58, 60, 62, 64, 66, 67,
525 69, 71, 73, 74, 76, 78, 79, 81,
526 83, 84, 86, 87, 89, 90, 92, 93,
527 94, 96, 97, 98, 99, 101, 102, 103,
528 104, 105, 106, 107, 108, 109, 110, 111, 112
531 static const s16 hsv_blue_y[] = {
532 -11, -13, -15, -17, -19, -21, -23, -25,
533 -27, -29, -31, -33, -35, -37, -39, -41,
534 -43, -45, -46, -48, -50, -52, -54, -55,
535 -57, -59, -61, -62, -64, -66, -67, -69,
536 -71, -72, -74, -75, -77, -78, -80, -81,
537 -83, -84, -86, -87, -88, -90, -91, -92,
538 -93, -95, -96, -97, -98, -99, -100, -101,
539 -102, -103, -104, -105, -106, -106, -107, -108,
540 -109, -109, -110, -111, -111, -112, -112, -113,
541 -113, -114, -114, -114, -115, -115, -115, -115,
542 -116, -116, -116, -116, -116, -116, -116, -116,
543 -116, -115, -115, -115, -115, -114, -114, -114,
544 -113, -113, -112, -112, -111, -111, -110, -110,
545 -109, -108, -108, -107, -106, -105, -104, -103,
546 -102, -101, -100, -99, -98, -97, -96, -95,
547 -94, -93, -91, -90, -89, -88, -86, -85,
548 -84, -82, -81, -79, -78, -76, -75, -73,
549 -71, -70, -68, -67, -65, -63, -62, -60,
550 -58, -56, -55, -53, -51, -49, -47, -45,
551 -44, -42, -40, -38, -36, -34, -32, -30,
552 -28, -26, -24, -22, -20, -18, -16, -14,
553 -12, -10, -8, -6, -4, -2, 0, 1,
554 3, 5, 7, 9, 11, 13, 15, 17,
555 19, 21, 23, 25, 27, 29, 31, 33,
556 35, 37, 39, 41, 43, 45, 46, 48,
557 50, 52, 54, 55, 57, 59, 61, 62,
558 64, 66, 67, 69, 71, 72, 74, 75,
559 77, 78, 80, 81, 83, 84, 86, 87,
560 88, 90, 91, 92, 93, 95, 96, 97,
561 98, 99, 100, 101, 102, 103, 104, 105,
562 106, 106, 107, 108, 109, 109, 110, 111,
563 111, 112, 112, 113, 113, 114, 114, 114,
564 115, 115, 115, 115, 116, 116, 116, 116,
565 116, 116, 116, 116, 116, 115, 115, 115,
566 115, 114, 114, 114, 113, 113, 112, 112,
567 111, 111, 110, 110, 109, 108, 108, 107,
568 106, 105, 104, 103, 102, 101, 100, 99,
569 98, 97, 96, 95, 94, 93, 91, 90,
570 89, 88, 86, 85, 84, 82, 81, 79,
571 78, 76, 75, 73, 71, 70, 68, 67,
572 65, 63, 62, 60, 58, 56, 55, 53,
573 51, 49, 47, 45, 44, 42, 40, 38,
574 36, 34, 32, 30, 28, 26, 24, 22,
575 20, 18, 16, 14, 12, 10, 8, 6,
576 4, 2, 0, -1, -3, -5, -7, -9, -11
579 static const u16 bridge_init[][2] = {
580 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
581 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
582 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
583 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
584 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
585 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
586 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
587 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
588 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
589 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
590 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
591 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
592 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
593 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
594 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
595 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
596 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
597 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
598 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
602 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
603 static const u8 ov_gain[] = {
604 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
605 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
606 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
607 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
608 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
609 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
610 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
614 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
615 static const u16 micron1_gain[] = {
616 /* 1x 1.25x 1.5x 1.75x */
617 0x0020, 0x0028, 0x0030, 0x0038,
618 /* 2x 2.25x 2.5x 2.75x */
619 0x00a0, 0x00a4, 0x00a8, 0x00ac,
620 /* 3x 3.25x 3.5x 3.75x */
621 0x00b0, 0x00b4, 0x00b8, 0x00bc,
622 /* 4x 4.25x 4.5x 4.75x */
623 0x00c0, 0x00c4, 0x00c8, 0x00cc,
624 /* 5x 5.25x 5.5x 5.75x */
625 0x00d0, 0x00d4, 0x00d8, 0x00dc,
626 /* 6x 6.25x 6.5x 6.75x */
627 0x00e0, 0x00e4, 0x00e8, 0x00ec,
628 /* 7x 7.25x 7.5x 7.75x */
629 0x00f0, 0x00f4, 0x00f8, 0x00fc,
634 /* mt9m001 sensor uses a different gain formula then other micron sensors */
635 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
636 static const u16 micron2_gain[] = {
637 /* 1x 1.25x 1.5x 1.75x */
638 0x0008, 0x000a, 0x000c, 0x000e,
639 /* 2x 2.25x 2.5x 2.75x */
640 0x0010, 0x0012, 0x0014, 0x0016,
641 /* 3x 3.25x 3.5x 3.75x */
642 0x0018, 0x001a, 0x001c, 0x001e,
643 /* 4x 4.25x 4.5x 4.75x */
644 0x0020, 0x0051, 0x0052, 0x0053,
645 /* 5x 5.25x 5.5x 5.75x */
646 0x0054, 0x0055, 0x0056, 0x0057,
647 /* 6x 6.25x 6.5x 6.75x */
648 0x0058, 0x0059, 0x005a, 0x005b,
649 /* 7x 7.25x 7.5x 7.75x */
650 0x005c, 0x005d, 0x005e, 0x005f,
655 /* Gain = .5 + bit[7:0] / 16 */
656 static const u8 hv7131r_gain[] = {
657 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
658 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
659 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
660 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
661 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
662 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
663 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
667 static const struct i2c_reg_u8 soi968_init[] = {
668 {0x0c, 0x00}, {0x0f, 0x1f},
669 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
670 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
671 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
672 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
673 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
674 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
675 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
676 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
677 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
678 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
681 static const struct i2c_reg_u8 ov7660_init[] = {
682 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
683 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
684 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
685 /* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using
686 0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
687 {0x17, 0x10}, {0x18, 0x61},
688 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
689 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0x00},
690 {0x2e, 0x00}, {0x01, 0x78}, {0x02, 0x50},
693 static const struct i2c_reg_u8 ov7670_init[] = {
694 {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
695 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
696 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
697 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
698 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
699 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
700 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
701 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
702 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
703 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
704 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
705 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
706 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
707 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
708 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
709 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
710 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
711 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
712 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
713 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
714 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
715 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
716 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
717 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
718 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
719 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
720 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
721 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
722 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
723 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
724 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
725 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
726 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
727 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
728 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
729 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
730 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
731 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
732 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
733 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
734 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
735 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
736 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
737 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
738 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
739 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
740 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
741 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
742 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
743 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
744 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
745 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
746 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
750 static const struct i2c_reg_u8 ov9650_init[] = {
751 {0x00, 0x00}, {0x01, 0x78},
752 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
753 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
754 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
755 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
756 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
757 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
758 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
759 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
760 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
761 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
762 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
763 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
764 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
765 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
766 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
767 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
768 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
769 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
770 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
771 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
772 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
773 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
774 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
775 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
776 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
777 {0xaa, 0x92}, {0xab, 0x0a},
780 static const struct i2c_reg_u8 ov9655_init[] = {
781 {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
782 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
783 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
784 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
785 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
786 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
787 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
788 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
789 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
790 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
791 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
792 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
793 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
794 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
795 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
796 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
797 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
798 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
799 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
800 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
801 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
802 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
803 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
804 {0x04, 0x03}, {0x00, 0x13},
807 static const struct i2c_reg_u16 mt9v112_init[] = {
808 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
809 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
810 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
811 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
812 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
813 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
814 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
815 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
816 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
817 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
818 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
819 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
820 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
821 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
822 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
823 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
826 static const struct i2c_reg_u16 mt9v111_init[] = {
827 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
828 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
829 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
830 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
831 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
832 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
833 {0x0e, 0x0008}, {0x20, 0x0000}
836 static const struct i2c_reg_u16 mt9v011_init[] = {
837 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
838 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
839 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
840 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
841 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
842 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
843 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
844 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
845 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
846 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
847 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
848 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
849 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
850 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
851 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
852 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
853 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
854 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
855 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
856 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
857 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
858 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
859 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
860 {0x06, 0x0029}, {0x05, 0x0009},
863 static const struct i2c_reg_u16 mt9m001_init[] = {
866 {0x04, 0x0500}, /* hres = 1280 */
867 {0x03, 0x0400}, /* vres = 1024 */
879 static const struct i2c_reg_u16 mt9m111_init[] = {
880 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
881 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
882 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
886 static const struct i2c_reg_u16 mt9m112_init[] = {
887 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
888 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
889 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
893 static const struct i2c_reg_u8 hv7131r_init[] = {
894 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
895 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
896 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
897 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
898 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
899 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
900 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
901 {0x23, 0x09}, {0x01, 0x08},
904 static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
906 struct usb_device *dev = gspca_dev->dev;
909 if (gspca_dev->usb_err < 0)
911 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
913 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
919 if (unlikely(result < 0 || result != length)) {
920 pr_err("Read register %02x failed %d\n", reg, result);
921 gspca_dev->usb_err = result;
923 * Make sure the buffer is zeroed to avoid uninitialized
926 memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
930 static void reg_w(struct gspca_dev *gspca_dev, u16 reg,
931 const u8 *buffer, int length)
933 struct usb_device *dev = gspca_dev->dev;
936 if (gspca_dev->usb_err < 0)
938 memcpy(gspca_dev->usb_buf, buffer, length);
939 result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
941 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
947 if (unlikely(result < 0 || result != length)) {
948 pr_err("Write register %02x failed %d\n", reg, result);
949 gspca_dev->usb_err = result;
953 static void reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
955 reg_w(gspca_dev, reg, &value, 1);
958 static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
962 reg_w(gspca_dev, 0x10c0, buffer, 8);
963 for (i = 0; i < 5; i++) {
964 reg_r(gspca_dev, 0x10c0, 1);
965 if (gspca_dev->usb_err < 0)
967 if (gspca_dev->usb_buf[0] & 0x04) {
968 if (gspca_dev->usb_buf[0] & 0x08) {
969 pr_err("i2c_w error\n");
970 gspca_dev->usb_err = -EIO;
976 pr_err("i2c_w reg %02x no response\n", buffer[2]);
977 /* gspca_dev->usb_err = -EIO; fixme: may occur */
980 static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
982 struct sd *sd = (struct sd *) gspca_dev;
986 * from the point of view of the bridge, the length
987 * includes the address
989 row[0] = sd->i2c_intf | (2 << 4);
990 row[1] = sd->i2c_addr;
998 i2c_w(gspca_dev, row);
1001 static void i2c_w1_buf(struct gspca_dev *gspca_dev,
1002 const struct i2c_reg_u8 *buf, int sz)
1005 i2c_w1(gspca_dev, buf->reg, buf->val);
1010 static void i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1012 struct sd *sd = (struct sd *) gspca_dev;
1016 * from the point of view of the bridge, the length
1017 * includes the address
1019 row[0] = sd->i2c_intf | (3 << 4);
1020 row[1] = sd->i2c_addr;
1028 i2c_w(gspca_dev, row);
1031 static void i2c_w2_buf(struct gspca_dev *gspca_dev,
1032 const struct i2c_reg_u16 *buf, int sz)
1035 i2c_w2(gspca_dev, buf->reg, buf->val);
1040 static void i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1042 struct sd *sd = (struct sd *) gspca_dev;
1045 row[0] = sd->i2c_intf | (1 << 4);
1046 row[1] = sd->i2c_addr;
1053 i2c_w(gspca_dev, row);
1054 row[0] = sd->i2c_intf | (1 << 4) | 0x02;
1056 i2c_w(gspca_dev, row);
1057 reg_r(gspca_dev, 0x10c2, 5);
1058 *val = gspca_dev->usb_buf[4];
1061 static void i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1063 struct sd *sd = (struct sd *) gspca_dev;
1066 row[0] = sd->i2c_intf | (1 << 4);
1067 row[1] = sd->i2c_addr;
1074 i2c_w(gspca_dev, row);
1075 row[0] = sd->i2c_intf | (2 << 4) | 0x02;
1077 i2c_w(gspca_dev, row);
1078 reg_r(gspca_dev, 0x10c2, 5);
1079 *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1082 static void ov9650_init_sensor(struct gspca_dev *gspca_dev)
1085 struct sd *sd = (struct sd *) gspca_dev;
1087 i2c_r2(gspca_dev, 0x1c, &id);
1088 if (gspca_dev->usb_err < 0)
1092 pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id);
1093 gspca_dev->usb_err = -ENODEV;
1097 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1099 i2c_w1_buf(gspca_dev, ov9650_init, ARRAY_SIZE(ov9650_init));
1100 if (gspca_dev->usb_err < 0)
1101 pr_err("OV9650 sensor initialization failed\n");
1106 static void ov9655_init_sensor(struct gspca_dev *gspca_dev)
1108 struct sd *sd = (struct sd *) gspca_dev;
1110 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1112 i2c_w1_buf(gspca_dev, ov9655_init, ARRAY_SIZE(ov9655_init));
1113 if (gspca_dev->usb_err < 0)
1114 pr_err("OV9655 sensor initialization failed\n");
1120 static void soi968_init_sensor(struct gspca_dev *gspca_dev)
1122 struct sd *sd = (struct sd *) gspca_dev;
1124 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1126 i2c_w1_buf(gspca_dev, soi968_init, ARRAY_SIZE(soi968_init));
1127 if (gspca_dev->usb_err < 0)
1128 pr_err("SOI968 sensor initialization failed\n");
1134 static void ov7660_init_sensor(struct gspca_dev *gspca_dev)
1136 struct sd *sd = (struct sd *) gspca_dev;
1138 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1140 i2c_w1_buf(gspca_dev, ov7660_init, ARRAY_SIZE(ov7660_init));
1141 if (gspca_dev->usb_err < 0)
1142 pr_err("OV7660 sensor initialization failed\n");
1147 static void ov7670_init_sensor(struct gspca_dev *gspca_dev)
1149 struct sd *sd = (struct sd *) gspca_dev;
1151 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1153 i2c_w1_buf(gspca_dev, ov7670_init, ARRAY_SIZE(ov7670_init));
1154 if (gspca_dev->usb_err < 0)
1155 pr_err("OV7670 sensor initialization failed\n");
1161 static void mt9v_init_sensor(struct gspca_dev *gspca_dev)
1163 struct sd *sd = (struct sd *) gspca_dev;
1166 sd->i2c_addr = 0x5d;
1167 i2c_r2(gspca_dev, 0xff, &value);
1168 if (gspca_dev->usb_err >= 0
1169 && value == 0x8243) {
1170 i2c_w2_buf(gspca_dev, mt9v011_init, ARRAY_SIZE(mt9v011_init));
1171 if (gspca_dev->usb_err < 0) {
1172 pr_err("MT9V011 sensor initialization failed\n");
1177 sd->sensor = SENSOR_MT9V011;
1178 pr_info("MT9V011 sensor detected\n");
1182 gspca_dev->usb_err = 0;
1183 sd->i2c_addr = 0x5c;
1184 i2c_w2(gspca_dev, 0x01, 0x0004);
1185 i2c_r2(gspca_dev, 0xff, &value);
1186 if (gspca_dev->usb_err >= 0
1187 && value == 0x823a) {
1188 i2c_w2_buf(gspca_dev, mt9v111_init, ARRAY_SIZE(mt9v111_init));
1189 if (gspca_dev->usb_err < 0) {
1190 pr_err("MT9V111 sensor initialization failed\n");
1195 sd->sensor = SENSOR_MT9V111;
1196 pr_info("MT9V111 sensor detected\n");
1200 gspca_dev->usb_err = 0;
1201 sd->i2c_addr = 0x5d;
1202 i2c_w2(gspca_dev, 0xf0, 0x0000);
1203 if (gspca_dev->usb_err < 0) {
1204 gspca_dev->usb_err = 0;
1205 sd->i2c_addr = 0x48;
1206 i2c_w2(gspca_dev, 0xf0, 0x0000);
1208 i2c_r2(gspca_dev, 0x00, &value);
1209 if (gspca_dev->usb_err >= 0
1210 && value == 0x1229) {
1211 i2c_w2_buf(gspca_dev, mt9v112_init, ARRAY_SIZE(mt9v112_init));
1212 if (gspca_dev->usb_err < 0) {
1213 pr_err("MT9V112 sensor initialization failed\n");
1218 sd->sensor = SENSOR_MT9V112;
1219 pr_info("MT9V112 sensor detected\n");
1223 gspca_dev->usb_err = -ENODEV;
1226 static void mt9m112_init_sensor(struct gspca_dev *gspca_dev)
1228 struct sd *sd = (struct sd *) gspca_dev;
1230 i2c_w2_buf(gspca_dev, mt9m112_init, ARRAY_SIZE(mt9m112_init));
1231 if (gspca_dev->usb_err < 0)
1232 pr_err("MT9M112 sensor initialization failed\n");
1238 static void mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1240 struct sd *sd = (struct sd *) gspca_dev;
1242 i2c_w2_buf(gspca_dev, mt9m111_init, ARRAY_SIZE(mt9m111_init));
1243 if (gspca_dev->usb_err < 0)
1244 pr_err("MT9M111 sensor initialization failed\n");
1250 static void mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1252 struct sd *sd = (struct sd *) gspca_dev;
1255 i2c_r2(gspca_dev, 0x00, &id);
1256 if (gspca_dev->usb_err < 0)
1259 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
1263 pr_info("MT9M001 color sensor detected\n");
1266 pr_info("MT9M001 mono sensor detected\n");
1269 pr_err("No MT9M001 chip detected, ID = %x\n\n", id);
1270 gspca_dev->usb_err = -ENODEV;
1274 i2c_w2_buf(gspca_dev, mt9m001_init, ARRAY_SIZE(mt9m001_init));
1275 if (gspca_dev->usb_err < 0)
1276 pr_err("MT9M001 sensor initialization failed\n");
1282 static void hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1284 struct sd *sd = (struct sd *) gspca_dev;
1286 i2c_w1_buf(gspca_dev, hv7131r_init, ARRAY_SIZE(hv7131r_init));
1287 if (gspca_dev->usb_err < 0)
1288 pr_err("HV7131R Sensor initialization failed\n");
1294 static void set_cmatrix(struct gspca_dev *gspca_dev,
1295 s32 brightness, s32 contrast, s32 satur, s32 hue)
1297 s32 hue_coord, hue_index = 180 + hue;
1300 memset(cmatrix, 0, sizeof(cmatrix));
1301 cmatrix[2] = (contrast * 0x25 / 0x100) + 0x26;
1302 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1303 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1304 cmatrix[18] = brightness - 0x80;
1306 hue_coord = (hsv_red_x[hue_index] * satur) >> 8;
1307 cmatrix[6] = hue_coord;
1308 cmatrix[7] = (hue_coord >> 8) & 0x0f;
1310 hue_coord = (hsv_red_y[hue_index] * satur) >> 8;
1311 cmatrix[8] = hue_coord;
1312 cmatrix[9] = (hue_coord >> 8) & 0x0f;
1314 hue_coord = (hsv_green_x[hue_index] * satur) >> 8;
1315 cmatrix[10] = hue_coord;
1316 cmatrix[11] = (hue_coord >> 8) & 0x0f;
1318 hue_coord = (hsv_green_y[hue_index] * satur) >> 8;
1319 cmatrix[12] = hue_coord;
1320 cmatrix[13] = (hue_coord >> 8) & 0x0f;
1322 hue_coord = (hsv_blue_x[hue_index] * satur) >> 8;
1323 cmatrix[14] = hue_coord;
1324 cmatrix[15] = (hue_coord >> 8) & 0x0f;
1326 hue_coord = (hsv_blue_y[hue_index] * satur) >> 8;
1327 cmatrix[16] = hue_coord;
1328 cmatrix[17] = (hue_coord >> 8) & 0x0f;
1330 reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1333 static void set_gamma(struct gspca_dev *gspca_dev, s32 val)
1336 u8 gval = val * 0xb8 / 0x100;
1339 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
1340 gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8);
1341 gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8);
1342 gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8);
1343 gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8);
1344 gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8);
1345 gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8);
1346 gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8);
1347 gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8);
1348 gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8);
1349 gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8);
1350 gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8);
1351 gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8);
1352 gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8);
1353 gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
1356 reg_w(gspca_dev, 0x1190, gamma, 17);
1359 static void set_redblue(struct gspca_dev *gspca_dev, s32 blue, s32 red)
1361 reg_w1(gspca_dev, 0x118c, red);
1362 reg_w1(gspca_dev, 0x118f, blue);
1365 static void set_hvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip)
1369 struct sd *sd = (struct sd *) gspca_dev;
1371 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1376 switch (sd->sensor) {
1387 reg_w1(gspca_dev, 0x1182, sd->vstart);
1388 i2c_w1(gspca_dev, 0x1e, value);
1391 i2c_r1(gspca_dev, 0x1e, &value);
1400 i2c_w1(gspca_dev, 0x1e, value);
1401 i2c_w1(gspca_dev, 0x3a, tslb);
1403 case SENSOR_MT9V111:
1404 case SENSOR_MT9V011:
1405 i2c_r2(gspca_dev, 0x20, &value2);
1411 i2c_w2(gspca_dev, 0x20, value2);
1413 case SENSOR_MT9M112:
1414 case SENSOR_MT9M111:
1415 case SENSOR_MT9V112:
1416 i2c_r2(gspca_dev, 0x20, &value2);
1422 i2c_w2(gspca_dev, 0x20, value2);
1424 case SENSOR_HV7131R:
1425 i2c_r1(gspca_dev, 0x01, &value);
1431 i2c_w1(gspca_dev, 0x01, value);
1436 static void set_exposure(struct gspca_dev *gspca_dev, s32 expo)
1438 struct sd *sd = (struct sd *) gspca_dev;
1439 u8 exp[8] = {sd->i2c_intf, sd->i2c_addr,
1440 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1443 if (gspca_dev->streaming)
1446 switch (sd->sensor) {
1456 exp[2] = 0x10; /* AECH */
1457 exp[3] = expo2 >> 2;
1459 i2c_w(gspca_dev, exp);
1460 exp[2] = 0x04; /* COM1 */
1461 exp[3] = expo2 & 0x0003;
1463 i2c_w(gspca_dev, exp);
1467 exp[2] = 0x2d; /* ADVFL & ADVFH */
1471 case SENSOR_MT9M001:
1472 case SENSOR_MT9V112:
1473 case SENSOR_MT9V011:
1479 case SENSOR_HV7131R:
1489 i2c_w(gspca_dev, exp);
1492 static void set_gain(struct gspca_dev *gspca_dev, s32 g)
1494 struct sd *sd = (struct sd *) gspca_dev;
1495 u8 gain[8] = {sd->i2c_intf, sd->i2c_addr,
1496 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1498 if (gspca_dev->streaming)
1499 gain[7] = 0x15; /* or 1d ? */
1501 switch (sd->sensor) {
1507 gain[0] |= (2 << 4);
1508 gain[3] = ov_gain[g];
1510 case SENSOR_MT9V011:
1511 gain[0] |= (3 << 4);
1513 gain[3] = micron1_gain[g] >> 8;
1514 gain[4] = micron1_gain[g];
1516 case SENSOR_MT9V112:
1517 gain[0] |= (3 << 4);
1519 gain[3] = micron1_gain[g] >> 8;
1520 gain[4] = micron1_gain[g];
1522 case SENSOR_MT9M001:
1523 gain[0] |= (3 << 4);
1525 gain[3] = micron2_gain[g] >> 8;
1526 gain[4] = micron2_gain[g];
1528 case SENSOR_HV7131R:
1529 gain[0] |= (2 << 4);
1531 gain[3] = hv7131r_gain[g];
1536 i2c_w(gspca_dev, gain);
1539 static void set_led_mode(struct gspca_dev *gspca_dev, s32 val)
1541 reg_w1(gspca_dev, 0x1007, 0x60);
1542 reg_w1(gspca_dev, 0x1006, val ? 0x40 : 0x00);
1545 static void set_quality(struct gspca_dev *gspca_dev, s32 val)
1547 struct sd *sd = (struct sd *) gspca_dev;
1549 jpeg_set_qual(sd->jpeg_hdr, val);
1550 reg_w1(gspca_dev, 0x1061, 0x01); /* stop transfer */
1551 reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20); /* write QTAB */
1552 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
1553 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
1554 reg_w1(gspca_dev, 0x1061, 0x03); /* restart transfer */
1555 reg_w1(gspca_dev, 0x10e0, sd->fmt);
1556 sd->fmt ^= 0x0c; /* invert QTAB use + write */
1557 reg_w1(gspca_dev, 0x10e0, sd->fmt);
1560 #ifdef CONFIG_VIDEO_ADV_DEBUG
1561 static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1562 struct v4l2_dbg_register *reg)
1564 struct sd *sd = (struct sd *) gspca_dev;
1567 switch (reg->match.addr) {
1569 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1571 reg_r(gspca_dev, reg->reg, 1);
1572 reg->val = gspca_dev->usb_buf[0];
1573 return gspca_dev->usb_err;
1575 if (sd->sensor >= SENSOR_MT9V011 &&
1576 sd->sensor <= SENSOR_MT9M112) {
1577 i2c_r2(gspca_dev, reg->reg, (u16 *) ®->val);
1580 i2c_r1(gspca_dev, reg->reg, (u8 *) ®->val);
1582 return gspca_dev->usb_err;
1587 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1588 const struct v4l2_dbg_register *reg)
1590 struct sd *sd = (struct sd *) gspca_dev;
1592 switch (reg->match.addr) {
1594 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1596 reg_w1(gspca_dev, reg->reg, reg->val);
1597 return gspca_dev->usb_err;
1599 if (sd->sensor >= SENSOR_MT9V011 &&
1600 sd->sensor <= SENSOR_MT9M112) {
1601 i2c_w2(gspca_dev, reg->reg, reg->val);
1603 i2c_w1(gspca_dev, reg->reg, reg->val);
1605 return gspca_dev->usb_err;
1610 static int sd_chip_info(struct gspca_dev *gspca_dev,
1611 struct v4l2_dbg_chip_info *chip)
1613 if (chip->match.addr > 1)
1615 if (chip->match.addr == 1)
1616 strscpy(chip->name, "sensor", sizeof(chip->name));
1621 static int sd_config(struct gspca_dev *gspca_dev,
1622 const struct usb_device_id *id)
1624 struct sd *sd = (struct sd *) gspca_dev;
1627 cam = &gspca_dev->cam;
1628 cam->needs_full_bandwidth = 1;
1630 sd->sensor = id->driver_info >> 8;
1631 sd->i2c_addr = id->driver_info;
1632 sd->flags = id->driver_info >> 16;
1633 sd->i2c_intf = 0x80; /* i2c 100 Kb/s */
1635 switch (sd->sensor) {
1636 case SENSOR_MT9M112:
1637 case SENSOR_MT9M111:
1640 cam->cam_mode = sxga_mode;
1641 cam->nmodes = ARRAY_SIZE(sxga_mode);
1643 case SENSOR_MT9M001:
1644 cam->cam_mode = mono_mode;
1645 cam->nmodes = ARRAY_SIZE(mono_mode);
1647 case SENSOR_HV7131R:
1648 sd->i2c_intf = 0x81; /* i2c 400 Kb/s */
1651 cam->cam_mode = vga_mode;
1652 cam->nmodes = ARRAY_SIZE(vga_mode);
1658 sd->exposure_step = 16;
1660 INIT_WORK(&sd->work, qual_upd);
1665 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
1667 struct gspca_dev *gspca_dev =
1668 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
1669 struct sd *sd = (struct sd *)gspca_dev;
1671 gspca_dev->usb_err = 0;
1673 if (!gspca_dev->streaming)
1677 /* color control cluster */
1678 case V4L2_CID_BRIGHTNESS:
1679 set_cmatrix(gspca_dev, sd->brightness->val,
1680 sd->contrast->val, sd->saturation->val, sd->hue->val);
1682 case V4L2_CID_GAMMA:
1683 set_gamma(gspca_dev, ctrl->val);
1685 /* blue/red balance cluster */
1686 case V4L2_CID_BLUE_BALANCE:
1687 set_redblue(gspca_dev, sd->blue->val, sd->red->val);
1689 /* h/vflip cluster */
1690 case V4L2_CID_HFLIP:
1691 set_hvflip(gspca_dev, sd->hflip->val, sd->vflip->val);
1693 /* standalone exposure control */
1694 case V4L2_CID_EXPOSURE:
1695 set_exposure(gspca_dev, ctrl->val);
1697 /* standalone gain control */
1699 set_gain(gspca_dev, ctrl->val);
1701 /* autogain + exposure or gain control cluster */
1702 case V4L2_CID_AUTOGAIN:
1703 if (sd->sensor == SENSOR_SOI968)
1704 set_gain(gspca_dev, sd->gain->val);
1706 set_exposure(gspca_dev, sd->exposure->val);
1708 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1709 set_quality(gspca_dev, ctrl->val);
1711 case V4L2_CID_FLASH_LED_MODE:
1712 set_led_mode(gspca_dev, ctrl->val);
1715 return gspca_dev->usb_err;
1718 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1719 .s_ctrl = sd_s_ctrl,
1722 static int sd_init_controls(struct gspca_dev *gspca_dev)
1724 struct sd *sd = (struct sd *) gspca_dev;
1725 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1727 gspca_dev->vdev.ctrl_handler = hdl;
1728 v4l2_ctrl_handler_init(hdl, 13);
1730 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1731 V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
1732 sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1733 V4L2_CID_CONTRAST, 0, 255, 1, 127);
1734 sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1735 V4L2_CID_SATURATION, 0, 255, 1, 127);
1736 sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1737 V4L2_CID_HUE, -180, 180, 1, 0);
1739 sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1740 V4L2_CID_GAMMA, 0, 255, 1, 0x10);
1742 sd->blue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1743 V4L2_CID_BLUE_BALANCE, 0, 127, 1, 0x28);
1744 sd->red = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1745 V4L2_CID_RED_BALANCE, 0, 127, 1, 0x28);
1747 if (sd->sensor != SENSOR_OV9655 && sd->sensor != SENSOR_SOI968 &&
1748 sd->sensor != SENSOR_OV7670 && sd->sensor != SENSOR_MT9M001 &&
1749 sd->sensor != SENSOR_MT9VPRB) {
1750 sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1751 V4L2_CID_HFLIP, 0, 1, 1, 0);
1752 sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1753 V4L2_CID_VFLIP, 0, 1, 1, 0);
1756 if (sd->sensor != SENSOR_SOI968 && sd->sensor != SENSOR_MT9VPRB &&
1757 sd->sensor != SENSOR_MT9M112 && sd->sensor != SENSOR_MT9M111 &&
1758 sd->sensor != SENSOR_MT9V111)
1759 sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1760 V4L2_CID_EXPOSURE, 0, 0x1780, 1, 0x33);
1762 if (sd->sensor != SENSOR_MT9VPRB && sd->sensor != SENSOR_MT9M112 &&
1763 sd->sensor != SENSOR_MT9M111 && sd->sensor != SENSOR_MT9V111) {
1764 sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1765 V4L2_CID_GAIN, 0, 28, 1, 0);
1766 sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1767 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1770 sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1771 V4L2_CID_JPEG_COMPRESSION_QUALITY, 50, 90, 1, 80);
1773 if (sd->flags & HAS_LED_TORCH)
1774 sd->led_mode = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
1775 V4L2_CID_FLASH_LED_MODE, V4L2_FLASH_LED_MODE_TORCH,
1776 ~0x5, V4L2_FLASH_LED_MODE_NONE);
1779 pr_err("Could not initialize controls\n");
1783 v4l2_ctrl_cluster(4, &sd->brightness);
1784 v4l2_ctrl_cluster(2, &sd->blue);
1786 v4l2_ctrl_cluster(2, &sd->hflip);
1788 if (sd->sensor == SENSOR_SOI968)
1789 /* this sensor doesn't have the exposure control and
1790 autogain is clustered with gain instead. This works
1791 because sd->exposure == NULL. */
1792 v4l2_ctrl_auto_cluster(3, &sd->autogain, 0, false);
1794 /* Otherwise autogain is clustered with exposure. */
1795 v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false);
1800 static int sd_init(struct gspca_dev *gspca_dev)
1802 struct sd *sd = (struct sd *) gspca_dev;
1806 0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
1809 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
1810 value = bridge_init[i][1];
1811 reg_w(gspca_dev, bridge_init[i][0], &value, 1);
1812 if (gspca_dev->usb_err < 0) {
1813 pr_err("Device initialization failed\n");
1814 return gspca_dev->usb_err;
1818 if (sd->flags & LED_REVERSE)
1819 reg_w1(gspca_dev, 0x1006, 0x00);
1821 reg_w1(gspca_dev, 0x1006, 0x20);
1823 reg_w(gspca_dev, 0x10c0, i2c_init, 9);
1824 if (gspca_dev->usb_err < 0) {
1825 pr_err("Device initialization failed\n");
1826 return gspca_dev->usb_err;
1829 switch (sd->sensor) {
1831 ov9650_init_sensor(gspca_dev);
1832 if (gspca_dev->usb_err < 0)
1834 pr_info("OV9650 sensor detected\n");
1837 ov9655_init_sensor(gspca_dev);
1838 if (gspca_dev->usb_err < 0)
1840 pr_info("OV9655 sensor detected\n");
1843 soi968_init_sensor(gspca_dev);
1844 if (gspca_dev->usb_err < 0)
1846 pr_info("SOI968 sensor detected\n");
1849 ov7660_init_sensor(gspca_dev);
1850 if (gspca_dev->usb_err < 0)
1852 pr_info("OV7660 sensor detected\n");
1855 ov7670_init_sensor(gspca_dev);
1856 if (gspca_dev->usb_err < 0)
1858 pr_info("OV7670 sensor detected\n");
1860 case SENSOR_MT9VPRB:
1861 mt9v_init_sensor(gspca_dev);
1862 if (gspca_dev->usb_err < 0)
1864 pr_info("MT9VPRB sensor detected\n");
1866 case SENSOR_MT9M111:
1867 mt9m111_init_sensor(gspca_dev);
1868 if (gspca_dev->usb_err < 0)
1870 pr_info("MT9M111 sensor detected\n");
1872 case SENSOR_MT9M112:
1873 mt9m112_init_sensor(gspca_dev);
1874 if (gspca_dev->usb_err < 0)
1876 pr_info("MT9M112 sensor detected\n");
1878 case SENSOR_MT9M001:
1879 mt9m001_init_sensor(gspca_dev);
1880 if (gspca_dev->usb_err < 0)
1883 case SENSOR_HV7131R:
1884 hv7131r_init_sensor(gspca_dev);
1885 if (gspca_dev->usb_err < 0)
1887 pr_info("HV7131R sensor detected\n");
1890 pr_err("Unsupported sensor\n");
1891 gspca_dev->usb_err = -ENODEV;
1893 return gspca_dev->usb_err;
1896 static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
1898 struct sd *sd = (struct sd *) gspca_dev;
1901 switch (sd->sensor) {
1903 if (mode & MODE_SXGA) {
1904 i2c_w1(gspca_dev, 0x17, 0x1d);
1905 i2c_w1(gspca_dev, 0x18, 0xbd);
1906 i2c_w1(gspca_dev, 0x19, 0x01);
1907 i2c_w1(gspca_dev, 0x1a, 0x81);
1908 i2c_w1(gspca_dev, 0x12, 0x00);
1912 i2c_w1(gspca_dev, 0x17, 0x13);
1913 i2c_w1(gspca_dev, 0x18, 0x63);
1914 i2c_w1(gspca_dev, 0x19, 0x01);
1915 i2c_w1(gspca_dev, 0x1a, 0x79);
1916 i2c_w1(gspca_dev, 0x12, 0x40);
1922 if (mode & MODE_SXGA) {
1923 i2c_w1(gspca_dev, 0x17, 0x1b);
1924 i2c_w1(gspca_dev, 0x18, 0xbc);
1925 i2c_w1(gspca_dev, 0x19, 0x01);
1926 i2c_w1(gspca_dev, 0x1a, 0x82);
1927 i2c_r1(gspca_dev, 0x12, &value);
1928 i2c_w1(gspca_dev, 0x12, value & 0x07);
1930 i2c_w1(gspca_dev, 0x17, 0x24);
1931 i2c_w1(gspca_dev, 0x18, 0xc5);
1932 i2c_w1(gspca_dev, 0x19, 0x00);
1933 i2c_w1(gspca_dev, 0x1a, 0x3c);
1934 i2c_r1(gspca_dev, 0x12, &value);
1935 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
1938 case SENSOR_MT9M112:
1939 case SENSOR_MT9M111:
1940 if (mode & MODE_SXGA) {
1941 i2c_w2(gspca_dev, 0xf0, 0x0002);
1942 i2c_w2(gspca_dev, 0xc8, 0x970b);
1943 i2c_w2(gspca_dev, 0xf0, 0x0000);
1945 i2c_w2(gspca_dev, 0xf0, 0x0002);
1946 i2c_w2(gspca_dev, 0xc8, 0x8000);
1947 i2c_w2(gspca_dev, 0xf0, 0x0000);
1953 static int sd_isoc_init(struct gspca_dev *gspca_dev)
1955 struct usb_interface *intf;
1956 u32 flags = gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv;
1959 * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth
1960 * than our regular bandwidth calculations reserve, so we force the
1961 * use of a specific altsetting when using the SN9C20X_I420 fmt.
1963 if (!(flags & (MODE_RAW | MODE_JPEG))) {
1964 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
1966 if (intf->num_altsetting != 9) {
1967 pr_warn("sn9c20x camera with unknown number of alt settings (%d), please report!\n",
1968 intf->num_altsetting);
1969 gspca_dev->alt = intf->num_altsetting;
1973 switch (gspca_dev->pixfmt.width) {
1974 case 160: /* 160x120 */
1977 case 320: /* 320x240 */
1980 default: /* >= 640x480 */
1989 #define HW_WIN(mode, hstart, vstart) \
1990 ((const u8 []){hstart, 0, vstart, 0, \
1991 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
1992 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
1994 #define CLR_WIN(width, height) \
1996 {0, width >> 2, 0, height >> 1,\
1997 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
1999 static int sd_start(struct gspca_dev *gspca_dev)
2001 struct sd *sd = (struct sd *) gspca_dev;
2002 int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
2003 int width = gspca_dev->pixfmt.width;
2004 int height = gspca_dev->pixfmt.height;
2007 jpeg_define(sd->jpeg_hdr, height, width,
2009 jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual));
2011 if (mode & MODE_RAW)
2013 else if (mode & MODE_JPEG)
2016 fmt = 0x2f; /* YUV 420 */
2019 switch (mode & SCALE_MASK) {
2020 case SCALE_1280x1024:
2022 pr_info("Set 1280x1024\n");
2026 pr_info("Set 640x480\n");
2030 pr_info("Set 320x240\n");
2034 pr_info("Set 160x120\n");
2038 configure_sensor_output(gspca_dev, mode);
2039 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2040 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2041 reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2042 reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2043 reg_w1(gspca_dev, 0x1189, scale);
2044 reg_w1(gspca_dev, 0x10e0, fmt);
2046 set_cmatrix(gspca_dev, v4l2_ctrl_g_ctrl(sd->brightness),
2047 v4l2_ctrl_g_ctrl(sd->contrast),
2048 v4l2_ctrl_g_ctrl(sd->saturation),
2049 v4l2_ctrl_g_ctrl(sd->hue));
2050 set_gamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma));
2051 set_redblue(gspca_dev, v4l2_ctrl_g_ctrl(sd->blue),
2052 v4l2_ctrl_g_ctrl(sd->red));
2054 set_gain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain));
2056 set_exposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure));
2058 set_hvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip),
2059 v4l2_ctrl_g_ctrl(sd->vflip));
2061 reg_w1(gspca_dev, 0x1007, 0x20);
2062 reg_w1(gspca_dev, 0x1061, 0x03);
2064 /* if JPEG, prepare the compression quality update */
2065 if (mode & MODE_JPEG) {
2066 sd->pktsz = sd->npkt = 0;
2070 v4l2_ctrl_s_ctrl(sd->led_mode, 0);
2072 return gspca_dev->usb_err;
2075 static void sd_stopN(struct gspca_dev *gspca_dev)
2077 reg_w1(gspca_dev, 0x1007, 0x00);
2078 reg_w1(gspca_dev, 0x1061, 0x01);
2081 /* called on streamoff with alt==0 and on disconnect */
2082 /* the usb_lock is held at entry - restore on exit */
2083 static void sd_stop0(struct gspca_dev *gspca_dev)
2085 struct sd *sd = (struct sd *) gspca_dev;
2087 mutex_unlock(&gspca_dev->usb_lock);
2088 flush_work(&sd->work);
2089 mutex_lock(&gspca_dev->usb_lock);
2092 static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2094 struct sd *sd = (struct sd *) gspca_dev;
2095 s32 cur_exp = v4l2_ctrl_g_ctrl(sd->exposure);
2096 s32 max = sd->exposure->maximum - sd->exposure_step;
2097 s32 min = sd->exposure->minimum + sd->exposure_step;
2101 * some hardcoded values are present
2102 * like those for maximal/minimal exposure
2103 * and exposure steps
2105 if (avg_lum < MIN_AVG_LUM) {
2109 new_exp = cur_exp + sd->exposure_step;
2114 v4l2_ctrl_s_ctrl(sd->exposure, new_exp);
2116 sd->older_step = sd->old_step;
2119 if (sd->old_step ^ sd->older_step)
2120 sd->exposure_step /= 2;
2122 sd->exposure_step += 2;
2124 if (avg_lum > MAX_AVG_LUM) {
2127 new_exp = cur_exp - sd->exposure_step;
2132 v4l2_ctrl_s_ctrl(sd->exposure, new_exp);
2133 sd->older_step = sd->old_step;
2136 if (sd->old_step ^ sd->older_step)
2137 sd->exposure_step /= 2;
2139 sd->exposure_step += 2;
2143 static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2145 struct sd *sd = (struct sd *) gspca_dev;
2146 s32 cur_gain = v4l2_ctrl_g_ctrl(sd->gain);
2148 if (avg_lum < MIN_AVG_LUM && cur_gain < sd->gain->maximum)
2149 v4l2_ctrl_s_ctrl(sd->gain, cur_gain + 1);
2150 if (avg_lum > MAX_AVG_LUM && cur_gain > sd->gain->minimum)
2151 v4l2_ctrl_s_ctrl(sd->gain, cur_gain - 1);
2154 static void sd_dqcallback(struct gspca_dev *gspca_dev)
2156 struct sd *sd = (struct sd *) gspca_dev;
2159 if (sd->autogain == NULL || !v4l2_ctrl_g_ctrl(sd->autogain))
2162 avg_lum = atomic_read(&sd->avg_lum);
2163 if (sd->sensor == SENSOR_SOI968)
2164 do_autogain(gspca_dev, avg_lum);
2166 do_autoexposure(gspca_dev, avg_lum);
2169 /* JPEG quality update */
2170 /* This function is executed from a work queue. */
2171 static void qual_upd(struct work_struct *work)
2173 struct sd *sd = container_of(work, struct sd, work);
2174 struct gspca_dev *gspca_dev = &sd->gspca_dev;
2175 s32 qual = v4l2_ctrl_g_ctrl(sd->jpegqual);
2177 /* To protect gspca_dev->usb_buf and gspca_dev->usb_err */
2178 mutex_lock(&gspca_dev->usb_lock);
2179 gspca_dbg(gspca_dev, D_STREAM, "qual_upd %d%%\n", qual);
2180 gspca_dev->usb_err = 0;
2181 set_quality(gspca_dev, qual);
2182 mutex_unlock(&gspca_dev->usb_lock);
2185 #if IS_ENABLED(CONFIG_INPUT)
2186 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2187 u8 *data, /* interrupt packet */
2188 int len) /* interrupt packet length */
2190 struct sd *sd = (struct sd *) gspca_dev;
2192 if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
2193 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2194 input_sync(gspca_dev->input_dev);
2195 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2196 input_sync(gspca_dev->input_dev);
2203 /* check the JPEG compression */
2204 static void transfer_check(struct gspca_dev *gspca_dev,
2207 struct sd *sd = (struct sd *) gspca_dev;
2212 /* if USB error, discard the frame and decrease the quality */
2213 if (data[6] & 0x08) { /* USB FIFO full */
2214 gspca_dev->last_packet_type = DISCARD_PACKET;
2218 /* else, compute the filling rate and a new JPEG quality */
2219 r = (sd->pktsz * 100) /
2221 gspca_dev->urb[0]->iso_frame_desc[0].length);
2227 if (new_qual != 0) {
2228 sd->nchg += new_qual;
2229 if (sd->nchg < -6 || sd->nchg >= 12) {
2230 /* Note: we are in interrupt context, so we can't
2231 use v4l2_ctrl_g/s_ctrl here. Access the value
2232 directly instead. */
2233 s32 curqual = sd->jpegqual->cur.val;
2235 new_qual += curqual;
2236 if (new_qual < sd->jpegqual->minimum)
2237 new_qual = sd->jpegqual->minimum;
2238 else if (new_qual > sd->jpegqual->maximum)
2239 new_qual = sd->jpegqual->maximum;
2240 if (new_qual != curqual) {
2241 sd->jpegqual->cur.val = new_qual;
2242 schedule_work(&sd->work);
2248 sd->pktsz = sd->npkt = 0;
2251 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2252 u8 *data, /* isoc packet */
2253 int len) /* iso packet length */
2255 struct sd *sd = (struct sd *) gspca_dev;
2256 int avg_lum, is_jpeg;
2257 static const u8 frame_header[] = {
2258 0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96
2261 is_jpeg = (sd->fmt & 0x03) == 0;
2262 if (len >= 64 && memcmp(data, frame_header, 6) == 0) {
2263 avg_lum = ((data[35] >> 2) & 3) |
2266 avg_lum += ((data[35] >> 4) & 3) |
2269 avg_lum += ((data[35] >> 6) & 3) |
2272 avg_lum += (data[36] & 3) |
2275 avg_lum += ((data[36] >> 2) & 3) |
2278 avg_lum += ((data[36] >> 4) & 3) |
2281 avg_lum += ((data[36] >> 6) & 3) |
2284 avg_lum += ((data[44] >> 4) & 3) |
2288 atomic_set(&sd->avg_lum, avg_lum);
2291 transfer_check(gspca_dev, data);
2293 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2299 if (gspca_dev->last_packet_type == LAST_PACKET) {
2301 gspca_frame_add(gspca_dev, FIRST_PACKET,
2302 sd->jpeg_hdr, JPEG_HDR_SZ);
2303 gspca_frame_add(gspca_dev, INTER_PACKET,
2306 gspca_frame_add(gspca_dev, FIRST_PACKET,
2310 /* if JPEG, count the packets and their size */
2315 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2319 /* sub-driver description */
2320 static const struct sd_desc sd_desc = {
2321 .name = KBUILD_MODNAME,
2322 .config = sd_config,
2324 .init_controls = sd_init_controls,
2325 .isoc_init = sd_isoc_init,
2329 .pkt_scan = sd_pkt_scan,
2330 #if IS_ENABLED(CONFIG_INPUT)
2331 .int_pkt_scan = sd_int_pkt_scan,
2333 .dq_callback = sd_dqcallback,
2334 #ifdef CONFIG_VIDEO_ADV_DEBUG
2335 .set_register = sd_dbg_s_register,
2336 .get_register = sd_dbg_g_register,
2337 .get_chip_info = sd_chip_info,
2341 #define SN9C20X(sensor, i2c_addr, flags) \
2342 .driver_info = ((flags & 0xff) << 16) \
2343 | (SENSOR_ ## sensor << 8) \
2346 static const struct usb_device_id device_table[] = {
2347 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2348 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, HAS_LED_TORCH)},
2349 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2350 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
2351 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
2352 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
2353 (FLIP_DETECT | HAS_NO_BUTTON))},
2354 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2355 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2356 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2357 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2358 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, FLIP_DETECT)},
2359 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2360 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2361 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2362 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2363 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
2364 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
2365 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2366 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2367 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2368 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2369 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, LED_REVERSE)},
2370 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, LED_REVERSE)},
2371 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2372 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2373 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2374 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2375 {USB_DEVICE(0x0458, 0x7045), SN9C20X(MT9M112, 0x5d, LED_REVERSE)},
2376 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
2377 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
2378 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2379 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2380 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2381 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2382 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
2383 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2384 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2387 MODULE_DEVICE_TABLE(usb, device_table);
2389 /* -- device connect -- */
2390 static int sd_probe(struct usb_interface *intf,
2391 const struct usb_device_id *id)
2393 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2397 static struct usb_driver sd_driver = {
2398 .name = KBUILD_MODNAME,
2399 .id_table = device_table,
2401 .disconnect = gspca_disconnect,
2403 .suspend = gspca_suspend,
2404 .resume = gspca_resume,
2405 .reset_resume = gspca_resume,
2409 module_usb_driver(sd_driver);