2 * Sonix sn9c201 sn9c202 library
4 * Copyright (C) 2012 Jean-Francois Moine <http://moinejf.free.fr>
5 * Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com>
6 * Copyright (C) 2009 Brian Johnson <brijohn@gmail.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25 #include <linux/input.h>
30 #include <linux/dmi.h>
32 MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, microdia project <microdia@googlegroups.com>");
33 MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
34 MODULE_LICENSE("GPL");
37 * Pixel format private data
39 #define SCALE_MASK 0x0f
40 #define SCALE_160x120 0
41 #define SCALE_320x240 1
42 #define SCALE_640x480 2
43 #define SCALE_1280x1024 3
45 #define MODE_JPEG 0x20
46 #define MODE_SXGA 0x80
48 #define SENSOR_OV9650 0
49 #define SENSOR_OV9655 1
50 #define SENSOR_SOI968 2
51 #define SENSOR_OV7660 3
52 #define SENSOR_OV7670 4
53 #define SENSOR_MT9V011 5
54 #define SENSOR_MT9V111 6
55 #define SENSOR_MT9V112 7
56 #define SENSOR_MT9M001 8
57 #define SENSOR_MT9M111 9
58 #define SENSOR_MT9M112 10
59 #define SENSOR_HV7131R 11
60 #define SENSOR_MT9VPRB 12
63 #define HAS_NO_BUTTON 0x1
64 #define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
65 #define FLIP_DETECT 0x4
67 /* specific webcam descriptor */
69 struct gspca_dev gspca_dev
;
71 struct { /* color control cluster */
72 struct v4l2_ctrl
*brightness
;
73 struct v4l2_ctrl
*contrast
;
74 struct v4l2_ctrl
*saturation
;
75 struct v4l2_ctrl
*hue
;
77 struct { /* blue/red balance control cluster */
78 struct v4l2_ctrl
*blue
;
79 struct v4l2_ctrl
*red
;
81 struct { /* h/vflip control cluster */
82 struct v4l2_ctrl
*hflip
;
83 struct v4l2_ctrl
*vflip
;
85 struct v4l2_ctrl
*gamma
;
86 struct { /* autogain and exposure or gain control cluster */
87 struct v4l2_ctrl
*autogain
;
88 struct v4l2_ctrl
*exposure
;
89 struct v4l2_ctrl
*gain
;
91 struct v4l2_ctrl
*jpegqual
;
93 struct work_struct work
;
95 u32 pktsz
; /* (used by pkt_scan) */
98 u8 fmt
; /* (used for JPEG QTAB update */
100 #define MIN_AVG_LUM 80
101 #define MAX_AVG_LUM 130
113 u8 jpeg_hdr
[JPEG_HDR_SZ
];
118 static void qual_upd(struct work_struct
*work
);
130 static const struct dmi_system_id flip_dmi_table
[] = {
132 .ident
= "MSI MS-1034",
134 DMI_MATCH(DMI_SYS_VENDOR
, "MICRO-STAR INT'L CO.,LTD."),
135 DMI_MATCH(DMI_PRODUCT_NAME
, "MS-1034"),
136 DMI_MATCH(DMI_PRODUCT_VERSION
, "0341")
140 .ident
= "MSI MS-1632",
142 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
143 DMI_MATCH(DMI_BOARD_NAME
, "MS-1632")
147 .ident
= "MSI MS-1633X",
149 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
150 DMI_MATCH(DMI_BOARD_NAME
, "MS-1633X")
154 .ident
= "MSI MS-1635X",
156 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
157 DMI_MATCH(DMI_BOARD_NAME
, "MS-1635X")
161 .ident
= "ASUSTeK W7J",
163 DMI_MATCH(DMI_BOARD_VENDOR
, "ASUSTeK Computer Inc."),
164 DMI_MATCH(DMI_BOARD_NAME
, "W7J ")
170 static const struct v4l2_pix_format vga_mode
[] = {
171 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
173 .sizeimage
= 160 * 120 * 4 / 8 + 590,
174 .colorspace
= V4L2_COLORSPACE_JPEG
,
175 .priv
= SCALE_160x120
| MODE_JPEG
},
176 {160, 120, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
178 .sizeimage
= 160 * 120,
179 .colorspace
= V4L2_COLORSPACE_SRGB
,
180 .priv
= SCALE_160x120
| MODE_RAW
},
181 {160, 120, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
183 .sizeimage
= 240 * 120,
184 .colorspace
= V4L2_COLORSPACE_SRGB
,
185 .priv
= SCALE_160x120
},
186 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
188 .sizeimage
= 320 * 240 * 4 / 8 + 590,
189 .colorspace
= V4L2_COLORSPACE_JPEG
,
190 .priv
= SCALE_320x240
| MODE_JPEG
},
191 {320, 240, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
193 .sizeimage
= 320 * 240 ,
194 .colorspace
= V4L2_COLORSPACE_SRGB
,
195 .priv
= SCALE_320x240
| MODE_RAW
},
196 {320, 240, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
198 .sizeimage
= 480 * 240 ,
199 .colorspace
= V4L2_COLORSPACE_SRGB
,
200 .priv
= SCALE_320x240
},
201 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
203 .sizeimage
= 640 * 480 * 4 / 8 + 590,
204 .colorspace
= V4L2_COLORSPACE_JPEG
,
205 .priv
= SCALE_640x480
| MODE_JPEG
},
206 {640, 480, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
208 .sizeimage
= 640 * 480,
209 .colorspace
= V4L2_COLORSPACE_SRGB
,
210 .priv
= SCALE_640x480
| MODE_RAW
},
211 {640, 480, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
213 .sizeimage
= 960 * 480,
214 .colorspace
= V4L2_COLORSPACE_SRGB
,
215 .priv
= SCALE_640x480
},
218 static const struct v4l2_pix_format sxga_mode
[] = {
219 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
221 .sizeimage
= 160 * 120 * 4 / 8 + 590,
222 .colorspace
= V4L2_COLORSPACE_JPEG
,
223 .priv
= SCALE_160x120
| MODE_JPEG
},
224 {160, 120, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
226 .sizeimage
= 160 * 120,
227 .colorspace
= V4L2_COLORSPACE_SRGB
,
228 .priv
= SCALE_160x120
| MODE_RAW
},
229 {160, 120, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
231 .sizeimage
= 240 * 120,
232 .colorspace
= V4L2_COLORSPACE_SRGB
,
233 .priv
= SCALE_160x120
},
234 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
236 .sizeimage
= 320 * 240 * 4 / 8 + 590,
237 .colorspace
= V4L2_COLORSPACE_JPEG
,
238 .priv
= SCALE_320x240
| MODE_JPEG
},
239 {320, 240, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
241 .sizeimage
= 320 * 240 ,
242 .colorspace
= V4L2_COLORSPACE_SRGB
,
243 .priv
= SCALE_320x240
| MODE_RAW
},
244 {320, 240, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
246 .sizeimage
= 480 * 240 ,
247 .colorspace
= V4L2_COLORSPACE_SRGB
,
248 .priv
= SCALE_320x240
},
249 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
251 .sizeimage
= 640 * 480 * 4 / 8 + 590,
252 .colorspace
= V4L2_COLORSPACE_JPEG
,
253 .priv
= SCALE_640x480
| MODE_JPEG
},
254 {640, 480, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
256 .sizeimage
= 640 * 480,
257 .colorspace
= V4L2_COLORSPACE_SRGB
,
258 .priv
= SCALE_640x480
| MODE_RAW
},
259 {640, 480, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
261 .sizeimage
= 960 * 480,
262 .colorspace
= V4L2_COLORSPACE_SRGB
,
263 .priv
= SCALE_640x480
},
264 {1280, 1024, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
265 .bytesperline
= 1280,
266 .sizeimage
= 1280 * 1024,
267 .colorspace
= V4L2_COLORSPACE_SRGB
,
268 .priv
= SCALE_1280x1024
| MODE_RAW
| MODE_SXGA
},
271 static const struct v4l2_pix_format mono_mode
[] = {
272 {160, 120, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
274 .sizeimage
= 160 * 120,
275 .colorspace
= V4L2_COLORSPACE_SRGB
,
276 .priv
= SCALE_160x120
| MODE_RAW
},
277 {320, 240, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
279 .sizeimage
= 320 * 240 ,
280 .colorspace
= V4L2_COLORSPACE_SRGB
,
281 .priv
= SCALE_320x240
| MODE_RAW
},
282 {640, 480, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
284 .sizeimage
= 640 * 480,
285 .colorspace
= V4L2_COLORSPACE_SRGB
,
286 .priv
= SCALE_640x480
| MODE_RAW
},
287 {1280, 1024, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
288 .bytesperline
= 1280,
289 .sizeimage
= 1280 * 1024,
290 .colorspace
= V4L2_COLORSPACE_SRGB
,
291 .priv
= SCALE_1280x1024
| MODE_RAW
| MODE_SXGA
},
294 static const s16 hsv_red_x
[] = {
295 41, 44, 46, 48, 50, 52, 54, 56,
296 58, 60, 62, 64, 66, 68, 70, 72,
297 74, 76, 78, 80, 81, 83, 85, 87,
298 88, 90, 92, 93, 95, 97, 98, 100,
299 101, 102, 104, 105, 107, 108, 109, 110,
300 112, 113, 114, 115, 116, 117, 118, 119,
301 120, 121, 122, 123, 123, 124, 125, 125,
302 126, 127, 127, 128, 128, 129, 129, 129,
303 130, 130, 130, 130, 131, 131, 131, 131,
304 131, 131, 131, 131, 130, 130, 130, 130,
305 129, 129, 129, 128, 128, 127, 127, 126,
306 125, 125, 124, 123, 122, 122, 121, 120,
307 119, 118, 117, 116, 115, 114, 112, 111,
308 110, 109, 107, 106, 105, 103, 102, 101,
309 99, 98, 96, 94, 93, 91, 90, 88,
310 86, 84, 83, 81, 79, 77, 75, 74,
311 72, 70, 68, 66, 64, 62, 60, 58,
312 56, 54, 52, 49, 47, 45, 43, 41,
313 39, 36, 34, 32, 30, 28, 25, 23,
314 21, 19, 16, 14, 12, 9, 7, 5,
315 3, 0, -1, -3, -6, -8, -10, -12,
316 -15, -17, -19, -22, -24, -26, -28, -30,
317 -33, -35, -37, -39, -41, -44, -46, -48,
318 -50, -52, -54, -56, -58, -60, -62, -64,
319 -66, -68, -70, -72, -74, -76, -78, -80,
320 -81, -83, -85, -87, -88, -90, -92, -93,
321 -95, -97, -98, -100, -101, -102, -104, -105,
322 -107, -108, -109, -110, -112, -113, -114, -115,
323 -116, -117, -118, -119, -120, -121, -122, -123,
324 -123, -124, -125, -125, -126, -127, -127, -128,
325 -128, -128, -128, -128, -128, -128, -128, -128,
326 -128, -128, -128, -128, -128, -128, -128, -128,
327 -128, -128, -128, -128, -128, -128, -128, -128,
328 -128, -127, -127, -126, -125, -125, -124, -123,
329 -122, -122, -121, -120, -119, -118, -117, -116,
330 -115, -114, -112, -111, -110, -109, -107, -106,
331 -105, -103, -102, -101, -99, -98, -96, -94,
332 -93, -91, -90, -88, -86, -84, -83, -81,
333 -79, -77, -75, -74, -72, -70, -68, -66,
334 -64, -62, -60, -58, -56, -54, -52, -49,
335 -47, -45, -43, -41, -39, -36, -34, -32,
336 -30, -28, -25, -23, -21, -19, -16, -14,
337 -12, -9, -7, -5, -3, 0, 1, 3,
338 6, 8, 10, 12, 15, 17, 19, 22,
339 24, 26, 28, 30, 33, 35, 37, 39, 41
342 static const s16 hsv_red_y
[] = {
343 82, 80, 78, 76, 74, 73, 71, 69,
344 67, 65, 63, 61, 58, 56, 54, 52,
345 50, 48, 46, 44, 41, 39, 37, 35,
346 32, 30, 28, 26, 23, 21, 19, 16,
347 14, 12, 10, 7, 5, 3, 0, -1,
348 -3, -6, -8, -10, -13, -15, -17, -19,
349 -22, -24, -26, -29, -31, -33, -35, -38,
350 -40, -42, -44, -46, -48, -51, -53, -55,
351 -57, -59, -61, -63, -65, -67, -69, -71,
352 -73, -75, -77, -79, -81, -82, -84, -86,
353 -88, -89, -91, -93, -94, -96, -98, -99,
354 -101, -102, -104, -105, -106, -108, -109, -110,
355 -112, -113, -114, -115, -116, -117, -119, -120,
356 -120, -121, -122, -123, -124, -125, -126, -126,
357 -127, -128, -128, -128, -128, -128, -128, -128,
358 -128, -128, -128, -128, -128, -128, -128, -128,
359 -128, -128, -128, -128, -128, -128, -128, -128,
360 -128, -128, -128, -128, -128, -128, -128, -128,
361 -127, -127, -126, -125, -125, -124, -123, -122,
362 -121, -120, -119, -118, -117, -116, -115, -114,
363 -113, -111, -110, -109, -107, -106, -105, -103,
364 -102, -100, -99, -97, -96, -94, -92, -91,
365 -89, -87, -85, -84, -82, -80, -78, -76,
366 -74, -73, -71, -69, -67, -65, -63, -61,
367 -58, -56, -54, -52, -50, -48, -46, -44,
368 -41, -39, -37, -35, -32, -30, -28, -26,
369 -23, -21, -19, -16, -14, -12, -10, -7,
370 -5, -3, 0, 1, 3, 6, 8, 10,
371 13, 15, 17, 19, 22, 24, 26, 29,
372 31, 33, 35, 38, 40, 42, 44, 46,
373 48, 51, 53, 55, 57, 59, 61, 63,
374 65, 67, 69, 71, 73, 75, 77, 79,
375 81, 82, 84, 86, 88, 89, 91, 93,
376 94, 96, 98, 99, 101, 102, 104, 105,
377 106, 108, 109, 110, 112, 113, 114, 115,
378 116, 117, 119, 120, 120, 121, 122, 123,
379 124, 125, 126, 126, 127, 128, 128, 129,
380 129, 130, 130, 131, 131, 131, 131, 132,
381 132, 132, 132, 132, 132, 132, 132, 132,
382 132, 132, 132, 131, 131, 131, 130, 130,
383 130, 129, 129, 128, 127, 127, 126, 125,
384 125, 124, 123, 122, 121, 120, 119, 118,
385 117, 116, 115, 114, 113, 111, 110, 109,
386 107, 106, 105, 103, 102, 100, 99, 97,
387 96, 94, 92, 91, 89, 87, 85, 84, 82
390 static const s16 hsv_green_x
[] = {
391 -124, -124, -125, -125, -125, -125, -125, -125,
392 -125, -126, -126, -125, -125, -125, -125, -125,
393 -125, -124, -124, -124, -123, -123, -122, -122,
394 -121, -121, -120, -120, -119, -118, -117, -117,
395 -116, -115, -114, -113, -112, -111, -110, -109,
396 -108, -107, -105, -104, -103, -102, -100, -99,
397 -98, -96, -95, -93, -92, -91, -89, -87,
398 -86, -84, -83, -81, -79, -77, -76, -74,
399 -72, -70, -69, -67, -65, -63, -61, -59,
400 -57, -55, -53, -51, -49, -47, -45, -43,
401 -41, -39, -37, -35, -33, -30, -28, -26,
402 -24, -22, -20, -18, -15, -13, -11, -9,
403 -7, -4, -2, 0, 1, 3, 6, 8,
404 10, 12, 14, 17, 19, 21, 23, 25,
405 27, 29, 32, 34, 36, 38, 40, 42,
406 44, 46, 48, 50, 52, 54, 56, 58,
407 60, 62, 64, 66, 68, 70, 71, 73,
408 75, 77, 78, 80, 82, 83, 85, 87,
409 88, 90, 91, 93, 94, 96, 97, 98,
410 100, 101, 102, 104, 105, 106, 107, 108,
411 109, 111, 112, 113, 113, 114, 115, 116,
412 117, 118, 118, 119, 120, 120, 121, 122,
413 122, 123, 123, 124, 124, 124, 125, 125,
414 125, 125, 125, 125, 125, 126, 126, 125,
415 125, 125, 125, 125, 125, 124, 124, 124,
416 123, 123, 122, 122, 121, 121, 120, 120,
417 119, 118, 117, 117, 116, 115, 114, 113,
418 112, 111, 110, 109, 108, 107, 105, 104,
419 103, 102, 100, 99, 98, 96, 95, 93,
420 92, 91, 89, 87, 86, 84, 83, 81,
421 79, 77, 76, 74, 72, 70, 69, 67,
422 65, 63, 61, 59, 57, 55, 53, 51,
423 49, 47, 45, 43, 41, 39, 37, 35,
424 33, 30, 28, 26, 24, 22, 20, 18,
425 15, 13, 11, 9, 7, 4, 2, 0,
426 -1, -3, -6, -8, -10, -12, -14, -17,
427 -19, -21, -23, -25, -27, -29, -32, -34,
428 -36, -38, -40, -42, -44, -46, -48, -50,
429 -52, -54, -56, -58, -60, -62, -64, -66,
430 -68, -70, -71, -73, -75, -77, -78, -80,
431 -82, -83, -85, -87, -88, -90, -91, -93,
432 -94, -96, -97, -98, -100, -101, -102, -104,
433 -105, -106, -107, -108, -109, -111, -112, -113,
434 -113, -114, -115, -116, -117, -118, -118, -119,
435 -120, -120, -121, -122, -122, -123, -123, -124, -124
438 static const s16 hsv_green_y
[] = {
439 -100, -99, -98, -97, -95, -94, -93, -91,
440 -90, -89, -87, -86, -84, -83, -81, -80,
441 -78, -76, -75, -73, -71, -70, -68, -66,
442 -64, -63, -61, -59, -57, -55, -53, -51,
443 -49, -48, -46, -44, -42, -40, -38, -36,
444 -34, -32, -30, -27, -25, -23, -21, -19,
445 -17, -15, -13, -11, -9, -7, -4, -2,
446 0, 1, 3, 5, 7, 9, 11, 14,
447 16, 18, 20, 22, 24, 26, 28, 30,
448 32, 34, 36, 38, 40, 42, 44, 46,
449 48, 50, 52, 54, 56, 58, 59, 61,
450 63, 65, 67, 68, 70, 72, 74, 75,
451 77, 78, 80, 82, 83, 85, 86, 88,
452 89, 90, 92, 93, 95, 96, 97, 98,
453 100, 101, 102, 103, 104, 105, 106, 107,
454 108, 109, 110, 111, 112, 112, 113, 114,
455 115, 115, 116, 116, 117, 117, 118, 118,
456 119, 119, 119, 120, 120, 120, 120, 120,
457 121, 121, 121, 121, 121, 121, 120, 120,
458 120, 120, 120, 119, 119, 119, 118, 118,
459 117, 117, 116, 116, 115, 114, 114, 113,
460 112, 111, 111, 110, 109, 108, 107, 106,
461 105, 104, 103, 102, 100, 99, 98, 97,
462 95, 94, 93, 91, 90, 89, 87, 86,
463 84, 83, 81, 80, 78, 76, 75, 73,
464 71, 70, 68, 66, 64, 63, 61, 59,
465 57, 55, 53, 51, 49, 48, 46, 44,
466 42, 40, 38, 36, 34, 32, 30, 27,
467 25, 23, 21, 19, 17, 15, 13, 11,
468 9, 7, 4, 2, 0, -1, -3, -5,
469 -7, -9, -11, -14, -16, -18, -20, -22,
470 -24, -26, -28, -30, -32, -34, -36, -38,
471 -40, -42, -44, -46, -48, -50, -52, -54,
472 -56, -58, -59, -61, -63, -65, -67, -68,
473 -70, -72, -74, -75, -77, -78, -80, -82,
474 -83, -85, -86, -88, -89, -90, -92, -93,
475 -95, -96, -97, -98, -100, -101, -102, -103,
476 -104, -105, -106, -107, -108, -109, -110, -111,
477 -112, -112, -113, -114, -115, -115, -116, -116,
478 -117, -117, -118, -118, -119, -119, -119, -120,
479 -120, -120, -120, -120, -121, -121, -121, -121,
480 -121, -121, -120, -120, -120, -120, -120, -119,
481 -119, -119, -118, -118, -117, -117, -116, -116,
482 -115, -114, -114, -113, -112, -111, -111, -110,
483 -109, -108, -107, -106, -105, -104, -103, -102, -100
486 static const s16 hsv_blue_x
[] = {
487 112, 113, 114, 114, 115, 116, 117, 117,
488 118, 118, 119, 119, 120, 120, 120, 121,
489 121, 121, 122, 122, 122, 122, 122, 122,
490 122, 122, 122, 122, 122, 122, 121, 121,
491 121, 120, 120, 120, 119, 119, 118, 118,
492 117, 116, 116, 115, 114, 113, 113, 112,
493 111, 110, 109, 108, 107, 106, 105, 104,
494 103, 102, 100, 99, 98, 97, 95, 94,
495 93, 91, 90, 88, 87, 85, 84, 82,
496 80, 79, 77, 76, 74, 72, 70, 69,
497 67, 65, 63, 61, 60, 58, 56, 54,
498 52, 50, 48, 46, 44, 42, 40, 38,
499 36, 34, 32, 30, 28, 26, 24, 22,
500 19, 17, 15, 13, 11, 9, 7, 5,
501 2, 0, -1, -3, -5, -7, -9, -12,
502 -14, -16, -18, -20, -22, -24, -26, -28,
503 -31, -33, -35, -37, -39, -41, -43, -45,
504 -47, -49, -51, -53, -54, -56, -58, -60,
505 -62, -64, -66, -67, -69, -71, -73, -74,
506 -76, -78, -79, -81, -83, -84, -86, -87,
507 -89, -90, -92, -93, -94, -96, -97, -98,
508 -99, -101, -102, -103, -104, -105, -106, -107,
509 -108, -109, -110, -111, -112, -113, -114, -114,
510 -115, -116, -117, -117, -118, -118, -119, -119,
511 -120, -120, -120, -121, -121, -121, -122, -122,
512 -122, -122, -122, -122, -122, -122, -122, -122,
513 -122, -122, -121, -121, -121, -120, -120, -120,
514 -119, -119, -118, -118, -117, -116, -116, -115,
515 -114, -113, -113, -112, -111, -110, -109, -108,
516 -107, -106, -105, -104, -103, -102, -100, -99,
517 -98, -97, -95, -94, -93, -91, -90, -88,
518 -87, -85, -84, -82, -80, -79, -77, -76,
519 -74, -72, -70, -69, -67, -65, -63, -61,
520 -60, -58, -56, -54, -52, -50, -48, -46,
521 -44, -42, -40, -38, -36, -34, -32, -30,
522 -28, -26, -24, -22, -19, -17, -15, -13,
523 -11, -9, -7, -5, -2, 0, 1, 3,
524 5, 7, 9, 12, 14, 16, 18, 20,
525 22, 24, 26, 28, 31, 33, 35, 37,
526 39, 41, 43, 45, 47, 49, 51, 53,
527 54, 56, 58, 60, 62, 64, 66, 67,
528 69, 71, 73, 74, 76, 78, 79, 81,
529 83, 84, 86, 87, 89, 90, 92, 93,
530 94, 96, 97, 98, 99, 101, 102, 103,
531 104, 105, 106, 107, 108, 109, 110, 111, 112
534 static const s16 hsv_blue_y
[] = {
535 -11, -13, -15, -17, -19, -21, -23, -25,
536 -27, -29, -31, -33, -35, -37, -39, -41,
537 -43, -45, -46, -48, -50, -52, -54, -55,
538 -57, -59, -61, -62, -64, -66, -67, -69,
539 -71, -72, -74, -75, -77, -78, -80, -81,
540 -83, -84, -86, -87, -88, -90, -91, -92,
541 -93, -95, -96, -97, -98, -99, -100, -101,
542 -102, -103, -104, -105, -106, -106, -107, -108,
543 -109, -109, -110, -111, -111, -112, -112, -113,
544 -113, -114, -114, -114, -115, -115, -115, -115,
545 -116, -116, -116, -116, -116, -116, -116, -116,
546 -116, -115, -115, -115, -115, -114, -114, -114,
547 -113, -113, -112, -112, -111, -111, -110, -110,
548 -109, -108, -108, -107, -106, -105, -104, -103,
549 -102, -101, -100, -99, -98, -97, -96, -95,
550 -94, -93, -91, -90, -89, -88, -86, -85,
551 -84, -82, -81, -79, -78, -76, -75, -73,
552 -71, -70, -68, -67, -65, -63, -62, -60,
553 -58, -56, -55, -53, -51, -49, -47, -45,
554 -44, -42, -40, -38, -36, -34, -32, -30,
555 -28, -26, -24, -22, -20, -18, -16, -14,
556 -12, -10, -8, -6, -4, -2, 0, 1,
557 3, 5, 7, 9, 11, 13, 15, 17,
558 19, 21, 23, 25, 27, 29, 31, 33,
559 35, 37, 39, 41, 43, 45, 46, 48,
560 50, 52, 54, 55, 57, 59, 61, 62,
561 64, 66, 67, 69, 71, 72, 74, 75,
562 77, 78, 80, 81, 83, 84, 86, 87,
563 88, 90, 91, 92, 93, 95, 96, 97,
564 98, 99, 100, 101, 102, 103, 104, 105,
565 106, 106, 107, 108, 109, 109, 110, 111,
566 111, 112, 112, 113, 113, 114, 114, 114,
567 115, 115, 115, 115, 116, 116, 116, 116,
568 116, 116, 116, 116, 116, 115, 115, 115,
569 115, 114, 114, 114, 113, 113, 112, 112,
570 111, 111, 110, 110, 109, 108, 108, 107,
571 106, 105, 104, 103, 102, 101, 100, 99,
572 98, 97, 96, 95, 94, 93, 91, 90,
573 89, 88, 86, 85, 84, 82, 81, 79,
574 78, 76, 75, 73, 71, 70, 68, 67,
575 65, 63, 62, 60, 58, 56, 55, 53,
576 51, 49, 47, 45, 44, 42, 40, 38,
577 36, 34, 32, 30, 28, 26, 24, 22,
578 20, 18, 16, 14, 12, 10, 8, 6,
579 4, 2, 0, -1, -3, -5, -7, -9, -11
582 static const u16 bridge_init
[][2] = {
583 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
584 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
585 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
586 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
587 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
588 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
589 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
590 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
591 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
592 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
593 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
594 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
595 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
596 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
597 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
598 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
599 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
600 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
601 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
605 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
606 static const u8 ov_gain
[] = {
607 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
608 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
609 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
610 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
611 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
612 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
613 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
617 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
618 static const u16 micron1_gain
[] = {
619 /* 1x 1.25x 1.5x 1.75x */
620 0x0020, 0x0028, 0x0030, 0x0038,
621 /* 2x 2.25x 2.5x 2.75x */
622 0x00a0, 0x00a4, 0x00a8, 0x00ac,
623 /* 3x 3.25x 3.5x 3.75x */
624 0x00b0, 0x00b4, 0x00b8, 0x00bc,
625 /* 4x 4.25x 4.5x 4.75x */
626 0x00c0, 0x00c4, 0x00c8, 0x00cc,
627 /* 5x 5.25x 5.5x 5.75x */
628 0x00d0, 0x00d4, 0x00d8, 0x00dc,
629 /* 6x 6.25x 6.5x 6.75x */
630 0x00e0, 0x00e4, 0x00e8, 0x00ec,
631 /* 7x 7.25x 7.5x 7.75x */
632 0x00f0, 0x00f4, 0x00f8, 0x00fc,
637 /* mt9m001 sensor uses a different gain formula then other micron sensors */
638 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
639 static const u16 micron2_gain
[] = {
640 /* 1x 1.25x 1.5x 1.75x */
641 0x0008, 0x000a, 0x000c, 0x000e,
642 /* 2x 2.25x 2.5x 2.75x */
643 0x0010, 0x0012, 0x0014, 0x0016,
644 /* 3x 3.25x 3.5x 3.75x */
645 0x0018, 0x001a, 0x001c, 0x001e,
646 /* 4x 4.25x 4.5x 4.75x */
647 0x0020, 0x0051, 0x0052, 0x0053,
648 /* 5x 5.25x 5.5x 5.75x */
649 0x0054, 0x0055, 0x0056, 0x0057,
650 /* 6x 6.25x 6.5x 6.75x */
651 0x0058, 0x0059, 0x005a, 0x005b,
652 /* 7x 7.25x 7.5x 7.75x */
653 0x005c, 0x005d, 0x005e, 0x005f,
658 /* Gain = .5 + bit[7:0] / 16 */
659 static const u8 hv7131r_gain
[] = {
660 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
661 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
662 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
663 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
664 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
665 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
666 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
670 static const struct i2c_reg_u8 soi968_init
[] = {
671 {0x0c, 0x00}, {0x0f, 0x1f},
672 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
673 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
674 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
675 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
676 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
677 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
678 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
679 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
680 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
681 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
684 static const struct i2c_reg_u8 ov7660_init
[] = {
685 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
686 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
687 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
688 /* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using
689 0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
690 {0x17, 0x10}, {0x18, 0x61},
691 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
692 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0x00},
693 {0x2e, 0x00}, {0x01, 0x78}, {0x02, 0x50},
696 static const struct i2c_reg_u8 ov7670_init
[] = {
697 {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
698 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
699 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
700 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
701 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
702 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
703 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
704 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
705 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
706 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
707 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
708 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
709 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
710 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
711 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
712 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
713 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
714 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
715 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
716 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
717 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
718 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
719 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
720 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
721 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
722 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
723 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
724 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
725 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
726 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
727 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
728 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
729 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
730 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
731 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
732 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
733 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
734 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
735 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
736 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
737 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
738 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
739 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
740 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
741 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
742 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
743 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
744 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
745 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
746 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
747 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
748 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
749 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
753 static const struct i2c_reg_u8 ov9650_init
[] = {
754 {0x00, 0x00}, {0x01, 0x78},
755 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
756 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
757 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
758 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
759 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
760 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
761 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
762 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
763 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
764 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
765 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
766 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
767 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
768 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
769 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
770 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
771 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
772 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
773 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
774 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
775 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
776 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
777 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
778 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
779 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
780 {0xaa, 0x92}, {0xab, 0x0a},
783 static const struct i2c_reg_u8 ov9655_init
[] = {
784 {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
785 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
786 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
787 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
788 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
789 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
790 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
791 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
792 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
793 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
794 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
795 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
796 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
797 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
798 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
799 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
800 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
801 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
802 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
803 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
804 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
805 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
806 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
807 {0x04, 0x03}, {0x00, 0x13},
810 static const struct i2c_reg_u16 mt9v112_init
[] = {
811 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
812 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
813 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
814 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
815 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
816 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
817 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
818 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
819 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
820 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
821 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
822 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
823 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
824 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
825 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
826 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
829 static const struct i2c_reg_u16 mt9v111_init
[] = {
830 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
831 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
832 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
833 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
834 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
835 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
836 {0x0e, 0x0008}, {0x20, 0x0000}
839 static const struct i2c_reg_u16 mt9v011_init
[] = {
840 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
841 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
842 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
843 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
844 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
845 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
846 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
847 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
848 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
849 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
850 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
851 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
852 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
853 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
854 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
855 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
856 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
857 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
858 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
859 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
860 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
861 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
862 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
863 {0x06, 0x0029}, {0x05, 0x0009},
866 static const struct i2c_reg_u16 mt9m001_init
[] = {
869 {0x04, 0x0500}, /* hres = 1280 */
870 {0x03, 0x0400}, /* vres = 1024 */
882 static const struct i2c_reg_u16 mt9m111_init
[] = {
883 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
884 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
885 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
889 static const struct i2c_reg_u16 mt9m112_init
[] = {
890 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
891 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
892 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
896 static const struct i2c_reg_u8 hv7131r_init
[] = {
897 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
898 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
899 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
900 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
901 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
902 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
903 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
904 {0x23, 0x09}, {0x01, 0x08},
907 static void reg_r(struct gspca_dev
*gspca_dev
, u16 reg
, u16 length
)
909 struct usb_device
*dev
= gspca_dev
->dev
;
912 if (gspca_dev
->usb_err
< 0)
914 result
= usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
916 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
922 if (unlikely(result
< 0 || result
!= length
)) {
923 pr_err("Read register %02x failed %d\n", reg
, result
);
924 gspca_dev
->usb_err
= result
;
928 static void reg_w(struct gspca_dev
*gspca_dev
, u16 reg
,
929 const u8
*buffer
, int length
)
931 struct usb_device
*dev
= gspca_dev
->dev
;
934 if (gspca_dev
->usb_err
< 0)
936 memcpy(gspca_dev
->usb_buf
, buffer
, length
);
937 result
= usb_control_msg(dev
, usb_sndctrlpipe(dev
, 0),
939 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
945 if (unlikely(result
< 0 || result
!= length
)) {
946 pr_err("Write register %02x failed %d\n", reg
, result
);
947 gspca_dev
->usb_err
= result
;
951 static void reg_w1(struct gspca_dev
*gspca_dev
, u16 reg
, const u8 value
)
953 reg_w(gspca_dev
, reg
, &value
, 1);
956 static void i2c_w(struct gspca_dev
*gspca_dev
, const u8
*buffer
)
960 reg_w(gspca_dev
, 0x10c0, buffer
, 8);
961 for (i
= 0; i
< 5; i
++) {
962 reg_r(gspca_dev
, 0x10c0, 1);
963 if (gspca_dev
->usb_err
< 0)
965 if (gspca_dev
->usb_buf
[0] & 0x04) {
966 if (gspca_dev
->usb_buf
[0] & 0x08) {
967 pr_err("i2c_w error\n");
968 gspca_dev
->usb_err
= -EIO
;
974 pr_err("i2c_w reg %02x no response\n", buffer
[2]);
975 /* gspca_dev->usb_err = -EIO; fixme: may occur */
978 static void i2c_w1(struct gspca_dev
*gspca_dev
, u8 reg
, u8 val
)
980 struct sd
*sd
= (struct sd
*) gspca_dev
;
984 * from the point of view of the bridge, the length
985 * includes the address
987 row
[0] = sd
->i2c_intf
| (2 << 4);
988 row
[1] = sd
->i2c_addr
;
996 i2c_w(gspca_dev
, row
);
999 static void i2c_w1_buf(struct gspca_dev
*gspca_dev
,
1000 const struct i2c_reg_u8
*buf
, int sz
)
1003 i2c_w1(gspca_dev
, buf
->reg
, buf
->val
);
1008 static void i2c_w2(struct gspca_dev
*gspca_dev
, u8 reg
, u16 val
)
1010 struct sd
*sd
= (struct sd
*) gspca_dev
;
1014 * from the point of view of the bridge, the length
1015 * includes the address
1017 row
[0] = sd
->i2c_intf
| (3 << 4);
1018 row
[1] = sd
->i2c_addr
;
1026 i2c_w(gspca_dev
, row
);
1029 static void i2c_w2_buf(struct gspca_dev
*gspca_dev
,
1030 const struct i2c_reg_u16
*buf
, int sz
)
1033 i2c_w2(gspca_dev
, buf
->reg
, buf
->val
);
1038 static void i2c_r1(struct gspca_dev
*gspca_dev
, u8 reg
, u8
*val
)
1040 struct sd
*sd
= (struct sd
*) gspca_dev
;
1043 row
[0] = sd
->i2c_intf
| (1 << 4);
1044 row
[1] = sd
->i2c_addr
;
1051 i2c_w(gspca_dev
, row
);
1052 row
[0] = sd
->i2c_intf
| (1 << 4) | 0x02;
1054 i2c_w(gspca_dev
, row
);
1055 reg_r(gspca_dev
, 0x10c2, 5);
1056 *val
= gspca_dev
->usb_buf
[4];
1059 static void i2c_r2(struct gspca_dev
*gspca_dev
, u8 reg
, u16
*val
)
1061 struct sd
*sd
= (struct sd
*) gspca_dev
;
1064 row
[0] = sd
->i2c_intf
| (1 << 4);
1065 row
[1] = sd
->i2c_addr
;
1072 i2c_w(gspca_dev
, row
);
1073 row
[0] = sd
->i2c_intf
| (2 << 4) | 0x02;
1075 i2c_w(gspca_dev
, row
);
1076 reg_r(gspca_dev
, 0x10c2, 5);
1077 *val
= (gspca_dev
->usb_buf
[3] << 8) | gspca_dev
->usb_buf
[4];
1080 static void ov9650_init_sensor(struct gspca_dev
*gspca_dev
)
1083 struct sd
*sd
= (struct sd
*) gspca_dev
;
1085 i2c_r2(gspca_dev
, 0x1c, &id
);
1086 if (gspca_dev
->usb_err
< 0)
1090 pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id
);
1091 gspca_dev
->usb_err
= -ENODEV
;
1095 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1097 i2c_w1_buf(gspca_dev
, ov9650_init
, ARRAY_SIZE(ov9650_init
));
1098 if (gspca_dev
->usb_err
< 0)
1099 pr_err("OV9650 sensor initialization failed\n");
1104 static void ov9655_init_sensor(struct gspca_dev
*gspca_dev
)
1106 struct sd
*sd
= (struct sd
*) gspca_dev
;
1108 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1110 i2c_w1_buf(gspca_dev
, ov9655_init
, ARRAY_SIZE(ov9655_init
));
1111 if (gspca_dev
->usb_err
< 0)
1112 pr_err("OV9655 sensor initialization failed\n");
1118 static void soi968_init_sensor(struct gspca_dev
*gspca_dev
)
1120 struct sd
*sd
= (struct sd
*) gspca_dev
;
1122 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1124 i2c_w1_buf(gspca_dev
, soi968_init
, ARRAY_SIZE(soi968_init
));
1125 if (gspca_dev
->usb_err
< 0)
1126 pr_err("SOI968 sensor initialization failed\n");
1132 static void ov7660_init_sensor(struct gspca_dev
*gspca_dev
)
1134 struct sd
*sd
= (struct sd
*) gspca_dev
;
1136 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1138 i2c_w1_buf(gspca_dev
, ov7660_init
, ARRAY_SIZE(ov7660_init
));
1139 if (gspca_dev
->usb_err
< 0)
1140 pr_err("OV7660 sensor initialization failed\n");
1145 static void ov7670_init_sensor(struct gspca_dev
*gspca_dev
)
1147 struct sd
*sd
= (struct sd
*) gspca_dev
;
1149 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1151 i2c_w1_buf(gspca_dev
, ov7670_init
, ARRAY_SIZE(ov7670_init
));
1152 if (gspca_dev
->usb_err
< 0)
1153 pr_err("OV7670 sensor initialization failed\n");
1159 static void mt9v_init_sensor(struct gspca_dev
*gspca_dev
)
1161 struct sd
*sd
= (struct sd
*) gspca_dev
;
1164 sd
->i2c_addr
= 0x5d;
1165 i2c_r2(gspca_dev
, 0xff, &value
);
1166 if (gspca_dev
->usb_err
>= 0
1167 && value
== 0x8243) {
1168 i2c_w2_buf(gspca_dev
, mt9v011_init
, ARRAY_SIZE(mt9v011_init
));
1169 if (gspca_dev
->usb_err
< 0) {
1170 pr_err("MT9V011 sensor initialization failed\n");
1175 sd
->sensor
= SENSOR_MT9V011
;
1176 pr_info("MT9V011 sensor detected\n");
1180 gspca_dev
->usb_err
= 0;
1181 sd
->i2c_addr
= 0x5c;
1182 i2c_w2(gspca_dev
, 0x01, 0x0004);
1183 i2c_r2(gspca_dev
, 0xff, &value
);
1184 if (gspca_dev
->usb_err
>= 0
1185 && value
== 0x823a) {
1186 i2c_w2_buf(gspca_dev
, mt9v111_init
, ARRAY_SIZE(mt9v111_init
));
1187 if (gspca_dev
->usb_err
< 0) {
1188 pr_err("MT9V111 sensor initialization failed\n");
1193 sd
->sensor
= SENSOR_MT9V111
;
1194 pr_info("MT9V111 sensor detected\n");
1198 gspca_dev
->usb_err
= 0;
1199 sd
->i2c_addr
= 0x5d;
1200 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1201 if (gspca_dev
->usb_err
< 0) {
1202 gspca_dev
->usb_err
= 0;
1203 sd
->i2c_addr
= 0x48;
1204 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1206 i2c_r2(gspca_dev
, 0x00, &value
);
1207 if (gspca_dev
->usb_err
>= 0
1208 && value
== 0x1229) {
1209 i2c_w2_buf(gspca_dev
, mt9v112_init
, ARRAY_SIZE(mt9v112_init
));
1210 if (gspca_dev
->usb_err
< 0) {
1211 pr_err("MT9V112 sensor initialization failed\n");
1216 sd
->sensor
= SENSOR_MT9V112
;
1217 pr_info("MT9V112 sensor detected\n");
1221 gspca_dev
->usb_err
= -ENODEV
;
1224 static void mt9m112_init_sensor(struct gspca_dev
*gspca_dev
)
1226 struct sd
*sd
= (struct sd
*) gspca_dev
;
1228 i2c_w2_buf(gspca_dev
, mt9m112_init
, ARRAY_SIZE(mt9m112_init
));
1229 if (gspca_dev
->usb_err
< 0)
1230 pr_err("MT9M112 sensor initialization failed\n");
1236 static void mt9m111_init_sensor(struct gspca_dev
*gspca_dev
)
1238 struct sd
*sd
= (struct sd
*) gspca_dev
;
1240 i2c_w2_buf(gspca_dev
, mt9m111_init
, ARRAY_SIZE(mt9m111_init
));
1241 if (gspca_dev
->usb_err
< 0)
1242 pr_err("MT9M111 sensor initialization failed\n");
1248 static void mt9m001_init_sensor(struct gspca_dev
*gspca_dev
)
1250 struct sd
*sd
= (struct sd
*) gspca_dev
;
1253 i2c_r2(gspca_dev
, 0x00, &id
);
1254 if (gspca_dev
->usb_err
< 0)
1257 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
1261 pr_info("MT9M001 color sensor detected\n");
1264 pr_info("MT9M001 mono sensor detected\n");
1267 pr_err("No MT9M001 chip detected, ID = %x\n\n", id
);
1268 gspca_dev
->usb_err
= -ENODEV
;
1272 i2c_w2_buf(gspca_dev
, mt9m001_init
, ARRAY_SIZE(mt9m001_init
));
1273 if (gspca_dev
->usb_err
< 0)
1274 pr_err("MT9M001 sensor initialization failed\n");
1280 static void hv7131r_init_sensor(struct gspca_dev
*gspca_dev
)
1282 struct sd
*sd
= (struct sd
*) gspca_dev
;
1284 i2c_w1_buf(gspca_dev
, hv7131r_init
, ARRAY_SIZE(hv7131r_init
));
1285 if (gspca_dev
->usb_err
< 0)
1286 pr_err("HV7131R Sensor initialization failed\n");
1292 static void set_cmatrix(struct gspca_dev
*gspca_dev
,
1293 s32 brightness
, s32 contrast
, s32 satur
, s32 hue
)
1295 s32 hue_coord
, hue_index
= 180 + hue
;
1298 memset(cmatrix
, 0, sizeof(cmatrix
));
1299 cmatrix
[2] = (contrast
* 0x25 / 0x100) + 0x26;
1300 cmatrix
[0] = 0x13 + (cmatrix
[2] - 0x26) * 0x13 / 0x25;
1301 cmatrix
[4] = 0x07 + (cmatrix
[2] - 0x26) * 0x07 / 0x25;
1302 cmatrix
[18] = brightness
- 0x80;
1304 hue_coord
= (hsv_red_x
[hue_index
] * satur
) >> 8;
1305 cmatrix
[6] = hue_coord
;
1306 cmatrix
[7] = (hue_coord
>> 8) & 0x0f;
1308 hue_coord
= (hsv_red_y
[hue_index
] * satur
) >> 8;
1309 cmatrix
[8] = hue_coord
;
1310 cmatrix
[9] = (hue_coord
>> 8) & 0x0f;
1312 hue_coord
= (hsv_green_x
[hue_index
] * satur
) >> 8;
1313 cmatrix
[10] = hue_coord
;
1314 cmatrix
[11] = (hue_coord
>> 8) & 0x0f;
1316 hue_coord
= (hsv_green_y
[hue_index
] * satur
) >> 8;
1317 cmatrix
[12] = hue_coord
;
1318 cmatrix
[13] = (hue_coord
>> 8) & 0x0f;
1320 hue_coord
= (hsv_blue_x
[hue_index
] * satur
) >> 8;
1321 cmatrix
[14] = hue_coord
;
1322 cmatrix
[15] = (hue_coord
>> 8) & 0x0f;
1324 hue_coord
= (hsv_blue_y
[hue_index
] * satur
) >> 8;
1325 cmatrix
[16] = hue_coord
;
1326 cmatrix
[17] = (hue_coord
>> 8) & 0x0f;
1328 reg_w(gspca_dev
, 0x10e1, cmatrix
, 21);
1331 static void set_gamma(struct gspca_dev
*gspca_dev
, s32 val
)
1334 u8 gval
= val
* 0xb8 / 0x100;
1337 gamma
[1] = 0x13 + (gval
* (0xcb - 0x13) / 0xb8);
1338 gamma
[2] = 0x25 + (gval
* (0xee - 0x25) / 0xb8);
1339 gamma
[3] = 0x37 + (gval
* (0xfa - 0x37) / 0xb8);
1340 gamma
[4] = 0x45 + (gval
* (0xfc - 0x45) / 0xb8);
1341 gamma
[5] = 0x55 + (gval
* (0xfb - 0x55) / 0xb8);
1342 gamma
[6] = 0x65 + (gval
* (0xfc - 0x65) / 0xb8);
1343 gamma
[7] = 0x74 + (gval
* (0xfd - 0x74) / 0xb8);
1344 gamma
[8] = 0x83 + (gval
* (0xfe - 0x83) / 0xb8);
1345 gamma
[9] = 0x92 + (gval
* (0xfc - 0x92) / 0xb8);
1346 gamma
[10] = 0xa1 + (gval
* (0xfc - 0xa1) / 0xb8);
1347 gamma
[11] = 0xb0 + (gval
* (0xfc - 0xb0) / 0xb8);
1348 gamma
[12] = 0xbf + (gval
* (0xfb - 0xbf) / 0xb8);
1349 gamma
[13] = 0xce + (gval
* (0xfb - 0xce) / 0xb8);
1350 gamma
[14] = 0xdf + (gval
* (0xfd - 0xdf) / 0xb8);
1351 gamma
[15] = 0xea + (gval
* (0xf9 - 0xea) / 0xb8);
1354 reg_w(gspca_dev
, 0x1190, gamma
, 17);
1357 static void set_redblue(struct gspca_dev
*gspca_dev
, s32 blue
, s32 red
)
1359 reg_w1(gspca_dev
, 0x118c, red
);
1360 reg_w1(gspca_dev
, 0x118f, blue
);
1363 static void set_hvflip(struct gspca_dev
*gspca_dev
, s32 hflip
, s32 vflip
)
1367 struct sd
*sd
= (struct sd
*) gspca_dev
;
1369 if ((sd
->flags
& FLIP_DETECT
) && dmi_check_system(flip_dmi_table
)) {
1374 switch (sd
->sensor
) {
1385 reg_w1(gspca_dev
, 0x1182, sd
->vstart
);
1386 i2c_w1(gspca_dev
, 0x1e, value
);
1389 i2c_r1(gspca_dev
, 0x1e, &value
);
1398 i2c_w1(gspca_dev
, 0x1e, value
);
1399 i2c_w1(gspca_dev
, 0x3a, tslb
);
1401 case SENSOR_MT9V111
:
1402 case SENSOR_MT9V011
:
1403 i2c_r2(gspca_dev
, 0x20, &value2
);
1409 i2c_w2(gspca_dev
, 0x20, value2
);
1411 case SENSOR_MT9M112
:
1412 case SENSOR_MT9M111
:
1413 case SENSOR_MT9V112
:
1414 i2c_r2(gspca_dev
, 0x20, &value2
);
1420 i2c_w2(gspca_dev
, 0x20, value2
);
1422 case SENSOR_HV7131R
:
1423 i2c_r1(gspca_dev
, 0x01, &value
);
1429 i2c_w1(gspca_dev
, 0x01, value
);
1434 static void set_exposure(struct gspca_dev
*gspca_dev
, s32 expo
)
1436 struct sd
*sd
= (struct sd
*) gspca_dev
;
1437 u8 exp
[8] = {sd
->i2c_intf
, sd
->i2c_addr
,
1438 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1441 if (gspca_dev
->streaming
)
1444 switch (sd
->sensor
) {
1454 exp
[2] = 0x10; /* AECH */
1455 exp
[3] = expo2
>> 2;
1457 i2c_w(gspca_dev
, exp
);
1458 exp
[2] = 0x04; /* COM1 */
1459 exp
[3] = expo2
& 0x0003;
1461 i2c_w(gspca_dev
, exp
);
1465 exp
[2] = 0x2d; /* ADVFL & ADVFH */
1469 case SENSOR_MT9M001
:
1470 case SENSOR_MT9V112
:
1471 case SENSOR_MT9V011
:
1477 case SENSOR_HV7131R
:
1487 i2c_w(gspca_dev
, exp
);
1490 static void set_gain(struct gspca_dev
*gspca_dev
, s32 g
)
1492 struct sd
*sd
= (struct sd
*) gspca_dev
;
1493 u8 gain
[8] = {sd
->i2c_intf
, sd
->i2c_addr
,
1494 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1496 if (gspca_dev
->streaming
)
1497 gain
[7] = 0x15; /* or 1d ? */
1499 switch (sd
->sensor
) {
1505 gain
[0] |= (2 << 4);
1506 gain
[3] = ov_gain
[g
];
1508 case SENSOR_MT9V011
:
1509 gain
[0] |= (3 << 4);
1511 gain
[3] = micron1_gain
[g
] >> 8;
1512 gain
[4] = micron1_gain
[g
];
1514 case SENSOR_MT9V112
:
1515 gain
[0] |= (3 << 4);
1517 gain
[3] = micron1_gain
[g
] >> 8;
1518 gain
[4] = micron1_gain
[g
];
1520 case SENSOR_MT9M001
:
1521 gain
[0] |= (3 << 4);
1523 gain
[3] = micron2_gain
[g
] >> 8;
1524 gain
[4] = micron2_gain
[g
];
1526 case SENSOR_HV7131R
:
1527 gain
[0] |= (2 << 4);
1529 gain
[3] = hv7131r_gain
[g
];
1534 i2c_w(gspca_dev
, gain
);
1537 static void set_quality(struct gspca_dev
*gspca_dev
, s32 val
)
1539 struct sd
*sd
= (struct sd
*) gspca_dev
;
1541 jpeg_set_qual(sd
->jpeg_hdr
, val
);
1542 reg_w1(gspca_dev
, 0x1061, 0x01); /* stop transfer */
1543 reg_w1(gspca_dev
, 0x10e0, sd
->fmt
| 0x20); /* write QTAB */
1544 reg_w(gspca_dev
, 0x1100, &sd
->jpeg_hdr
[JPEG_QT0_OFFSET
], 64);
1545 reg_w(gspca_dev
, 0x1140, &sd
->jpeg_hdr
[JPEG_QT1_OFFSET
], 64);
1546 reg_w1(gspca_dev
, 0x1061, 0x03); /* restart transfer */
1547 reg_w1(gspca_dev
, 0x10e0, sd
->fmt
);
1548 sd
->fmt
^= 0x0c; /* invert QTAB use + write */
1549 reg_w1(gspca_dev
, 0x10e0, sd
->fmt
);
1552 #ifdef CONFIG_VIDEO_ADV_DEBUG
1553 static int sd_dbg_g_register(struct gspca_dev
*gspca_dev
,
1554 struct v4l2_dbg_register
*reg
)
1556 struct sd
*sd
= (struct sd
*) gspca_dev
;
1559 switch (reg
->match
.addr
) {
1561 if (reg
->reg
< 0x1000 || reg
->reg
> 0x11ff)
1563 reg_r(gspca_dev
, reg
->reg
, 1);
1564 reg
->val
= gspca_dev
->usb_buf
[0];
1565 return gspca_dev
->usb_err
;
1567 if (sd
->sensor
>= SENSOR_MT9V011
&&
1568 sd
->sensor
<= SENSOR_MT9M112
) {
1569 i2c_r2(gspca_dev
, reg
->reg
, (u16
*) ®
->val
);
1572 i2c_r1(gspca_dev
, reg
->reg
, (u8
*) ®
->val
);
1574 return gspca_dev
->usb_err
;
1579 static int sd_dbg_s_register(struct gspca_dev
*gspca_dev
,
1580 const struct v4l2_dbg_register
*reg
)
1582 struct sd
*sd
= (struct sd
*) gspca_dev
;
1584 switch (reg
->match
.addr
) {
1586 if (reg
->reg
< 0x1000 || reg
->reg
> 0x11ff)
1588 reg_w1(gspca_dev
, reg
->reg
, reg
->val
);
1589 return gspca_dev
->usb_err
;
1591 if (sd
->sensor
>= SENSOR_MT9V011
&&
1592 sd
->sensor
<= SENSOR_MT9M112
) {
1593 i2c_w2(gspca_dev
, reg
->reg
, reg
->val
);
1595 i2c_w1(gspca_dev
, reg
->reg
, reg
->val
);
1597 return gspca_dev
->usb_err
;
1602 static int sd_chip_info(struct gspca_dev
*gspca_dev
,
1603 struct v4l2_dbg_chip_info
*chip
)
1605 if (chip
->match
.addr
> 1)
1607 if (chip
->match
.addr
== 1)
1608 strlcpy(chip
->name
, "sensor", sizeof(chip
->name
));
1613 static int sd_config(struct gspca_dev
*gspca_dev
,
1614 const struct usb_device_id
*id
)
1616 struct sd
*sd
= (struct sd
*) gspca_dev
;
1619 cam
= &gspca_dev
->cam
;
1620 cam
->needs_full_bandwidth
= 1;
1622 sd
->sensor
= id
->driver_info
>> 8;
1623 sd
->i2c_addr
= id
->driver_info
;
1624 sd
->flags
= id
->driver_info
>> 16;
1625 sd
->i2c_intf
= 0x80; /* i2c 100 Kb/s */
1627 switch (sd
->sensor
) {
1628 case SENSOR_MT9M112
:
1629 case SENSOR_MT9M111
:
1632 cam
->cam_mode
= sxga_mode
;
1633 cam
->nmodes
= ARRAY_SIZE(sxga_mode
);
1635 case SENSOR_MT9M001
:
1636 cam
->cam_mode
= mono_mode
;
1637 cam
->nmodes
= ARRAY_SIZE(mono_mode
);
1639 case SENSOR_HV7131R
:
1640 sd
->i2c_intf
= 0x81; /* i2c 400 Kb/s */
1643 cam
->cam_mode
= vga_mode
;
1644 cam
->nmodes
= ARRAY_SIZE(vga_mode
);
1650 sd
->exposure_step
= 16;
1652 INIT_WORK(&sd
->work
, qual_upd
);
1657 static int sd_s_ctrl(struct v4l2_ctrl
*ctrl
)
1659 struct gspca_dev
*gspca_dev
=
1660 container_of(ctrl
->handler
, struct gspca_dev
, ctrl_handler
);
1661 struct sd
*sd
= (struct sd
*)gspca_dev
;
1663 gspca_dev
->usb_err
= 0;
1665 if (!gspca_dev
->streaming
)
1669 /* color control cluster */
1670 case V4L2_CID_BRIGHTNESS
:
1671 set_cmatrix(gspca_dev
, sd
->brightness
->val
,
1672 sd
->contrast
->val
, sd
->saturation
->val
, sd
->hue
->val
);
1674 case V4L2_CID_GAMMA
:
1675 set_gamma(gspca_dev
, ctrl
->val
);
1677 /* blue/red balance cluster */
1678 case V4L2_CID_BLUE_BALANCE
:
1679 set_redblue(gspca_dev
, sd
->blue
->val
, sd
->red
->val
);
1681 /* h/vflip cluster */
1682 case V4L2_CID_HFLIP
:
1683 set_hvflip(gspca_dev
, sd
->hflip
->val
, sd
->vflip
->val
);
1685 /* standalone exposure control */
1686 case V4L2_CID_EXPOSURE
:
1687 set_exposure(gspca_dev
, ctrl
->val
);
1689 /* standalone gain control */
1691 set_gain(gspca_dev
, ctrl
->val
);
1693 /* autogain + exposure or gain control cluster */
1694 case V4L2_CID_AUTOGAIN
:
1695 if (sd
->sensor
== SENSOR_SOI968
)
1696 set_gain(gspca_dev
, sd
->gain
->val
);
1698 set_exposure(gspca_dev
, sd
->exposure
->val
);
1700 case V4L2_CID_JPEG_COMPRESSION_QUALITY
:
1701 set_quality(gspca_dev
, ctrl
->val
);
1704 return gspca_dev
->usb_err
;
1707 static const struct v4l2_ctrl_ops sd_ctrl_ops
= {
1708 .s_ctrl
= sd_s_ctrl
,
1711 static int sd_init_controls(struct gspca_dev
*gspca_dev
)
1713 struct sd
*sd
= (struct sd
*) gspca_dev
;
1714 struct v4l2_ctrl_handler
*hdl
= &gspca_dev
->ctrl_handler
;
1716 gspca_dev
->vdev
.ctrl_handler
= hdl
;
1717 v4l2_ctrl_handler_init(hdl
, 13);
1719 sd
->brightness
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1720 V4L2_CID_BRIGHTNESS
, 0, 255, 1, 127);
1721 sd
->contrast
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1722 V4L2_CID_CONTRAST
, 0, 255, 1, 127);
1723 sd
->saturation
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1724 V4L2_CID_SATURATION
, 0, 255, 1, 127);
1725 sd
->hue
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1726 V4L2_CID_HUE
, -180, 180, 1, 0);
1728 sd
->gamma
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1729 V4L2_CID_GAMMA
, 0, 255, 1, 0x10);
1731 sd
->blue
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1732 V4L2_CID_BLUE_BALANCE
, 0, 127, 1, 0x28);
1733 sd
->red
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1734 V4L2_CID_RED_BALANCE
, 0, 127, 1, 0x28);
1736 if (sd
->sensor
!= SENSOR_OV9655
&& sd
->sensor
!= SENSOR_SOI968
&&
1737 sd
->sensor
!= SENSOR_OV7670
&& sd
->sensor
!= SENSOR_MT9M001
&&
1738 sd
->sensor
!= SENSOR_MT9VPRB
) {
1739 sd
->hflip
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1740 V4L2_CID_HFLIP
, 0, 1, 1, 0);
1741 sd
->vflip
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1742 V4L2_CID_VFLIP
, 0, 1, 1, 0);
1745 if (sd
->sensor
!= SENSOR_SOI968
&& sd
->sensor
!= SENSOR_MT9VPRB
&&
1746 sd
->sensor
!= SENSOR_MT9M112
&& sd
->sensor
!= SENSOR_MT9M111
&&
1747 sd
->sensor
!= SENSOR_MT9V111
)
1748 sd
->exposure
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1749 V4L2_CID_EXPOSURE
, 0, 0x1780, 1, 0x33);
1751 if (sd
->sensor
!= SENSOR_MT9VPRB
&& sd
->sensor
!= SENSOR_MT9M112
&&
1752 sd
->sensor
!= SENSOR_MT9M111
&& sd
->sensor
!= SENSOR_MT9V111
) {
1753 sd
->gain
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1754 V4L2_CID_GAIN
, 0, 28, 1, 0);
1755 sd
->autogain
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1756 V4L2_CID_AUTOGAIN
, 0, 1, 1, 1);
1759 sd
->jpegqual
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1760 V4L2_CID_JPEG_COMPRESSION_QUALITY
, 50, 90, 1, 80);
1762 pr_err("Could not initialize controls\n");
1766 v4l2_ctrl_cluster(4, &sd
->brightness
);
1767 v4l2_ctrl_cluster(2, &sd
->blue
);
1769 v4l2_ctrl_cluster(2, &sd
->hflip
);
1771 if (sd
->sensor
== SENSOR_SOI968
)
1772 /* this sensor doesn't have the exposure control and
1773 autogain is clustered with gain instead. This works
1774 because sd->exposure == NULL. */
1775 v4l2_ctrl_auto_cluster(3, &sd
->autogain
, 0, false);
1777 /* Otherwise autogain is clustered with exposure. */
1778 v4l2_ctrl_auto_cluster(2, &sd
->autogain
, 0, false);
1783 static int sd_init(struct gspca_dev
*gspca_dev
)
1785 struct sd
*sd
= (struct sd
*) gspca_dev
;
1789 0x80, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
1792 for (i
= 0; i
< ARRAY_SIZE(bridge_init
); i
++) {
1793 value
= bridge_init
[i
][1];
1794 reg_w(gspca_dev
, bridge_init
[i
][0], &value
, 1);
1795 if (gspca_dev
->usb_err
< 0) {
1796 pr_err("Device initialization failed\n");
1797 return gspca_dev
->usb_err
;
1801 if (sd
->flags
& LED_REVERSE
)
1802 reg_w1(gspca_dev
, 0x1006, 0x00);
1804 reg_w1(gspca_dev
, 0x1006, 0x20);
1806 reg_w(gspca_dev
, 0x10c0, i2c_init
, 9);
1807 if (gspca_dev
->usb_err
< 0) {
1808 pr_err("Device initialization failed\n");
1809 return gspca_dev
->usb_err
;
1812 switch (sd
->sensor
) {
1814 ov9650_init_sensor(gspca_dev
);
1815 if (gspca_dev
->usb_err
< 0)
1817 pr_info("OV9650 sensor detected\n");
1820 ov9655_init_sensor(gspca_dev
);
1821 if (gspca_dev
->usb_err
< 0)
1823 pr_info("OV9655 sensor detected\n");
1826 soi968_init_sensor(gspca_dev
);
1827 if (gspca_dev
->usb_err
< 0)
1829 pr_info("SOI968 sensor detected\n");
1832 ov7660_init_sensor(gspca_dev
);
1833 if (gspca_dev
->usb_err
< 0)
1835 pr_info("OV7660 sensor detected\n");
1838 ov7670_init_sensor(gspca_dev
);
1839 if (gspca_dev
->usb_err
< 0)
1841 pr_info("OV7670 sensor detected\n");
1843 case SENSOR_MT9VPRB
:
1844 mt9v_init_sensor(gspca_dev
);
1845 if (gspca_dev
->usb_err
< 0)
1847 pr_info("MT9VPRB sensor detected\n");
1849 case SENSOR_MT9M111
:
1850 mt9m111_init_sensor(gspca_dev
);
1851 if (gspca_dev
->usb_err
< 0)
1853 pr_info("MT9M111 sensor detected\n");
1855 case SENSOR_MT9M112
:
1856 mt9m112_init_sensor(gspca_dev
);
1857 if (gspca_dev
->usb_err
< 0)
1859 pr_info("MT9M112 sensor detected\n");
1861 case SENSOR_MT9M001
:
1862 mt9m001_init_sensor(gspca_dev
);
1863 if (gspca_dev
->usb_err
< 0)
1866 case SENSOR_HV7131R
:
1867 hv7131r_init_sensor(gspca_dev
);
1868 if (gspca_dev
->usb_err
< 0)
1870 pr_info("HV7131R sensor detected\n");
1873 pr_err("Unsupported sensor\n");
1874 gspca_dev
->usb_err
= -ENODEV
;
1876 return gspca_dev
->usb_err
;
1879 static void configure_sensor_output(struct gspca_dev
*gspca_dev
, int mode
)
1881 struct sd
*sd
= (struct sd
*) gspca_dev
;
1884 switch (sd
->sensor
) {
1886 if (mode
& MODE_SXGA
) {
1887 i2c_w1(gspca_dev
, 0x17, 0x1d);
1888 i2c_w1(gspca_dev
, 0x18, 0xbd);
1889 i2c_w1(gspca_dev
, 0x19, 0x01);
1890 i2c_w1(gspca_dev
, 0x1a, 0x81);
1891 i2c_w1(gspca_dev
, 0x12, 0x00);
1895 i2c_w1(gspca_dev
, 0x17, 0x13);
1896 i2c_w1(gspca_dev
, 0x18, 0x63);
1897 i2c_w1(gspca_dev
, 0x19, 0x01);
1898 i2c_w1(gspca_dev
, 0x1a, 0x79);
1899 i2c_w1(gspca_dev
, 0x12, 0x40);
1905 if (mode
& MODE_SXGA
) {
1906 i2c_w1(gspca_dev
, 0x17, 0x1b);
1907 i2c_w1(gspca_dev
, 0x18, 0xbc);
1908 i2c_w1(gspca_dev
, 0x19, 0x01);
1909 i2c_w1(gspca_dev
, 0x1a, 0x82);
1910 i2c_r1(gspca_dev
, 0x12, &value
);
1911 i2c_w1(gspca_dev
, 0x12, value
& 0x07);
1913 i2c_w1(gspca_dev
, 0x17, 0x24);
1914 i2c_w1(gspca_dev
, 0x18, 0xc5);
1915 i2c_w1(gspca_dev
, 0x19, 0x00);
1916 i2c_w1(gspca_dev
, 0x1a, 0x3c);
1917 i2c_r1(gspca_dev
, 0x12, &value
);
1918 i2c_w1(gspca_dev
, 0x12, (value
& 0x7) | 0x40);
1921 case SENSOR_MT9M112
:
1922 case SENSOR_MT9M111
:
1923 if (mode
& MODE_SXGA
) {
1924 i2c_w2(gspca_dev
, 0xf0, 0x0002);
1925 i2c_w2(gspca_dev
, 0xc8, 0x970b);
1926 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1928 i2c_w2(gspca_dev
, 0xf0, 0x0002);
1929 i2c_w2(gspca_dev
, 0xc8, 0x8000);
1930 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1936 static int sd_isoc_init(struct gspca_dev
*gspca_dev
)
1938 struct usb_interface
*intf
;
1939 u32 flags
= gspca_dev
->cam
.cam_mode
[(int)gspca_dev
->curr_mode
].priv
;
1942 * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth
1943 * than our regular bandwidth calculations reserve, so we force the
1944 * use of a specific altsetting when using the SN9C20X_I420 fmt.
1946 if (!(flags
& (MODE_RAW
| MODE_JPEG
))) {
1947 intf
= usb_ifnum_to_if(gspca_dev
->dev
, gspca_dev
->iface
);
1949 if (intf
->num_altsetting
!= 9) {
1950 pr_warn("sn9c20x camera with unknown number of alt settings (%d), please report!\n",
1951 intf
->num_altsetting
);
1952 gspca_dev
->alt
= intf
->num_altsetting
;
1956 switch (gspca_dev
->pixfmt
.width
) {
1957 case 160: /* 160x120 */
1960 case 320: /* 320x240 */
1963 default: /* >= 640x480 */
1972 #define HW_WIN(mode, hstart, vstart) \
1973 ((const u8 []){hstart, 0, vstart, 0, \
1974 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
1975 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
1977 #define CLR_WIN(width, height) \
1979 {0, width >> 2, 0, height >> 1,\
1980 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
1982 static int sd_start(struct gspca_dev
*gspca_dev
)
1984 struct sd
*sd
= (struct sd
*) gspca_dev
;
1985 int mode
= gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
;
1986 int width
= gspca_dev
->pixfmt
.width
;
1987 int height
= gspca_dev
->pixfmt
.height
;
1990 jpeg_define(sd
->jpeg_hdr
, height
, width
,
1992 jpeg_set_qual(sd
->jpeg_hdr
, v4l2_ctrl_g_ctrl(sd
->jpegqual
));
1994 if (mode
& MODE_RAW
)
1996 else if (mode
& MODE_JPEG
)
1999 fmt
= 0x2f; /* YUV 420 */
2002 switch (mode
& SCALE_MASK
) {
2003 case SCALE_1280x1024
:
2005 pr_info("Set 1280x1024\n");
2009 pr_info("Set 640x480\n");
2013 pr_info("Set 320x240\n");
2017 pr_info("Set 160x120\n");
2021 configure_sensor_output(gspca_dev
, mode
);
2022 reg_w(gspca_dev
, 0x1100, &sd
->jpeg_hdr
[JPEG_QT0_OFFSET
], 64);
2023 reg_w(gspca_dev
, 0x1140, &sd
->jpeg_hdr
[JPEG_QT1_OFFSET
], 64);
2024 reg_w(gspca_dev
, 0x10fb, CLR_WIN(width
, height
), 5);
2025 reg_w(gspca_dev
, 0x1180, HW_WIN(mode
, sd
->hstart
, sd
->vstart
), 6);
2026 reg_w1(gspca_dev
, 0x1189, scale
);
2027 reg_w1(gspca_dev
, 0x10e0, fmt
);
2029 set_cmatrix(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->brightness
),
2030 v4l2_ctrl_g_ctrl(sd
->contrast
),
2031 v4l2_ctrl_g_ctrl(sd
->saturation
),
2032 v4l2_ctrl_g_ctrl(sd
->hue
));
2033 set_gamma(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->gamma
));
2034 set_redblue(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->blue
),
2035 v4l2_ctrl_g_ctrl(sd
->red
));
2037 set_gain(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->gain
));
2039 set_exposure(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->exposure
));
2041 set_hvflip(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->hflip
),
2042 v4l2_ctrl_g_ctrl(sd
->vflip
));
2044 reg_w1(gspca_dev
, 0x1007, 0x20);
2045 reg_w1(gspca_dev
, 0x1061, 0x03);
2047 /* if JPEG, prepare the compression quality update */
2048 if (mode
& MODE_JPEG
) {
2049 sd
->pktsz
= sd
->npkt
= 0;
2053 return gspca_dev
->usb_err
;
2056 static void sd_stopN(struct gspca_dev
*gspca_dev
)
2058 reg_w1(gspca_dev
, 0x1007, 0x00);
2059 reg_w1(gspca_dev
, 0x1061, 0x01);
2062 /* called on streamoff with alt==0 and on disconnect */
2063 /* the usb_lock is held at entry - restore on exit */
2064 static void sd_stop0(struct gspca_dev
*gspca_dev
)
2066 struct sd
*sd
= (struct sd
*) gspca_dev
;
2068 mutex_unlock(&gspca_dev
->usb_lock
);
2069 flush_work(&sd
->work
);
2070 mutex_lock(&gspca_dev
->usb_lock
);
2073 static void do_autoexposure(struct gspca_dev
*gspca_dev
, u16 avg_lum
)
2075 struct sd
*sd
= (struct sd
*) gspca_dev
;
2076 s32 cur_exp
= v4l2_ctrl_g_ctrl(sd
->exposure
);
2077 s32 max
= sd
->exposure
->maximum
- sd
->exposure_step
;
2078 s32 min
= sd
->exposure
->minimum
+ sd
->exposure_step
;
2082 * some hardcoded values are present
2083 * like those for maximal/minimal exposure
2084 * and exposure steps
2086 if (avg_lum
< MIN_AVG_LUM
) {
2090 new_exp
= cur_exp
+ sd
->exposure_step
;
2095 v4l2_ctrl_s_ctrl(sd
->exposure
, new_exp
);
2097 sd
->older_step
= sd
->old_step
;
2100 if (sd
->old_step
^ sd
->older_step
)
2101 sd
->exposure_step
/= 2;
2103 sd
->exposure_step
+= 2;
2105 if (avg_lum
> MAX_AVG_LUM
) {
2108 new_exp
= cur_exp
- sd
->exposure_step
;
2113 v4l2_ctrl_s_ctrl(sd
->exposure
, new_exp
);
2114 sd
->older_step
= sd
->old_step
;
2117 if (sd
->old_step
^ sd
->older_step
)
2118 sd
->exposure_step
/= 2;
2120 sd
->exposure_step
+= 2;
2124 static void do_autogain(struct gspca_dev
*gspca_dev
, u16 avg_lum
)
2126 struct sd
*sd
= (struct sd
*) gspca_dev
;
2127 s32 cur_gain
= v4l2_ctrl_g_ctrl(sd
->gain
);
2129 if (avg_lum
< MIN_AVG_LUM
&& cur_gain
< sd
->gain
->maximum
)
2130 v4l2_ctrl_s_ctrl(sd
->gain
, cur_gain
+ 1);
2131 if (avg_lum
> MAX_AVG_LUM
&& cur_gain
> sd
->gain
->minimum
)
2132 v4l2_ctrl_s_ctrl(sd
->gain
, cur_gain
- 1);
2135 static void sd_dqcallback(struct gspca_dev
*gspca_dev
)
2137 struct sd
*sd
= (struct sd
*) gspca_dev
;
2140 if (sd
->autogain
== NULL
|| !v4l2_ctrl_g_ctrl(sd
->autogain
))
2143 avg_lum
= atomic_read(&sd
->avg_lum
);
2144 if (sd
->sensor
== SENSOR_SOI968
)
2145 do_autogain(gspca_dev
, avg_lum
);
2147 do_autoexposure(gspca_dev
, avg_lum
);
2150 /* JPEG quality update */
2151 /* This function is executed from a work queue. */
2152 static void qual_upd(struct work_struct
*work
)
2154 struct sd
*sd
= container_of(work
, struct sd
, work
);
2155 struct gspca_dev
*gspca_dev
= &sd
->gspca_dev
;
2156 s32 qual
= v4l2_ctrl_g_ctrl(sd
->jpegqual
);
2158 /* To protect gspca_dev->usb_buf and gspca_dev->usb_err */
2159 mutex_lock(&gspca_dev
->usb_lock
);
2160 PDEBUG(D_STREAM
, "qual_upd %d%%", qual
);
2161 gspca_dev
->usb_err
= 0;
2162 set_quality(gspca_dev
, qual
);
2163 mutex_unlock(&gspca_dev
->usb_lock
);
2166 #if IS_ENABLED(CONFIG_INPUT)
2167 static int sd_int_pkt_scan(struct gspca_dev
*gspca_dev
,
2168 u8
*data
, /* interrupt packet */
2169 int len
) /* interrupt packet length */
2171 struct sd
*sd
= (struct sd
*) gspca_dev
;
2173 if (!(sd
->flags
& HAS_NO_BUTTON
) && len
== 1) {
2174 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 1);
2175 input_sync(gspca_dev
->input_dev
);
2176 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 0);
2177 input_sync(gspca_dev
->input_dev
);
2184 /* check the JPEG compression */
2185 static void transfer_check(struct gspca_dev
*gspca_dev
,
2188 struct sd
*sd
= (struct sd
*) gspca_dev
;
2193 /* if USB error, discard the frame and decrease the quality */
2194 if (data
[6] & 0x08) { /* USB FIFO full */
2195 gspca_dev
->last_packet_type
= DISCARD_PACKET
;
2199 /* else, compute the filling rate and a new JPEG quality */
2200 r
= (sd
->pktsz
* 100) /
2202 gspca_dev
->urb
[0]->iso_frame_desc
[0].length
);
2208 if (new_qual
!= 0) {
2209 sd
->nchg
+= new_qual
;
2210 if (sd
->nchg
< -6 || sd
->nchg
>= 12) {
2211 /* Note: we are in interrupt context, so we can't
2212 use v4l2_ctrl_g/s_ctrl here. Access the value
2213 directly instead. */
2214 s32 curqual
= sd
->jpegqual
->cur
.val
;
2216 new_qual
+= curqual
;
2217 if (new_qual
< sd
->jpegqual
->minimum
)
2218 new_qual
= sd
->jpegqual
->minimum
;
2219 else if (new_qual
> sd
->jpegqual
->maximum
)
2220 new_qual
= sd
->jpegqual
->maximum
;
2221 if (new_qual
!= curqual
) {
2222 sd
->jpegqual
->cur
.val
= new_qual
;
2223 schedule_work(&sd
->work
);
2229 sd
->pktsz
= sd
->npkt
= 0;
2232 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
2233 u8
*data
, /* isoc packet */
2234 int len
) /* iso packet length */
2236 struct sd
*sd
= (struct sd
*) gspca_dev
;
2237 int avg_lum
, is_jpeg
;
2238 static const u8 frame_header
[] = {
2239 0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96
2242 is_jpeg
= (sd
->fmt
& 0x03) == 0;
2243 if (len
>= 64 && memcmp(data
, frame_header
, 6) == 0) {
2244 avg_lum
= ((data
[35] >> 2) & 3) |
2247 avg_lum
+= ((data
[35] >> 4) & 3) |
2250 avg_lum
+= ((data
[35] >> 6) & 3) |
2253 avg_lum
+= (data
[36] & 3) |
2256 avg_lum
+= ((data
[36] >> 2) & 3) |
2259 avg_lum
+= ((data
[36] >> 4) & 3) |
2262 avg_lum
+= ((data
[36] >> 6) & 3) |
2265 avg_lum
+= ((data
[44] >> 4) & 3) |
2269 atomic_set(&sd
->avg_lum
, avg_lum
);
2272 transfer_check(gspca_dev
, data
);
2274 gspca_frame_add(gspca_dev
, LAST_PACKET
, NULL
, 0);
2280 if (gspca_dev
->last_packet_type
== LAST_PACKET
) {
2282 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
2283 sd
->jpeg_hdr
, JPEG_HDR_SZ
);
2284 gspca_frame_add(gspca_dev
, INTER_PACKET
,
2287 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
2291 /* if JPEG, count the packets and their size */
2296 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, len
);
2300 /* sub-driver description */
2301 static const struct sd_desc sd_desc
= {
2302 .name
= KBUILD_MODNAME
,
2303 .config
= sd_config
,
2305 .init_controls
= sd_init_controls
,
2306 .isoc_init
= sd_isoc_init
,
2310 .pkt_scan
= sd_pkt_scan
,
2311 #if IS_ENABLED(CONFIG_INPUT)
2312 .int_pkt_scan
= sd_int_pkt_scan
,
2314 .dq_callback
= sd_dqcallback
,
2315 #ifdef CONFIG_VIDEO_ADV_DEBUG
2316 .set_register
= sd_dbg_s_register
,
2317 .get_register
= sd_dbg_g_register
,
2318 .get_chip_info
= sd_chip_info
,
2322 #define SN9C20X(sensor, i2c_addr, flags) \
2323 .driver_info = ((flags & 0xff) << 16) \
2324 | (SENSOR_ ## sensor << 8) \
2327 static const struct usb_device_id device_table
[] = {
2328 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001
, 0x5d, 0)},
2329 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111
, 0x5d, 0)},
2330 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655
, 0x30, 0)},
2331 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112
, 0x5d, 0)},
2332 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968
, 0x30, LED_REVERSE
)},
2333 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650
, 0x30,
2334 (FLIP_DETECT
| HAS_NO_BUTTON
))},
2335 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650
, 0x30, 0)},
2336 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650
, 0x30, 0)},
2337 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670
, 0x21, 0)},
2338 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB
, 0x00, 0)},
2339 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660
, 0x21, FLIP_DETECT
)},
2340 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R
, 0x11, 0)},
2341 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650
, 0x30, 0)},
2342 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001
, 0x5d, 0)},
2343 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111
, 0x5d, 0)},
2344 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655
, 0x30, 0)},
2345 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112
, 0x5d, 0)},
2346 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968
, 0x30, 0)},
2347 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650
, 0x30, 0)},
2348 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670
, 0x21, 0)},
2349 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB
, 0x00, 0)},
2350 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655
, 0x30, LED_REVERSE
)},
2351 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660
, 0x21, LED_REVERSE
)},
2352 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R
, 0x11, 0)},
2353 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650
, 0x30, 0)},
2354 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660
, 0x21, 0)},
2355 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R
, 0x11, 0)},
2356 {USB_DEVICE(0x0458, 0x7045), SN9C20X(MT9M112
, 0x5d, LED_REVERSE
)},
2357 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112
, 0x5d, 0)},
2358 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112
, 0x5d, 0)},
2359 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R
, 0x11, 0)},
2360 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R
, 0x11, 0)},
2361 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R
, 0x11, 0)},
2362 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R
, 0x11, 0)},
2363 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111
, 0x5d, 0)},
2364 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111
, 0x5d, 0)},
2365 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111
, 0x5d, 0)},
2368 MODULE_DEVICE_TABLE(usb
, device_table
);
2370 /* -- device connect -- */
2371 static int sd_probe(struct usb_interface
*intf
,
2372 const struct usb_device_id
*id
)
2374 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
2378 static struct usb_driver sd_driver
= {
2379 .name
= KBUILD_MODNAME
,
2380 .id_table
= device_table
,
2382 .disconnect
= gspca_disconnect
,
2384 .suspend
= gspca_suspend
,
2385 .resume
= gspca_resume
,
2386 .reset_resume
= gspca_resume
,
2390 module_usb_driver(sd_driver
);