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 <media/v4l2-chip-ident.h>
31 #include <linux/dmi.h>
33 MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, "
34 "microdia project <microdia@googlegroups.com>");
35 MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
36 MODULE_LICENSE("GPL");
39 * Pixel format private data
41 #define SCALE_MASK 0x0f
42 #define SCALE_160x120 0
43 #define SCALE_320x240 1
44 #define SCALE_640x480 2
45 #define SCALE_1280x1024 3
47 #define MODE_JPEG 0x20
48 #define MODE_SXGA 0x80
50 #define SENSOR_OV9650 0
51 #define SENSOR_OV9655 1
52 #define SENSOR_SOI968 2
53 #define SENSOR_OV7660 3
54 #define SENSOR_OV7670 4
55 #define SENSOR_MT9V011 5
56 #define SENSOR_MT9V111 6
57 #define SENSOR_MT9V112 7
58 #define SENSOR_MT9M001 8
59 #define SENSOR_MT9M111 9
60 #define SENSOR_MT9M112 10
61 #define SENSOR_HV7131R 11
62 #define SENSOR_MT9VPRB 12
65 #define HAS_NO_BUTTON 0x1
66 #define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
67 #define FLIP_DETECT 0x4
69 /* specific webcam descriptor */
71 struct gspca_dev gspca_dev
;
73 struct { /* color control cluster */
74 struct v4l2_ctrl
*brightness
;
75 struct v4l2_ctrl
*contrast
;
76 struct v4l2_ctrl
*saturation
;
77 struct v4l2_ctrl
*hue
;
79 struct { /* blue/red balance control cluster */
80 struct v4l2_ctrl
*blue
;
81 struct v4l2_ctrl
*red
;
83 struct { /* h/vflip control cluster */
84 struct v4l2_ctrl
*hflip
;
85 struct v4l2_ctrl
*vflip
;
87 struct v4l2_ctrl
*gamma
;
88 struct { /* autogain and exposure or gain control cluster */
89 struct v4l2_ctrl
*autogain
;
90 struct v4l2_ctrl
*exposure
;
91 struct v4l2_ctrl
*gain
;
93 struct v4l2_ctrl
*jpegqual
;
95 struct work_struct work
;
96 struct workqueue_struct
*work_thread
;
98 u32 pktsz
; /* (used by pkt_scan) */
101 u8 fmt
; /* (used for JPEG QTAB update */
103 #define MIN_AVG_LUM 80
104 #define MAX_AVG_LUM 130
116 u8 jpeg_hdr
[JPEG_HDR_SZ
];
121 static void qual_upd(struct work_struct
*work
);
133 static const struct dmi_system_id flip_dmi_table
[] = {
135 .ident
= "MSI MS-1034",
137 DMI_MATCH(DMI_SYS_VENDOR
, "MICRO-STAR INT'L CO.,LTD."),
138 DMI_MATCH(DMI_PRODUCT_NAME
, "MS-1034"),
139 DMI_MATCH(DMI_PRODUCT_VERSION
, "0341")
143 .ident
= "MSI MS-1632",
145 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
146 DMI_MATCH(DMI_BOARD_NAME
, "MS-1632")
150 .ident
= "MSI MS-1633X",
152 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
153 DMI_MATCH(DMI_BOARD_NAME
, "MS-1633X")
157 .ident
= "MSI MS-1635X",
159 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
160 DMI_MATCH(DMI_BOARD_NAME
, "MS-1635X")
164 .ident
= "ASUSTeK W7J",
166 DMI_MATCH(DMI_BOARD_VENDOR
, "ASUSTeK Computer Inc."),
167 DMI_MATCH(DMI_BOARD_NAME
, "W7J ")
173 static const struct v4l2_pix_format vga_mode
[] = {
174 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
176 .sizeimage
= 160 * 120 * 4 / 8 + 590,
177 .colorspace
= V4L2_COLORSPACE_JPEG
,
178 .priv
= SCALE_160x120
| MODE_JPEG
},
179 {160, 120, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
181 .sizeimage
= 160 * 120,
182 .colorspace
= V4L2_COLORSPACE_SRGB
,
183 .priv
= SCALE_160x120
| MODE_RAW
},
184 {160, 120, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
186 .sizeimage
= 240 * 120,
187 .colorspace
= V4L2_COLORSPACE_SRGB
,
188 .priv
= SCALE_160x120
},
189 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
191 .sizeimage
= 320 * 240 * 4 / 8 + 590,
192 .colorspace
= V4L2_COLORSPACE_JPEG
,
193 .priv
= SCALE_320x240
| MODE_JPEG
},
194 {320, 240, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
196 .sizeimage
= 320 * 240 ,
197 .colorspace
= V4L2_COLORSPACE_SRGB
,
198 .priv
= SCALE_320x240
| MODE_RAW
},
199 {320, 240, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
201 .sizeimage
= 480 * 240 ,
202 .colorspace
= V4L2_COLORSPACE_SRGB
,
203 .priv
= SCALE_320x240
},
204 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
206 .sizeimage
= 640 * 480 * 4 / 8 + 590,
207 .colorspace
= V4L2_COLORSPACE_JPEG
,
208 .priv
= SCALE_640x480
| MODE_JPEG
},
209 {640, 480, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
211 .sizeimage
= 640 * 480,
212 .colorspace
= V4L2_COLORSPACE_SRGB
,
213 .priv
= SCALE_640x480
| MODE_RAW
},
214 {640, 480, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
216 .sizeimage
= 960 * 480,
217 .colorspace
= V4L2_COLORSPACE_SRGB
,
218 .priv
= SCALE_640x480
},
221 static const struct v4l2_pix_format sxga_mode
[] = {
222 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
224 .sizeimage
= 160 * 120 * 4 / 8 + 590,
225 .colorspace
= V4L2_COLORSPACE_JPEG
,
226 .priv
= SCALE_160x120
| MODE_JPEG
},
227 {160, 120, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
229 .sizeimage
= 160 * 120,
230 .colorspace
= V4L2_COLORSPACE_SRGB
,
231 .priv
= SCALE_160x120
| MODE_RAW
},
232 {160, 120, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
234 .sizeimage
= 240 * 120,
235 .colorspace
= V4L2_COLORSPACE_SRGB
,
236 .priv
= SCALE_160x120
},
237 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
239 .sizeimage
= 320 * 240 * 4 / 8 + 590,
240 .colorspace
= V4L2_COLORSPACE_JPEG
,
241 .priv
= SCALE_320x240
| MODE_JPEG
},
242 {320, 240, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
244 .sizeimage
= 320 * 240 ,
245 .colorspace
= V4L2_COLORSPACE_SRGB
,
246 .priv
= SCALE_320x240
| MODE_RAW
},
247 {320, 240, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
249 .sizeimage
= 480 * 240 ,
250 .colorspace
= V4L2_COLORSPACE_SRGB
,
251 .priv
= SCALE_320x240
},
252 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
254 .sizeimage
= 640 * 480 * 4 / 8 + 590,
255 .colorspace
= V4L2_COLORSPACE_JPEG
,
256 .priv
= SCALE_640x480
| MODE_JPEG
},
257 {640, 480, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
259 .sizeimage
= 640 * 480,
260 .colorspace
= V4L2_COLORSPACE_SRGB
,
261 .priv
= SCALE_640x480
| MODE_RAW
},
262 {640, 480, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
264 .sizeimage
= 960 * 480,
265 .colorspace
= V4L2_COLORSPACE_SRGB
,
266 .priv
= SCALE_640x480
},
267 {1280, 1024, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
268 .bytesperline
= 1280,
269 .sizeimage
= 1280 * 1024,
270 .colorspace
= V4L2_COLORSPACE_SRGB
,
271 .priv
= SCALE_1280x1024
| MODE_RAW
| MODE_SXGA
},
274 static const struct v4l2_pix_format mono_mode
[] = {
275 {160, 120, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
277 .sizeimage
= 160 * 120,
278 .colorspace
= V4L2_COLORSPACE_SRGB
,
279 .priv
= SCALE_160x120
| MODE_RAW
},
280 {320, 240, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
282 .sizeimage
= 320 * 240 ,
283 .colorspace
= V4L2_COLORSPACE_SRGB
,
284 .priv
= SCALE_320x240
| MODE_RAW
},
285 {640, 480, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
287 .sizeimage
= 640 * 480,
288 .colorspace
= V4L2_COLORSPACE_SRGB
,
289 .priv
= SCALE_640x480
| MODE_RAW
},
290 {1280, 1024, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
291 .bytesperline
= 1280,
292 .sizeimage
= 1280 * 1024,
293 .colorspace
= V4L2_COLORSPACE_SRGB
,
294 .priv
= SCALE_1280x1024
| MODE_RAW
| MODE_SXGA
},
297 static const s16 hsv_red_x
[] = {
298 41, 44, 46, 48, 50, 52, 54, 56,
299 58, 60, 62, 64, 66, 68, 70, 72,
300 74, 76, 78, 80, 81, 83, 85, 87,
301 88, 90, 92, 93, 95, 97, 98, 100,
302 101, 102, 104, 105, 107, 108, 109, 110,
303 112, 113, 114, 115, 116, 117, 118, 119,
304 120, 121, 122, 123, 123, 124, 125, 125,
305 126, 127, 127, 128, 128, 129, 129, 129,
306 130, 130, 130, 130, 131, 131, 131, 131,
307 131, 131, 131, 131, 130, 130, 130, 130,
308 129, 129, 129, 128, 128, 127, 127, 126,
309 125, 125, 124, 123, 122, 122, 121, 120,
310 119, 118, 117, 116, 115, 114, 112, 111,
311 110, 109, 107, 106, 105, 103, 102, 101,
312 99, 98, 96, 94, 93, 91, 90, 88,
313 86, 84, 83, 81, 79, 77, 75, 74,
314 72, 70, 68, 66, 64, 62, 60, 58,
315 56, 54, 52, 49, 47, 45, 43, 41,
316 39, 36, 34, 32, 30, 28, 25, 23,
317 21, 19, 16, 14, 12, 9, 7, 5,
318 3, 0, -1, -3, -6, -8, -10, -12,
319 -15, -17, -19, -22, -24, -26, -28, -30,
320 -33, -35, -37, -39, -41, -44, -46, -48,
321 -50, -52, -54, -56, -58, -60, -62, -64,
322 -66, -68, -70, -72, -74, -76, -78, -80,
323 -81, -83, -85, -87, -88, -90, -92, -93,
324 -95, -97, -98, -100, -101, -102, -104, -105,
325 -107, -108, -109, -110, -112, -113, -114, -115,
326 -116, -117, -118, -119, -120, -121, -122, -123,
327 -123, -124, -125, -125, -126, -127, -127, -128,
328 -128, -128, -128, -128, -128, -128, -128, -128,
329 -128, -128, -128, -128, -128, -128, -128, -128,
330 -128, -128, -128, -128, -128, -128, -128, -128,
331 -128, -127, -127, -126, -125, -125, -124, -123,
332 -122, -122, -121, -120, -119, -118, -117, -116,
333 -115, -114, -112, -111, -110, -109, -107, -106,
334 -105, -103, -102, -101, -99, -98, -96, -94,
335 -93, -91, -90, -88, -86, -84, -83, -81,
336 -79, -77, -75, -74, -72, -70, -68, -66,
337 -64, -62, -60, -58, -56, -54, -52, -49,
338 -47, -45, -43, -41, -39, -36, -34, -32,
339 -30, -28, -25, -23, -21, -19, -16, -14,
340 -12, -9, -7, -5, -3, 0, 1, 3,
341 6, 8, 10, 12, 15, 17, 19, 22,
342 24, 26, 28, 30, 33, 35, 37, 39, 41
345 static const s16 hsv_red_y
[] = {
346 82, 80, 78, 76, 74, 73, 71, 69,
347 67, 65, 63, 61, 58, 56, 54, 52,
348 50, 48, 46, 44, 41, 39, 37, 35,
349 32, 30, 28, 26, 23, 21, 19, 16,
350 14, 12, 10, 7, 5, 3, 0, -1,
351 -3, -6, -8, -10, -13, -15, -17, -19,
352 -22, -24, -26, -29, -31, -33, -35, -38,
353 -40, -42, -44, -46, -48, -51, -53, -55,
354 -57, -59, -61, -63, -65, -67, -69, -71,
355 -73, -75, -77, -79, -81, -82, -84, -86,
356 -88, -89, -91, -93, -94, -96, -98, -99,
357 -101, -102, -104, -105, -106, -108, -109, -110,
358 -112, -113, -114, -115, -116, -117, -119, -120,
359 -120, -121, -122, -123, -124, -125, -126, -126,
360 -127, -128, -128, -128, -128, -128, -128, -128,
361 -128, -128, -128, -128, -128, -128, -128, -128,
362 -128, -128, -128, -128, -128, -128, -128, -128,
363 -128, -128, -128, -128, -128, -128, -128, -128,
364 -127, -127, -126, -125, -125, -124, -123, -122,
365 -121, -120, -119, -118, -117, -116, -115, -114,
366 -113, -111, -110, -109, -107, -106, -105, -103,
367 -102, -100, -99, -97, -96, -94, -92, -91,
368 -89, -87, -85, -84, -82, -80, -78, -76,
369 -74, -73, -71, -69, -67, -65, -63, -61,
370 -58, -56, -54, -52, -50, -48, -46, -44,
371 -41, -39, -37, -35, -32, -30, -28, -26,
372 -23, -21, -19, -16, -14, -12, -10, -7,
373 -5, -3, 0, 1, 3, 6, 8, 10,
374 13, 15, 17, 19, 22, 24, 26, 29,
375 31, 33, 35, 38, 40, 42, 44, 46,
376 48, 51, 53, 55, 57, 59, 61, 63,
377 65, 67, 69, 71, 73, 75, 77, 79,
378 81, 82, 84, 86, 88, 89, 91, 93,
379 94, 96, 98, 99, 101, 102, 104, 105,
380 106, 108, 109, 110, 112, 113, 114, 115,
381 116, 117, 119, 120, 120, 121, 122, 123,
382 124, 125, 126, 126, 127, 128, 128, 129,
383 129, 130, 130, 131, 131, 131, 131, 132,
384 132, 132, 132, 132, 132, 132, 132, 132,
385 132, 132, 132, 131, 131, 131, 130, 130,
386 130, 129, 129, 128, 127, 127, 126, 125,
387 125, 124, 123, 122, 121, 120, 119, 118,
388 117, 116, 115, 114, 113, 111, 110, 109,
389 107, 106, 105, 103, 102, 100, 99, 97,
390 96, 94, 92, 91, 89, 87, 85, 84, 82
393 static const s16 hsv_green_x
[] = {
394 -124, -124, -125, -125, -125, -125, -125, -125,
395 -125, -126, -126, -125, -125, -125, -125, -125,
396 -125, -124, -124, -124, -123, -123, -122, -122,
397 -121, -121, -120, -120, -119, -118, -117, -117,
398 -116, -115, -114, -113, -112, -111, -110, -109,
399 -108, -107, -105, -104, -103, -102, -100, -99,
400 -98, -96, -95, -93, -92, -91, -89, -87,
401 -86, -84, -83, -81, -79, -77, -76, -74,
402 -72, -70, -69, -67, -65, -63, -61, -59,
403 -57, -55, -53, -51, -49, -47, -45, -43,
404 -41, -39, -37, -35, -33, -30, -28, -26,
405 -24, -22, -20, -18, -15, -13, -11, -9,
406 -7, -4, -2, 0, 1, 3, 6, 8,
407 10, 12, 14, 17, 19, 21, 23, 25,
408 27, 29, 32, 34, 36, 38, 40, 42,
409 44, 46, 48, 50, 52, 54, 56, 58,
410 60, 62, 64, 66, 68, 70, 71, 73,
411 75, 77, 78, 80, 82, 83, 85, 87,
412 88, 90, 91, 93, 94, 96, 97, 98,
413 100, 101, 102, 104, 105, 106, 107, 108,
414 109, 111, 112, 113, 113, 114, 115, 116,
415 117, 118, 118, 119, 120, 120, 121, 122,
416 122, 123, 123, 124, 124, 124, 125, 125,
417 125, 125, 125, 125, 125, 126, 126, 125,
418 125, 125, 125, 125, 125, 124, 124, 124,
419 123, 123, 122, 122, 121, 121, 120, 120,
420 119, 118, 117, 117, 116, 115, 114, 113,
421 112, 111, 110, 109, 108, 107, 105, 104,
422 103, 102, 100, 99, 98, 96, 95, 93,
423 92, 91, 89, 87, 86, 84, 83, 81,
424 79, 77, 76, 74, 72, 70, 69, 67,
425 65, 63, 61, 59, 57, 55, 53, 51,
426 49, 47, 45, 43, 41, 39, 37, 35,
427 33, 30, 28, 26, 24, 22, 20, 18,
428 15, 13, 11, 9, 7, 4, 2, 0,
429 -1, -3, -6, -8, -10, -12, -14, -17,
430 -19, -21, -23, -25, -27, -29, -32, -34,
431 -36, -38, -40, -42, -44, -46, -48, -50,
432 -52, -54, -56, -58, -60, -62, -64, -66,
433 -68, -70, -71, -73, -75, -77, -78, -80,
434 -82, -83, -85, -87, -88, -90, -91, -93,
435 -94, -96, -97, -98, -100, -101, -102, -104,
436 -105, -106, -107, -108, -109, -111, -112, -113,
437 -113, -114, -115, -116, -117, -118, -118, -119,
438 -120, -120, -121, -122, -122, -123, -123, -124, -124
441 static const s16 hsv_green_y
[] = {
442 -100, -99, -98, -97, -95, -94, -93, -91,
443 -90, -89, -87, -86, -84, -83, -81, -80,
444 -78, -76, -75, -73, -71, -70, -68, -66,
445 -64, -63, -61, -59, -57, -55, -53, -51,
446 -49, -48, -46, -44, -42, -40, -38, -36,
447 -34, -32, -30, -27, -25, -23, -21, -19,
448 -17, -15, -13, -11, -9, -7, -4, -2,
449 0, 1, 3, 5, 7, 9, 11, 14,
450 16, 18, 20, 22, 24, 26, 28, 30,
451 32, 34, 36, 38, 40, 42, 44, 46,
452 48, 50, 52, 54, 56, 58, 59, 61,
453 63, 65, 67, 68, 70, 72, 74, 75,
454 77, 78, 80, 82, 83, 85, 86, 88,
455 89, 90, 92, 93, 95, 96, 97, 98,
456 100, 101, 102, 103, 104, 105, 106, 107,
457 108, 109, 110, 111, 112, 112, 113, 114,
458 115, 115, 116, 116, 117, 117, 118, 118,
459 119, 119, 119, 120, 120, 120, 120, 120,
460 121, 121, 121, 121, 121, 121, 120, 120,
461 120, 120, 120, 119, 119, 119, 118, 118,
462 117, 117, 116, 116, 115, 114, 114, 113,
463 112, 111, 111, 110, 109, 108, 107, 106,
464 105, 104, 103, 102, 100, 99, 98, 97,
465 95, 94, 93, 91, 90, 89, 87, 86,
466 84, 83, 81, 80, 78, 76, 75, 73,
467 71, 70, 68, 66, 64, 63, 61, 59,
468 57, 55, 53, 51, 49, 48, 46, 44,
469 42, 40, 38, 36, 34, 32, 30, 27,
470 25, 23, 21, 19, 17, 15, 13, 11,
471 9, 7, 4, 2, 0, -1, -3, -5,
472 -7, -9, -11, -14, -16, -18, -20, -22,
473 -24, -26, -28, -30, -32, -34, -36, -38,
474 -40, -42, -44, -46, -48, -50, -52, -54,
475 -56, -58, -59, -61, -63, -65, -67, -68,
476 -70, -72, -74, -75, -77, -78, -80, -82,
477 -83, -85, -86, -88, -89, -90, -92, -93,
478 -95, -96, -97, -98, -100, -101, -102, -103,
479 -104, -105, -106, -107, -108, -109, -110, -111,
480 -112, -112, -113, -114, -115, -115, -116, -116,
481 -117, -117, -118, -118, -119, -119, -119, -120,
482 -120, -120, -120, -120, -121, -121, -121, -121,
483 -121, -121, -120, -120, -120, -120, -120, -119,
484 -119, -119, -118, -118, -117, -117, -116, -116,
485 -115, -114, -114, -113, -112, -111, -111, -110,
486 -109, -108, -107, -106, -105, -104, -103, -102, -100
489 static const s16 hsv_blue_x
[] = {
490 112, 113, 114, 114, 115, 116, 117, 117,
491 118, 118, 119, 119, 120, 120, 120, 121,
492 121, 121, 122, 122, 122, 122, 122, 122,
493 122, 122, 122, 122, 122, 122, 121, 121,
494 121, 120, 120, 120, 119, 119, 118, 118,
495 117, 116, 116, 115, 114, 113, 113, 112,
496 111, 110, 109, 108, 107, 106, 105, 104,
497 103, 102, 100, 99, 98, 97, 95, 94,
498 93, 91, 90, 88, 87, 85, 84, 82,
499 80, 79, 77, 76, 74, 72, 70, 69,
500 67, 65, 63, 61, 60, 58, 56, 54,
501 52, 50, 48, 46, 44, 42, 40, 38,
502 36, 34, 32, 30, 28, 26, 24, 22,
503 19, 17, 15, 13, 11, 9, 7, 5,
504 2, 0, -1, -3, -5, -7, -9, -12,
505 -14, -16, -18, -20, -22, -24, -26, -28,
506 -31, -33, -35, -37, -39, -41, -43, -45,
507 -47, -49, -51, -53, -54, -56, -58, -60,
508 -62, -64, -66, -67, -69, -71, -73, -74,
509 -76, -78, -79, -81, -83, -84, -86, -87,
510 -89, -90, -92, -93, -94, -96, -97, -98,
511 -99, -101, -102, -103, -104, -105, -106, -107,
512 -108, -109, -110, -111, -112, -113, -114, -114,
513 -115, -116, -117, -117, -118, -118, -119, -119,
514 -120, -120, -120, -121, -121, -121, -122, -122,
515 -122, -122, -122, -122, -122, -122, -122, -122,
516 -122, -122, -121, -121, -121, -120, -120, -120,
517 -119, -119, -118, -118, -117, -116, -116, -115,
518 -114, -113, -113, -112, -111, -110, -109, -108,
519 -107, -106, -105, -104, -103, -102, -100, -99,
520 -98, -97, -95, -94, -93, -91, -90, -88,
521 -87, -85, -84, -82, -80, -79, -77, -76,
522 -74, -72, -70, -69, -67, -65, -63, -61,
523 -60, -58, -56, -54, -52, -50, -48, -46,
524 -44, -42, -40, -38, -36, -34, -32, -30,
525 -28, -26, -24, -22, -19, -17, -15, -13,
526 -11, -9, -7, -5, -2, 0, 1, 3,
527 5, 7, 9, 12, 14, 16, 18, 20,
528 22, 24, 26, 28, 31, 33, 35, 37,
529 39, 41, 43, 45, 47, 49, 51, 53,
530 54, 56, 58, 60, 62, 64, 66, 67,
531 69, 71, 73, 74, 76, 78, 79, 81,
532 83, 84, 86, 87, 89, 90, 92, 93,
533 94, 96, 97, 98, 99, 101, 102, 103,
534 104, 105, 106, 107, 108, 109, 110, 111, 112
537 static const s16 hsv_blue_y
[] = {
538 -11, -13, -15, -17, -19, -21, -23, -25,
539 -27, -29, -31, -33, -35, -37, -39, -41,
540 -43, -45, -46, -48, -50, -52, -54, -55,
541 -57, -59, -61, -62, -64, -66, -67, -69,
542 -71, -72, -74, -75, -77, -78, -80, -81,
543 -83, -84, -86, -87, -88, -90, -91, -92,
544 -93, -95, -96, -97, -98, -99, -100, -101,
545 -102, -103, -104, -105, -106, -106, -107, -108,
546 -109, -109, -110, -111, -111, -112, -112, -113,
547 -113, -114, -114, -114, -115, -115, -115, -115,
548 -116, -116, -116, -116, -116, -116, -116, -116,
549 -116, -115, -115, -115, -115, -114, -114, -114,
550 -113, -113, -112, -112, -111, -111, -110, -110,
551 -109, -108, -108, -107, -106, -105, -104, -103,
552 -102, -101, -100, -99, -98, -97, -96, -95,
553 -94, -93, -91, -90, -89, -88, -86, -85,
554 -84, -82, -81, -79, -78, -76, -75, -73,
555 -71, -70, -68, -67, -65, -63, -62, -60,
556 -58, -56, -55, -53, -51, -49, -47, -45,
557 -44, -42, -40, -38, -36, -34, -32, -30,
558 -28, -26, -24, -22, -20, -18, -16, -14,
559 -12, -10, -8, -6, -4, -2, 0, 1,
560 3, 5, 7, 9, 11, 13, 15, 17,
561 19, 21, 23, 25, 27, 29, 31, 33,
562 35, 37, 39, 41, 43, 45, 46, 48,
563 50, 52, 54, 55, 57, 59, 61, 62,
564 64, 66, 67, 69, 71, 72, 74, 75,
565 77, 78, 80, 81, 83, 84, 86, 87,
566 88, 90, 91, 92, 93, 95, 96, 97,
567 98, 99, 100, 101, 102, 103, 104, 105,
568 106, 106, 107, 108, 109, 109, 110, 111,
569 111, 112, 112, 113, 113, 114, 114, 114,
570 115, 115, 115, 115, 116, 116, 116, 116,
571 116, 116, 116, 116, 116, 115, 115, 115,
572 115, 114, 114, 114, 113, 113, 112, 112,
573 111, 111, 110, 110, 109, 108, 108, 107,
574 106, 105, 104, 103, 102, 101, 100, 99,
575 98, 97, 96, 95, 94, 93, 91, 90,
576 89, 88, 86, 85, 84, 82, 81, 79,
577 78, 76, 75, 73, 71, 70, 68, 67,
578 65, 63, 62, 60, 58, 56, 55, 53,
579 51, 49, 47, 45, 44, 42, 40, 38,
580 36, 34, 32, 30, 28, 26, 24, 22,
581 20, 18, 16, 14, 12, 10, 8, 6,
582 4, 2, 0, -1, -3, -5, -7, -9, -11
585 static const u16 i2c_ident
[] = {
594 V4L2_IDENT_MT9M001C12ST
,
598 [SENSOR_MT9VPRB
] = V4L2_IDENT_UNKNOWN
,
601 static const u16 bridge_init
[][2] = {
602 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
603 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
604 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
605 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
606 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
607 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
608 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
609 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
610 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
611 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
612 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
613 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
614 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
615 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
616 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
617 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
618 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
619 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
620 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
624 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
625 static const u8 ov_gain
[] = {
626 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
627 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
628 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
629 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
630 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
631 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
632 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
636 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
637 static const u16 micron1_gain
[] = {
638 /* 1x 1.25x 1.5x 1.75x */
639 0x0020, 0x0028, 0x0030, 0x0038,
640 /* 2x 2.25x 2.5x 2.75x */
641 0x00a0, 0x00a4, 0x00a8, 0x00ac,
642 /* 3x 3.25x 3.5x 3.75x */
643 0x00b0, 0x00b4, 0x00b8, 0x00bc,
644 /* 4x 4.25x 4.5x 4.75x */
645 0x00c0, 0x00c4, 0x00c8, 0x00cc,
646 /* 5x 5.25x 5.5x 5.75x */
647 0x00d0, 0x00d4, 0x00d8, 0x00dc,
648 /* 6x 6.25x 6.5x 6.75x */
649 0x00e0, 0x00e4, 0x00e8, 0x00ec,
650 /* 7x 7.25x 7.5x 7.75x */
651 0x00f0, 0x00f4, 0x00f8, 0x00fc,
656 /* mt9m001 sensor uses a different gain formula then other micron sensors */
657 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
658 static const u16 micron2_gain
[] = {
659 /* 1x 1.25x 1.5x 1.75x */
660 0x0008, 0x000a, 0x000c, 0x000e,
661 /* 2x 2.25x 2.5x 2.75x */
662 0x0010, 0x0012, 0x0014, 0x0016,
663 /* 3x 3.25x 3.5x 3.75x */
664 0x0018, 0x001a, 0x001c, 0x001e,
665 /* 4x 4.25x 4.5x 4.75x */
666 0x0020, 0x0051, 0x0052, 0x0053,
667 /* 5x 5.25x 5.5x 5.75x */
668 0x0054, 0x0055, 0x0056, 0x0057,
669 /* 6x 6.25x 6.5x 6.75x */
670 0x0058, 0x0059, 0x005a, 0x005b,
671 /* 7x 7.25x 7.5x 7.75x */
672 0x005c, 0x005d, 0x005e, 0x005f,
677 /* Gain = .5 + bit[7:0] / 16 */
678 static const u8 hv7131r_gain
[] = {
679 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
680 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
681 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
682 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
683 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
684 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
685 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
689 static const struct i2c_reg_u8 soi968_init
[] = {
690 {0x0c, 0x00}, {0x0f, 0x1f},
691 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
692 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
693 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
694 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
695 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
696 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
697 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
698 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
699 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
700 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
703 static const struct i2c_reg_u8 ov7660_init
[] = {
704 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
705 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
706 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
707 /* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using
708 0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
709 {0x17, 0x10}, {0x18, 0x61},
710 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
711 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0x00},
712 {0x2e, 0x00}, {0x01, 0x78}, {0x02, 0x50},
715 static const struct i2c_reg_u8 ov7670_init
[] = {
716 {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
717 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
718 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
719 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
720 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
721 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
722 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
723 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
724 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
725 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
726 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
727 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
728 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
729 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
730 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
731 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
732 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
733 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
734 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
735 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
736 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
737 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
738 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
739 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
740 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
741 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
742 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
743 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
744 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
745 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
746 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
747 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
748 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
749 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
750 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
751 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
752 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
753 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
754 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
755 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
756 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
757 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
758 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
759 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
760 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
761 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
762 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
763 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
764 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
765 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
766 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
767 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
768 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
772 static const struct i2c_reg_u8 ov9650_init
[] = {
773 {0x00, 0x00}, {0x01, 0x78},
774 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
775 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
776 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
777 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
778 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
779 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
780 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
781 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
782 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
783 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
784 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
785 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
786 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
787 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
788 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
789 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
790 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
791 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
792 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
793 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
794 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
795 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
796 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
797 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
798 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
799 {0xaa, 0x92}, {0xab, 0x0a},
802 static const struct i2c_reg_u8 ov9655_init
[] = {
803 {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
804 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
805 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
806 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
807 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
808 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
809 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
810 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
811 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
812 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
813 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
814 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
815 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
816 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
817 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
818 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
819 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
820 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
821 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
822 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
823 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
824 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
825 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
826 {0x04, 0x03}, {0x00, 0x13},
829 static const struct i2c_reg_u16 mt9v112_init
[] = {
830 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
831 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
832 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
833 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
834 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
835 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
836 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
837 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
838 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
839 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
840 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
841 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
842 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
843 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
844 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
845 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
848 static const struct i2c_reg_u16 mt9v111_init
[] = {
849 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
850 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
851 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
852 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
853 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
854 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
855 {0x0e, 0x0008}, {0x20, 0x0000}
858 static const struct i2c_reg_u16 mt9v011_init
[] = {
859 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
860 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
861 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
862 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
863 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
864 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
865 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
866 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
867 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
868 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
869 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
870 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
871 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
872 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
873 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
874 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
875 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
876 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
877 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
878 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
879 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
880 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
881 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
882 {0x06, 0x0029}, {0x05, 0x0009},
885 static const struct i2c_reg_u16 mt9m001_init
[] = {
888 {0x04, 0x0500}, /* hres = 1280 */
889 {0x03, 0x0400}, /* vres = 1024 */
901 static const struct i2c_reg_u16 mt9m111_init
[] = {
902 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
903 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
904 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
908 static const struct i2c_reg_u16 mt9m112_init
[] = {
909 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
910 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
911 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
915 static const struct i2c_reg_u8 hv7131r_init
[] = {
916 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
917 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
918 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
919 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
920 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
921 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
922 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
923 {0x23, 0x09}, {0x01, 0x08},
926 static void reg_r(struct gspca_dev
*gspca_dev
, u16 reg
, u16 length
)
928 struct usb_device
*dev
= gspca_dev
->dev
;
931 if (gspca_dev
->usb_err
< 0)
933 result
= usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
935 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
941 if (unlikely(result
< 0 || result
!= length
)) {
942 pr_err("Read register %02x failed %d\n", reg
, result
);
943 gspca_dev
->usb_err
= result
;
947 static void reg_w(struct gspca_dev
*gspca_dev
, u16 reg
,
948 const u8
*buffer
, int length
)
950 struct usb_device
*dev
= gspca_dev
->dev
;
953 if (gspca_dev
->usb_err
< 0)
955 memcpy(gspca_dev
->usb_buf
, buffer
, length
);
956 result
= usb_control_msg(dev
, usb_sndctrlpipe(dev
, 0),
958 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
964 if (unlikely(result
< 0 || result
!= length
)) {
965 pr_err("Write register %02x failed %d\n", reg
, result
);
966 gspca_dev
->usb_err
= result
;
970 static void reg_w1(struct gspca_dev
*gspca_dev
, u16 reg
, const u8 value
)
972 reg_w(gspca_dev
, reg
, &value
, 1);
975 static void i2c_w(struct gspca_dev
*gspca_dev
, const u8
*buffer
)
979 reg_w(gspca_dev
, 0x10c0, buffer
, 8);
980 for (i
= 0; i
< 5; i
++) {
981 reg_r(gspca_dev
, 0x10c0, 1);
982 if (gspca_dev
->usb_err
< 0)
984 if (gspca_dev
->usb_buf
[0] & 0x04) {
985 if (gspca_dev
->usb_buf
[0] & 0x08) {
986 pr_err("i2c_w error\n");
987 gspca_dev
->usb_err
= -EIO
;
993 pr_err("i2c_w reg %02x no response\n", buffer
[2]);
994 /* gspca_dev->usb_err = -EIO; fixme: may occur */
997 static void i2c_w1(struct gspca_dev
*gspca_dev
, u8 reg
, u8 val
)
999 struct sd
*sd
= (struct sd
*) gspca_dev
;
1003 * from the point of view of the bridge, the length
1004 * includes the address
1006 row
[0] = sd
->i2c_intf
| (2 << 4);
1007 row
[1] = sd
->i2c_addr
;
1015 i2c_w(gspca_dev
, row
);
1018 static void i2c_w1_buf(struct gspca_dev
*gspca_dev
,
1019 const struct i2c_reg_u8
*buf
, int sz
)
1022 i2c_w1(gspca_dev
, buf
->reg
, buf
->val
);
1027 static void i2c_w2(struct gspca_dev
*gspca_dev
, u8 reg
, u16 val
)
1029 struct sd
*sd
= (struct sd
*) gspca_dev
;
1033 * from the point of view of the bridge, the length
1034 * includes the address
1036 row
[0] = sd
->i2c_intf
| (3 << 4);
1037 row
[1] = sd
->i2c_addr
;
1045 i2c_w(gspca_dev
, row
);
1048 static void i2c_w2_buf(struct gspca_dev
*gspca_dev
,
1049 const struct i2c_reg_u16
*buf
, int sz
)
1052 i2c_w2(gspca_dev
, buf
->reg
, buf
->val
);
1057 static void i2c_r1(struct gspca_dev
*gspca_dev
, u8 reg
, u8
*val
)
1059 struct sd
*sd
= (struct sd
*) gspca_dev
;
1062 row
[0] = sd
->i2c_intf
| (1 << 4);
1063 row
[1] = sd
->i2c_addr
;
1070 i2c_w(gspca_dev
, row
);
1071 row
[0] = sd
->i2c_intf
| (1 << 4) | 0x02;
1073 i2c_w(gspca_dev
, row
);
1074 reg_r(gspca_dev
, 0x10c2, 5);
1075 *val
= gspca_dev
->usb_buf
[4];
1078 static void i2c_r2(struct gspca_dev
*gspca_dev
, u8 reg
, u16
*val
)
1080 struct sd
*sd
= (struct sd
*) gspca_dev
;
1083 row
[0] = sd
->i2c_intf
| (1 << 4);
1084 row
[1] = sd
->i2c_addr
;
1091 i2c_w(gspca_dev
, row
);
1092 row
[0] = sd
->i2c_intf
| (2 << 4) | 0x02;
1094 i2c_w(gspca_dev
, row
);
1095 reg_r(gspca_dev
, 0x10c2, 5);
1096 *val
= (gspca_dev
->usb_buf
[3] << 8) | gspca_dev
->usb_buf
[4];
1099 static void ov9650_init_sensor(struct gspca_dev
*gspca_dev
)
1102 struct sd
*sd
= (struct sd
*) gspca_dev
;
1104 i2c_r2(gspca_dev
, 0x1c, &id
);
1105 if (gspca_dev
->usb_err
< 0)
1109 pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id
);
1110 gspca_dev
->usb_err
= -ENODEV
;
1114 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1116 i2c_w1_buf(gspca_dev
, ov9650_init
, ARRAY_SIZE(ov9650_init
));
1117 if (gspca_dev
->usb_err
< 0)
1118 pr_err("OV9650 sensor initialization failed\n");
1123 static void ov9655_init_sensor(struct gspca_dev
*gspca_dev
)
1125 struct sd
*sd
= (struct sd
*) gspca_dev
;
1127 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1129 i2c_w1_buf(gspca_dev
, ov9655_init
, ARRAY_SIZE(ov9655_init
));
1130 if (gspca_dev
->usb_err
< 0)
1131 pr_err("OV9655 sensor initialization failed\n");
1137 static void soi968_init_sensor(struct gspca_dev
*gspca_dev
)
1139 struct sd
*sd
= (struct sd
*) gspca_dev
;
1141 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1143 i2c_w1_buf(gspca_dev
, soi968_init
, ARRAY_SIZE(soi968_init
));
1144 if (gspca_dev
->usb_err
< 0)
1145 pr_err("SOI968 sensor initialization failed\n");
1151 static void ov7660_init_sensor(struct gspca_dev
*gspca_dev
)
1153 struct sd
*sd
= (struct sd
*) gspca_dev
;
1155 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1157 i2c_w1_buf(gspca_dev
, ov7660_init
, ARRAY_SIZE(ov7660_init
));
1158 if (gspca_dev
->usb_err
< 0)
1159 pr_err("OV7660 sensor initialization failed\n");
1164 static void ov7670_init_sensor(struct gspca_dev
*gspca_dev
)
1166 struct sd
*sd
= (struct sd
*) gspca_dev
;
1168 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1170 i2c_w1_buf(gspca_dev
, ov7670_init
, ARRAY_SIZE(ov7670_init
));
1171 if (gspca_dev
->usb_err
< 0)
1172 pr_err("OV7670 sensor initialization failed\n");
1178 static void mt9v_init_sensor(struct gspca_dev
*gspca_dev
)
1180 struct sd
*sd
= (struct sd
*) gspca_dev
;
1183 sd
->i2c_addr
= 0x5d;
1184 i2c_r2(gspca_dev
, 0xff, &value
);
1185 if (gspca_dev
->usb_err
>= 0
1186 && value
== 0x8243) {
1187 i2c_w2_buf(gspca_dev
, mt9v011_init
, ARRAY_SIZE(mt9v011_init
));
1188 if (gspca_dev
->usb_err
< 0) {
1189 pr_err("MT9V011 sensor initialization failed\n");
1194 sd
->sensor
= SENSOR_MT9V011
;
1195 pr_info("MT9V011 sensor detected\n");
1199 gspca_dev
->usb_err
= 0;
1200 sd
->i2c_addr
= 0x5c;
1201 i2c_w2(gspca_dev
, 0x01, 0x0004);
1202 i2c_r2(gspca_dev
, 0xff, &value
);
1203 if (gspca_dev
->usb_err
>= 0
1204 && value
== 0x823a) {
1205 i2c_w2_buf(gspca_dev
, mt9v111_init
, ARRAY_SIZE(mt9v111_init
));
1206 if (gspca_dev
->usb_err
< 0) {
1207 pr_err("MT9V111 sensor initialization failed\n");
1212 sd
->sensor
= SENSOR_MT9V111
;
1213 pr_info("MT9V111 sensor detected\n");
1217 gspca_dev
->usb_err
= 0;
1218 sd
->i2c_addr
= 0x5d;
1219 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1220 if (gspca_dev
->usb_err
< 0) {
1221 gspca_dev
->usb_err
= 0;
1222 sd
->i2c_addr
= 0x48;
1223 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1225 i2c_r2(gspca_dev
, 0x00, &value
);
1226 if (gspca_dev
->usb_err
>= 0
1227 && value
== 0x1229) {
1228 i2c_w2_buf(gspca_dev
, mt9v112_init
, ARRAY_SIZE(mt9v112_init
));
1229 if (gspca_dev
->usb_err
< 0) {
1230 pr_err("MT9V112 sensor initialization failed\n");
1235 sd
->sensor
= SENSOR_MT9V112
;
1236 pr_info("MT9V112 sensor detected\n");
1240 gspca_dev
->usb_err
= -ENODEV
;
1243 static void mt9m112_init_sensor(struct gspca_dev
*gspca_dev
)
1245 struct sd
*sd
= (struct sd
*) gspca_dev
;
1247 i2c_w2_buf(gspca_dev
, mt9m112_init
, ARRAY_SIZE(mt9m112_init
));
1248 if (gspca_dev
->usb_err
< 0)
1249 pr_err("MT9M112 sensor initialization failed\n");
1255 static void mt9m111_init_sensor(struct gspca_dev
*gspca_dev
)
1257 struct sd
*sd
= (struct sd
*) gspca_dev
;
1259 i2c_w2_buf(gspca_dev
, mt9m111_init
, ARRAY_SIZE(mt9m111_init
));
1260 if (gspca_dev
->usb_err
< 0)
1261 pr_err("MT9M111 sensor initialization failed\n");
1267 static void mt9m001_init_sensor(struct gspca_dev
*gspca_dev
)
1269 struct sd
*sd
= (struct sd
*) gspca_dev
;
1272 i2c_r2(gspca_dev
, 0x00, &id
);
1273 if (gspca_dev
->usb_err
< 0)
1276 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
1280 pr_info("MT9M001 color sensor detected\n");
1283 pr_info("MT9M001 mono sensor detected\n");
1286 pr_err("No MT9M001 chip detected, ID = %x\n\n", id
);
1287 gspca_dev
->usb_err
= -ENODEV
;
1291 i2c_w2_buf(gspca_dev
, mt9m001_init
, ARRAY_SIZE(mt9m001_init
));
1292 if (gspca_dev
->usb_err
< 0)
1293 pr_err("MT9M001 sensor initialization failed\n");
1299 static void hv7131r_init_sensor(struct gspca_dev
*gspca_dev
)
1301 struct sd
*sd
= (struct sd
*) gspca_dev
;
1303 i2c_w1_buf(gspca_dev
, hv7131r_init
, ARRAY_SIZE(hv7131r_init
));
1304 if (gspca_dev
->usb_err
< 0)
1305 pr_err("HV7131R Sensor initialization failed\n");
1311 static void set_cmatrix(struct gspca_dev
*gspca_dev
,
1312 s32 brightness
, s32 contrast
, s32 satur
, s32 hue
)
1314 s32 hue_coord
, hue_index
= 180 + hue
;
1317 memset(cmatrix
, 0, sizeof cmatrix
);
1318 cmatrix
[2] = (contrast
* 0x25 / 0x100) + 0x26;
1319 cmatrix
[0] = 0x13 + (cmatrix
[2] - 0x26) * 0x13 / 0x25;
1320 cmatrix
[4] = 0x07 + (cmatrix
[2] - 0x26) * 0x07 / 0x25;
1321 cmatrix
[18] = brightness
- 0x80;
1323 hue_coord
= (hsv_red_x
[hue_index
] * satur
) >> 8;
1324 cmatrix
[6] = hue_coord
;
1325 cmatrix
[7] = (hue_coord
>> 8) & 0x0f;
1327 hue_coord
= (hsv_red_y
[hue_index
] * satur
) >> 8;
1328 cmatrix
[8] = hue_coord
;
1329 cmatrix
[9] = (hue_coord
>> 8) & 0x0f;
1331 hue_coord
= (hsv_green_x
[hue_index
] * satur
) >> 8;
1332 cmatrix
[10] = hue_coord
;
1333 cmatrix
[11] = (hue_coord
>> 8) & 0x0f;
1335 hue_coord
= (hsv_green_y
[hue_index
] * satur
) >> 8;
1336 cmatrix
[12] = hue_coord
;
1337 cmatrix
[13] = (hue_coord
>> 8) & 0x0f;
1339 hue_coord
= (hsv_blue_x
[hue_index
] * satur
) >> 8;
1340 cmatrix
[14] = hue_coord
;
1341 cmatrix
[15] = (hue_coord
>> 8) & 0x0f;
1343 hue_coord
= (hsv_blue_y
[hue_index
] * satur
) >> 8;
1344 cmatrix
[16] = hue_coord
;
1345 cmatrix
[17] = (hue_coord
>> 8) & 0x0f;
1347 reg_w(gspca_dev
, 0x10e1, cmatrix
, 21);
1350 static void set_gamma(struct gspca_dev
*gspca_dev
, s32 val
)
1353 u8 gval
= val
* 0xb8 / 0x100;
1356 gamma
[1] = 0x13 + (gval
* (0xcb - 0x13) / 0xb8);
1357 gamma
[2] = 0x25 + (gval
* (0xee - 0x25) / 0xb8);
1358 gamma
[3] = 0x37 + (gval
* (0xfa - 0x37) / 0xb8);
1359 gamma
[4] = 0x45 + (gval
* (0xfc - 0x45) / 0xb8);
1360 gamma
[5] = 0x55 + (gval
* (0xfb - 0x55) / 0xb8);
1361 gamma
[6] = 0x65 + (gval
* (0xfc - 0x65) / 0xb8);
1362 gamma
[7] = 0x74 + (gval
* (0xfd - 0x74) / 0xb8);
1363 gamma
[8] = 0x83 + (gval
* (0xfe - 0x83) / 0xb8);
1364 gamma
[9] = 0x92 + (gval
* (0xfc - 0x92) / 0xb8);
1365 gamma
[10] = 0xa1 + (gval
* (0xfc - 0xa1) / 0xb8);
1366 gamma
[11] = 0xb0 + (gval
* (0xfc - 0xb0) / 0xb8);
1367 gamma
[12] = 0xbf + (gval
* (0xfb - 0xbf) / 0xb8);
1368 gamma
[13] = 0xce + (gval
* (0xfb - 0xce) / 0xb8);
1369 gamma
[14] = 0xdf + (gval
* (0xfd - 0xdf) / 0xb8);
1370 gamma
[15] = 0xea + (gval
* (0xf9 - 0xea) / 0xb8);
1373 reg_w(gspca_dev
, 0x1190, gamma
, 17);
1376 static void set_redblue(struct gspca_dev
*gspca_dev
, s32 blue
, s32 red
)
1378 reg_w1(gspca_dev
, 0x118c, red
);
1379 reg_w1(gspca_dev
, 0x118f, blue
);
1382 static void set_hvflip(struct gspca_dev
*gspca_dev
, s32 hflip
, s32 vflip
)
1386 struct sd
*sd
= (struct sd
*) gspca_dev
;
1388 if ((sd
->flags
& FLIP_DETECT
) && dmi_check_system(flip_dmi_table
)) {
1393 switch (sd
->sensor
) {
1404 reg_w1(gspca_dev
, 0x1182, sd
->vstart
);
1405 i2c_w1(gspca_dev
, 0x1e, value
);
1408 i2c_r1(gspca_dev
, 0x1e, &value
);
1417 i2c_w1(gspca_dev
, 0x1e, value
);
1418 i2c_w1(gspca_dev
, 0x3a, tslb
);
1420 case SENSOR_MT9V111
:
1421 case SENSOR_MT9V011
:
1422 i2c_r2(gspca_dev
, 0x20, &value2
);
1428 i2c_w2(gspca_dev
, 0x20, value2
);
1430 case SENSOR_MT9M112
:
1431 case SENSOR_MT9M111
:
1432 case SENSOR_MT9V112
:
1433 i2c_r2(gspca_dev
, 0x20, &value2
);
1439 i2c_w2(gspca_dev
, 0x20, value2
);
1441 case SENSOR_HV7131R
:
1442 i2c_r1(gspca_dev
, 0x01, &value
);
1448 i2c_w1(gspca_dev
, 0x01, value
);
1453 static void set_exposure(struct gspca_dev
*gspca_dev
, s32 expo
)
1455 struct sd
*sd
= (struct sd
*) gspca_dev
;
1456 u8 exp
[8] = {sd
->i2c_intf
, sd
->i2c_addr
,
1457 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1460 if (gspca_dev
->streaming
)
1463 switch (sd
->sensor
) {
1473 exp
[2] = 0x10; /* AECH */
1474 exp
[3] = expo2
>> 2;
1476 i2c_w(gspca_dev
, exp
);
1477 exp
[2] = 0x04; /* COM1 */
1478 exp
[3] = expo2
& 0x0003;
1480 i2c_w(gspca_dev
, exp
);
1484 exp
[2] = 0x2d; /* ADVFL & ADVFH */
1488 case SENSOR_MT9M001
:
1489 case SENSOR_MT9V112
:
1490 case SENSOR_MT9V011
:
1496 case SENSOR_HV7131R
:
1506 i2c_w(gspca_dev
, exp
);
1509 static void set_gain(struct gspca_dev
*gspca_dev
, s32 g
)
1511 struct sd
*sd
= (struct sd
*) gspca_dev
;
1512 u8 gain
[8] = {sd
->i2c_intf
, sd
->i2c_addr
,
1513 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1515 if (gspca_dev
->streaming
)
1516 gain
[7] = 0x15; /* or 1d ? */
1518 switch (sd
->sensor
) {
1524 gain
[0] |= (2 << 4);
1525 gain
[3] = ov_gain
[g
];
1527 case SENSOR_MT9V011
:
1528 gain
[0] |= (3 << 4);
1530 gain
[3] = micron1_gain
[g
] >> 8;
1531 gain
[4] = micron1_gain
[g
];
1533 case SENSOR_MT9V112
:
1534 gain
[0] |= (3 << 4);
1536 gain
[3] = micron1_gain
[g
] >> 8;
1537 gain
[4] = micron1_gain
[g
];
1539 case SENSOR_MT9M001
:
1540 gain
[0] |= (3 << 4);
1542 gain
[3] = micron2_gain
[g
] >> 8;
1543 gain
[4] = micron2_gain
[g
];
1545 case SENSOR_HV7131R
:
1546 gain
[0] |= (2 << 4);
1548 gain
[3] = hv7131r_gain
[g
];
1553 i2c_w(gspca_dev
, gain
);
1556 static void set_quality(struct gspca_dev
*gspca_dev
, s32 val
)
1558 struct sd
*sd
= (struct sd
*) gspca_dev
;
1560 jpeg_set_qual(sd
->jpeg_hdr
, val
);
1561 reg_w1(gspca_dev
, 0x1061, 0x01); /* stop transfer */
1562 reg_w1(gspca_dev
, 0x10e0, sd
->fmt
| 0x20); /* write QTAB */
1563 reg_w(gspca_dev
, 0x1100, &sd
->jpeg_hdr
[JPEG_QT0_OFFSET
], 64);
1564 reg_w(gspca_dev
, 0x1140, &sd
->jpeg_hdr
[JPEG_QT1_OFFSET
], 64);
1565 reg_w1(gspca_dev
, 0x1061, 0x03); /* restart transfer */
1566 reg_w1(gspca_dev
, 0x10e0, sd
->fmt
);
1567 sd
->fmt
^= 0x0c; /* invert QTAB use + write */
1568 reg_w1(gspca_dev
, 0x10e0, sd
->fmt
);
1571 #ifdef CONFIG_VIDEO_ADV_DEBUG
1572 static int sd_dbg_g_register(struct gspca_dev
*gspca_dev
,
1573 struct v4l2_dbg_register
*reg
)
1575 struct sd
*sd
= (struct sd
*) gspca_dev
;
1577 switch (reg
->match
.type
) {
1578 case V4L2_CHIP_MATCH_HOST
:
1579 if (reg
->match
.addr
!= 0)
1581 if (reg
->reg
< 0x1000 || reg
->reg
> 0x11ff)
1583 reg_r(gspca_dev
, reg
->reg
, 1);
1584 reg
->val
= gspca_dev
->usb_buf
[0];
1585 return gspca_dev
->usb_err
;
1586 case V4L2_CHIP_MATCH_I2C_ADDR
:
1587 if (reg
->match
.addr
!= sd
->i2c_addr
)
1589 if (sd
->sensor
>= SENSOR_MT9V011
&&
1590 sd
->sensor
<= SENSOR_MT9M112
) {
1591 i2c_r2(gspca_dev
, reg
->reg
, (u16
*) ®
->val
);
1593 i2c_r1(gspca_dev
, reg
->reg
, (u8
*) ®
->val
);
1595 return gspca_dev
->usb_err
;
1600 static int sd_dbg_s_register(struct gspca_dev
*gspca_dev
,
1601 struct v4l2_dbg_register
*reg
)
1603 struct sd
*sd
= (struct sd
*) gspca_dev
;
1605 switch (reg
->match
.type
) {
1606 case V4L2_CHIP_MATCH_HOST
:
1607 if (reg
->match
.addr
!= 0)
1609 if (reg
->reg
< 0x1000 || reg
->reg
> 0x11ff)
1611 reg_w1(gspca_dev
, reg
->reg
, reg
->val
);
1612 return gspca_dev
->usb_err
;
1613 case V4L2_CHIP_MATCH_I2C_ADDR
:
1614 if (reg
->match
.addr
!= sd
->i2c_addr
)
1616 if (sd
->sensor
>= SENSOR_MT9V011
&&
1617 sd
->sensor
<= SENSOR_MT9M112
) {
1618 i2c_w2(gspca_dev
, reg
->reg
, reg
->val
);
1620 i2c_w1(gspca_dev
, reg
->reg
, reg
->val
);
1622 return gspca_dev
->usb_err
;
1628 static int sd_chip_ident(struct gspca_dev
*gspca_dev
,
1629 struct v4l2_dbg_chip_ident
*chip
)
1631 struct sd
*sd
= (struct sd
*) gspca_dev
;
1633 switch (chip
->match
.type
) {
1634 case V4L2_CHIP_MATCH_HOST
:
1635 if (chip
->match
.addr
!= 0)
1638 chip
->ident
= V4L2_IDENT_SN9C20X
;
1640 case V4L2_CHIP_MATCH_I2C_ADDR
:
1641 if (chip
->match
.addr
!= sd
->i2c_addr
)
1644 chip
->ident
= i2c_ident
[sd
->sensor
];
1650 static int sd_config(struct gspca_dev
*gspca_dev
,
1651 const struct usb_device_id
*id
)
1653 struct sd
*sd
= (struct sd
*) gspca_dev
;
1656 cam
= &gspca_dev
->cam
;
1657 cam
->needs_full_bandwidth
= 1;
1659 sd
->sensor
= id
->driver_info
>> 8;
1660 sd
->i2c_addr
= id
->driver_info
;
1661 sd
->flags
= id
->driver_info
>> 16;
1662 sd
->i2c_intf
= 0x80; /* i2c 100 Kb/s */
1664 switch (sd
->sensor
) {
1665 case SENSOR_MT9M112
:
1666 case SENSOR_MT9M111
:
1669 cam
->cam_mode
= sxga_mode
;
1670 cam
->nmodes
= ARRAY_SIZE(sxga_mode
);
1672 case SENSOR_MT9M001
:
1673 cam
->cam_mode
= mono_mode
;
1674 cam
->nmodes
= ARRAY_SIZE(mono_mode
);
1676 case SENSOR_HV7131R
:
1677 sd
->i2c_intf
= 0x81; /* i2c 400 Kb/s */
1680 cam
->cam_mode
= vga_mode
;
1681 cam
->nmodes
= ARRAY_SIZE(vga_mode
);
1687 sd
->exposure_step
= 16;
1689 INIT_WORK(&sd
->work
, qual_upd
);
1694 static int sd_s_ctrl(struct v4l2_ctrl
*ctrl
)
1696 struct gspca_dev
*gspca_dev
=
1697 container_of(ctrl
->handler
, struct gspca_dev
, ctrl_handler
);
1698 struct sd
*sd
= (struct sd
*)gspca_dev
;
1700 gspca_dev
->usb_err
= 0;
1702 if (!gspca_dev
->streaming
)
1706 /* color control cluster */
1707 case V4L2_CID_BRIGHTNESS
:
1708 set_cmatrix(gspca_dev
, sd
->brightness
->val
,
1709 sd
->contrast
->val
, sd
->saturation
->val
, sd
->hue
->val
);
1711 case V4L2_CID_GAMMA
:
1712 set_gamma(gspca_dev
, ctrl
->val
);
1714 /* blue/red balance cluster */
1715 case V4L2_CID_BLUE_BALANCE
:
1716 set_redblue(gspca_dev
, sd
->blue
->val
, sd
->red
->val
);
1718 /* h/vflip cluster */
1719 case V4L2_CID_HFLIP
:
1720 set_hvflip(gspca_dev
, sd
->hflip
->val
, sd
->vflip
->val
);
1722 /* standalone exposure control */
1723 case V4L2_CID_EXPOSURE
:
1724 set_exposure(gspca_dev
, ctrl
->val
);
1726 /* standalone gain control */
1728 set_gain(gspca_dev
, ctrl
->val
);
1730 /* autogain + exposure or gain control cluster */
1731 case V4L2_CID_AUTOGAIN
:
1732 if (sd
->sensor
== SENSOR_SOI968
)
1733 set_gain(gspca_dev
, sd
->gain
->val
);
1735 set_exposure(gspca_dev
, sd
->exposure
->val
);
1737 case V4L2_CID_JPEG_COMPRESSION_QUALITY
:
1738 set_quality(gspca_dev
, ctrl
->val
);
1741 return gspca_dev
->usb_err
;
1744 static const struct v4l2_ctrl_ops sd_ctrl_ops
= {
1745 .s_ctrl
= sd_s_ctrl
,
1748 static int sd_init_controls(struct gspca_dev
*gspca_dev
)
1750 struct sd
*sd
= (struct sd
*) gspca_dev
;
1751 struct v4l2_ctrl_handler
*hdl
= &gspca_dev
->ctrl_handler
;
1753 gspca_dev
->vdev
.ctrl_handler
= hdl
;
1754 v4l2_ctrl_handler_init(hdl
, 13);
1756 sd
->brightness
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1757 V4L2_CID_BRIGHTNESS
, 0, 255, 1, 127);
1758 sd
->contrast
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1759 V4L2_CID_CONTRAST
, 0, 255, 1, 127);
1760 sd
->saturation
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1761 V4L2_CID_SATURATION
, 0, 255, 1, 127);
1762 sd
->hue
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1763 V4L2_CID_HUE
, -180, 180, 1, 0);
1764 v4l2_ctrl_cluster(4, &sd
->brightness
);
1766 sd
->gamma
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1767 V4L2_CID_GAMMA
, 0, 255, 1, 0x10);
1769 sd
->blue
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1770 V4L2_CID_BLUE_BALANCE
, 0, 127, 1, 0x28);
1771 sd
->red
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1772 V4L2_CID_RED_BALANCE
, 0, 127, 1, 0x28);
1773 v4l2_ctrl_cluster(2, &sd
->blue
);
1775 if (sd
->sensor
!= SENSOR_OV9655
&& sd
->sensor
!= SENSOR_SOI968
&&
1776 sd
->sensor
!= SENSOR_OV7670
&& sd
->sensor
!= SENSOR_MT9M001
&&
1777 sd
->sensor
!= SENSOR_MT9VPRB
) {
1778 sd
->hflip
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1779 V4L2_CID_HFLIP
, 0, 1, 1, 0);
1780 sd
->vflip
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1781 V4L2_CID_VFLIP
, 0, 1, 1, 0);
1782 v4l2_ctrl_cluster(2, &sd
->hflip
);
1785 if (sd
->sensor
!= SENSOR_SOI968
&& sd
->sensor
!= SENSOR_MT9VPRB
&&
1786 sd
->sensor
!= SENSOR_MT9M112
&& sd
->sensor
!= SENSOR_MT9M111
&&
1787 sd
->sensor
!= SENSOR_MT9V111
)
1788 sd
->exposure
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1789 V4L2_CID_EXPOSURE
, 0, 0x1780, 1, 0x33);
1791 if (sd
->sensor
!= SENSOR_MT9VPRB
&& sd
->sensor
!= SENSOR_MT9M112
&&
1792 sd
->sensor
!= SENSOR_MT9M111
&& sd
->sensor
!= SENSOR_MT9V111
) {
1793 sd
->gain
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1794 V4L2_CID_GAIN
, 0, 28, 1, 0);
1795 sd
->autogain
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1796 V4L2_CID_AUTOGAIN
, 0, 1, 1, 1);
1797 if (sd
->sensor
== SENSOR_SOI968
)
1798 /* this sensor doesn't have the exposure control and
1799 autogain is clustered with gain instead. This works
1800 because sd->exposure == NULL. */
1801 v4l2_ctrl_auto_cluster(3, &sd
->autogain
, 0, false);
1803 /* Otherwise autogain is clustered with exposure. */
1804 v4l2_ctrl_auto_cluster(2, &sd
->autogain
, 0, false);
1807 sd
->jpegqual
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1808 V4L2_CID_JPEG_COMPRESSION_QUALITY
, 50, 90, 1, 80);
1810 pr_err("Could not initialize controls\n");
1816 static int sd_init(struct gspca_dev
*gspca_dev
)
1818 struct sd
*sd
= (struct sd
*) gspca_dev
;
1822 {0x80, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};
1824 for (i
= 0; i
< ARRAY_SIZE(bridge_init
); i
++) {
1825 value
= bridge_init
[i
][1];
1826 reg_w(gspca_dev
, bridge_init
[i
][0], &value
, 1);
1827 if (gspca_dev
->usb_err
< 0) {
1828 pr_err("Device initialization failed\n");
1829 return gspca_dev
->usb_err
;
1833 if (sd
->flags
& LED_REVERSE
)
1834 reg_w1(gspca_dev
, 0x1006, 0x00);
1836 reg_w1(gspca_dev
, 0x1006, 0x20);
1838 reg_w(gspca_dev
, 0x10c0, i2c_init
, 9);
1839 if (gspca_dev
->usb_err
< 0) {
1840 pr_err("Device initialization failed\n");
1841 return gspca_dev
->usb_err
;
1844 switch (sd
->sensor
) {
1846 ov9650_init_sensor(gspca_dev
);
1847 if (gspca_dev
->usb_err
< 0)
1849 pr_info("OV9650 sensor detected\n");
1852 ov9655_init_sensor(gspca_dev
);
1853 if (gspca_dev
->usb_err
< 0)
1855 pr_info("OV9655 sensor detected\n");
1858 soi968_init_sensor(gspca_dev
);
1859 if (gspca_dev
->usb_err
< 0)
1861 pr_info("SOI968 sensor detected\n");
1864 ov7660_init_sensor(gspca_dev
);
1865 if (gspca_dev
->usb_err
< 0)
1867 pr_info("OV7660 sensor detected\n");
1870 ov7670_init_sensor(gspca_dev
);
1871 if (gspca_dev
->usb_err
< 0)
1873 pr_info("OV7670 sensor detected\n");
1875 case SENSOR_MT9VPRB
:
1876 mt9v_init_sensor(gspca_dev
);
1877 if (gspca_dev
->usb_err
< 0)
1879 pr_info("MT9VPRB sensor detected\n");
1881 case SENSOR_MT9M111
:
1882 mt9m111_init_sensor(gspca_dev
);
1883 if (gspca_dev
->usb_err
< 0)
1885 pr_info("MT9M111 sensor detected\n");
1887 case SENSOR_MT9M112
:
1888 mt9m112_init_sensor(gspca_dev
);
1889 if (gspca_dev
->usb_err
< 0)
1891 pr_info("MT9M112 sensor detected\n");
1893 case SENSOR_MT9M001
:
1894 mt9m001_init_sensor(gspca_dev
);
1895 if (gspca_dev
->usb_err
< 0)
1898 case SENSOR_HV7131R
:
1899 hv7131r_init_sensor(gspca_dev
);
1900 if (gspca_dev
->usb_err
< 0)
1902 pr_info("HV7131R sensor detected\n");
1905 pr_err("Unsupported sensor\n");
1906 gspca_dev
->usb_err
= -ENODEV
;
1908 return gspca_dev
->usb_err
;
1911 static void configure_sensor_output(struct gspca_dev
*gspca_dev
, int mode
)
1913 struct sd
*sd
= (struct sd
*) gspca_dev
;
1916 switch (sd
->sensor
) {
1918 if (mode
& MODE_SXGA
) {
1919 i2c_w1(gspca_dev
, 0x17, 0x1d);
1920 i2c_w1(gspca_dev
, 0x18, 0xbd);
1921 i2c_w1(gspca_dev
, 0x19, 0x01);
1922 i2c_w1(gspca_dev
, 0x1a, 0x81);
1923 i2c_w1(gspca_dev
, 0x12, 0x00);
1927 i2c_w1(gspca_dev
, 0x17, 0x13);
1928 i2c_w1(gspca_dev
, 0x18, 0x63);
1929 i2c_w1(gspca_dev
, 0x19, 0x01);
1930 i2c_w1(gspca_dev
, 0x1a, 0x79);
1931 i2c_w1(gspca_dev
, 0x12, 0x40);
1937 if (mode
& MODE_SXGA
) {
1938 i2c_w1(gspca_dev
, 0x17, 0x1b);
1939 i2c_w1(gspca_dev
, 0x18, 0xbc);
1940 i2c_w1(gspca_dev
, 0x19, 0x01);
1941 i2c_w1(gspca_dev
, 0x1a, 0x82);
1942 i2c_r1(gspca_dev
, 0x12, &value
);
1943 i2c_w1(gspca_dev
, 0x12, value
& 0x07);
1945 i2c_w1(gspca_dev
, 0x17, 0x24);
1946 i2c_w1(gspca_dev
, 0x18, 0xc5);
1947 i2c_w1(gspca_dev
, 0x19, 0x00);
1948 i2c_w1(gspca_dev
, 0x1a, 0x3c);
1949 i2c_r1(gspca_dev
, 0x12, &value
);
1950 i2c_w1(gspca_dev
, 0x12, (value
& 0x7) | 0x40);
1953 case SENSOR_MT9M112
:
1954 case SENSOR_MT9M111
:
1955 if (mode
& MODE_SXGA
) {
1956 i2c_w2(gspca_dev
, 0xf0, 0x0002);
1957 i2c_w2(gspca_dev
, 0xc8, 0x970b);
1958 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1960 i2c_w2(gspca_dev
, 0xf0, 0x0002);
1961 i2c_w2(gspca_dev
, 0xc8, 0x8000);
1962 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1968 static int sd_isoc_init(struct gspca_dev
*gspca_dev
)
1970 struct usb_interface
*intf
;
1971 u32 flags
= gspca_dev
->cam
.cam_mode
[(int)gspca_dev
->curr_mode
].priv
;
1974 * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth
1975 * than our regular bandwidth calculations reserve, so we force the
1976 * use of a specific altsetting when using the SN9C20X_I420 fmt.
1978 if (!(flags
& (MODE_RAW
| MODE_JPEG
))) {
1979 intf
= usb_ifnum_to_if(gspca_dev
->dev
, gspca_dev
->iface
);
1981 if (intf
->num_altsetting
!= 9) {
1982 pr_warn("sn9c20x camera with unknown number of alt "
1983 "settings (%d), please report!\n",
1984 intf
->num_altsetting
);
1985 gspca_dev
->alt
= intf
->num_altsetting
;
1989 switch (gspca_dev
->width
) {
1990 case 160: /* 160x120 */
1993 case 320: /* 320x240 */
1996 default: /* >= 640x480 */
2005 #define HW_WIN(mode, hstart, vstart) \
2006 ((const u8 []){hstart, 0, vstart, 0, \
2007 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
2008 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
2010 #define CLR_WIN(width, height) \
2012 {0, width >> 2, 0, height >> 1,\
2013 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
2015 static int sd_start(struct gspca_dev
*gspca_dev
)
2017 struct sd
*sd
= (struct sd
*) gspca_dev
;
2018 int mode
= gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
;
2019 int width
= gspca_dev
->width
;
2020 int height
= gspca_dev
->height
;
2023 jpeg_define(sd
->jpeg_hdr
, height
, width
,
2025 jpeg_set_qual(sd
->jpeg_hdr
, v4l2_ctrl_g_ctrl(sd
->jpegqual
));
2027 if (mode
& MODE_RAW
)
2029 else if (mode
& MODE_JPEG
)
2032 fmt
= 0x2f; /* YUV 420 */
2035 switch (mode
& SCALE_MASK
) {
2036 case SCALE_1280x1024
:
2038 pr_info("Set 1280x1024\n");
2042 pr_info("Set 640x480\n");
2046 pr_info("Set 320x240\n");
2050 pr_info("Set 160x120\n");
2054 configure_sensor_output(gspca_dev
, mode
);
2055 reg_w(gspca_dev
, 0x1100, &sd
->jpeg_hdr
[JPEG_QT0_OFFSET
], 64);
2056 reg_w(gspca_dev
, 0x1140, &sd
->jpeg_hdr
[JPEG_QT1_OFFSET
], 64);
2057 reg_w(gspca_dev
, 0x10fb, CLR_WIN(width
, height
), 5);
2058 reg_w(gspca_dev
, 0x1180, HW_WIN(mode
, sd
->hstart
, sd
->vstart
), 6);
2059 reg_w1(gspca_dev
, 0x1189, scale
);
2060 reg_w1(gspca_dev
, 0x10e0, fmt
);
2062 set_cmatrix(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->brightness
),
2063 v4l2_ctrl_g_ctrl(sd
->contrast
),
2064 v4l2_ctrl_g_ctrl(sd
->saturation
),
2065 v4l2_ctrl_g_ctrl(sd
->hue
));
2066 set_gamma(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->gamma
));
2067 set_redblue(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->blue
),
2068 v4l2_ctrl_g_ctrl(sd
->red
));
2069 set_gain(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->gain
));
2070 set_exposure(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->exposure
));
2071 set_hvflip(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->hflip
),
2072 v4l2_ctrl_g_ctrl(sd
->vflip
));
2074 reg_w1(gspca_dev
, 0x1007, 0x20);
2075 reg_w1(gspca_dev
, 0x1061, 0x03);
2077 /* if JPEG, prepare the compression quality update */
2078 if (mode
& MODE_JPEG
) {
2079 sd
->pktsz
= sd
->npkt
= 0;
2082 create_singlethread_workqueue(KBUILD_MODNAME
);
2085 return gspca_dev
->usb_err
;
2088 static void sd_stopN(struct gspca_dev
*gspca_dev
)
2090 reg_w1(gspca_dev
, 0x1007, 0x00);
2091 reg_w1(gspca_dev
, 0x1061, 0x01);
2094 /* called on streamoff with alt==0 and on disconnect */
2095 /* the usb_lock is held at entry - restore on exit */
2096 static void sd_stop0(struct gspca_dev
*gspca_dev
)
2098 struct sd
*sd
= (struct sd
*) gspca_dev
;
2100 if (sd
->work_thread
!= NULL
) {
2101 mutex_unlock(&gspca_dev
->usb_lock
);
2102 destroy_workqueue(sd
->work_thread
);
2103 mutex_lock(&gspca_dev
->usb_lock
);
2104 sd
->work_thread
= NULL
;
2108 static void do_autoexposure(struct gspca_dev
*gspca_dev
, u16 avg_lum
)
2110 struct sd
*sd
= (struct sd
*) gspca_dev
;
2111 s32 cur_exp
= v4l2_ctrl_g_ctrl(sd
->exposure
);
2112 s32 max
= sd
->exposure
->maximum
- sd
->exposure_step
;
2113 s32 min
= sd
->exposure
->minimum
+ sd
->exposure_step
;
2117 * some hardcoded values are present
2118 * like those for maximal/minimal exposure
2119 * and exposure steps
2121 if (avg_lum
< MIN_AVG_LUM
) {
2125 new_exp
= cur_exp
+ sd
->exposure_step
;
2130 v4l2_ctrl_s_ctrl(sd
->exposure
, new_exp
);
2132 sd
->older_step
= sd
->old_step
;
2135 if (sd
->old_step
^ sd
->older_step
)
2136 sd
->exposure_step
/= 2;
2138 sd
->exposure_step
+= 2;
2140 if (avg_lum
> MAX_AVG_LUM
) {
2143 new_exp
= cur_exp
- sd
->exposure_step
;
2148 v4l2_ctrl_s_ctrl(sd
->exposure
, new_exp
);
2149 sd
->older_step
= sd
->old_step
;
2152 if (sd
->old_step
^ sd
->older_step
)
2153 sd
->exposure_step
/= 2;
2155 sd
->exposure_step
+= 2;
2159 static void do_autogain(struct gspca_dev
*gspca_dev
, u16 avg_lum
)
2161 struct sd
*sd
= (struct sd
*) gspca_dev
;
2162 s32 cur_gain
= v4l2_ctrl_g_ctrl(sd
->gain
);
2164 if (avg_lum
< MIN_AVG_LUM
&& cur_gain
< sd
->gain
->maximum
)
2165 v4l2_ctrl_s_ctrl(sd
->gain
, cur_gain
+ 1);
2166 if (avg_lum
> MAX_AVG_LUM
&& cur_gain
> sd
->gain
->minimum
)
2167 v4l2_ctrl_s_ctrl(sd
->gain
, cur_gain
- 1);
2170 static void sd_dqcallback(struct gspca_dev
*gspca_dev
)
2172 struct sd
*sd
= (struct sd
*) gspca_dev
;
2175 if (!v4l2_ctrl_g_ctrl(sd
->autogain
))
2178 avg_lum
= atomic_read(&sd
->avg_lum
);
2179 if (sd
->sensor
== SENSOR_SOI968
)
2180 do_autogain(gspca_dev
, avg_lum
);
2182 do_autoexposure(gspca_dev
, avg_lum
);
2185 /* JPEG quality update */
2186 /* This function is executed from a work queue. */
2187 static void qual_upd(struct work_struct
*work
)
2189 struct sd
*sd
= container_of(work
, struct sd
, work
);
2190 struct gspca_dev
*gspca_dev
= &sd
->gspca_dev
;
2191 s32 qual
= v4l2_ctrl_g_ctrl(sd
->jpegqual
);
2193 mutex_lock(&gspca_dev
->usb_lock
);
2194 PDEBUG(D_STREAM
, "qual_upd %d%%", qual
);
2195 set_quality(gspca_dev
, qual
);
2196 mutex_unlock(&gspca_dev
->usb_lock
);
2199 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2200 static int sd_int_pkt_scan(struct gspca_dev
*gspca_dev
,
2201 u8
*data
, /* interrupt packet */
2202 int len
) /* interrupt packet length */
2204 struct sd
*sd
= (struct sd
*) gspca_dev
;
2206 if (!(sd
->flags
& HAS_NO_BUTTON
) && len
== 1) {
2207 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 1);
2208 input_sync(gspca_dev
->input_dev
);
2209 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 0);
2210 input_sync(gspca_dev
->input_dev
);
2217 /* check the JPEG compression */
2218 static void transfer_check(struct gspca_dev
*gspca_dev
,
2221 struct sd
*sd
= (struct sd
*) gspca_dev
;
2226 /* if USB error, discard the frame and decrease the quality */
2227 if (data
[6] & 0x08) { /* USB FIFO full */
2228 gspca_dev
->last_packet_type
= DISCARD_PACKET
;
2232 /* else, compute the filling rate and a new JPEG quality */
2233 r
= (sd
->pktsz
* 100) /
2235 gspca_dev
->urb
[0]->iso_frame_desc
[0].length
);
2241 if (new_qual
!= 0) {
2242 sd
->nchg
+= new_qual
;
2243 if (sd
->nchg
< -6 || sd
->nchg
>= 12) {
2244 /* Note: we are in interrupt context, so we can't
2245 use v4l2_ctrl_g/s_ctrl here. Access the value
2246 directly instead. */
2247 s32 curqual
= sd
->jpegqual
->cur
.val
;
2249 new_qual
+= curqual
;
2250 if (new_qual
< sd
->jpegqual
->minimum
)
2251 new_qual
= sd
->jpegqual
->minimum
;
2252 else if (new_qual
> sd
->jpegqual
->maximum
)
2253 new_qual
= sd
->jpegqual
->maximum
;
2254 if (new_qual
!= curqual
) {
2255 sd
->jpegqual
->cur
.val
= new_qual
;
2256 queue_work(sd
->work_thread
, &sd
->work
);
2262 sd
->pktsz
= sd
->npkt
= 0;
2265 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
2266 u8
*data
, /* isoc packet */
2267 int len
) /* iso packet length */
2269 struct sd
*sd
= (struct sd
*) gspca_dev
;
2270 int avg_lum
, is_jpeg
;
2271 static const u8 frame_header
[] =
2272 {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2274 is_jpeg
= (sd
->fmt
& 0x03) == 0;
2275 if (len
>= 64 && memcmp(data
, frame_header
, 6) == 0) {
2276 avg_lum
= ((data
[35] >> 2) & 3) |
2279 avg_lum
+= ((data
[35] >> 4) & 3) |
2282 avg_lum
+= ((data
[35] >> 6) & 3) |
2285 avg_lum
+= (data
[36] & 3) |
2288 avg_lum
+= ((data
[36] >> 2) & 3) |
2291 avg_lum
+= ((data
[36] >> 4) & 3) |
2294 avg_lum
+= ((data
[36] >> 6) & 3) |
2297 avg_lum
+= ((data
[44] >> 4) & 3) |
2301 atomic_set(&sd
->avg_lum
, avg_lum
);
2304 transfer_check(gspca_dev
, data
);
2306 gspca_frame_add(gspca_dev
, LAST_PACKET
, NULL
, 0);
2312 if (gspca_dev
->last_packet_type
== LAST_PACKET
) {
2314 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
2315 sd
->jpeg_hdr
, JPEG_HDR_SZ
);
2316 gspca_frame_add(gspca_dev
, INTER_PACKET
,
2319 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
2323 /* if JPEG, count the packets and their size */
2328 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, len
);
2332 /* sub-driver description */
2333 static const struct sd_desc sd_desc
= {
2334 .name
= KBUILD_MODNAME
,
2335 .config
= sd_config
,
2337 .init_controls
= sd_init_controls
,
2338 .isoc_init
= sd_isoc_init
,
2342 .pkt_scan
= sd_pkt_scan
,
2343 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2344 .int_pkt_scan
= sd_int_pkt_scan
,
2346 .dq_callback
= sd_dqcallback
,
2347 #ifdef CONFIG_VIDEO_ADV_DEBUG
2348 .set_register
= sd_dbg_s_register
,
2349 .get_register
= sd_dbg_g_register
,
2351 .get_chip_ident
= sd_chip_ident
,
2354 #define SN9C20X(sensor, i2c_addr, flags) \
2355 .driver_info = ((flags & 0xff) << 16) \
2356 | (SENSOR_ ## sensor << 8) \
2359 static const struct usb_device_id device_table
[] = {
2360 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001
, 0x5d, 0)},
2361 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111
, 0x5d, 0)},
2362 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655
, 0x30, 0)},
2363 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112
, 0x5d, 0)},
2364 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968
, 0x30, LED_REVERSE
)},
2365 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650
, 0x30,
2366 (FLIP_DETECT
| HAS_NO_BUTTON
))},
2367 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650
, 0x30, 0)},
2368 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650
, 0x30, 0)},
2369 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670
, 0x21, 0)},
2370 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB
, 0x00, 0)},
2371 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660
, 0x21, FLIP_DETECT
)},
2372 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R
, 0x11, 0)},
2373 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650
, 0x30, 0)},
2374 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001
, 0x5d, 0)},
2375 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111
, 0x5d, 0)},
2376 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655
, 0x30, 0)},
2377 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112
, 0x5d, 0)},
2378 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968
, 0x30, 0)},
2379 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650
, 0x30, 0)},
2380 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670
, 0x21, 0)},
2381 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB
, 0x00, 0)},
2382 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655
, 0x30, LED_REVERSE
)},
2383 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660
, 0x21, LED_REVERSE
)},
2384 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R
, 0x11, 0)},
2385 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650
, 0x30, 0)},
2386 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660
, 0x21, 0)},
2387 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R
, 0x11, 0)},
2388 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112
, 0x5d, 0)},
2389 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112
, 0x5d, 0)},
2390 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R
, 0x11, 0)},
2391 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R
, 0x11, 0)},
2392 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R
, 0x11, 0)},
2393 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R
, 0x11, 0)},
2394 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111
, 0x5d, 0)},
2395 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111
, 0x5d, 0)},
2396 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111
, 0x5d, 0)},
2399 MODULE_DEVICE_TABLE(usb
, device_table
);
2401 /* -- device connect -- */
2402 static int sd_probe(struct usb_interface
*intf
,
2403 const struct usb_device_id
*id
)
2405 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
2409 static struct usb_driver sd_driver
= {
2410 .name
= KBUILD_MODNAME
,
2411 .id_table
= device_table
,
2413 .disconnect
= gspca_disconnect
,
2415 .suspend
= gspca_suspend
,
2416 .resume
= gspca_resume
,
2417 .reset_resume
= gspca_resume
,
2421 module_usb_driver(sd_driver
);