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
54 /* specific webcam descriptor */
56 struct gspca_dev gspca_dev
;
58 struct { /* color control cluster */
59 struct v4l2_ctrl
*brightness
;
60 struct v4l2_ctrl
*contrast
;
61 struct v4l2_ctrl
*saturation
;
62 struct v4l2_ctrl
*hue
;
64 struct { /* blue/red balance control cluster */
65 struct v4l2_ctrl
*blue
;
66 struct v4l2_ctrl
*red
;
68 struct { /* h/vflip control cluster */
69 struct v4l2_ctrl
*hflip
;
70 struct v4l2_ctrl
*vflip
;
72 struct v4l2_ctrl
*gamma
;
73 struct { /* autogain and exposure or gain control cluster */
74 struct v4l2_ctrl
*autogain
;
75 struct v4l2_ctrl
*exposure
;
76 struct v4l2_ctrl
*gain
;
78 struct v4l2_ctrl
*jpegqual
;
80 struct work_struct work
;
82 u32 pktsz
; /* (used by pkt_scan) */
85 u8 fmt
; /* (used for JPEG QTAB update */
87 #define MIN_AVG_LUM 80
88 #define MAX_AVG_LUM 130
100 u8 jpeg_hdr
[JPEG_HDR_SZ
];
105 static void qual_upd(struct work_struct
*work
);
117 static const struct dmi_system_id flip_dmi_table
[] = {
119 .ident
= "MSI MS-1034",
121 DMI_MATCH(DMI_SYS_VENDOR
, "MICRO-STAR INT'L CO.,LTD."),
122 DMI_MATCH(DMI_PRODUCT_NAME
, "MS-1034"),
123 DMI_MATCH(DMI_PRODUCT_VERSION
, "0341")
127 .ident
= "MSI MS-1039",
129 DMI_MATCH(DMI_SYS_VENDOR
, "MICRO-STAR INT'L CO.,LTD."),
130 DMI_MATCH(DMI_PRODUCT_NAME
, "MS-1039"),
134 .ident
= "MSI MS-1632",
136 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
137 DMI_MATCH(DMI_BOARD_NAME
, "MS-1632")
141 .ident
= "MSI MS-1633X",
143 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
144 DMI_MATCH(DMI_BOARD_NAME
, "MS-1633X")
148 .ident
= "MSI MS-1635X",
150 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
151 DMI_MATCH(DMI_BOARD_NAME
, "MS-1635X")
155 .ident
= "ASUSTeK W7J",
157 DMI_MATCH(DMI_BOARD_VENDOR
, "ASUSTeK Computer Inc."),
158 DMI_MATCH(DMI_BOARD_NAME
, "W7J ")
164 static const struct v4l2_pix_format vga_mode
[] = {
165 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
167 .sizeimage
= 160 * 120 * 4 / 8 + 590,
168 .colorspace
= V4L2_COLORSPACE_JPEG
,
169 .priv
= SCALE_160x120
| MODE_JPEG
},
170 {160, 120, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
172 .sizeimage
= 160 * 120,
173 .colorspace
= V4L2_COLORSPACE_SRGB
,
174 .priv
= SCALE_160x120
| MODE_RAW
},
175 {160, 120, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
177 .sizeimage
= 240 * 120,
178 .colorspace
= V4L2_COLORSPACE_SRGB
,
179 .priv
= SCALE_160x120
},
180 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
182 .sizeimage
= 320 * 240 * 4 / 8 + 590,
183 .colorspace
= V4L2_COLORSPACE_JPEG
,
184 .priv
= SCALE_320x240
| MODE_JPEG
},
185 {320, 240, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
187 .sizeimage
= 320 * 240 ,
188 .colorspace
= V4L2_COLORSPACE_SRGB
,
189 .priv
= SCALE_320x240
| MODE_RAW
},
190 {320, 240, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
192 .sizeimage
= 480 * 240 ,
193 .colorspace
= V4L2_COLORSPACE_SRGB
,
194 .priv
= SCALE_320x240
},
195 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
197 .sizeimage
= 640 * 480 * 4 / 8 + 590,
198 .colorspace
= V4L2_COLORSPACE_JPEG
,
199 .priv
= SCALE_640x480
| MODE_JPEG
},
200 {640, 480, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
202 .sizeimage
= 640 * 480,
203 .colorspace
= V4L2_COLORSPACE_SRGB
,
204 .priv
= SCALE_640x480
| MODE_RAW
},
205 {640, 480, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
207 .sizeimage
= 960 * 480,
208 .colorspace
= V4L2_COLORSPACE_SRGB
,
209 .priv
= SCALE_640x480
},
212 static const struct v4l2_pix_format sxga_mode
[] = {
213 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
215 .sizeimage
= 160 * 120 * 4 / 8 + 590,
216 .colorspace
= V4L2_COLORSPACE_JPEG
,
217 .priv
= SCALE_160x120
| MODE_JPEG
},
218 {160, 120, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
220 .sizeimage
= 160 * 120,
221 .colorspace
= V4L2_COLORSPACE_SRGB
,
222 .priv
= SCALE_160x120
| MODE_RAW
},
223 {160, 120, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
225 .sizeimage
= 240 * 120,
226 .colorspace
= V4L2_COLORSPACE_SRGB
,
227 .priv
= SCALE_160x120
},
228 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
230 .sizeimage
= 320 * 240 * 4 / 8 + 590,
231 .colorspace
= V4L2_COLORSPACE_JPEG
,
232 .priv
= SCALE_320x240
| MODE_JPEG
},
233 {320, 240, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
235 .sizeimage
= 320 * 240 ,
236 .colorspace
= V4L2_COLORSPACE_SRGB
,
237 .priv
= SCALE_320x240
| MODE_RAW
},
238 {320, 240, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
240 .sizeimage
= 480 * 240 ,
241 .colorspace
= V4L2_COLORSPACE_SRGB
,
242 .priv
= SCALE_320x240
},
243 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
245 .sizeimage
= 640 * 480 * 4 / 8 + 590,
246 .colorspace
= V4L2_COLORSPACE_JPEG
,
247 .priv
= SCALE_640x480
| MODE_JPEG
},
248 {640, 480, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
250 .sizeimage
= 640 * 480,
251 .colorspace
= V4L2_COLORSPACE_SRGB
,
252 .priv
= SCALE_640x480
| MODE_RAW
},
253 {640, 480, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
255 .sizeimage
= 960 * 480,
256 .colorspace
= V4L2_COLORSPACE_SRGB
,
257 .priv
= SCALE_640x480
},
258 {1280, 1024, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
259 .bytesperline
= 1280,
260 .sizeimage
= 1280 * 1024,
261 .colorspace
= V4L2_COLORSPACE_SRGB
,
262 .priv
= SCALE_1280x1024
| MODE_RAW
| MODE_SXGA
},
265 static const struct v4l2_pix_format mono_mode
[] = {
266 {160, 120, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
268 .sizeimage
= 160 * 120,
269 .colorspace
= V4L2_COLORSPACE_SRGB
,
270 .priv
= SCALE_160x120
| MODE_RAW
},
271 {320, 240, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
273 .sizeimage
= 320 * 240 ,
274 .colorspace
= V4L2_COLORSPACE_SRGB
,
275 .priv
= SCALE_320x240
| MODE_RAW
},
276 {640, 480, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
278 .sizeimage
= 640 * 480,
279 .colorspace
= V4L2_COLORSPACE_SRGB
,
280 .priv
= SCALE_640x480
| MODE_RAW
},
281 {1280, 1024, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
282 .bytesperline
= 1280,
283 .sizeimage
= 1280 * 1024,
284 .colorspace
= V4L2_COLORSPACE_SRGB
,
285 .priv
= SCALE_1280x1024
| MODE_RAW
| MODE_SXGA
},
288 static const s16 hsv_red_x
[] = {
289 41, 44, 46, 48, 50, 52, 54, 56,
290 58, 60, 62, 64, 66, 68, 70, 72,
291 74, 76, 78, 80, 81, 83, 85, 87,
292 88, 90, 92, 93, 95, 97, 98, 100,
293 101, 102, 104, 105, 107, 108, 109, 110,
294 112, 113, 114, 115, 116, 117, 118, 119,
295 120, 121, 122, 123, 123, 124, 125, 125,
296 126, 127, 127, 128, 128, 129, 129, 129,
297 130, 130, 130, 130, 131, 131, 131, 131,
298 131, 131, 131, 131, 130, 130, 130, 130,
299 129, 129, 129, 128, 128, 127, 127, 126,
300 125, 125, 124, 123, 122, 122, 121, 120,
301 119, 118, 117, 116, 115, 114, 112, 111,
302 110, 109, 107, 106, 105, 103, 102, 101,
303 99, 98, 96, 94, 93, 91, 90, 88,
304 86, 84, 83, 81, 79, 77, 75, 74,
305 72, 70, 68, 66, 64, 62, 60, 58,
306 56, 54, 52, 49, 47, 45, 43, 41,
307 39, 36, 34, 32, 30, 28, 25, 23,
308 21, 19, 16, 14, 12, 9, 7, 5,
309 3, 0, -1, -3, -6, -8, -10, -12,
310 -15, -17, -19, -22, -24, -26, -28, -30,
311 -33, -35, -37, -39, -41, -44, -46, -48,
312 -50, -52, -54, -56, -58, -60, -62, -64,
313 -66, -68, -70, -72, -74, -76, -78, -80,
314 -81, -83, -85, -87, -88, -90, -92, -93,
315 -95, -97, -98, -100, -101, -102, -104, -105,
316 -107, -108, -109, -110, -112, -113, -114, -115,
317 -116, -117, -118, -119, -120, -121, -122, -123,
318 -123, -124, -125, -125, -126, -127, -127, -128,
319 -128, -128, -128, -128, -128, -128, -128, -128,
320 -128, -128, -128, -128, -128, -128, -128, -128,
321 -128, -128, -128, -128, -128, -128, -128, -128,
322 -128, -127, -127, -126, -125, -125, -124, -123,
323 -122, -122, -121, -120, -119, -118, -117, -116,
324 -115, -114, -112, -111, -110, -109, -107, -106,
325 -105, -103, -102, -101, -99, -98, -96, -94,
326 -93, -91, -90, -88, -86, -84, -83, -81,
327 -79, -77, -75, -74, -72, -70, -68, -66,
328 -64, -62, -60, -58, -56, -54, -52, -49,
329 -47, -45, -43, -41, -39, -36, -34, -32,
330 -30, -28, -25, -23, -21, -19, -16, -14,
331 -12, -9, -7, -5, -3, 0, 1, 3,
332 6, 8, 10, 12, 15, 17, 19, 22,
333 24, 26, 28, 30, 33, 35, 37, 39, 41
336 static const s16 hsv_red_y
[] = {
337 82, 80, 78, 76, 74, 73, 71, 69,
338 67, 65, 63, 61, 58, 56, 54, 52,
339 50, 48, 46, 44, 41, 39, 37, 35,
340 32, 30, 28, 26, 23, 21, 19, 16,
341 14, 12, 10, 7, 5, 3, 0, -1,
342 -3, -6, -8, -10, -13, -15, -17, -19,
343 -22, -24, -26, -29, -31, -33, -35, -38,
344 -40, -42, -44, -46, -48, -51, -53, -55,
345 -57, -59, -61, -63, -65, -67, -69, -71,
346 -73, -75, -77, -79, -81, -82, -84, -86,
347 -88, -89, -91, -93, -94, -96, -98, -99,
348 -101, -102, -104, -105, -106, -108, -109, -110,
349 -112, -113, -114, -115, -116, -117, -119, -120,
350 -120, -121, -122, -123, -124, -125, -126, -126,
351 -127, -128, -128, -128, -128, -128, -128, -128,
352 -128, -128, -128, -128, -128, -128, -128, -128,
353 -128, -128, -128, -128, -128, -128, -128, -128,
354 -128, -128, -128, -128, -128, -128, -128, -128,
355 -127, -127, -126, -125, -125, -124, -123, -122,
356 -121, -120, -119, -118, -117, -116, -115, -114,
357 -113, -111, -110, -109, -107, -106, -105, -103,
358 -102, -100, -99, -97, -96, -94, -92, -91,
359 -89, -87, -85, -84, -82, -80, -78, -76,
360 -74, -73, -71, -69, -67, -65, -63, -61,
361 -58, -56, -54, -52, -50, -48, -46, -44,
362 -41, -39, -37, -35, -32, -30, -28, -26,
363 -23, -21, -19, -16, -14, -12, -10, -7,
364 -5, -3, 0, 1, 3, 6, 8, 10,
365 13, 15, 17, 19, 22, 24, 26, 29,
366 31, 33, 35, 38, 40, 42, 44, 46,
367 48, 51, 53, 55, 57, 59, 61, 63,
368 65, 67, 69, 71, 73, 75, 77, 79,
369 81, 82, 84, 86, 88, 89, 91, 93,
370 94, 96, 98, 99, 101, 102, 104, 105,
371 106, 108, 109, 110, 112, 113, 114, 115,
372 116, 117, 119, 120, 120, 121, 122, 123,
373 124, 125, 126, 126, 127, 128, 128, 129,
374 129, 130, 130, 131, 131, 131, 131, 132,
375 132, 132, 132, 132, 132, 132, 132, 132,
376 132, 132, 132, 131, 131, 131, 130, 130,
377 130, 129, 129, 128, 127, 127, 126, 125,
378 125, 124, 123, 122, 121, 120, 119, 118,
379 117, 116, 115, 114, 113, 111, 110, 109,
380 107, 106, 105, 103, 102, 100, 99, 97,
381 96, 94, 92, 91, 89, 87, 85, 84, 82
384 static const s16 hsv_green_x
[] = {
385 -124, -124, -125, -125, -125, -125, -125, -125,
386 -125, -126, -126, -125, -125, -125, -125, -125,
387 -125, -124, -124, -124, -123, -123, -122, -122,
388 -121, -121, -120, -120, -119, -118, -117, -117,
389 -116, -115, -114, -113, -112, -111, -110, -109,
390 -108, -107, -105, -104, -103, -102, -100, -99,
391 -98, -96, -95, -93, -92, -91, -89, -87,
392 -86, -84, -83, -81, -79, -77, -76, -74,
393 -72, -70, -69, -67, -65, -63, -61, -59,
394 -57, -55, -53, -51, -49, -47, -45, -43,
395 -41, -39, -37, -35, -33, -30, -28, -26,
396 -24, -22, -20, -18, -15, -13, -11, -9,
397 -7, -4, -2, 0, 1, 3, 6, 8,
398 10, 12, 14, 17, 19, 21, 23, 25,
399 27, 29, 32, 34, 36, 38, 40, 42,
400 44, 46, 48, 50, 52, 54, 56, 58,
401 60, 62, 64, 66, 68, 70, 71, 73,
402 75, 77, 78, 80, 82, 83, 85, 87,
403 88, 90, 91, 93, 94, 96, 97, 98,
404 100, 101, 102, 104, 105, 106, 107, 108,
405 109, 111, 112, 113, 113, 114, 115, 116,
406 117, 118, 118, 119, 120, 120, 121, 122,
407 122, 123, 123, 124, 124, 124, 125, 125,
408 125, 125, 125, 125, 125, 126, 126, 125,
409 125, 125, 125, 125, 125, 124, 124, 124,
410 123, 123, 122, 122, 121, 121, 120, 120,
411 119, 118, 117, 117, 116, 115, 114, 113,
412 112, 111, 110, 109, 108, 107, 105, 104,
413 103, 102, 100, 99, 98, 96, 95, 93,
414 92, 91, 89, 87, 86, 84, 83, 81,
415 79, 77, 76, 74, 72, 70, 69, 67,
416 65, 63, 61, 59, 57, 55, 53, 51,
417 49, 47, 45, 43, 41, 39, 37, 35,
418 33, 30, 28, 26, 24, 22, 20, 18,
419 15, 13, 11, 9, 7, 4, 2, 0,
420 -1, -3, -6, -8, -10, -12, -14, -17,
421 -19, -21, -23, -25, -27, -29, -32, -34,
422 -36, -38, -40, -42, -44, -46, -48, -50,
423 -52, -54, -56, -58, -60, -62, -64, -66,
424 -68, -70, -71, -73, -75, -77, -78, -80,
425 -82, -83, -85, -87, -88, -90, -91, -93,
426 -94, -96, -97, -98, -100, -101, -102, -104,
427 -105, -106, -107, -108, -109, -111, -112, -113,
428 -113, -114, -115, -116, -117, -118, -118, -119,
429 -120, -120, -121, -122, -122, -123, -123, -124, -124
432 static const s16 hsv_green_y
[] = {
433 -100, -99, -98, -97, -95, -94, -93, -91,
434 -90, -89, -87, -86, -84, -83, -81, -80,
435 -78, -76, -75, -73, -71, -70, -68, -66,
436 -64, -63, -61, -59, -57, -55, -53, -51,
437 -49, -48, -46, -44, -42, -40, -38, -36,
438 -34, -32, -30, -27, -25, -23, -21, -19,
439 -17, -15, -13, -11, -9, -7, -4, -2,
440 0, 1, 3, 5, 7, 9, 11, 14,
441 16, 18, 20, 22, 24, 26, 28, 30,
442 32, 34, 36, 38, 40, 42, 44, 46,
443 48, 50, 52, 54, 56, 58, 59, 61,
444 63, 65, 67, 68, 70, 72, 74, 75,
445 77, 78, 80, 82, 83, 85, 86, 88,
446 89, 90, 92, 93, 95, 96, 97, 98,
447 100, 101, 102, 103, 104, 105, 106, 107,
448 108, 109, 110, 111, 112, 112, 113, 114,
449 115, 115, 116, 116, 117, 117, 118, 118,
450 119, 119, 119, 120, 120, 120, 120, 120,
451 121, 121, 121, 121, 121, 121, 120, 120,
452 120, 120, 120, 119, 119, 119, 118, 118,
453 117, 117, 116, 116, 115, 114, 114, 113,
454 112, 111, 111, 110, 109, 108, 107, 106,
455 105, 104, 103, 102, 100, 99, 98, 97,
456 95, 94, 93, 91, 90, 89, 87, 86,
457 84, 83, 81, 80, 78, 76, 75, 73,
458 71, 70, 68, 66, 64, 63, 61, 59,
459 57, 55, 53, 51, 49, 48, 46, 44,
460 42, 40, 38, 36, 34, 32, 30, 27,
461 25, 23, 21, 19, 17, 15, 13, 11,
462 9, 7, 4, 2, 0, -1, -3, -5,
463 -7, -9, -11, -14, -16, -18, -20, -22,
464 -24, -26, -28, -30, -32, -34, -36, -38,
465 -40, -42, -44, -46, -48, -50, -52, -54,
466 -56, -58, -59, -61, -63, -65, -67, -68,
467 -70, -72, -74, -75, -77, -78, -80, -82,
468 -83, -85, -86, -88, -89, -90, -92, -93,
469 -95, -96, -97, -98, -100, -101, -102, -103,
470 -104, -105, -106, -107, -108, -109, -110, -111,
471 -112, -112, -113, -114, -115, -115, -116, -116,
472 -117, -117, -118, -118, -119, -119, -119, -120,
473 -120, -120, -120, -120, -121, -121, -121, -121,
474 -121, -121, -120, -120, -120, -120, -120, -119,
475 -119, -119, -118, -118, -117, -117, -116, -116,
476 -115, -114, -114, -113, -112, -111, -111, -110,
477 -109, -108, -107, -106, -105, -104, -103, -102, -100
480 static const s16 hsv_blue_x
[] = {
481 112, 113, 114, 114, 115, 116, 117, 117,
482 118, 118, 119, 119, 120, 120, 120, 121,
483 121, 121, 122, 122, 122, 122, 122, 122,
484 122, 122, 122, 122, 122, 122, 121, 121,
485 121, 120, 120, 120, 119, 119, 118, 118,
486 117, 116, 116, 115, 114, 113, 113, 112,
487 111, 110, 109, 108, 107, 106, 105, 104,
488 103, 102, 100, 99, 98, 97, 95, 94,
489 93, 91, 90, 88, 87, 85, 84, 82,
490 80, 79, 77, 76, 74, 72, 70, 69,
491 67, 65, 63, 61, 60, 58, 56, 54,
492 52, 50, 48, 46, 44, 42, 40, 38,
493 36, 34, 32, 30, 28, 26, 24, 22,
494 19, 17, 15, 13, 11, 9, 7, 5,
495 2, 0, -1, -3, -5, -7, -9, -12,
496 -14, -16, -18, -20, -22, -24, -26, -28,
497 -31, -33, -35, -37, -39, -41, -43, -45,
498 -47, -49, -51, -53, -54, -56, -58, -60,
499 -62, -64, -66, -67, -69, -71, -73, -74,
500 -76, -78, -79, -81, -83, -84, -86, -87,
501 -89, -90, -92, -93, -94, -96, -97, -98,
502 -99, -101, -102, -103, -104, -105, -106, -107,
503 -108, -109, -110, -111, -112, -113, -114, -114,
504 -115, -116, -117, -117, -118, -118, -119, -119,
505 -120, -120, -120, -121, -121, -121, -122, -122,
506 -122, -122, -122, -122, -122, -122, -122, -122,
507 -122, -122, -121, -121, -121, -120, -120, -120,
508 -119, -119, -118, -118, -117, -116, -116, -115,
509 -114, -113, -113, -112, -111, -110, -109, -108,
510 -107, -106, -105, -104, -103, -102, -100, -99,
511 -98, -97, -95, -94, -93, -91, -90, -88,
512 -87, -85, -84, -82, -80, -79, -77, -76,
513 -74, -72, -70, -69, -67, -65, -63, -61,
514 -60, -58, -56, -54, -52, -50, -48, -46,
515 -44, -42, -40, -38, -36, -34, -32, -30,
516 -28, -26, -24, -22, -19, -17, -15, -13,
517 -11, -9, -7, -5, -2, 0, 1, 3,
518 5, 7, 9, 12, 14, 16, 18, 20,
519 22, 24, 26, 28, 31, 33, 35, 37,
520 39, 41, 43, 45, 47, 49, 51, 53,
521 54, 56, 58, 60, 62, 64, 66, 67,
522 69, 71, 73, 74, 76, 78, 79, 81,
523 83, 84, 86, 87, 89, 90, 92, 93,
524 94, 96, 97, 98, 99, 101, 102, 103,
525 104, 105, 106, 107, 108, 109, 110, 111, 112
528 static const s16 hsv_blue_y
[] = {
529 -11, -13, -15, -17, -19, -21, -23, -25,
530 -27, -29, -31, -33, -35, -37, -39, -41,
531 -43, -45, -46, -48, -50, -52, -54, -55,
532 -57, -59, -61, -62, -64, -66, -67, -69,
533 -71, -72, -74, -75, -77, -78, -80, -81,
534 -83, -84, -86, -87, -88, -90, -91, -92,
535 -93, -95, -96, -97, -98, -99, -100, -101,
536 -102, -103, -104, -105, -106, -106, -107, -108,
537 -109, -109, -110, -111, -111, -112, -112, -113,
538 -113, -114, -114, -114, -115, -115, -115, -115,
539 -116, -116, -116, -116, -116, -116, -116, -116,
540 -116, -115, -115, -115, -115, -114, -114, -114,
541 -113, -113, -112, -112, -111, -111, -110, -110,
542 -109, -108, -108, -107, -106, -105, -104, -103,
543 -102, -101, -100, -99, -98, -97, -96, -95,
544 -94, -93, -91, -90, -89, -88, -86, -85,
545 -84, -82, -81, -79, -78, -76, -75, -73,
546 -71, -70, -68, -67, -65, -63, -62, -60,
547 -58, -56, -55, -53, -51, -49, -47, -45,
548 -44, -42, -40, -38, -36, -34, -32, -30,
549 -28, -26, -24, -22, -20, -18, -16, -14,
550 -12, -10, -8, -6, -4, -2, 0, 1,
551 3, 5, 7, 9, 11, 13, 15, 17,
552 19, 21, 23, 25, 27, 29, 31, 33,
553 35, 37, 39, 41, 43, 45, 46, 48,
554 50, 52, 54, 55, 57, 59, 61, 62,
555 64, 66, 67, 69, 71, 72, 74, 75,
556 77, 78, 80, 81, 83, 84, 86, 87,
557 88, 90, 91, 92, 93, 95, 96, 97,
558 98, 99, 100, 101, 102, 103, 104, 105,
559 106, 106, 107, 108, 109, 109, 110, 111,
560 111, 112, 112, 113, 113, 114, 114, 114,
561 115, 115, 115, 115, 116, 116, 116, 116,
562 116, 116, 116, 116, 116, 115, 115, 115,
563 115, 114, 114, 114, 113, 113, 112, 112,
564 111, 111, 110, 110, 109, 108, 108, 107,
565 106, 105, 104, 103, 102, 101, 100, 99,
566 98, 97, 96, 95, 94, 93, 91, 90,
567 89, 88, 86, 85, 84, 82, 81, 79,
568 78, 76, 75, 73, 71, 70, 68, 67,
569 65, 63, 62, 60, 58, 56, 55, 53,
570 51, 49, 47, 45, 44, 42, 40, 38,
571 36, 34, 32, 30, 28, 26, 24, 22,
572 20, 18, 16, 14, 12, 10, 8, 6,
573 4, 2, 0, -1, -3, -5, -7, -9, -11
576 static const u16 bridge_init
[][2] = {
577 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
578 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
579 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
580 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
581 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
582 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
583 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
584 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
585 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
586 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
587 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
588 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
589 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
590 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
591 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
592 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
593 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
594 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
595 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
599 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
600 static const u8 ov_gain
[] = {
601 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
602 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
603 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
604 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
605 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
606 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
607 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
611 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
612 static const u16 micron1_gain
[] = {
613 /* 1x 1.25x 1.5x 1.75x */
614 0x0020, 0x0028, 0x0030, 0x0038,
615 /* 2x 2.25x 2.5x 2.75x */
616 0x00a0, 0x00a4, 0x00a8, 0x00ac,
617 /* 3x 3.25x 3.5x 3.75x */
618 0x00b0, 0x00b4, 0x00b8, 0x00bc,
619 /* 4x 4.25x 4.5x 4.75x */
620 0x00c0, 0x00c4, 0x00c8, 0x00cc,
621 /* 5x 5.25x 5.5x 5.75x */
622 0x00d0, 0x00d4, 0x00d8, 0x00dc,
623 /* 6x 6.25x 6.5x 6.75x */
624 0x00e0, 0x00e4, 0x00e8, 0x00ec,
625 /* 7x 7.25x 7.5x 7.75x */
626 0x00f0, 0x00f4, 0x00f8, 0x00fc,
631 /* mt9m001 sensor uses a different gain formula then other micron sensors */
632 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
633 static const u16 micron2_gain
[] = {
634 /* 1x 1.25x 1.5x 1.75x */
635 0x0008, 0x000a, 0x000c, 0x000e,
636 /* 2x 2.25x 2.5x 2.75x */
637 0x0010, 0x0012, 0x0014, 0x0016,
638 /* 3x 3.25x 3.5x 3.75x */
639 0x0018, 0x001a, 0x001c, 0x001e,
640 /* 4x 4.25x 4.5x 4.75x */
641 0x0020, 0x0051, 0x0052, 0x0053,
642 /* 5x 5.25x 5.5x 5.75x */
643 0x0054, 0x0055, 0x0056, 0x0057,
644 /* 6x 6.25x 6.5x 6.75x */
645 0x0058, 0x0059, 0x005a, 0x005b,
646 /* 7x 7.25x 7.5x 7.75x */
647 0x005c, 0x005d, 0x005e, 0x005f,
652 /* Gain = .5 + bit[7:0] / 16 */
653 static const u8 hv7131r_gain
[] = {
654 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
655 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
656 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
657 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
658 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
659 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
660 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
664 static const struct i2c_reg_u8 soi968_init
[] = {
665 {0x0c, 0x00}, {0x0f, 0x1f},
666 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
667 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
668 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
669 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
670 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
671 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
672 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
673 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
674 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
675 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
678 static const struct i2c_reg_u8 ov7660_init
[] = {
679 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
680 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
681 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
682 /* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using
683 0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
684 {0x17, 0x10}, {0x18, 0x61},
685 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
686 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0x00},
687 {0x2e, 0x00}, {0x01, 0x78}, {0x02, 0x50},
690 static const struct i2c_reg_u8 ov7670_init
[] = {
691 {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
692 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
693 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
694 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
695 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
696 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
697 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
698 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
699 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
700 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
701 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
702 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
703 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
704 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
705 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
706 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
707 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
708 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
709 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
710 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
711 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
712 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
713 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
714 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
715 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
716 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
717 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
718 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
719 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
720 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
721 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
722 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
723 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
724 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
725 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
726 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
727 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
728 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
729 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
730 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
731 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
732 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
733 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
734 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
735 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
736 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
737 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
738 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
739 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
740 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
741 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
742 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
743 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
747 static const struct i2c_reg_u8 ov9650_init
[] = {
748 {0x00, 0x00}, {0x01, 0x78},
749 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
750 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
751 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
752 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
753 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
754 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
755 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
756 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
757 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
758 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
759 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
760 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
761 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
762 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
763 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
764 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
765 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
766 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
767 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
768 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
769 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
770 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
771 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
772 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
773 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
774 {0xaa, 0x92}, {0xab, 0x0a},
777 static const struct i2c_reg_u8 ov9655_init
[] = {
778 {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
779 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
780 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
781 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
782 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
783 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
784 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
785 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
786 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
787 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
788 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
789 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
790 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
791 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
792 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
793 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
794 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
795 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
796 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
797 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
798 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
799 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
800 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
801 {0x04, 0x03}, {0x00, 0x13},
804 static const struct i2c_reg_u16 mt9v112_init
[] = {
805 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
806 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
807 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
808 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
809 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
810 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
811 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
812 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
813 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
814 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
815 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
816 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
817 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
818 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
819 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
820 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
823 static const struct i2c_reg_u16 mt9v111_init
[] = {
824 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
825 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
826 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
827 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
828 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
829 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
830 {0x0e, 0x0008}, {0x20, 0x0000}
833 static const struct i2c_reg_u16 mt9v011_init
[] = {
834 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
835 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
836 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
837 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
838 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
839 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
840 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
841 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
842 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
843 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
844 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
845 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
846 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
847 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
848 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
849 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
850 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
851 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
852 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
853 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
854 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
855 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
856 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
857 {0x06, 0x0029}, {0x05, 0x0009},
860 static const struct i2c_reg_u16 mt9m001_init
[] = {
863 {0x04, 0x0500}, /* hres = 1280 */
864 {0x03, 0x0400}, /* vres = 1024 */
876 static const struct i2c_reg_u16 mt9m111_init
[] = {
877 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
878 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
879 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
883 static const struct i2c_reg_u16 mt9m112_init
[] = {
884 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
885 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
886 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
890 static const struct i2c_reg_u8 hv7131r_init
[] = {
891 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
892 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
893 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
894 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
895 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
896 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
897 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
898 {0x23, 0x09}, {0x01, 0x08},
901 static void reg_r(struct gspca_dev
*gspca_dev
, u16 reg
, u16 length
)
903 struct usb_device
*dev
= gspca_dev
->dev
;
906 if (gspca_dev
->usb_err
< 0)
908 result
= usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
910 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
916 if (unlikely(result
< 0 || result
!= length
)) {
917 pr_err("Read register %02x failed %d\n", reg
, result
);
918 gspca_dev
->usb_err
= result
;
920 * Make sure the buffer is zeroed to avoid uninitialized
923 memset(gspca_dev
->usb_buf
, 0, USB_BUF_SZ
);
927 static void reg_w(struct gspca_dev
*gspca_dev
, u16 reg
,
928 const u8
*buffer
, int length
)
930 struct usb_device
*dev
= gspca_dev
->dev
;
933 if (gspca_dev
->usb_err
< 0)
935 memcpy(gspca_dev
->usb_buf
, buffer
, length
);
936 result
= usb_control_msg(dev
, usb_sndctrlpipe(dev
, 0),
938 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
944 if (unlikely(result
< 0 || result
!= length
)) {
945 pr_err("Write register %02x failed %d\n", reg
, result
);
946 gspca_dev
->usb_err
= result
;
950 static void reg_w1(struct gspca_dev
*gspca_dev
, u16 reg
, const u8 value
)
952 reg_w(gspca_dev
, reg
, &value
, 1);
955 static void i2c_w(struct gspca_dev
*gspca_dev
, const u8
*buffer
)
959 reg_w(gspca_dev
, 0x10c0, buffer
, 8);
960 for (i
= 0; i
< 5; i
++) {
961 reg_r(gspca_dev
, 0x10c0, 1);
962 if (gspca_dev
->usb_err
< 0)
964 if (gspca_dev
->usb_buf
[0] & 0x04) {
965 if (gspca_dev
->usb_buf
[0] & 0x08) {
966 pr_err("i2c_w error\n");
967 gspca_dev
->usb_err
= -EIO
;
973 pr_err("i2c_w reg %02x no response\n", buffer
[2]);
974 /* gspca_dev->usb_err = -EIO; fixme: may occur */
977 static void i2c_w1(struct gspca_dev
*gspca_dev
, u8 reg
, u8 val
)
979 struct sd
*sd
= (struct sd
*) gspca_dev
;
983 * from the point of view of the bridge, the length
984 * includes the address
986 row
[0] = sd
->i2c_intf
| (2 << 4);
987 row
[1] = sd
->i2c_addr
;
995 i2c_w(gspca_dev
, row
);
998 static void i2c_w1_buf(struct gspca_dev
*gspca_dev
,
999 const struct i2c_reg_u8
*buf
, int sz
)
1002 i2c_w1(gspca_dev
, buf
->reg
, buf
->val
);
1007 static void i2c_w2(struct gspca_dev
*gspca_dev
, u8 reg
, u16 val
)
1009 struct sd
*sd
= (struct sd
*) gspca_dev
;
1013 * from the point of view of the bridge, the length
1014 * includes the address
1016 row
[0] = sd
->i2c_intf
| (3 << 4);
1017 row
[1] = sd
->i2c_addr
;
1025 i2c_w(gspca_dev
, row
);
1028 static void i2c_w2_buf(struct gspca_dev
*gspca_dev
,
1029 const struct i2c_reg_u16
*buf
, int sz
)
1032 i2c_w2(gspca_dev
, buf
->reg
, buf
->val
);
1037 static void i2c_r1(struct gspca_dev
*gspca_dev
, u8 reg
, u8
*val
)
1039 struct sd
*sd
= (struct sd
*) gspca_dev
;
1042 row
[0] = sd
->i2c_intf
| (1 << 4);
1043 row
[1] = sd
->i2c_addr
;
1050 i2c_w(gspca_dev
, row
);
1051 row
[0] = sd
->i2c_intf
| (1 << 4) | 0x02;
1053 i2c_w(gspca_dev
, row
);
1054 reg_r(gspca_dev
, 0x10c2, 5);
1055 *val
= gspca_dev
->usb_buf
[4];
1058 static void i2c_r2(struct gspca_dev
*gspca_dev
, u8 reg
, u16
*val
)
1060 struct sd
*sd
= (struct sd
*) gspca_dev
;
1063 row
[0] = sd
->i2c_intf
| (1 << 4);
1064 row
[1] = sd
->i2c_addr
;
1071 i2c_w(gspca_dev
, row
);
1072 row
[0] = sd
->i2c_intf
| (2 << 4) | 0x02;
1074 i2c_w(gspca_dev
, row
);
1075 reg_r(gspca_dev
, 0x10c2, 5);
1076 *val
= (gspca_dev
->usb_buf
[3] << 8) | gspca_dev
->usb_buf
[4];
1079 static void ov9650_init_sensor(struct gspca_dev
*gspca_dev
)
1082 struct sd
*sd
= (struct sd
*) gspca_dev
;
1084 i2c_r2(gspca_dev
, 0x1c, &id
);
1085 if (gspca_dev
->usb_err
< 0)
1089 pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id
);
1090 gspca_dev
->usb_err
= -ENODEV
;
1094 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1096 i2c_w1_buf(gspca_dev
, ov9650_init
, ARRAY_SIZE(ov9650_init
));
1097 if (gspca_dev
->usb_err
< 0)
1098 pr_err("OV9650 sensor initialization failed\n");
1103 static void ov9655_init_sensor(struct gspca_dev
*gspca_dev
)
1105 struct sd
*sd
= (struct sd
*) gspca_dev
;
1107 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1109 i2c_w1_buf(gspca_dev
, ov9655_init
, ARRAY_SIZE(ov9655_init
));
1110 if (gspca_dev
->usb_err
< 0)
1111 pr_err("OV9655 sensor initialization failed\n");
1117 static void soi968_init_sensor(struct gspca_dev
*gspca_dev
)
1119 struct sd
*sd
= (struct sd
*) gspca_dev
;
1121 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1123 i2c_w1_buf(gspca_dev
, soi968_init
, ARRAY_SIZE(soi968_init
));
1124 if (gspca_dev
->usb_err
< 0)
1125 pr_err("SOI968 sensor initialization failed\n");
1131 static void ov7660_init_sensor(struct gspca_dev
*gspca_dev
)
1133 struct sd
*sd
= (struct sd
*) gspca_dev
;
1135 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1137 i2c_w1_buf(gspca_dev
, ov7660_init
, ARRAY_SIZE(ov7660_init
));
1138 if (gspca_dev
->usb_err
< 0)
1139 pr_err("OV7660 sensor initialization failed\n");
1144 static void ov7670_init_sensor(struct gspca_dev
*gspca_dev
)
1146 struct sd
*sd
= (struct sd
*) gspca_dev
;
1148 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1150 i2c_w1_buf(gspca_dev
, ov7670_init
, ARRAY_SIZE(ov7670_init
));
1151 if (gspca_dev
->usb_err
< 0)
1152 pr_err("OV7670 sensor initialization failed\n");
1158 static void mt9v_init_sensor(struct gspca_dev
*gspca_dev
)
1160 struct sd
*sd
= (struct sd
*) gspca_dev
;
1163 sd
->i2c_addr
= 0x5d;
1164 i2c_r2(gspca_dev
, 0xff, &value
);
1165 if (gspca_dev
->usb_err
>= 0
1166 && value
== 0x8243) {
1167 i2c_w2_buf(gspca_dev
, mt9v011_init
, ARRAY_SIZE(mt9v011_init
));
1168 if (gspca_dev
->usb_err
< 0) {
1169 pr_err("MT9V011 sensor initialization failed\n");
1174 sd
->sensor
= SENSOR_MT9V011
;
1175 pr_info("MT9V011 sensor detected\n");
1179 gspca_dev
->usb_err
= 0;
1180 sd
->i2c_addr
= 0x5c;
1181 i2c_w2(gspca_dev
, 0x01, 0x0004);
1182 i2c_r2(gspca_dev
, 0xff, &value
);
1183 if (gspca_dev
->usb_err
>= 0
1184 && value
== 0x823a) {
1185 i2c_w2_buf(gspca_dev
, mt9v111_init
, ARRAY_SIZE(mt9v111_init
));
1186 if (gspca_dev
->usb_err
< 0) {
1187 pr_err("MT9V111 sensor initialization failed\n");
1192 sd
->sensor
= SENSOR_MT9V111
;
1193 pr_info("MT9V111 sensor detected\n");
1197 gspca_dev
->usb_err
= 0;
1198 sd
->i2c_addr
= 0x5d;
1199 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1200 if (gspca_dev
->usb_err
< 0) {
1201 gspca_dev
->usb_err
= 0;
1202 sd
->i2c_addr
= 0x48;
1203 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1205 i2c_r2(gspca_dev
, 0x00, &value
);
1206 if (gspca_dev
->usb_err
>= 0
1207 && value
== 0x1229) {
1208 i2c_w2_buf(gspca_dev
, mt9v112_init
, ARRAY_SIZE(mt9v112_init
));
1209 if (gspca_dev
->usb_err
< 0) {
1210 pr_err("MT9V112 sensor initialization failed\n");
1215 sd
->sensor
= SENSOR_MT9V112
;
1216 pr_info("MT9V112 sensor detected\n");
1220 gspca_dev
->usb_err
= -ENODEV
;
1223 static void mt9m112_init_sensor(struct gspca_dev
*gspca_dev
)
1225 struct sd
*sd
= (struct sd
*) gspca_dev
;
1227 i2c_w2_buf(gspca_dev
, mt9m112_init
, ARRAY_SIZE(mt9m112_init
));
1228 if (gspca_dev
->usb_err
< 0)
1229 pr_err("MT9M112 sensor initialization failed\n");
1235 static void mt9m111_init_sensor(struct gspca_dev
*gspca_dev
)
1237 struct sd
*sd
= (struct sd
*) gspca_dev
;
1239 i2c_w2_buf(gspca_dev
, mt9m111_init
, ARRAY_SIZE(mt9m111_init
));
1240 if (gspca_dev
->usb_err
< 0)
1241 pr_err("MT9M111 sensor initialization failed\n");
1247 static void mt9m001_init_sensor(struct gspca_dev
*gspca_dev
)
1249 struct sd
*sd
= (struct sd
*) gspca_dev
;
1252 i2c_r2(gspca_dev
, 0x00, &id
);
1253 if (gspca_dev
->usb_err
< 0)
1256 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
1260 pr_info("MT9M001 color sensor detected\n");
1263 pr_info("MT9M001 mono sensor detected\n");
1266 pr_err("No MT9M001 chip detected, ID = %x\n\n", id
);
1267 gspca_dev
->usb_err
= -ENODEV
;
1271 i2c_w2_buf(gspca_dev
, mt9m001_init
, ARRAY_SIZE(mt9m001_init
));
1272 if (gspca_dev
->usb_err
< 0)
1273 pr_err("MT9M001 sensor initialization failed\n");
1279 static void hv7131r_init_sensor(struct gspca_dev
*gspca_dev
)
1281 struct sd
*sd
= (struct sd
*) gspca_dev
;
1283 i2c_w1_buf(gspca_dev
, hv7131r_init
, ARRAY_SIZE(hv7131r_init
));
1284 if (gspca_dev
->usb_err
< 0)
1285 pr_err("HV7131R Sensor initialization failed\n");
1291 static void set_cmatrix(struct gspca_dev
*gspca_dev
,
1292 s32 brightness
, s32 contrast
, s32 satur
, s32 hue
)
1294 s32 hue_coord
, hue_index
= 180 + hue
;
1297 memset(cmatrix
, 0, sizeof(cmatrix
));
1298 cmatrix
[2] = (contrast
* 0x25 / 0x100) + 0x26;
1299 cmatrix
[0] = 0x13 + (cmatrix
[2] - 0x26) * 0x13 / 0x25;
1300 cmatrix
[4] = 0x07 + (cmatrix
[2] - 0x26) * 0x07 / 0x25;
1301 cmatrix
[18] = brightness
- 0x80;
1303 hue_coord
= (hsv_red_x
[hue_index
] * satur
) >> 8;
1304 cmatrix
[6] = hue_coord
;
1305 cmatrix
[7] = (hue_coord
>> 8) & 0x0f;
1307 hue_coord
= (hsv_red_y
[hue_index
] * satur
) >> 8;
1308 cmatrix
[8] = hue_coord
;
1309 cmatrix
[9] = (hue_coord
>> 8) & 0x0f;
1311 hue_coord
= (hsv_green_x
[hue_index
] * satur
) >> 8;
1312 cmatrix
[10] = hue_coord
;
1313 cmatrix
[11] = (hue_coord
>> 8) & 0x0f;
1315 hue_coord
= (hsv_green_y
[hue_index
] * satur
) >> 8;
1316 cmatrix
[12] = hue_coord
;
1317 cmatrix
[13] = (hue_coord
>> 8) & 0x0f;
1319 hue_coord
= (hsv_blue_x
[hue_index
] * satur
) >> 8;
1320 cmatrix
[14] = hue_coord
;
1321 cmatrix
[15] = (hue_coord
>> 8) & 0x0f;
1323 hue_coord
= (hsv_blue_y
[hue_index
] * satur
) >> 8;
1324 cmatrix
[16] = hue_coord
;
1325 cmatrix
[17] = (hue_coord
>> 8) & 0x0f;
1327 reg_w(gspca_dev
, 0x10e1, cmatrix
, 21);
1330 static void set_gamma(struct gspca_dev
*gspca_dev
, s32 val
)
1333 u8 gval
= val
* 0xb8 / 0x100;
1336 gamma
[1] = 0x13 + (gval
* (0xcb - 0x13) / 0xb8);
1337 gamma
[2] = 0x25 + (gval
* (0xee - 0x25) / 0xb8);
1338 gamma
[3] = 0x37 + (gval
* (0xfa - 0x37) / 0xb8);
1339 gamma
[4] = 0x45 + (gval
* (0xfc - 0x45) / 0xb8);
1340 gamma
[5] = 0x55 + (gval
* (0xfb - 0x55) / 0xb8);
1341 gamma
[6] = 0x65 + (gval
* (0xfc - 0x65) / 0xb8);
1342 gamma
[7] = 0x74 + (gval
* (0xfd - 0x74) / 0xb8);
1343 gamma
[8] = 0x83 + (gval
* (0xfe - 0x83) / 0xb8);
1344 gamma
[9] = 0x92 + (gval
* (0xfc - 0x92) / 0xb8);
1345 gamma
[10] = 0xa1 + (gval
* (0xfc - 0xa1) / 0xb8);
1346 gamma
[11] = 0xb0 + (gval
* (0xfc - 0xb0) / 0xb8);
1347 gamma
[12] = 0xbf + (gval
* (0xfb - 0xbf) / 0xb8);
1348 gamma
[13] = 0xce + (gval
* (0xfb - 0xce) / 0xb8);
1349 gamma
[14] = 0xdf + (gval
* (0xfd - 0xdf) / 0xb8);
1350 gamma
[15] = 0xea + (gval
* (0xf9 - 0xea) / 0xb8);
1353 reg_w(gspca_dev
, 0x1190, gamma
, 17);
1356 static void set_redblue(struct gspca_dev
*gspca_dev
, s32 blue
, s32 red
)
1358 reg_w1(gspca_dev
, 0x118c, red
);
1359 reg_w1(gspca_dev
, 0x118f, blue
);
1362 static void set_hvflip(struct gspca_dev
*gspca_dev
, s32 hflip
, s32 vflip
)
1366 struct sd
*sd
= (struct sd
*) gspca_dev
;
1368 if ((sd
->flags
& FLIP_DETECT
) && dmi_check_system(flip_dmi_table
)) {
1373 switch (sd
->sensor
) {
1384 reg_w1(gspca_dev
, 0x1182, sd
->vstart
);
1385 i2c_w1(gspca_dev
, 0x1e, value
);
1388 i2c_r1(gspca_dev
, 0x1e, &value
);
1397 i2c_w1(gspca_dev
, 0x1e, value
);
1398 i2c_w1(gspca_dev
, 0x3a, tslb
);
1400 case SENSOR_MT9V111
:
1401 case SENSOR_MT9V011
:
1402 i2c_r2(gspca_dev
, 0x20, &value2
);
1408 i2c_w2(gspca_dev
, 0x20, value2
);
1410 case SENSOR_MT9M112
:
1411 case SENSOR_MT9M111
:
1412 case SENSOR_MT9V112
:
1413 i2c_r2(gspca_dev
, 0x20, &value2
);
1419 i2c_w2(gspca_dev
, 0x20, value2
);
1421 case SENSOR_HV7131R
:
1422 i2c_r1(gspca_dev
, 0x01, &value
);
1428 i2c_w1(gspca_dev
, 0x01, value
);
1433 static void set_exposure(struct gspca_dev
*gspca_dev
, s32 expo
)
1435 struct sd
*sd
= (struct sd
*) gspca_dev
;
1436 u8 exp
[8] = {sd
->i2c_intf
, sd
->i2c_addr
,
1437 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1440 if (gspca_dev
->streaming
)
1443 switch (sd
->sensor
) {
1453 exp
[2] = 0x10; /* AECH */
1454 exp
[3] = expo2
>> 2;
1456 i2c_w(gspca_dev
, exp
);
1457 exp
[2] = 0x04; /* COM1 */
1458 exp
[3] = expo2
& 0x0003;
1460 i2c_w(gspca_dev
, exp
);
1464 exp
[2] = 0x2d; /* ADVFL & ADVFH */
1468 case SENSOR_MT9M001
:
1469 case SENSOR_MT9V112
:
1470 case SENSOR_MT9V011
:
1476 case SENSOR_HV7131R
:
1486 i2c_w(gspca_dev
, exp
);
1489 static void set_gain(struct gspca_dev
*gspca_dev
, s32 g
)
1491 struct sd
*sd
= (struct sd
*) gspca_dev
;
1492 u8 gain
[8] = {sd
->i2c_intf
, sd
->i2c_addr
,
1493 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1495 if (gspca_dev
->streaming
)
1496 gain
[7] = 0x15; /* or 1d ? */
1498 switch (sd
->sensor
) {
1504 gain
[0] |= (2 << 4);
1505 gain
[3] = ov_gain
[g
];
1507 case SENSOR_MT9V011
:
1508 gain
[0] |= (3 << 4);
1510 gain
[3] = micron1_gain
[g
] >> 8;
1511 gain
[4] = micron1_gain
[g
];
1513 case SENSOR_MT9V112
:
1514 gain
[0] |= (3 << 4);
1516 gain
[3] = micron1_gain
[g
] >> 8;
1517 gain
[4] = micron1_gain
[g
];
1519 case SENSOR_MT9M001
:
1520 gain
[0] |= (3 << 4);
1522 gain
[3] = micron2_gain
[g
] >> 8;
1523 gain
[4] = micron2_gain
[g
];
1525 case SENSOR_HV7131R
:
1526 gain
[0] |= (2 << 4);
1528 gain
[3] = hv7131r_gain
[g
];
1533 i2c_w(gspca_dev
, gain
);
1536 static void set_quality(struct gspca_dev
*gspca_dev
, s32 val
)
1538 struct sd
*sd
= (struct sd
*) gspca_dev
;
1540 jpeg_set_qual(sd
->jpeg_hdr
, val
);
1541 reg_w1(gspca_dev
, 0x1061, 0x01); /* stop transfer */
1542 reg_w1(gspca_dev
, 0x10e0, sd
->fmt
| 0x20); /* write QTAB */
1543 reg_w(gspca_dev
, 0x1100, &sd
->jpeg_hdr
[JPEG_QT0_OFFSET
], 64);
1544 reg_w(gspca_dev
, 0x1140, &sd
->jpeg_hdr
[JPEG_QT1_OFFSET
], 64);
1545 reg_w1(gspca_dev
, 0x1061, 0x03); /* restart transfer */
1546 reg_w1(gspca_dev
, 0x10e0, sd
->fmt
);
1547 sd
->fmt
^= 0x0c; /* invert QTAB use + write */
1548 reg_w1(gspca_dev
, 0x10e0, sd
->fmt
);
1551 #ifdef CONFIG_VIDEO_ADV_DEBUG
1552 static int sd_dbg_g_register(struct gspca_dev
*gspca_dev
,
1553 struct v4l2_dbg_register
*reg
)
1555 struct sd
*sd
= (struct sd
*) gspca_dev
;
1558 switch (reg
->match
.addr
) {
1560 if (reg
->reg
< 0x1000 || reg
->reg
> 0x11ff)
1562 reg_r(gspca_dev
, reg
->reg
, 1);
1563 reg
->val
= gspca_dev
->usb_buf
[0];
1564 return gspca_dev
->usb_err
;
1566 if (sd
->sensor
>= SENSOR_MT9V011
&&
1567 sd
->sensor
<= SENSOR_MT9M112
) {
1568 i2c_r2(gspca_dev
, reg
->reg
, (u16
*) ®
->val
);
1571 i2c_r1(gspca_dev
, reg
->reg
, (u8
*) ®
->val
);
1573 return gspca_dev
->usb_err
;
1578 static int sd_dbg_s_register(struct gspca_dev
*gspca_dev
,
1579 const struct v4l2_dbg_register
*reg
)
1581 struct sd
*sd
= (struct sd
*) gspca_dev
;
1583 switch (reg
->match
.addr
) {
1585 if (reg
->reg
< 0x1000 || reg
->reg
> 0x11ff)
1587 reg_w1(gspca_dev
, reg
->reg
, reg
->val
);
1588 return gspca_dev
->usb_err
;
1590 if (sd
->sensor
>= SENSOR_MT9V011
&&
1591 sd
->sensor
<= SENSOR_MT9M112
) {
1592 i2c_w2(gspca_dev
, reg
->reg
, reg
->val
);
1594 i2c_w1(gspca_dev
, reg
->reg
, reg
->val
);
1596 return gspca_dev
->usb_err
;
1601 static int sd_chip_info(struct gspca_dev
*gspca_dev
,
1602 struct v4l2_dbg_chip_info
*chip
)
1604 if (chip
->match
.addr
> 1)
1606 if (chip
->match
.addr
== 1)
1607 strscpy(chip
->name
, "sensor", sizeof(chip
->name
));
1612 static int sd_config(struct gspca_dev
*gspca_dev
,
1613 const struct usb_device_id
*id
)
1615 struct sd
*sd
= (struct sd
*) gspca_dev
;
1618 cam
= &gspca_dev
->cam
;
1619 cam
->needs_full_bandwidth
= 1;
1621 sd
->sensor
= id
->driver_info
>> 8;
1622 sd
->i2c_addr
= id
->driver_info
;
1623 sd
->flags
= id
->driver_info
>> 16;
1624 sd
->i2c_intf
= 0x80; /* i2c 100 Kb/s */
1626 switch (sd
->sensor
) {
1627 case SENSOR_MT9M112
:
1628 case SENSOR_MT9M111
:
1631 cam
->cam_mode
= sxga_mode
;
1632 cam
->nmodes
= ARRAY_SIZE(sxga_mode
);
1634 case SENSOR_MT9M001
:
1635 cam
->cam_mode
= mono_mode
;
1636 cam
->nmodes
= ARRAY_SIZE(mono_mode
);
1638 case SENSOR_HV7131R
:
1639 sd
->i2c_intf
= 0x81; /* i2c 400 Kb/s */
1642 cam
->cam_mode
= vga_mode
;
1643 cam
->nmodes
= ARRAY_SIZE(vga_mode
);
1649 sd
->exposure_step
= 16;
1651 INIT_WORK(&sd
->work
, qual_upd
);
1656 static int sd_s_ctrl(struct v4l2_ctrl
*ctrl
)
1658 struct gspca_dev
*gspca_dev
=
1659 container_of(ctrl
->handler
, struct gspca_dev
, ctrl_handler
);
1660 struct sd
*sd
= (struct sd
*)gspca_dev
;
1662 gspca_dev
->usb_err
= 0;
1664 if (!gspca_dev
->streaming
)
1668 /* color control cluster */
1669 case V4L2_CID_BRIGHTNESS
:
1670 set_cmatrix(gspca_dev
, sd
->brightness
->val
,
1671 sd
->contrast
->val
, sd
->saturation
->val
, sd
->hue
->val
);
1673 case V4L2_CID_GAMMA
:
1674 set_gamma(gspca_dev
, ctrl
->val
);
1676 /* blue/red balance cluster */
1677 case V4L2_CID_BLUE_BALANCE
:
1678 set_redblue(gspca_dev
, sd
->blue
->val
, sd
->red
->val
);
1680 /* h/vflip cluster */
1681 case V4L2_CID_HFLIP
:
1682 set_hvflip(gspca_dev
, sd
->hflip
->val
, sd
->vflip
->val
);
1684 /* standalone exposure control */
1685 case V4L2_CID_EXPOSURE
:
1686 set_exposure(gspca_dev
, ctrl
->val
);
1688 /* standalone gain control */
1690 set_gain(gspca_dev
, ctrl
->val
);
1692 /* autogain + exposure or gain control cluster */
1693 case V4L2_CID_AUTOGAIN
:
1694 if (sd
->sensor
== SENSOR_SOI968
)
1695 set_gain(gspca_dev
, sd
->gain
->val
);
1697 set_exposure(gspca_dev
, sd
->exposure
->val
);
1699 case V4L2_CID_JPEG_COMPRESSION_QUALITY
:
1700 set_quality(gspca_dev
, ctrl
->val
);
1703 return gspca_dev
->usb_err
;
1706 static const struct v4l2_ctrl_ops sd_ctrl_ops
= {
1707 .s_ctrl
= sd_s_ctrl
,
1710 static int sd_init_controls(struct gspca_dev
*gspca_dev
)
1712 struct sd
*sd
= (struct sd
*) gspca_dev
;
1713 struct v4l2_ctrl_handler
*hdl
= &gspca_dev
->ctrl_handler
;
1715 gspca_dev
->vdev
.ctrl_handler
= hdl
;
1716 v4l2_ctrl_handler_init(hdl
, 13);
1718 sd
->brightness
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1719 V4L2_CID_BRIGHTNESS
, 0, 255, 1, 127);
1720 sd
->contrast
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1721 V4L2_CID_CONTRAST
, 0, 255, 1, 127);
1722 sd
->saturation
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1723 V4L2_CID_SATURATION
, 0, 255, 1, 127);
1724 sd
->hue
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1725 V4L2_CID_HUE
, -180, 180, 1, 0);
1727 sd
->gamma
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1728 V4L2_CID_GAMMA
, 0, 255, 1, 0x10);
1730 sd
->blue
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1731 V4L2_CID_BLUE_BALANCE
, 0, 127, 1, 0x28);
1732 sd
->red
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1733 V4L2_CID_RED_BALANCE
, 0, 127, 1, 0x28);
1735 if (sd
->sensor
!= SENSOR_OV9655
&& sd
->sensor
!= SENSOR_SOI968
&&
1736 sd
->sensor
!= SENSOR_OV7670
&& sd
->sensor
!= SENSOR_MT9M001
&&
1737 sd
->sensor
!= SENSOR_MT9VPRB
) {
1738 sd
->hflip
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1739 V4L2_CID_HFLIP
, 0, 1, 1, 0);
1740 sd
->vflip
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1741 V4L2_CID_VFLIP
, 0, 1, 1, 0);
1744 if (sd
->sensor
!= SENSOR_SOI968
&& sd
->sensor
!= SENSOR_MT9VPRB
&&
1745 sd
->sensor
!= SENSOR_MT9M112
&& sd
->sensor
!= SENSOR_MT9M111
&&
1746 sd
->sensor
!= SENSOR_MT9V111
)
1747 sd
->exposure
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1748 V4L2_CID_EXPOSURE
, 0, 0x1780, 1, 0x33);
1750 if (sd
->sensor
!= SENSOR_MT9VPRB
&& sd
->sensor
!= SENSOR_MT9M112
&&
1751 sd
->sensor
!= SENSOR_MT9M111
&& sd
->sensor
!= SENSOR_MT9V111
) {
1752 sd
->gain
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1753 V4L2_CID_GAIN
, 0, 28, 1, 0);
1754 sd
->autogain
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1755 V4L2_CID_AUTOGAIN
, 0, 1, 1, 1);
1758 sd
->jpegqual
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1759 V4L2_CID_JPEG_COMPRESSION_QUALITY
, 50, 90, 1, 80);
1761 pr_err("Could not initialize controls\n");
1765 v4l2_ctrl_cluster(4, &sd
->brightness
);
1766 v4l2_ctrl_cluster(2, &sd
->blue
);
1768 v4l2_ctrl_cluster(2, &sd
->hflip
);
1770 if (sd
->sensor
== SENSOR_SOI968
)
1771 /* this sensor doesn't have the exposure control and
1772 autogain is clustered with gain instead. This works
1773 because sd->exposure == NULL. */
1774 v4l2_ctrl_auto_cluster(3, &sd
->autogain
, 0, false);
1776 /* Otherwise autogain is clustered with exposure. */
1777 v4l2_ctrl_auto_cluster(2, &sd
->autogain
, 0, false);
1782 static int sd_init(struct gspca_dev
*gspca_dev
)
1784 struct sd
*sd
= (struct sd
*) gspca_dev
;
1788 0x80, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
1791 for (i
= 0; i
< ARRAY_SIZE(bridge_init
); i
++) {
1792 value
= bridge_init
[i
][1];
1793 reg_w(gspca_dev
, bridge_init
[i
][0], &value
, 1);
1794 if (gspca_dev
->usb_err
< 0) {
1795 pr_err("Device initialization failed\n");
1796 return gspca_dev
->usb_err
;
1800 if (sd
->flags
& LED_REVERSE
)
1801 reg_w1(gspca_dev
, 0x1006, 0x00);
1803 reg_w1(gspca_dev
, 0x1006, 0x20);
1805 reg_w(gspca_dev
, 0x10c0, i2c_init
, 9);
1806 if (gspca_dev
->usb_err
< 0) {
1807 pr_err("Device initialization failed\n");
1808 return gspca_dev
->usb_err
;
1811 switch (sd
->sensor
) {
1813 ov9650_init_sensor(gspca_dev
);
1814 if (gspca_dev
->usb_err
< 0)
1816 pr_info("OV9650 sensor detected\n");
1819 ov9655_init_sensor(gspca_dev
);
1820 if (gspca_dev
->usb_err
< 0)
1822 pr_info("OV9655 sensor detected\n");
1825 soi968_init_sensor(gspca_dev
);
1826 if (gspca_dev
->usb_err
< 0)
1828 pr_info("SOI968 sensor detected\n");
1831 ov7660_init_sensor(gspca_dev
);
1832 if (gspca_dev
->usb_err
< 0)
1834 pr_info("OV7660 sensor detected\n");
1837 ov7670_init_sensor(gspca_dev
);
1838 if (gspca_dev
->usb_err
< 0)
1840 pr_info("OV7670 sensor detected\n");
1842 case SENSOR_MT9VPRB
:
1843 mt9v_init_sensor(gspca_dev
);
1844 if (gspca_dev
->usb_err
< 0)
1846 pr_info("MT9VPRB sensor detected\n");
1848 case SENSOR_MT9M111
:
1849 mt9m111_init_sensor(gspca_dev
);
1850 if (gspca_dev
->usb_err
< 0)
1852 pr_info("MT9M111 sensor detected\n");
1854 case SENSOR_MT9M112
:
1855 mt9m112_init_sensor(gspca_dev
);
1856 if (gspca_dev
->usb_err
< 0)
1858 pr_info("MT9M112 sensor detected\n");
1860 case SENSOR_MT9M001
:
1861 mt9m001_init_sensor(gspca_dev
);
1862 if (gspca_dev
->usb_err
< 0)
1865 case SENSOR_HV7131R
:
1866 hv7131r_init_sensor(gspca_dev
);
1867 if (gspca_dev
->usb_err
< 0)
1869 pr_info("HV7131R sensor detected\n");
1872 pr_err("Unsupported sensor\n");
1873 gspca_dev
->usb_err
= -ENODEV
;
1875 return gspca_dev
->usb_err
;
1878 static void configure_sensor_output(struct gspca_dev
*gspca_dev
, int mode
)
1880 struct sd
*sd
= (struct sd
*) gspca_dev
;
1883 switch (sd
->sensor
) {
1885 if (mode
& MODE_SXGA
) {
1886 i2c_w1(gspca_dev
, 0x17, 0x1d);
1887 i2c_w1(gspca_dev
, 0x18, 0xbd);
1888 i2c_w1(gspca_dev
, 0x19, 0x01);
1889 i2c_w1(gspca_dev
, 0x1a, 0x81);
1890 i2c_w1(gspca_dev
, 0x12, 0x00);
1894 i2c_w1(gspca_dev
, 0x17, 0x13);
1895 i2c_w1(gspca_dev
, 0x18, 0x63);
1896 i2c_w1(gspca_dev
, 0x19, 0x01);
1897 i2c_w1(gspca_dev
, 0x1a, 0x79);
1898 i2c_w1(gspca_dev
, 0x12, 0x40);
1904 if (mode
& MODE_SXGA
) {
1905 i2c_w1(gspca_dev
, 0x17, 0x1b);
1906 i2c_w1(gspca_dev
, 0x18, 0xbc);
1907 i2c_w1(gspca_dev
, 0x19, 0x01);
1908 i2c_w1(gspca_dev
, 0x1a, 0x82);
1909 i2c_r1(gspca_dev
, 0x12, &value
);
1910 i2c_w1(gspca_dev
, 0x12, value
& 0x07);
1912 i2c_w1(gspca_dev
, 0x17, 0x24);
1913 i2c_w1(gspca_dev
, 0x18, 0xc5);
1914 i2c_w1(gspca_dev
, 0x19, 0x00);
1915 i2c_w1(gspca_dev
, 0x1a, 0x3c);
1916 i2c_r1(gspca_dev
, 0x12, &value
);
1917 i2c_w1(gspca_dev
, 0x12, (value
& 0x7) | 0x40);
1920 case SENSOR_MT9M112
:
1921 case SENSOR_MT9M111
:
1922 if (mode
& MODE_SXGA
) {
1923 i2c_w2(gspca_dev
, 0xf0, 0x0002);
1924 i2c_w2(gspca_dev
, 0xc8, 0x970b);
1925 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1927 i2c_w2(gspca_dev
, 0xf0, 0x0002);
1928 i2c_w2(gspca_dev
, 0xc8, 0x8000);
1929 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1935 static int sd_isoc_init(struct gspca_dev
*gspca_dev
)
1937 struct usb_interface
*intf
;
1938 u32 flags
= gspca_dev
->cam
.cam_mode
[(int)gspca_dev
->curr_mode
].priv
;
1941 * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth
1942 * than our regular bandwidth calculations reserve, so we force the
1943 * use of a specific altsetting when using the SN9C20X_I420 fmt.
1945 if (!(flags
& (MODE_RAW
| MODE_JPEG
))) {
1946 intf
= usb_ifnum_to_if(gspca_dev
->dev
, gspca_dev
->iface
);
1948 if (intf
->num_altsetting
!= 9) {
1949 pr_warn("sn9c20x camera with unknown number of alt settings (%d), please report!\n",
1950 intf
->num_altsetting
);
1951 gspca_dev
->alt
= intf
->num_altsetting
;
1955 switch (gspca_dev
->pixfmt
.width
) {
1956 case 160: /* 160x120 */
1959 case 320: /* 320x240 */
1962 default: /* >= 640x480 */
1971 #define HW_WIN(mode, hstart, vstart) \
1972 ((const u8 []){hstart, 0, vstart, 0, \
1973 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
1974 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
1976 #define CLR_WIN(width, height) \
1978 {0, width >> 2, 0, height >> 1,\
1979 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
1981 static int sd_start(struct gspca_dev
*gspca_dev
)
1983 struct sd
*sd
= (struct sd
*) gspca_dev
;
1984 int mode
= gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
;
1985 int width
= gspca_dev
->pixfmt
.width
;
1986 int height
= gspca_dev
->pixfmt
.height
;
1989 jpeg_define(sd
->jpeg_hdr
, height
, width
,
1991 jpeg_set_qual(sd
->jpeg_hdr
, v4l2_ctrl_g_ctrl(sd
->jpegqual
));
1993 if (mode
& MODE_RAW
)
1995 else if (mode
& MODE_JPEG
)
1998 fmt
= 0x2f; /* YUV 420 */
2001 switch (mode
& SCALE_MASK
) {
2002 case SCALE_1280x1024
:
2004 pr_info("Set 1280x1024\n");
2008 pr_info("Set 640x480\n");
2012 pr_info("Set 320x240\n");
2016 pr_info("Set 160x120\n");
2020 configure_sensor_output(gspca_dev
, mode
);
2021 reg_w(gspca_dev
, 0x1100, &sd
->jpeg_hdr
[JPEG_QT0_OFFSET
], 64);
2022 reg_w(gspca_dev
, 0x1140, &sd
->jpeg_hdr
[JPEG_QT1_OFFSET
], 64);
2023 reg_w(gspca_dev
, 0x10fb, CLR_WIN(width
, height
), 5);
2024 reg_w(gspca_dev
, 0x1180, HW_WIN(mode
, sd
->hstart
, sd
->vstart
), 6);
2025 reg_w1(gspca_dev
, 0x1189, scale
);
2026 reg_w1(gspca_dev
, 0x10e0, fmt
);
2028 set_cmatrix(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->brightness
),
2029 v4l2_ctrl_g_ctrl(sd
->contrast
),
2030 v4l2_ctrl_g_ctrl(sd
->saturation
),
2031 v4l2_ctrl_g_ctrl(sd
->hue
));
2032 set_gamma(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->gamma
));
2033 set_redblue(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->blue
),
2034 v4l2_ctrl_g_ctrl(sd
->red
));
2036 set_gain(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->gain
));
2038 set_exposure(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->exposure
));
2040 set_hvflip(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->hflip
),
2041 v4l2_ctrl_g_ctrl(sd
->vflip
));
2043 reg_w1(gspca_dev
, 0x1007, 0x20);
2044 reg_w1(gspca_dev
, 0x1061, 0x03);
2046 /* if JPEG, prepare the compression quality update */
2047 if (mode
& MODE_JPEG
) {
2048 sd
->pktsz
= sd
->npkt
= 0;
2052 return gspca_dev
->usb_err
;
2055 static void sd_stopN(struct gspca_dev
*gspca_dev
)
2057 reg_w1(gspca_dev
, 0x1007, 0x00);
2058 reg_w1(gspca_dev
, 0x1061, 0x01);
2061 /* called on streamoff with alt==0 and on disconnect */
2062 /* the usb_lock is held at entry - restore on exit */
2063 static void sd_stop0(struct gspca_dev
*gspca_dev
)
2065 struct sd
*sd
= (struct sd
*) gspca_dev
;
2067 mutex_unlock(&gspca_dev
->usb_lock
);
2068 flush_work(&sd
->work
);
2069 mutex_lock(&gspca_dev
->usb_lock
);
2072 static void do_autoexposure(struct gspca_dev
*gspca_dev
, u16 avg_lum
)
2074 struct sd
*sd
= (struct sd
*) gspca_dev
;
2075 s32 cur_exp
= v4l2_ctrl_g_ctrl(sd
->exposure
);
2076 s32 max
= sd
->exposure
->maximum
- sd
->exposure_step
;
2077 s32 min
= sd
->exposure
->minimum
+ sd
->exposure_step
;
2081 * some hardcoded values are present
2082 * like those for maximal/minimal exposure
2083 * and exposure steps
2085 if (avg_lum
< MIN_AVG_LUM
) {
2089 new_exp
= cur_exp
+ sd
->exposure_step
;
2094 v4l2_ctrl_s_ctrl(sd
->exposure
, new_exp
);
2096 sd
->older_step
= sd
->old_step
;
2099 if (sd
->old_step
^ sd
->older_step
)
2100 sd
->exposure_step
/= 2;
2102 sd
->exposure_step
+= 2;
2104 if (avg_lum
> MAX_AVG_LUM
) {
2107 new_exp
= cur_exp
- sd
->exposure_step
;
2112 v4l2_ctrl_s_ctrl(sd
->exposure
, new_exp
);
2113 sd
->older_step
= sd
->old_step
;
2116 if (sd
->old_step
^ sd
->older_step
)
2117 sd
->exposure_step
/= 2;
2119 sd
->exposure_step
+= 2;
2123 static void do_autogain(struct gspca_dev
*gspca_dev
, u16 avg_lum
)
2125 struct sd
*sd
= (struct sd
*) gspca_dev
;
2126 s32 cur_gain
= v4l2_ctrl_g_ctrl(sd
->gain
);
2128 if (avg_lum
< MIN_AVG_LUM
&& cur_gain
< sd
->gain
->maximum
)
2129 v4l2_ctrl_s_ctrl(sd
->gain
, cur_gain
+ 1);
2130 if (avg_lum
> MAX_AVG_LUM
&& cur_gain
> sd
->gain
->minimum
)
2131 v4l2_ctrl_s_ctrl(sd
->gain
, cur_gain
- 1);
2134 static void sd_dqcallback(struct gspca_dev
*gspca_dev
)
2136 struct sd
*sd
= (struct sd
*) gspca_dev
;
2139 if (sd
->autogain
== NULL
|| !v4l2_ctrl_g_ctrl(sd
->autogain
))
2142 avg_lum
= atomic_read(&sd
->avg_lum
);
2143 if (sd
->sensor
== SENSOR_SOI968
)
2144 do_autogain(gspca_dev
, avg_lum
);
2146 do_autoexposure(gspca_dev
, avg_lum
);
2149 /* JPEG quality update */
2150 /* This function is executed from a work queue. */
2151 static void qual_upd(struct work_struct
*work
)
2153 struct sd
*sd
= container_of(work
, struct sd
, work
);
2154 struct gspca_dev
*gspca_dev
= &sd
->gspca_dev
;
2155 s32 qual
= v4l2_ctrl_g_ctrl(sd
->jpegqual
);
2157 /* To protect gspca_dev->usb_buf and gspca_dev->usb_err */
2158 mutex_lock(&gspca_dev
->usb_lock
);
2159 gspca_dbg(gspca_dev
, D_STREAM
, "qual_upd %d%%\n", qual
);
2160 gspca_dev
->usb_err
= 0;
2161 set_quality(gspca_dev
, qual
);
2162 mutex_unlock(&gspca_dev
->usb_lock
);
2165 #if IS_ENABLED(CONFIG_INPUT)
2166 static int sd_int_pkt_scan(struct gspca_dev
*gspca_dev
,
2167 u8
*data
, /* interrupt packet */
2168 int len
) /* interrupt packet length */
2170 struct sd
*sd
= (struct sd
*) gspca_dev
;
2172 if (!(sd
->flags
& HAS_NO_BUTTON
) && len
== 1) {
2173 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 1);
2174 input_sync(gspca_dev
->input_dev
);
2175 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 0);
2176 input_sync(gspca_dev
->input_dev
);
2183 /* check the JPEG compression */
2184 static void transfer_check(struct gspca_dev
*gspca_dev
,
2187 struct sd
*sd
= (struct sd
*) gspca_dev
;
2192 /* if USB error, discard the frame and decrease the quality */
2193 if (data
[6] & 0x08) { /* USB FIFO full */
2194 gspca_dev
->last_packet_type
= DISCARD_PACKET
;
2198 /* else, compute the filling rate and a new JPEG quality */
2199 r
= (sd
->pktsz
* 100) /
2201 gspca_dev
->urb
[0]->iso_frame_desc
[0].length
);
2207 if (new_qual
!= 0) {
2208 sd
->nchg
+= new_qual
;
2209 if (sd
->nchg
< -6 || sd
->nchg
>= 12) {
2210 /* Note: we are in interrupt context, so we can't
2211 use v4l2_ctrl_g/s_ctrl here. Access the value
2212 directly instead. */
2213 s32 curqual
= sd
->jpegqual
->cur
.val
;
2215 new_qual
+= curqual
;
2216 if (new_qual
< sd
->jpegqual
->minimum
)
2217 new_qual
= sd
->jpegqual
->minimum
;
2218 else if (new_qual
> sd
->jpegqual
->maximum
)
2219 new_qual
= sd
->jpegqual
->maximum
;
2220 if (new_qual
!= curqual
) {
2221 sd
->jpegqual
->cur
.val
= new_qual
;
2222 schedule_work(&sd
->work
);
2228 sd
->pktsz
= sd
->npkt
= 0;
2231 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
2232 u8
*data
, /* isoc packet */
2233 int len
) /* iso packet length */
2235 struct sd
*sd
= (struct sd
*) gspca_dev
;
2236 int avg_lum
, is_jpeg
;
2237 static const u8 frame_header
[] = {
2238 0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96
2241 is_jpeg
= (sd
->fmt
& 0x03) == 0;
2242 if (len
>= 64 && memcmp(data
, frame_header
, 6) == 0) {
2243 avg_lum
= ((data
[35] >> 2) & 3) |
2246 avg_lum
+= ((data
[35] >> 4) & 3) |
2249 avg_lum
+= ((data
[35] >> 6) & 3) |
2252 avg_lum
+= (data
[36] & 3) |
2255 avg_lum
+= ((data
[36] >> 2) & 3) |
2258 avg_lum
+= ((data
[36] >> 4) & 3) |
2261 avg_lum
+= ((data
[36] >> 6) & 3) |
2264 avg_lum
+= ((data
[44] >> 4) & 3) |
2268 atomic_set(&sd
->avg_lum
, avg_lum
);
2271 transfer_check(gspca_dev
, data
);
2273 gspca_frame_add(gspca_dev
, LAST_PACKET
, NULL
, 0);
2279 if (gspca_dev
->last_packet_type
== LAST_PACKET
) {
2281 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
2282 sd
->jpeg_hdr
, JPEG_HDR_SZ
);
2283 gspca_frame_add(gspca_dev
, INTER_PACKET
,
2286 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
2290 /* if JPEG, count the packets and their size */
2295 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, len
);
2299 /* sub-driver description */
2300 static const struct sd_desc sd_desc
= {
2301 .name
= KBUILD_MODNAME
,
2302 .config
= sd_config
,
2304 .init_controls
= sd_init_controls
,
2305 .isoc_init
= sd_isoc_init
,
2309 .pkt_scan
= sd_pkt_scan
,
2310 #if IS_ENABLED(CONFIG_INPUT)
2311 .int_pkt_scan
= sd_int_pkt_scan
,
2313 .dq_callback
= sd_dqcallback
,
2314 #ifdef CONFIG_VIDEO_ADV_DEBUG
2315 .set_register
= sd_dbg_s_register
,
2316 .get_register
= sd_dbg_g_register
,
2317 .get_chip_info
= sd_chip_info
,
2321 #define SN9C20X(sensor, i2c_addr, flags) \
2322 .driver_info = ((flags & 0xff) << 16) \
2323 | (SENSOR_ ## sensor << 8) \
2326 static const struct usb_device_id device_table
[] = {
2327 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001
, 0x5d, 0)},
2328 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111
, 0x5d, 0)},
2329 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655
, 0x30, 0)},
2330 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112
, 0x5d, 0)},
2331 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968
, 0x30, LED_REVERSE
)},
2332 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650
, 0x30,
2333 (FLIP_DETECT
| HAS_NO_BUTTON
))},
2334 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650
, 0x30, 0)},
2335 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650
, 0x30, 0)},
2336 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670
, 0x21, 0)},
2337 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB
, 0x00, 0)},
2338 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660
, 0x21, FLIP_DETECT
)},
2339 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R
, 0x11, 0)},
2340 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650
, 0x30, 0)},
2341 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001
, 0x5d, 0)},
2342 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111
, 0x5d, 0)},
2343 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655
, 0x30, 0)},
2344 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112
, 0x5d, 0)},
2345 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968
, 0x30, 0)},
2346 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650
, 0x30, 0)},
2347 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670
, 0x21, 0)},
2348 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB
, 0x00, 0)},
2349 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655
, 0x30, LED_REVERSE
)},
2350 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660
, 0x21, LED_REVERSE
)},
2351 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R
, 0x11, 0)},
2352 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650
, 0x30, 0)},
2353 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660
, 0x21, 0)},
2354 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R
, 0x11, 0)},
2355 {USB_DEVICE(0x0458, 0x7045), SN9C20X(MT9M112
, 0x5d, LED_REVERSE
)},
2356 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112
, 0x5d, 0)},
2357 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112
, 0x5d, 0)},
2358 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R
, 0x11, 0)},
2359 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R
, 0x11, 0)},
2360 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R
, 0x11, 0)},
2361 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R
, 0x11, 0)},
2362 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111
, 0x5d, 0)},
2363 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111
, 0x5d, 0)},
2364 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111
, 0x5d, 0)},
2367 MODULE_DEVICE_TABLE(usb
, device_table
);
2369 /* -- device connect -- */
2370 static int sd_probe(struct usb_interface
*intf
,
2371 const struct usb_device_id
*id
)
2373 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
2377 static struct usb_driver sd_driver
= {
2378 .name
= KBUILD_MODNAME
,
2379 .id_table
= device_table
,
2381 .disconnect
= gspca_disconnect
,
2383 .suspend
= gspca_suspend
,
2384 .resume
= gspca_resume
,
2385 .reset_resume
= gspca_resume
,
2389 module_usb_driver(sd_driver
);