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.
19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
21 #include <linux/input.h>
26 #include <linux/dmi.h>
28 MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, microdia project <microdia@googlegroups.com>");
29 MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
30 MODULE_LICENSE("GPL");
33 * Pixel format private data
35 #define SCALE_MASK 0x0f
36 #define SCALE_160x120 0
37 #define SCALE_320x240 1
38 #define SCALE_640x480 2
39 #define SCALE_1280x1024 3
41 #define MODE_JPEG 0x20
42 #define MODE_SXGA 0x80
44 #define SENSOR_OV9650 0
45 #define SENSOR_OV9655 1
46 #define SENSOR_SOI968 2
47 #define SENSOR_OV7660 3
48 #define SENSOR_OV7670 4
49 #define SENSOR_MT9V011 5
50 #define SENSOR_MT9V111 6
51 #define SENSOR_MT9V112 7
52 #define SENSOR_MT9M001 8
53 #define SENSOR_MT9M111 9
54 #define SENSOR_MT9M112 10
55 #define SENSOR_HV7131R 11
56 #define SENSOR_MT9VPRB 12
59 #define HAS_NO_BUTTON 0x1
60 #define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
61 #define FLIP_DETECT 0x4
63 /* specific webcam descriptor */
65 struct gspca_dev gspca_dev
;
67 struct { /* color control cluster */
68 struct v4l2_ctrl
*brightness
;
69 struct v4l2_ctrl
*contrast
;
70 struct v4l2_ctrl
*saturation
;
71 struct v4l2_ctrl
*hue
;
73 struct { /* blue/red balance control cluster */
74 struct v4l2_ctrl
*blue
;
75 struct v4l2_ctrl
*red
;
77 struct { /* h/vflip control cluster */
78 struct v4l2_ctrl
*hflip
;
79 struct v4l2_ctrl
*vflip
;
81 struct v4l2_ctrl
*gamma
;
82 struct { /* autogain and exposure or gain control cluster */
83 struct v4l2_ctrl
*autogain
;
84 struct v4l2_ctrl
*exposure
;
85 struct v4l2_ctrl
*gain
;
87 struct v4l2_ctrl
*jpegqual
;
89 struct work_struct work
;
91 u32 pktsz
; /* (used by pkt_scan) */
94 u8 fmt
; /* (used for JPEG QTAB update */
96 #define MIN_AVG_LUM 80
97 #define MAX_AVG_LUM 130
109 u8 jpeg_hdr
[JPEG_HDR_SZ
];
114 static void qual_upd(struct work_struct
*work
);
126 static const struct dmi_system_id flip_dmi_table
[] = {
128 .ident
= "MSI MS-1034",
130 DMI_MATCH(DMI_SYS_VENDOR
, "MICRO-STAR INT'L CO.,LTD."),
131 DMI_MATCH(DMI_PRODUCT_NAME
, "MS-1034"),
132 DMI_MATCH(DMI_PRODUCT_VERSION
, "0341")
136 .ident
= "MSI MS-1039",
138 DMI_MATCH(DMI_SYS_VENDOR
, "MICRO-STAR INT'L CO.,LTD."),
139 DMI_MATCH(DMI_PRODUCT_NAME
, "MS-1039"),
143 .ident
= "MSI MS-1632",
145 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
146 DMI_MATCH(DMI_BOARD_NAME
, "MS-1632")
150 .ident
= "MSI MS-1633X",
152 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
153 DMI_MATCH(DMI_BOARD_NAME
, "MS-1633X")
157 .ident
= "MSI MS-1635X",
159 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
160 DMI_MATCH(DMI_BOARD_NAME
, "MS-1635X")
164 .ident
= "ASUSTeK W7J",
166 DMI_MATCH(DMI_BOARD_VENDOR
, "ASUSTeK Computer Inc."),
167 DMI_MATCH(DMI_BOARD_NAME
, "W7J ")
173 static const struct v4l2_pix_format vga_mode
[] = {
174 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
176 .sizeimage
= 160 * 120 * 4 / 8 + 590,
177 .colorspace
= V4L2_COLORSPACE_JPEG
,
178 .priv
= SCALE_160x120
| MODE_JPEG
},
179 {160, 120, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
181 .sizeimage
= 160 * 120,
182 .colorspace
= V4L2_COLORSPACE_SRGB
,
183 .priv
= SCALE_160x120
| MODE_RAW
},
184 {160, 120, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
186 .sizeimage
= 240 * 120,
187 .colorspace
= V4L2_COLORSPACE_SRGB
,
188 .priv
= SCALE_160x120
},
189 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
191 .sizeimage
= 320 * 240 * 4 / 8 + 590,
192 .colorspace
= V4L2_COLORSPACE_JPEG
,
193 .priv
= SCALE_320x240
| MODE_JPEG
},
194 {320, 240, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
196 .sizeimage
= 320 * 240 ,
197 .colorspace
= V4L2_COLORSPACE_SRGB
,
198 .priv
= SCALE_320x240
| MODE_RAW
},
199 {320, 240, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
201 .sizeimage
= 480 * 240 ,
202 .colorspace
= V4L2_COLORSPACE_SRGB
,
203 .priv
= SCALE_320x240
},
204 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
206 .sizeimage
= 640 * 480 * 4 / 8 + 590,
207 .colorspace
= V4L2_COLORSPACE_JPEG
,
208 .priv
= SCALE_640x480
| MODE_JPEG
},
209 {640, 480, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
211 .sizeimage
= 640 * 480,
212 .colorspace
= V4L2_COLORSPACE_SRGB
,
213 .priv
= SCALE_640x480
| MODE_RAW
},
214 {640, 480, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
216 .sizeimage
= 960 * 480,
217 .colorspace
= V4L2_COLORSPACE_SRGB
,
218 .priv
= SCALE_640x480
},
221 static const struct v4l2_pix_format sxga_mode
[] = {
222 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
224 .sizeimage
= 160 * 120 * 4 / 8 + 590,
225 .colorspace
= V4L2_COLORSPACE_JPEG
,
226 .priv
= SCALE_160x120
| MODE_JPEG
},
227 {160, 120, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
229 .sizeimage
= 160 * 120,
230 .colorspace
= V4L2_COLORSPACE_SRGB
,
231 .priv
= SCALE_160x120
| MODE_RAW
},
232 {160, 120, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
234 .sizeimage
= 240 * 120,
235 .colorspace
= V4L2_COLORSPACE_SRGB
,
236 .priv
= SCALE_160x120
},
237 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
239 .sizeimage
= 320 * 240 * 4 / 8 + 590,
240 .colorspace
= V4L2_COLORSPACE_JPEG
,
241 .priv
= SCALE_320x240
| MODE_JPEG
},
242 {320, 240, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
244 .sizeimage
= 320 * 240 ,
245 .colorspace
= V4L2_COLORSPACE_SRGB
,
246 .priv
= SCALE_320x240
| MODE_RAW
},
247 {320, 240, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
249 .sizeimage
= 480 * 240 ,
250 .colorspace
= V4L2_COLORSPACE_SRGB
,
251 .priv
= SCALE_320x240
},
252 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
254 .sizeimage
= 640 * 480 * 4 / 8 + 590,
255 .colorspace
= V4L2_COLORSPACE_JPEG
,
256 .priv
= SCALE_640x480
| MODE_JPEG
},
257 {640, 480, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
259 .sizeimage
= 640 * 480,
260 .colorspace
= V4L2_COLORSPACE_SRGB
,
261 .priv
= SCALE_640x480
| MODE_RAW
},
262 {640, 480, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
264 .sizeimage
= 960 * 480,
265 .colorspace
= V4L2_COLORSPACE_SRGB
,
266 .priv
= SCALE_640x480
},
267 {1280, 1024, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
268 .bytesperline
= 1280,
269 .sizeimage
= 1280 * 1024,
270 .colorspace
= V4L2_COLORSPACE_SRGB
,
271 .priv
= SCALE_1280x1024
| MODE_RAW
| MODE_SXGA
},
274 static const struct v4l2_pix_format mono_mode
[] = {
275 {160, 120, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
277 .sizeimage
= 160 * 120,
278 .colorspace
= V4L2_COLORSPACE_SRGB
,
279 .priv
= SCALE_160x120
| MODE_RAW
},
280 {320, 240, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
282 .sizeimage
= 320 * 240 ,
283 .colorspace
= V4L2_COLORSPACE_SRGB
,
284 .priv
= SCALE_320x240
| MODE_RAW
},
285 {640, 480, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
287 .sizeimage
= 640 * 480,
288 .colorspace
= V4L2_COLORSPACE_SRGB
,
289 .priv
= SCALE_640x480
| MODE_RAW
},
290 {1280, 1024, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
291 .bytesperline
= 1280,
292 .sizeimage
= 1280 * 1024,
293 .colorspace
= V4L2_COLORSPACE_SRGB
,
294 .priv
= SCALE_1280x1024
| MODE_RAW
| MODE_SXGA
},
297 static const s16 hsv_red_x
[] = {
298 41, 44, 46, 48, 50, 52, 54, 56,
299 58, 60, 62, 64, 66, 68, 70, 72,
300 74, 76, 78, 80, 81, 83, 85, 87,
301 88, 90, 92, 93, 95, 97, 98, 100,
302 101, 102, 104, 105, 107, 108, 109, 110,
303 112, 113, 114, 115, 116, 117, 118, 119,
304 120, 121, 122, 123, 123, 124, 125, 125,
305 126, 127, 127, 128, 128, 129, 129, 129,
306 130, 130, 130, 130, 131, 131, 131, 131,
307 131, 131, 131, 131, 130, 130, 130, 130,
308 129, 129, 129, 128, 128, 127, 127, 126,
309 125, 125, 124, 123, 122, 122, 121, 120,
310 119, 118, 117, 116, 115, 114, 112, 111,
311 110, 109, 107, 106, 105, 103, 102, 101,
312 99, 98, 96, 94, 93, 91, 90, 88,
313 86, 84, 83, 81, 79, 77, 75, 74,
314 72, 70, 68, 66, 64, 62, 60, 58,
315 56, 54, 52, 49, 47, 45, 43, 41,
316 39, 36, 34, 32, 30, 28, 25, 23,
317 21, 19, 16, 14, 12, 9, 7, 5,
318 3, 0, -1, -3, -6, -8, -10, -12,
319 -15, -17, -19, -22, -24, -26, -28, -30,
320 -33, -35, -37, -39, -41, -44, -46, -48,
321 -50, -52, -54, -56, -58, -60, -62, -64,
322 -66, -68, -70, -72, -74, -76, -78, -80,
323 -81, -83, -85, -87, -88, -90, -92, -93,
324 -95, -97, -98, -100, -101, -102, -104, -105,
325 -107, -108, -109, -110, -112, -113, -114, -115,
326 -116, -117, -118, -119, -120, -121, -122, -123,
327 -123, -124, -125, -125, -126, -127, -127, -128,
328 -128, -128, -128, -128, -128, -128, -128, -128,
329 -128, -128, -128, -128, -128, -128, -128, -128,
330 -128, -128, -128, -128, -128, -128, -128, -128,
331 -128, -127, -127, -126, -125, -125, -124, -123,
332 -122, -122, -121, -120, -119, -118, -117, -116,
333 -115, -114, -112, -111, -110, -109, -107, -106,
334 -105, -103, -102, -101, -99, -98, -96, -94,
335 -93, -91, -90, -88, -86, -84, -83, -81,
336 -79, -77, -75, -74, -72, -70, -68, -66,
337 -64, -62, -60, -58, -56, -54, -52, -49,
338 -47, -45, -43, -41, -39, -36, -34, -32,
339 -30, -28, -25, -23, -21, -19, -16, -14,
340 -12, -9, -7, -5, -3, 0, 1, 3,
341 6, 8, 10, 12, 15, 17, 19, 22,
342 24, 26, 28, 30, 33, 35, 37, 39, 41
345 static const s16 hsv_red_y
[] = {
346 82, 80, 78, 76, 74, 73, 71, 69,
347 67, 65, 63, 61, 58, 56, 54, 52,
348 50, 48, 46, 44, 41, 39, 37, 35,
349 32, 30, 28, 26, 23, 21, 19, 16,
350 14, 12, 10, 7, 5, 3, 0, -1,
351 -3, -6, -8, -10, -13, -15, -17, -19,
352 -22, -24, -26, -29, -31, -33, -35, -38,
353 -40, -42, -44, -46, -48, -51, -53, -55,
354 -57, -59, -61, -63, -65, -67, -69, -71,
355 -73, -75, -77, -79, -81, -82, -84, -86,
356 -88, -89, -91, -93, -94, -96, -98, -99,
357 -101, -102, -104, -105, -106, -108, -109, -110,
358 -112, -113, -114, -115, -116, -117, -119, -120,
359 -120, -121, -122, -123, -124, -125, -126, -126,
360 -127, -128, -128, -128, -128, -128, -128, -128,
361 -128, -128, -128, -128, -128, -128, -128, -128,
362 -128, -128, -128, -128, -128, -128, -128, -128,
363 -128, -128, -128, -128, -128, -128, -128, -128,
364 -127, -127, -126, -125, -125, -124, -123, -122,
365 -121, -120, -119, -118, -117, -116, -115, -114,
366 -113, -111, -110, -109, -107, -106, -105, -103,
367 -102, -100, -99, -97, -96, -94, -92, -91,
368 -89, -87, -85, -84, -82, -80, -78, -76,
369 -74, -73, -71, -69, -67, -65, -63, -61,
370 -58, -56, -54, -52, -50, -48, -46, -44,
371 -41, -39, -37, -35, -32, -30, -28, -26,
372 -23, -21, -19, -16, -14, -12, -10, -7,
373 -5, -3, 0, 1, 3, 6, 8, 10,
374 13, 15, 17, 19, 22, 24, 26, 29,
375 31, 33, 35, 38, 40, 42, 44, 46,
376 48, 51, 53, 55, 57, 59, 61, 63,
377 65, 67, 69, 71, 73, 75, 77, 79,
378 81, 82, 84, 86, 88, 89, 91, 93,
379 94, 96, 98, 99, 101, 102, 104, 105,
380 106, 108, 109, 110, 112, 113, 114, 115,
381 116, 117, 119, 120, 120, 121, 122, 123,
382 124, 125, 126, 126, 127, 128, 128, 129,
383 129, 130, 130, 131, 131, 131, 131, 132,
384 132, 132, 132, 132, 132, 132, 132, 132,
385 132, 132, 132, 131, 131, 131, 130, 130,
386 130, 129, 129, 128, 127, 127, 126, 125,
387 125, 124, 123, 122, 121, 120, 119, 118,
388 117, 116, 115, 114, 113, 111, 110, 109,
389 107, 106, 105, 103, 102, 100, 99, 97,
390 96, 94, 92, 91, 89, 87, 85, 84, 82
393 static const s16 hsv_green_x
[] = {
394 -124, -124, -125, -125, -125, -125, -125, -125,
395 -125, -126, -126, -125, -125, -125, -125, -125,
396 -125, -124, -124, -124, -123, -123, -122, -122,
397 -121, -121, -120, -120, -119, -118, -117, -117,
398 -116, -115, -114, -113, -112, -111, -110, -109,
399 -108, -107, -105, -104, -103, -102, -100, -99,
400 -98, -96, -95, -93, -92, -91, -89, -87,
401 -86, -84, -83, -81, -79, -77, -76, -74,
402 -72, -70, -69, -67, -65, -63, -61, -59,
403 -57, -55, -53, -51, -49, -47, -45, -43,
404 -41, -39, -37, -35, -33, -30, -28, -26,
405 -24, -22, -20, -18, -15, -13, -11, -9,
406 -7, -4, -2, 0, 1, 3, 6, 8,
407 10, 12, 14, 17, 19, 21, 23, 25,
408 27, 29, 32, 34, 36, 38, 40, 42,
409 44, 46, 48, 50, 52, 54, 56, 58,
410 60, 62, 64, 66, 68, 70, 71, 73,
411 75, 77, 78, 80, 82, 83, 85, 87,
412 88, 90, 91, 93, 94, 96, 97, 98,
413 100, 101, 102, 104, 105, 106, 107, 108,
414 109, 111, 112, 113, 113, 114, 115, 116,
415 117, 118, 118, 119, 120, 120, 121, 122,
416 122, 123, 123, 124, 124, 124, 125, 125,
417 125, 125, 125, 125, 125, 126, 126, 125,
418 125, 125, 125, 125, 125, 124, 124, 124,
419 123, 123, 122, 122, 121, 121, 120, 120,
420 119, 118, 117, 117, 116, 115, 114, 113,
421 112, 111, 110, 109, 108, 107, 105, 104,
422 103, 102, 100, 99, 98, 96, 95, 93,
423 92, 91, 89, 87, 86, 84, 83, 81,
424 79, 77, 76, 74, 72, 70, 69, 67,
425 65, 63, 61, 59, 57, 55, 53, 51,
426 49, 47, 45, 43, 41, 39, 37, 35,
427 33, 30, 28, 26, 24, 22, 20, 18,
428 15, 13, 11, 9, 7, 4, 2, 0,
429 -1, -3, -6, -8, -10, -12, -14, -17,
430 -19, -21, -23, -25, -27, -29, -32, -34,
431 -36, -38, -40, -42, -44, -46, -48, -50,
432 -52, -54, -56, -58, -60, -62, -64, -66,
433 -68, -70, -71, -73, -75, -77, -78, -80,
434 -82, -83, -85, -87, -88, -90, -91, -93,
435 -94, -96, -97, -98, -100, -101, -102, -104,
436 -105, -106, -107, -108, -109, -111, -112, -113,
437 -113, -114, -115, -116, -117, -118, -118, -119,
438 -120, -120, -121, -122, -122, -123, -123, -124, -124
441 static const s16 hsv_green_y
[] = {
442 -100, -99, -98, -97, -95, -94, -93, -91,
443 -90, -89, -87, -86, -84, -83, -81, -80,
444 -78, -76, -75, -73, -71, -70, -68, -66,
445 -64, -63, -61, -59, -57, -55, -53, -51,
446 -49, -48, -46, -44, -42, -40, -38, -36,
447 -34, -32, -30, -27, -25, -23, -21, -19,
448 -17, -15, -13, -11, -9, -7, -4, -2,
449 0, 1, 3, 5, 7, 9, 11, 14,
450 16, 18, 20, 22, 24, 26, 28, 30,
451 32, 34, 36, 38, 40, 42, 44, 46,
452 48, 50, 52, 54, 56, 58, 59, 61,
453 63, 65, 67, 68, 70, 72, 74, 75,
454 77, 78, 80, 82, 83, 85, 86, 88,
455 89, 90, 92, 93, 95, 96, 97, 98,
456 100, 101, 102, 103, 104, 105, 106, 107,
457 108, 109, 110, 111, 112, 112, 113, 114,
458 115, 115, 116, 116, 117, 117, 118, 118,
459 119, 119, 119, 120, 120, 120, 120, 120,
460 121, 121, 121, 121, 121, 121, 120, 120,
461 120, 120, 120, 119, 119, 119, 118, 118,
462 117, 117, 116, 116, 115, 114, 114, 113,
463 112, 111, 111, 110, 109, 108, 107, 106,
464 105, 104, 103, 102, 100, 99, 98, 97,
465 95, 94, 93, 91, 90, 89, 87, 86,
466 84, 83, 81, 80, 78, 76, 75, 73,
467 71, 70, 68, 66, 64, 63, 61, 59,
468 57, 55, 53, 51, 49, 48, 46, 44,
469 42, 40, 38, 36, 34, 32, 30, 27,
470 25, 23, 21, 19, 17, 15, 13, 11,
471 9, 7, 4, 2, 0, -1, -3, -5,
472 -7, -9, -11, -14, -16, -18, -20, -22,
473 -24, -26, -28, -30, -32, -34, -36, -38,
474 -40, -42, -44, -46, -48, -50, -52, -54,
475 -56, -58, -59, -61, -63, -65, -67, -68,
476 -70, -72, -74, -75, -77, -78, -80, -82,
477 -83, -85, -86, -88, -89, -90, -92, -93,
478 -95, -96, -97, -98, -100, -101, -102, -103,
479 -104, -105, -106, -107, -108, -109, -110, -111,
480 -112, -112, -113, -114, -115, -115, -116, -116,
481 -117, -117, -118, -118, -119, -119, -119, -120,
482 -120, -120, -120, -120, -121, -121, -121, -121,
483 -121, -121, -120, -120, -120, -120, -120, -119,
484 -119, -119, -118, -118, -117, -117, -116, -116,
485 -115, -114, -114, -113, -112, -111, -111, -110,
486 -109, -108, -107, -106, -105, -104, -103, -102, -100
489 static const s16 hsv_blue_x
[] = {
490 112, 113, 114, 114, 115, 116, 117, 117,
491 118, 118, 119, 119, 120, 120, 120, 121,
492 121, 121, 122, 122, 122, 122, 122, 122,
493 122, 122, 122, 122, 122, 122, 121, 121,
494 121, 120, 120, 120, 119, 119, 118, 118,
495 117, 116, 116, 115, 114, 113, 113, 112,
496 111, 110, 109, 108, 107, 106, 105, 104,
497 103, 102, 100, 99, 98, 97, 95, 94,
498 93, 91, 90, 88, 87, 85, 84, 82,
499 80, 79, 77, 76, 74, 72, 70, 69,
500 67, 65, 63, 61, 60, 58, 56, 54,
501 52, 50, 48, 46, 44, 42, 40, 38,
502 36, 34, 32, 30, 28, 26, 24, 22,
503 19, 17, 15, 13, 11, 9, 7, 5,
504 2, 0, -1, -3, -5, -7, -9, -12,
505 -14, -16, -18, -20, -22, -24, -26, -28,
506 -31, -33, -35, -37, -39, -41, -43, -45,
507 -47, -49, -51, -53, -54, -56, -58, -60,
508 -62, -64, -66, -67, -69, -71, -73, -74,
509 -76, -78, -79, -81, -83, -84, -86, -87,
510 -89, -90, -92, -93, -94, -96, -97, -98,
511 -99, -101, -102, -103, -104, -105, -106, -107,
512 -108, -109, -110, -111, -112, -113, -114, -114,
513 -115, -116, -117, -117, -118, -118, -119, -119,
514 -120, -120, -120, -121, -121, -121, -122, -122,
515 -122, -122, -122, -122, -122, -122, -122, -122,
516 -122, -122, -121, -121, -121, -120, -120, -120,
517 -119, -119, -118, -118, -117, -116, -116, -115,
518 -114, -113, -113, -112, -111, -110, -109, -108,
519 -107, -106, -105, -104, -103, -102, -100, -99,
520 -98, -97, -95, -94, -93, -91, -90, -88,
521 -87, -85, -84, -82, -80, -79, -77, -76,
522 -74, -72, -70, -69, -67, -65, -63, -61,
523 -60, -58, -56, -54, -52, -50, -48, -46,
524 -44, -42, -40, -38, -36, -34, -32, -30,
525 -28, -26, -24, -22, -19, -17, -15, -13,
526 -11, -9, -7, -5, -2, 0, 1, 3,
527 5, 7, 9, 12, 14, 16, 18, 20,
528 22, 24, 26, 28, 31, 33, 35, 37,
529 39, 41, 43, 45, 47, 49, 51, 53,
530 54, 56, 58, 60, 62, 64, 66, 67,
531 69, 71, 73, 74, 76, 78, 79, 81,
532 83, 84, 86, 87, 89, 90, 92, 93,
533 94, 96, 97, 98, 99, 101, 102, 103,
534 104, 105, 106, 107, 108, 109, 110, 111, 112
537 static const s16 hsv_blue_y
[] = {
538 -11, -13, -15, -17, -19, -21, -23, -25,
539 -27, -29, -31, -33, -35, -37, -39, -41,
540 -43, -45, -46, -48, -50, -52, -54, -55,
541 -57, -59, -61, -62, -64, -66, -67, -69,
542 -71, -72, -74, -75, -77, -78, -80, -81,
543 -83, -84, -86, -87, -88, -90, -91, -92,
544 -93, -95, -96, -97, -98, -99, -100, -101,
545 -102, -103, -104, -105, -106, -106, -107, -108,
546 -109, -109, -110, -111, -111, -112, -112, -113,
547 -113, -114, -114, -114, -115, -115, -115, -115,
548 -116, -116, -116, -116, -116, -116, -116, -116,
549 -116, -115, -115, -115, -115, -114, -114, -114,
550 -113, -113, -112, -112, -111, -111, -110, -110,
551 -109, -108, -108, -107, -106, -105, -104, -103,
552 -102, -101, -100, -99, -98, -97, -96, -95,
553 -94, -93, -91, -90, -89, -88, -86, -85,
554 -84, -82, -81, -79, -78, -76, -75, -73,
555 -71, -70, -68, -67, -65, -63, -62, -60,
556 -58, -56, -55, -53, -51, -49, -47, -45,
557 -44, -42, -40, -38, -36, -34, -32, -30,
558 -28, -26, -24, -22, -20, -18, -16, -14,
559 -12, -10, -8, -6, -4, -2, 0, 1,
560 3, 5, 7, 9, 11, 13, 15, 17,
561 19, 21, 23, 25, 27, 29, 31, 33,
562 35, 37, 39, 41, 43, 45, 46, 48,
563 50, 52, 54, 55, 57, 59, 61, 62,
564 64, 66, 67, 69, 71, 72, 74, 75,
565 77, 78, 80, 81, 83, 84, 86, 87,
566 88, 90, 91, 92, 93, 95, 96, 97,
567 98, 99, 100, 101, 102, 103, 104, 105,
568 106, 106, 107, 108, 109, 109, 110, 111,
569 111, 112, 112, 113, 113, 114, 114, 114,
570 115, 115, 115, 115, 116, 116, 116, 116,
571 116, 116, 116, 116, 116, 115, 115, 115,
572 115, 114, 114, 114, 113, 113, 112, 112,
573 111, 111, 110, 110, 109, 108, 108, 107,
574 106, 105, 104, 103, 102, 101, 100, 99,
575 98, 97, 96, 95, 94, 93, 91, 90,
576 89, 88, 86, 85, 84, 82, 81, 79,
577 78, 76, 75, 73, 71, 70, 68, 67,
578 65, 63, 62, 60, 58, 56, 55, 53,
579 51, 49, 47, 45, 44, 42, 40, 38,
580 36, 34, 32, 30, 28, 26, 24, 22,
581 20, 18, 16, 14, 12, 10, 8, 6,
582 4, 2, 0, -1, -3, -5, -7, -9, -11
585 static const u16 bridge_init
[][2] = {
586 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
587 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
588 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
589 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
590 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
591 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
592 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
593 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
594 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
595 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
596 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
597 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
598 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
599 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
600 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
601 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
602 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
603 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
604 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
608 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
609 static const u8 ov_gain
[] = {
610 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
611 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
612 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
613 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
614 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
615 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
616 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
620 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
621 static const u16 micron1_gain
[] = {
622 /* 1x 1.25x 1.5x 1.75x */
623 0x0020, 0x0028, 0x0030, 0x0038,
624 /* 2x 2.25x 2.5x 2.75x */
625 0x00a0, 0x00a4, 0x00a8, 0x00ac,
626 /* 3x 3.25x 3.5x 3.75x */
627 0x00b0, 0x00b4, 0x00b8, 0x00bc,
628 /* 4x 4.25x 4.5x 4.75x */
629 0x00c0, 0x00c4, 0x00c8, 0x00cc,
630 /* 5x 5.25x 5.5x 5.75x */
631 0x00d0, 0x00d4, 0x00d8, 0x00dc,
632 /* 6x 6.25x 6.5x 6.75x */
633 0x00e0, 0x00e4, 0x00e8, 0x00ec,
634 /* 7x 7.25x 7.5x 7.75x */
635 0x00f0, 0x00f4, 0x00f8, 0x00fc,
640 /* mt9m001 sensor uses a different gain formula then other micron sensors */
641 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
642 static const u16 micron2_gain
[] = {
643 /* 1x 1.25x 1.5x 1.75x */
644 0x0008, 0x000a, 0x000c, 0x000e,
645 /* 2x 2.25x 2.5x 2.75x */
646 0x0010, 0x0012, 0x0014, 0x0016,
647 /* 3x 3.25x 3.5x 3.75x */
648 0x0018, 0x001a, 0x001c, 0x001e,
649 /* 4x 4.25x 4.5x 4.75x */
650 0x0020, 0x0051, 0x0052, 0x0053,
651 /* 5x 5.25x 5.5x 5.75x */
652 0x0054, 0x0055, 0x0056, 0x0057,
653 /* 6x 6.25x 6.5x 6.75x */
654 0x0058, 0x0059, 0x005a, 0x005b,
655 /* 7x 7.25x 7.5x 7.75x */
656 0x005c, 0x005d, 0x005e, 0x005f,
661 /* Gain = .5 + bit[7:0] / 16 */
662 static const u8 hv7131r_gain
[] = {
663 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
664 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
665 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
666 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
667 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
668 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
669 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
673 static const struct i2c_reg_u8 soi968_init
[] = {
674 {0x0c, 0x00}, {0x0f, 0x1f},
675 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
676 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
677 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
678 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
679 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
680 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
681 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
682 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
683 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
684 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
687 static const struct i2c_reg_u8 ov7660_init
[] = {
688 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
689 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
690 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
691 /* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using
692 0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
693 {0x17, 0x10}, {0x18, 0x61},
694 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
695 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0x00},
696 {0x2e, 0x00}, {0x01, 0x78}, {0x02, 0x50},
699 static const struct i2c_reg_u8 ov7670_init
[] = {
700 {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
701 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
702 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
703 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
704 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
705 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
706 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
707 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
708 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
709 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
710 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
711 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
712 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
713 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
714 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
715 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
716 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
717 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
718 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
719 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
720 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
721 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
722 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
723 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
724 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
725 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
726 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
727 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
728 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
729 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
730 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
731 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
732 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
733 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
734 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
735 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
736 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
737 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
738 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
739 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
740 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
741 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
742 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
743 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
744 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
745 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
746 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
747 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
748 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
749 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
750 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
751 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
752 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
756 static const struct i2c_reg_u8 ov9650_init
[] = {
757 {0x00, 0x00}, {0x01, 0x78},
758 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
759 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
760 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
761 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
762 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
763 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
764 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
765 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
766 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
767 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
768 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
769 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
770 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
771 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
772 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
773 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
774 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
775 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
776 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
777 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
778 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
779 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
780 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
781 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
782 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
783 {0xaa, 0x92}, {0xab, 0x0a},
786 static const struct i2c_reg_u8 ov9655_init
[] = {
787 {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
788 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
789 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
790 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
791 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
792 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
793 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
794 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
795 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
796 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
797 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
798 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
799 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
800 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
801 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
802 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
803 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
804 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
805 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
806 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
807 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
808 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
809 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
810 {0x04, 0x03}, {0x00, 0x13},
813 static const struct i2c_reg_u16 mt9v112_init
[] = {
814 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
815 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
816 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
817 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
818 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
819 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
820 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
821 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
822 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
823 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
824 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
825 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
826 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
827 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
828 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
829 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
832 static const struct i2c_reg_u16 mt9v111_init
[] = {
833 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
834 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
835 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
836 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
837 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
838 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
839 {0x0e, 0x0008}, {0x20, 0x0000}
842 static const struct i2c_reg_u16 mt9v011_init
[] = {
843 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
844 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
845 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
846 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
847 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
848 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
849 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
850 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
851 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
852 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
853 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
854 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
855 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
856 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
857 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
858 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
859 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
860 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
861 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
862 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
863 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
864 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
865 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
866 {0x06, 0x0029}, {0x05, 0x0009},
869 static const struct i2c_reg_u16 mt9m001_init
[] = {
872 {0x04, 0x0500}, /* hres = 1280 */
873 {0x03, 0x0400}, /* vres = 1024 */
885 static const struct i2c_reg_u16 mt9m111_init
[] = {
886 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
887 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
888 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
892 static const struct i2c_reg_u16 mt9m112_init
[] = {
893 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
894 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
895 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
899 static const struct i2c_reg_u8 hv7131r_init
[] = {
900 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
901 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
902 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
903 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
904 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
905 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
906 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
907 {0x23, 0x09}, {0x01, 0x08},
910 static void reg_r(struct gspca_dev
*gspca_dev
, u16 reg
, u16 length
)
912 struct usb_device
*dev
= gspca_dev
->dev
;
915 if (gspca_dev
->usb_err
< 0)
917 result
= usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
919 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
925 if (unlikely(result
< 0 || result
!= length
)) {
926 pr_err("Read register %02x failed %d\n", reg
, result
);
927 gspca_dev
->usb_err
= result
;
929 * Make sure the buffer is zeroed to avoid uninitialized
932 memset(gspca_dev
->usb_buf
, 0, USB_BUF_SZ
);
936 static void reg_w(struct gspca_dev
*gspca_dev
, u16 reg
,
937 const u8
*buffer
, int length
)
939 struct usb_device
*dev
= gspca_dev
->dev
;
942 if (gspca_dev
->usb_err
< 0)
944 memcpy(gspca_dev
->usb_buf
, buffer
, length
);
945 result
= usb_control_msg(dev
, usb_sndctrlpipe(dev
, 0),
947 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
953 if (unlikely(result
< 0 || result
!= length
)) {
954 pr_err("Write register %02x failed %d\n", reg
, result
);
955 gspca_dev
->usb_err
= result
;
959 static void reg_w1(struct gspca_dev
*gspca_dev
, u16 reg
, const u8 value
)
961 reg_w(gspca_dev
, reg
, &value
, 1);
964 static void i2c_w(struct gspca_dev
*gspca_dev
, const u8
*buffer
)
968 reg_w(gspca_dev
, 0x10c0, buffer
, 8);
969 for (i
= 0; i
< 5; i
++) {
970 reg_r(gspca_dev
, 0x10c0, 1);
971 if (gspca_dev
->usb_err
< 0)
973 if (gspca_dev
->usb_buf
[0] & 0x04) {
974 if (gspca_dev
->usb_buf
[0] & 0x08) {
975 pr_err("i2c_w error\n");
976 gspca_dev
->usb_err
= -EIO
;
982 pr_err("i2c_w reg %02x no response\n", buffer
[2]);
983 /* gspca_dev->usb_err = -EIO; fixme: may occur */
986 static void i2c_w1(struct gspca_dev
*gspca_dev
, u8 reg
, u8 val
)
988 struct sd
*sd
= (struct sd
*) gspca_dev
;
992 * from the point of view of the bridge, the length
993 * includes the address
995 row
[0] = sd
->i2c_intf
| (2 << 4);
996 row
[1] = sd
->i2c_addr
;
1004 i2c_w(gspca_dev
, row
);
1007 static void i2c_w1_buf(struct gspca_dev
*gspca_dev
,
1008 const struct i2c_reg_u8
*buf
, int sz
)
1011 i2c_w1(gspca_dev
, buf
->reg
, buf
->val
);
1016 static void i2c_w2(struct gspca_dev
*gspca_dev
, u8 reg
, u16 val
)
1018 struct sd
*sd
= (struct sd
*) gspca_dev
;
1022 * from the point of view of the bridge, the length
1023 * includes the address
1025 row
[0] = sd
->i2c_intf
| (3 << 4);
1026 row
[1] = sd
->i2c_addr
;
1034 i2c_w(gspca_dev
, row
);
1037 static void i2c_w2_buf(struct gspca_dev
*gspca_dev
,
1038 const struct i2c_reg_u16
*buf
, int sz
)
1041 i2c_w2(gspca_dev
, buf
->reg
, buf
->val
);
1046 static void i2c_r1(struct gspca_dev
*gspca_dev
, u8 reg
, u8
*val
)
1048 struct sd
*sd
= (struct sd
*) gspca_dev
;
1051 row
[0] = sd
->i2c_intf
| (1 << 4);
1052 row
[1] = sd
->i2c_addr
;
1059 i2c_w(gspca_dev
, row
);
1060 row
[0] = sd
->i2c_intf
| (1 << 4) | 0x02;
1062 i2c_w(gspca_dev
, row
);
1063 reg_r(gspca_dev
, 0x10c2, 5);
1064 *val
= gspca_dev
->usb_buf
[4];
1067 static void i2c_r2(struct gspca_dev
*gspca_dev
, u8 reg
, u16
*val
)
1069 struct sd
*sd
= (struct sd
*) gspca_dev
;
1072 row
[0] = sd
->i2c_intf
| (1 << 4);
1073 row
[1] = sd
->i2c_addr
;
1080 i2c_w(gspca_dev
, row
);
1081 row
[0] = sd
->i2c_intf
| (2 << 4) | 0x02;
1083 i2c_w(gspca_dev
, row
);
1084 reg_r(gspca_dev
, 0x10c2, 5);
1085 *val
= (gspca_dev
->usb_buf
[3] << 8) | gspca_dev
->usb_buf
[4];
1088 static void ov9650_init_sensor(struct gspca_dev
*gspca_dev
)
1091 struct sd
*sd
= (struct sd
*) gspca_dev
;
1093 i2c_r2(gspca_dev
, 0x1c, &id
);
1094 if (gspca_dev
->usb_err
< 0)
1098 pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id
);
1099 gspca_dev
->usb_err
= -ENODEV
;
1103 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1105 i2c_w1_buf(gspca_dev
, ov9650_init
, ARRAY_SIZE(ov9650_init
));
1106 if (gspca_dev
->usb_err
< 0)
1107 pr_err("OV9650 sensor initialization failed\n");
1112 static void ov9655_init_sensor(struct gspca_dev
*gspca_dev
)
1114 struct sd
*sd
= (struct sd
*) gspca_dev
;
1116 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1118 i2c_w1_buf(gspca_dev
, ov9655_init
, ARRAY_SIZE(ov9655_init
));
1119 if (gspca_dev
->usb_err
< 0)
1120 pr_err("OV9655 sensor initialization failed\n");
1126 static void soi968_init_sensor(struct gspca_dev
*gspca_dev
)
1128 struct sd
*sd
= (struct sd
*) gspca_dev
;
1130 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1132 i2c_w1_buf(gspca_dev
, soi968_init
, ARRAY_SIZE(soi968_init
));
1133 if (gspca_dev
->usb_err
< 0)
1134 pr_err("SOI968 sensor initialization failed\n");
1140 static void ov7660_init_sensor(struct gspca_dev
*gspca_dev
)
1142 struct sd
*sd
= (struct sd
*) gspca_dev
;
1144 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1146 i2c_w1_buf(gspca_dev
, ov7660_init
, ARRAY_SIZE(ov7660_init
));
1147 if (gspca_dev
->usb_err
< 0)
1148 pr_err("OV7660 sensor initialization failed\n");
1153 static void ov7670_init_sensor(struct gspca_dev
*gspca_dev
)
1155 struct sd
*sd
= (struct sd
*) gspca_dev
;
1157 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1159 i2c_w1_buf(gspca_dev
, ov7670_init
, ARRAY_SIZE(ov7670_init
));
1160 if (gspca_dev
->usb_err
< 0)
1161 pr_err("OV7670 sensor initialization failed\n");
1167 static void mt9v_init_sensor(struct gspca_dev
*gspca_dev
)
1169 struct sd
*sd
= (struct sd
*) gspca_dev
;
1172 sd
->i2c_addr
= 0x5d;
1173 i2c_r2(gspca_dev
, 0xff, &value
);
1174 if (gspca_dev
->usb_err
>= 0
1175 && value
== 0x8243) {
1176 i2c_w2_buf(gspca_dev
, mt9v011_init
, ARRAY_SIZE(mt9v011_init
));
1177 if (gspca_dev
->usb_err
< 0) {
1178 pr_err("MT9V011 sensor initialization failed\n");
1183 sd
->sensor
= SENSOR_MT9V011
;
1184 pr_info("MT9V011 sensor detected\n");
1188 gspca_dev
->usb_err
= 0;
1189 sd
->i2c_addr
= 0x5c;
1190 i2c_w2(gspca_dev
, 0x01, 0x0004);
1191 i2c_r2(gspca_dev
, 0xff, &value
);
1192 if (gspca_dev
->usb_err
>= 0
1193 && value
== 0x823a) {
1194 i2c_w2_buf(gspca_dev
, mt9v111_init
, ARRAY_SIZE(mt9v111_init
));
1195 if (gspca_dev
->usb_err
< 0) {
1196 pr_err("MT9V111 sensor initialization failed\n");
1201 sd
->sensor
= SENSOR_MT9V111
;
1202 pr_info("MT9V111 sensor detected\n");
1206 gspca_dev
->usb_err
= 0;
1207 sd
->i2c_addr
= 0x5d;
1208 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1209 if (gspca_dev
->usb_err
< 0) {
1210 gspca_dev
->usb_err
= 0;
1211 sd
->i2c_addr
= 0x48;
1212 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1214 i2c_r2(gspca_dev
, 0x00, &value
);
1215 if (gspca_dev
->usb_err
>= 0
1216 && value
== 0x1229) {
1217 i2c_w2_buf(gspca_dev
, mt9v112_init
, ARRAY_SIZE(mt9v112_init
));
1218 if (gspca_dev
->usb_err
< 0) {
1219 pr_err("MT9V112 sensor initialization failed\n");
1224 sd
->sensor
= SENSOR_MT9V112
;
1225 pr_info("MT9V112 sensor detected\n");
1229 gspca_dev
->usb_err
= -ENODEV
;
1232 static void mt9m112_init_sensor(struct gspca_dev
*gspca_dev
)
1234 struct sd
*sd
= (struct sd
*) gspca_dev
;
1236 i2c_w2_buf(gspca_dev
, mt9m112_init
, ARRAY_SIZE(mt9m112_init
));
1237 if (gspca_dev
->usb_err
< 0)
1238 pr_err("MT9M112 sensor initialization failed\n");
1244 static void mt9m111_init_sensor(struct gspca_dev
*gspca_dev
)
1246 struct sd
*sd
= (struct sd
*) gspca_dev
;
1248 i2c_w2_buf(gspca_dev
, mt9m111_init
, ARRAY_SIZE(mt9m111_init
));
1249 if (gspca_dev
->usb_err
< 0)
1250 pr_err("MT9M111 sensor initialization failed\n");
1256 static void mt9m001_init_sensor(struct gspca_dev
*gspca_dev
)
1258 struct sd
*sd
= (struct sd
*) gspca_dev
;
1261 i2c_r2(gspca_dev
, 0x00, &id
);
1262 if (gspca_dev
->usb_err
< 0)
1265 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
1269 pr_info("MT9M001 color sensor detected\n");
1272 pr_info("MT9M001 mono sensor detected\n");
1275 pr_err("No MT9M001 chip detected, ID = %x\n\n", id
);
1276 gspca_dev
->usb_err
= -ENODEV
;
1280 i2c_w2_buf(gspca_dev
, mt9m001_init
, ARRAY_SIZE(mt9m001_init
));
1281 if (gspca_dev
->usb_err
< 0)
1282 pr_err("MT9M001 sensor initialization failed\n");
1288 static void hv7131r_init_sensor(struct gspca_dev
*gspca_dev
)
1290 struct sd
*sd
= (struct sd
*) gspca_dev
;
1292 i2c_w1_buf(gspca_dev
, hv7131r_init
, ARRAY_SIZE(hv7131r_init
));
1293 if (gspca_dev
->usb_err
< 0)
1294 pr_err("HV7131R Sensor initialization failed\n");
1300 static void set_cmatrix(struct gspca_dev
*gspca_dev
,
1301 s32 brightness
, s32 contrast
, s32 satur
, s32 hue
)
1303 s32 hue_coord
, hue_index
= 180 + hue
;
1306 memset(cmatrix
, 0, sizeof(cmatrix
));
1307 cmatrix
[2] = (contrast
* 0x25 / 0x100) + 0x26;
1308 cmatrix
[0] = 0x13 + (cmatrix
[2] - 0x26) * 0x13 / 0x25;
1309 cmatrix
[4] = 0x07 + (cmatrix
[2] - 0x26) * 0x07 / 0x25;
1310 cmatrix
[18] = brightness
- 0x80;
1312 hue_coord
= (hsv_red_x
[hue_index
] * satur
) >> 8;
1313 cmatrix
[6] = hue_coord
;
1314 cmatrix
[7] = (hue_coord
>> 8) & 0x0f;
1316 hue_coord
= (hsv_red_y
[hue_index
] * satur
) >> 8;
1317 cmatrix
[8] = hue_coord
;
1318 cmatrix
[9] = (hue_coord
>> 8) & 0x0f;
1320 hue_coord
= (hsv_green_x
[hue_index
] * satur
) >> 8;
1321 cmatrix
[10] = hue_coord
;
1322 cmatrix
[11] = (hue_coord
>> 8) & 0x0f;
1324 hue_coord
= (hsv_green_y
[hue_index
] * satur
) >> 8;
1325 cmatrix
[12] = hue_coord
;
1326 cmatrix
[13] = (hue_coord
>> 8) & 0x0f;
1328 hue_coord
= (hsv_blue_x
[hue_index
] * satur
) >> 8;
1329 cmatrix
[14] = hue_coord
;
1330 cmatrix
[15] = (hue_coord
>> 8) & 0x0f;
1332 hue_coord
= (hsv_blue_y
[hue_index
] * satur
) >> 8;
1333 cmatrix
[16] = hue_coord
;
1334 cmatrix
[17] = (hue_coord
>> 8) & 0x0f;
1336 reg_w(gspca_dev
, 0x10e1, cmatrix
, 21);
1339 static void set_gamma(struct gspca_dev
*gspca_dev
, s32 val
)
1342 u8 gval
= val
* 0xb8 / 0x100;
1345 gamma
[1] = 0x13 + (gval
* (0xcb - 0x13) / 0xb8);
1346 gamma
[2] = 0x25 + (gval
* (0xee - 0x25) / 0xb8);
1347 gamma
[3] = 0x37 + (gval
* (0xfa - 0x37) / 0xb8);
1348 gamma
[4] = 0x45 + (gval
* (0xfc - 0x45) / 0xb8);
1349 gamma
[5] = 0x55 + (gval
* (0xfb - 0x55) / 0xb8);
1350 gamma
[6] = 0x65 + (gval
* (0xfc - 0x65) / 0xb8);
1351 gamma
[7] = 0x74 + (gval
* (0xfd - 0x74) / 0xb8);
1352 gamma
[8] = 0x83 + (gval
* (0xfe - 0x83) / 0xb8);
1353 gamma
[9] = 0x92 + (gval
* (0xfc - 0x92) / 0xb8);
1354 gamma
[10] = 0xa1 + (gval
* (0xfc - 0xa1) / 0xb8);
1355 gamma
[11] = 0xb0 + (gval
* (0xfc - 0xb0) / 0xb8);
1356 gamma
[12] = 0xbf + (gval
* (0xfb - 0xbf) / 0xb8);
1357 gamma
[13] = 0xce + (gval
* (0xfb - 0xce) / 0xb8);
1358 gamma
[14] = 0xdf + (gval
* (0xfd - 0xdf) / 0xb8);
1359 gamma
[15] = 0xea + (gval
* (0xf9 - 0xea) / 0xb8);
1362 reg_w(gspca_dev
, 0x1190, gamma
, 17);
1365 static void set_redblue(struct gspca_dev
*gspca_dev
, s32 blue
, s32 red
)
1367 reg_w1(gspca_dev
, 0x118c, red
);
1368 reg_w1(gspca_dev
, 0x118f, blue
);
1371 static void set_hvflip(struct gspca_dev
*gspca_dev
, s32 hflip
, s32 vflip
)
1375 struct sd
*sd
= (struct sd
*) gspca_dev
;
1377 if ((sd
->flags
& FLIP_DETECT
) && dmi_check_system(flip_dmi_table
)) {
1382 switch (sd
->sensor
) {
1393 reg_w1(gspca_dev
, 0x1182, sd
->vstart
);
1394 i2c_w1(gspca_dev
, 0x1e, value
);
1397 i2c_r1(gspca_dev
, 0x1e, &value
);
1406 i2c_w1(gspca_dev
, 0x1e, value
);
1407 i2c_w1(gspca_dev
, 0x3a, tslb
);
1409 case SENSOR_MT9V111
:
1410 case SENSOR_MT9V011
:
1411 i2c_r2(gspca_dev
, 0x20, &value2
);
1417 i2c_w2(gspca_dev
, 0x20, value2
);
1419 case SENSOR_MT9M112
:
1420 case SENSOR_MT9M111
:
1421 case SENSOR_MT9V112
:
1422 i2c_r2(gspca_dev
, 0x20, &value2
);
1428 i2c_w2(gspca_dev
, 0x20, value2
);
1430 case SENSOR_HV7131R
:
1431 i2c_r1(gspca_dev
, 0x01, &value
);
1437 i2c_w1(gspca_dev
, 0x01, value
);
1442 static void set_exposure(struct gspca_dev
*gspca_dev
, s32 expo
)
1444 struct sd
*sd
= (struct sd
*) gspca_dev
;
1445 u8 exp
[8] = {sd
->i2c_intf
, sd
->i2c_addr
,
1446 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1449 if (gspca_dev
->streaming
)
1452 switch (sd
->sensor
) {
1462 exp
[2] = 0x10; /* AECH */
1463 exp
[3] = expo2
>> 2;
1465 i2c_w(gspca_dev
, exp
);
1466 exp
[2] = 0x04; /* COM1 */
1467 exp
[3] = expo2
& 0x0003;
1469 i2c_w(gspca_dev
, exp
);
1473 exp
[2] = 0x2d; /* ADVFL & ADVFH */
1477 case SENSOR_MT9M001
:
1478 case SENSOR_MT9V112
:
1479 case SENSOR_MT9V011
:
1485 case SENSOR_HV7131R
:
1495 i2c_w(gspca_dev
, exp
);
1498 static void set_gain(struct gspca_dev
*gspca_dev
, s32 g
)
1500 struct sd
*sd
= (struct sd
*) gspca_dev
;
1501 u8 gain
[8] = {sd
->i2c_intf
, sd
->i2c_addr
,
1502 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1504 if (gspca_dev
->streaming
)
1505 gain
[7] = 0x15; /* or 1d ? */
1507 switch (sd
->sensor
) {
1513 gain
[0] |= (2 << 4);
1514 gain
[3] = ov_gain
[g
];
1516 case SENSOR_MT9V011
:
1517 gain
[0] |= (3 << 4);
1519 gain
[3] = micron1_gain
[g
] >> 8;
1520 gain
[4] = micron1_gain
[g
];
1522 case SENSOR_MT9V112
:
1523 gain
[0] |= (3 << 4);
1525 gain
[3] = micron1_gain
[g
] >> 8;
1526 gain
[4] = micron1_gain
[g
];
1528 case SENSOR_MT9M001
:
1529 gain
[0] |= (3 << 4);
1531 gain
[3] = micron2_gain
[g
] >> 8;
1532 gain
[4] = micron2_gain
[g
];
1534 case SENSOR_HV7131R
:
1535 gain
[0] |= (2 << 4);
1537 gain
[3] = hv7131r_gain
[g
];
1542 i2c_w(gspca_dev
, gain
);
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 strlcpy(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
);
1712 return gspca_dev
->usb_err
;
1715 static const struct v4l2_ctrl_ops sd_ctrl_ops
= {
1716 .s_ctrl
= sd_s_ctrl
,
1719 static int sd_init_controls(struct gspca_dev
*gspca_dev
)
1721 struct sd
*sd
= (struct sd
*) gspca_dev
;
1722 struct v4l2_ctrl_handler
*hdl
= &gspca_dev
->ctrl_handler
;
1724 gspca_dev
->vdev
.ctrl_handler
= hdl
;
1725 v4l2_ctrl_handler_init(hdl
, 13);
1727 sd
->brightness
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1728 V4L2_CID_BRIGHTNESS
, 0, 255, 1, 127);
1729 sd
->contrast
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1730 V4L2_CID_CONTRAST
, 0, 255, 1, 127);
1731 sd
->saturation
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1732 V4L2_CID_SATURATION
, 0, 255, 1, 127);
1733 sd
->hue
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1734 V4L2_CID_HUE
, -180, 180, 1, 0);
1736 sd
->gamma
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1737 V4L2_CID_GAMMA
, 0, 255, 1, 0x10);
1739 sd
->blue
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1740 V4L2_CID_BLUE_BALANCE
, 0, 127, 1, 0x28);
1741 sd
->red
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1742 V4L2_CID_RED_BALANCE
, 0, 127, 1, 0x28);
1744 if (sd
->sensor
!= SENSOR_OV9655
&& sd
->sensor
!= SENSOR_SOI968
&&
1745 sd
->sensor
!= SENSOR_OV7670
&& sd
->sensor
!= SENSOR_MT9M001
&&
1746 sd
->sensor
!= SENSOR_MT9VPRB
) {
1747 sd
->hflip
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1748 V4L2_CID_HFLIP
, 0, 1, 1, 0);
1749 sd
->vflip
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1750 V4L2_CID_VFLIP
, 0, 1, 1, 0);
1753 if (sd
->sensor
!= SENSOR_SOI968
&& sd
->sensor
!= SENSOR_MT9VPRB
&&
1754 sd
->sensor
!= SENSOR_MT9M112
&& sd
->sensor
!= SENSOR_MT9M111
&&
1755 sd
->sensor
!= SENSOR_MT9V111
)
1756 sd
->exposure
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1757 V4L2_CID_EXPOSURE
, 0, 0x1780, 1, 0x33);
1759 if (sd
->sensor
!= SENSOR_MT9VPRB
&& sd
->sensor
!= SENSOR_MT9M112
&&
1760 sd
->sensor
!= SENSOR_MT9M111
&& sd
->sensor
!= SENSOR_MT9V111
) {
1761 sd
->gain
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1762 V4L2_CID_GAIN
, 0, 28, 1, 0);
1763 sd
->autogain
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1764 V4L2_CID_AUTOGAIN
, 0, 1, 1, 1);
1767 sd
->jpegqual
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1768 V4L2_CID_JPEG_COMPRESSION_QUALITY
, 50, 90, 1, 80);
1770 pr_err("Could not initialize controls\n");
1774 v4l2_ctrl_cluster(4, &sd
->brightness
);
1775 v4l2_ctrl_cluster(2, &sd
->blue
);
1777 v4l2_ctrl_cluster(2, &sd
->hflip
);
1779 if (sd
->sensor
== SENSOR_SOI968
)
1780 /* this sensor doesn't have the exposure control and
1781 autogain is clustered with gain instead. This works
1782 because sd->exposure == NULL. */
1783 v4l2_ctrl_auto_cluster(3, &sd
->autogain
, 0, false);
1785 /* Otherwise autogain is clustered with exposure. */
1786 v4l2_ctrl_auto_cluster(2, &sd
->autogain
, 0, false);
1791 static int sd_init(struct gspca_dev
*gspca_dev
)
1793 struct sd
*sd
= (struct sd
*) gspca_dev
;
1797 0x80, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
1800 for (i
= 0; i
< ARRAY_SIZE(bridge_init
); i
++) {
1801 value
= bridge_init
[i
][1];
1802 reg_w(gspca_dev
, bridge_init
[i
][0], &value
, 1);
1803 if (gspca_dev
->usb_err
< 0) {
1804 pr_err("Device initialization failed\n");
1805 return gspca_dev
->usb_err
;
1809 if (sd
->flags
& LED_REVERSE
)
1810 reg_w1(gspca_dev
, 0x1006, 0x00);
1812 reg_w1(gspca_dev
, 0x1006, 0x20);
1814 reg_w(gspca_dev
, 0x10c0, i2c_init
, 9);
1815 if (gspca_dev
->usb_err
< 0) {
1816 pr_err("Device initialization failed\n");
1817 return gspca_dev
->usb_err
;
1820 switch (sd
->sensor
) {
1822 ov9650_init_sensor(gspca_dev
);
1823 if (gspca_dev
->usb_err
< 0)
1825 pr_info("OV9650 sensor detected\n");
1828 ov9655_init_sensor(gspca_dev
);
1829 if (gspca_dev
->usb_err
< 0)
1831 pr_info("OV9655 sensor detected\n");
1834 soi968_init_sensor(gspca_dev
);
1835 if (gspca_dev
->usb_err
< 0)
1837 pr_info("SOI968 sensor detected\n");
1840 ov7660_init_sensor(gspca_dev
);
1841 if (gspca_dev
->usb_err
< 0)
1843 pr_info("OV7660 sensor detected\n");
1846 ov7670_init_sensor(gspca_dev
);
1847 if (gspca_dev
->usb_err
< 0)
1849 pr_info("OV7670 sensor detected\n");
1851 case SENSOR_MT9VPRB
:
1852 mt9v_init_sensor(gspca_dev
);
1853 if (gspca_dev
->usb_err
< 0)
1855 pr_info("MT9VPRB sensor detected\n");
1857 case SENSOR_MT9M111
:
1858 mt9m111_init_sensor(gspca_dev
);
1859 if (gspca_dev
->usb_err
< 0)
1861 pr_info("MT9M111 sensor detected\n");
1863 case SENSOR_MT9M112
:
1864 mt9m112_init_sensor(gspca_dev
);
1865 if (gspca_dev
->usb_err
< 0)
1867 pr_info("MT9M112 sensor detected\n");
1869 case SENSOR_MT9M001
:
1870 mt9m001_init_sensor(gspca_dev
);
1871 if (gspca_dev
->usb_err
< 0)
1874 case SENSOR_HV7131R
:
1875 hv7131r_init_sensor(gspca_dev
);
1876 if (gspca_dev
->usb_err
< 0)
1878 pr_info("HV7131R sensor detected\n");
1881 pr_err("Unsupported sensor\n");
1882 gspca_dev
->usb_err
= -ENODEV
;
1884 return gspca_dev
->usb_err
;
1887 static void configure_sensor_output(struct gspca_dev
*gspca_dev
, int mode
)
1889 struct sd
*sd
= (struct sd
*) gspca_dev
;
1892 switch (sd
->sensor
) {
1894 if (mode
& MODE_SXGA
) {
1895 i2c_w1(gspca_dev
, 0x17, 0x1d);
1896 i2c_w1(gspca_dev
, 0x18, 0xbd);
1897 i2c_w1(gspca_dev
, 0x19, 0x01);
1898 i2c_w1(gspca_dev
, 0x1a, 0x81);
1899 i2c_w1(gspca_dev
, 0x12, 0x00);
1903 i2c_w1(gspca_dev
, 0x17, 0x13);
1904 i2c_w1(gspca_dev
, 0x18, 0x63);
1905 i2c_w1(gspca_dev
, 0x19, 0x01);
1906 i2c_w1(gspca_dev
, 0x1a, 0x79);
1907 i2c_w1(gspca_dev
, 0x12, 0x40);
1913 if (mode
& MODE_SXGA
) {
1914 i2c_w1(gspca_dev
, 0x17, 0x1b);
1915 i2c_w1(gspca_dev
, 0x18, 0xbc);
1916 i2c_w1(gspca_dev
, 0x19, 0x01);
1917 i2c_w1(gspca_dev
, 0x1a, 0x82);
1918 i2c_r1(gspca_dev
, 0x12, &value
);
1919 i2c_w1(gspca_dev
, 0x12, value
& 0x07);
1921 i2c_w1(gspca_dev
, 0x17, 0x24);
1922 i2c_w1(gspca_dev
, 0x18, 0xc5);
1923 i2c_w1(gspca_dev
, 0x19, 0x00);
1924 i2c_w1(gspca_dev
, 0x1a, 0x3c);
1925 i2c_r1(gspca_dev
, 0x12, &value
);
1926 i2c_w1(gspca_dev
, 0x12, (value
& 0x7) | 0x40);
1929 case SENSOR_MT9M112
:
1930 case SENSOR_MT9M111
:
1931 if (mode
& MODE_SXGA
) {
1932 i2c_w2(gspca_dev
, 0xf0, 0x0002);
1933 i2c_w2(gspca_dev
, 0xc8, 0x970b);
1934 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1936 i2c_w2(gspca_dev
, 0xf0, 0x0002);
1937 i2c_w2(gspca_dev
, 0xc8, 0x8000);
1938 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1944 static int sd_isoc_init(struct gspca_dev
*gspca_dev
)
1946 struct usb_interface
*intf
;
1947 u32 flags
= gspca_dev
->cam
.cam_mode
[(int)gspca_dev
->curr_mode
].priv
;
1950 * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth
1951 * than our regular bandwidth calculations reserve, so we force the
1952 * use of a specific altsetting when using the SN9C20X_I420 fmt.
1954 if (!(flags
& (MODE_RAW
| MODE_JPEG
))) {
1955 intf
= usb_ifnum_to_if(gspca_dev
->dev
, gspca_dev
->iface
);
1957 if (intf
->num_altsetting
!= 9) {
1958 pr_warn("sn9c20x camera with unknown number of alt settings (%d), please report!\n",
1959 intf
->num_altsetting
);
1960 gspca_dev
->alt
= intf
->num_altsetting
;
1964 switch (gspca_dev
->pixfmt
.width
) {
1965 case 160: /* 160x120 */
1968 case 320: /* 320x240 */
1971 default: /* >= 640x480 */
1980 #define HW_WIN(mode, hstart, vstart) \
1981 ((const u8 []){hstart, 0, vstart, 0, \
1982 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
1983 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
1985 #define CLR_WIN(width, height) \
1987 {0, width >> 2, 0, height >> 1,\
1988 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
1990 static int sd_start(struct gspca_dev
*gspca_dev
)
1992 struct sd
*sd
= (struct sd
*) gspca_dev
;
1993 int mode
= gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
;
1994 int width
= gspca_dev
->pixfmt
.width
;
1995 int height
= gspca_dev
->pixfmt
.height
;
1998 jpeg_define(sd
->jpeg_hdr
, height
, width
,
2000 jpeg_set_qual(sd
->jpeg_hdr
, v4l2_ctrl_g_ctrl(sd
->jpegqual
));
2002 if (mode
& MODE_RAW
)
2004 else if (mode
& MODE_JPEG
)
2007 fmt
= 0x2f; /* YUV 420 */
2010 switch (mode
& SCALE_MASK
) {
2011 case SCALE_1280x1024
:
2013 pr_info("Set 1280x1024\n");
2017 pr_info("Set 640x480\n");
2021 pr_info("Set 320x240\n");
2025 pr_info("Set 160x120\n");
2029 configure_sensor_output(gspca_dev
, mode
);
2030 reg_w(gspca_dev
, 0x1100, &sd
->jpeg_hdr
[JPEG_QT0_OFFSET
], 64);
2031 reg_w(gspca_dev
, 0x1140, &sd
->jpeg_hdr
[JPEG_QT1_OFFSET
], 64);
2032 reg_w(gspca_dev
, 0x10fb, CLR_WIN(width
, height
), 5);
2033 reg_w(gspca_dev
, 0x1180, HW_WIN(mode
, sd
->hstart
, sd
->vstart
), 6);
2034 reg_w1(gspca_dev
, 0x1189, scale
);
2035 reg_w1(gspca_dev
, 0x10e0, fmt
);
2037 set_cmatrix(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->brightness
),
2038 v4l2_ctrl_g_ctrl(sd
->contrast
),
2039 v4l2_ctrl_g_ctrl(sd
->saturation
),
2040 v4l2_ctrl_g_ctrl(sd
->hue
));
2041 set_gamma(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->gamma
));
2042 set_redblue(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->blue
),
2043 v4l2_ctrl_g_ctrl(sd
->red
));
2045 set_gain(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->gain
));
2047 set_exposure(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->exposure
));
2049 set_hvflip(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->hflip
),
2050 v4l2_ctrl_g_ctrl(sd
->vflip
));
2052 reg_w1(gspca_dev
, 0x1007, 0x20);
2053 reg_w1(gspca_dev
, 0x1061, 0x03);
2055 /* if JPEG, prepare the compression quality update */
2056 if (mode
& MODE_JPEG
) {
2057 sd
->pktsz
= sd
->npkt
= 0;
2061 return gspca_dev
->usb_err
;
2064 static void sd_stopN(struct gspca_dev
*gspca_dev
)
2066 reg_w1(gspca_dev
, 0x1007, 0x00);
2067 reg_w1(gspca_dev
, 0x1061, 0x01);
2070 /* called on streamoff with alt==0 and on disconnect */
2071 /* the usb_lock is held at entry - restore on exit */
2072 static void sd_stop0(struct gspca_dev
*gspca_dev
)
2074 struct sd
*sd
= (struct sd
*) gspca_dev
;
2076 mutex_unlock(&gspca_dev
->usb_lock
);
2077 flush_work(&sd
->work
);
2078 mutex_lock(&gspca_dev
->usb_lock
);
2081 static void do_autoexposure(struct gspca_dev
*gspca_dev
, u16 avg_lum
)
2083 struct sd
*sd
= (struct sd
*) gspca_dev
;
2084 s32 cur_exp
= v4l2_ctrl_g_ctrl(sd
->exposure
);
2085 s32 max
= sd
->exposure
->maximum
- sd
->exposure_step
;
2086 s32 min
= sd
->exposure
->minimum
+ sd
->exposure_step
;
2090 * some hardcoded values are present
2091 * like those for maximal/minimal exposure
2092 * and exposure steps
2094 if (avg_lum
< MIN_AVG_LUM
) {
2098 new_exp
= cur_exp
+ sd
->exposure_step
;
2103 v4l2_ctrl_s_ctrl(sd
->exposure
, new_exp
);
2105 sd
->older_step
= sd
->old_step
;
2108 if (sd
->old_step
^ sd
->older_step
)
2109 sd
->exposure_step
/= 2;
2111 sd
->exposure_step
+= 2;
2113 if (avg_lum
> MAX_AVG_LUM
) {
2116 new_exp
= cur_exp
- sd
->exposure_step
;
2121 v4l2_ctrl_s_ctrl(sd
->exposure
, new_exp
);
2122 sd
->older_step
= sd
->old_step
;
2125 if (sd
->old_step
^ sd
->older_step
)
2126 sd
->exposure_step
/= 2;
2128 sd
->exposure_step
+= 2;
2132 static void do_autogain(struct gspca_dev
*gspca_dev
, u16 avg_lum
)
2134 struct sd
*sd
= (struct sd
*) gspca_dev
;
2135 s32 cur_gain
= v4l2_ctrl_g_ctrl(sd
->gain
);
2137 if (avg_lum
< MIN_AVG_LUM
&& cur_gain
< sd
->gain
->maximum
)
2138 v4l2_ctrl_s_ctrl(sd
->gain
, cur_gain
+ 1);
2139 if (avg_lum
> MAX_AVG_LUM
&& cur_gain
> sd
->gain
->minimum
)
2140 v4l2_ctrl_s_ctrl(sd
->gain
, cur_gain
- 1);
2143 static void sd_dqcallback(struct gspca_dev
*gspca_dev
)
2145 struct sd
*sd
= (struct sd
*) gspca_dev
;
2148 if (sd
->autogain
== NULL
|| !v4l2_ctrl_g_ctrl(sd
->autogain
))
2151 avg_lum
= atomic_read(&sd
->avg_lum
);
2152 if (sd
->sensor
== SENSOR_SOI968
)
2153 do_autogain(gspca_dev
, avg_lum
);
2155 do_autoexposure(gspca_dev
, avg_lum
);
2158 /* JPEG quality update */
2159 /* This function is executed from a work queue. */
2160 static void qual_upd(struct work_struct
*work
)
2162 struct sd
*sd
= container_of(work
, struct sd
, work
);
2163 struct gspca_dev
*gspca_dev
= &sd
->gspca_dev
;
2164 s32 qual
= v4l2_ctrl_g_ctrl(sd
->jpegqual
);
2166 /* To protect gspca_dev->usb_buf and gspca_dev->usb_err */
2167 mutex_lock(&gspca_dev
->usb_lock
);
2168 gspca_dbg(gspca_dev
, D_STREAM
, "qual_upd %d%%\n", qual
);
2169 gspca_dev
->usb_err
= 0;
2170 set_quality(gspca_dev
, qual
);
2171 mutex_unlock(&gspca_dev
->usb_lock
);
2174 #if IS_ENABLED(CONFIG_INPUT)
2175 static int sd_int_pkt_scan(struct gspca_dev
*gspca_dev
,
2176 u8
*data
, /* interrupt packet */
2177 int len
) /* interrupt packet length */
2179 struct sd
*sd
= (struct sd
*) gspca_dev
;
2181 if (!(sd
->flags
& HAS_NO_BUTTON
) && len
== 1) {
2182 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 1);
2183 input_sync(gspca_dev
->input_dev
);
2184 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 0);
2185 input_sync(gspca_dev
->input_dev
);
2192 /* check the JPEG compression */
2193 static void transfer_check(struct gspca_dev
*gspca_dev
,
2196 struct sd
*sd
= (struct sd
*) gspca_dev
;
2201 /* if USB error, discard the frame and decrease the quality */
2202 if (data
[6] & 0x08) { /* USB FIFO full */
2203 gspca_dev
->last_packet_type
= DISCARD_PACKET
;
2207 /* else, compute the filling rate and a new JPEG quality */
2208 r
= (sd
->pktsz
* 100) /
2210 gspca_dev
->urb
[0]->iso_frame_desc
[0].length
);
2216 if (new_qual
!= 0) {
2217 sd
->nchg
+= new_qual
;
2218 if (sd
->nchg
< -6 || sd
->nchg
>= 12) {
2219 /* Note: we are in interrupt context, so we can't
2220 use v4l2_ctrl_g/s_ctrl here. Access the value
2221 directly instead. */
2222 s32 curqual
= sd
->jpegqual
->cur
.val
;
2224 new_qual
+= curqual
;
2225 if (new_qual
< sd
->jpegqual
->minimum
)
2226 new_qual
= sd
->jpegqual
->minimum
;
2227 else if (new_qual
> sd
->jpegqual
->maximum
)
2228 new_qual
= sd
->jpegqual
->maximum
;
2229 if (new_qual
!= curqual
) {
2230 sd
->jpegqual
->cur
.val
= new_qual
;
2231 schedule_work(&sd
->work
);
2237 sd
->pktsz
= sd
->npkt
= 0;
2240 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
2241 u8
*data
, /* isoc packet */
2242 int len
) /* iso packet length */
2244 struct sd
*sd
= (struct sd
*) gspca_dev
;
2245 int avg_lum
, is_jpeg
;
2246 static const u8 frame_header
[] = {
2247 0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96
2250 is_jpeg
= (sd
->fmt
& 0x03) == 0;
2251 if (len
>= 64 && memcmp(data
, frame_header
, 6) == 0) {
2252 avg_lum
= ((data
[35] >> 2) & 3) |
2255 avg_lum
+= ((data
[35] >> 4) & 3) |
2258 avg_lum
+= ((data
[35] >> 6) & 3) |
2261 avg_lum
+= (data
[36] & 3) |
2264 avg_lum
+= ((data
[36] >> 2) & 3) |
2267 avg_lum
+= ((data
[36] >> 4) & 3) |
2270 avg_lum
+= ((data
[36] >> 6) & 3) |
2273 avg_lum
+= ((data
[44] >> 4) & 3) |
2277 atomic_set(&sd
->avg_lum
, avg_lum
);
2280 transfer_check(gspca_dev
, data
);
2282 gspca_frame_add(gspca_dev
, LAST_PACKET
, NULL
, 0);
2288 if (gspca_dev
->last_packet_type
== LAST_PACKET
) {
2290 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
2291 sd
->jpeg_hdr
, JPEG_HDR_SZ
);
2292 gspca_frame_add(gspca_dev
, INTER_PACKET
,
2295 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
2299 /* if JPEG, count the packets and their size */
2304 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, len
);
2308 /* sub-driver description */
2309 static const struct sd_desc sd_desc
= {
2310 .name
= KBUILD_MODNAME
,
2311 .config
= sd_config
,
2313 .init_controls
= sd_init_controls
,
2314 .isoc_init
= sd_isoc_init
,
2318 .pkt_scan
= sd_pkt_scan
,
2319 #if IS_ENABLED(CONFIG_INPUT)
2320 .int_pkt_scan
= sd_int_pkt_scan
,
2322 .dq_callback
= sd_dqcallback
,
2323 #ifdef CONFIG_VIDEO_ADV_DEBUG
2324 .set_register
= sd_dbg_s_register
,
2325 .get_register
= sd_dbg_g_register
,
2326 .get_chip_info
= sd_chip_info
,
2330 #define SN9C20X(sensor, i2c_addr, flags) \
2331 .driver_info = ((flags & 0xff) << 16) \
2332 | (SENSOR_ ## sensor << 8) \
2335 static const struct usb_device_id device_table
[] = {
2336 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001
, 0x5d, 0)},
2337 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111
, 0x5d, 0)},
2338 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655
, 0x30, 0)},
2339 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112
, 0x5d, 0)},
2340 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968
, 0x30, LED_REVERSE
)},
2341 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650
, 0x30,
2342 (FLIP_DETECT
| HAS_NO_BUTTON
))},
2343 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650
, 0x30, 0)},
2344 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650
, 0x30, 0)},
2345 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670
, 0x21, 0)},
2346 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB
, 0x00, 0)},
2347 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660
, 0x21, FLIP_DETECT
)},
2348 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R
, 0x11, 0)},
2349 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650
, 0x30, 0)},
2350 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001
, 0x5d, 0)},
2351 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111
, 0x5d, 0)},
2352 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655
, 0x30, 0)},
2353 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112
, 0x5d, 0)},
2354 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968
, 0x30, 0)},
2355 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650
, 0x30, 0)},
2356 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670
, 0x21, 0)},
2357 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB
, 0x00, 0)},
2358 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655
, 0x30, LED_REVERSE
)},
2359 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660
, 0x21, LED_REVERSE
)},
2360 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R
, 0x11, 0)},
2361 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650
, 0x30, 0)},
2362 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660
, 0x21, 0)},
2363 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R
, 0x11, 0)},
2364 {USB_DEVICE(0x0458, 0x7045), SN9C20X(MT9M112
, 0x5d, LED_REVERSE
)},
2365 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112
, 0x5d, 0)},
2366 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112
, 0x5d, 0)},
2367 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R
, 0x11, 0)},
2368 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R
, 0x11, 0)},
2369 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R
, 0x11, 0)},
2370 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R
, 0x11, 0)},
2371 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111
, 0x5d, 0)},
2372 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111
, 0x5d, 0)},
2373 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111
, 0x5d, 0)},
2376 MODULE_DEVICE_TABLE(usb
, device_table
);
2378 /* -- device connect -- */
2379 static int sd_probe(struct usb_interface
*intf
,
2380 const struct usb_device_id
*id
)
2382 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
2386 static struct usb_driver sd_driver
= {
2387 .name
= KBUILD_MODNAME
,
2388 .id_table
= device_table
,
2390 .disconnect
= gspca_disconnect
,
2392 .suspend
= gspca_suspend
,
2393 .resume
= gspca_resume
,
2394 .reset_resume
= gspca_resume
,
2398 module_usb_driver(sd_driver
);