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>, "
33 "microdia project <microdia@googlegroups.com>");
34 MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
35 MODULE_LICENSE("GPL");
38 * Pixel format private data
40 #define SCALE_MASK 0x0f
41 #define SCALE_160x120 0
42 #define SCALE_320x240 1
43 #define SCALE_640x480 2
44 #define SCALE_1280x1024 3
46 #define MODE_JPEG 0x20
47 #define MODE_SXGA 0x80
49 #define SENSOR_OV9650 0
50 #define SENSOR_OV9655 1
51 #define SENSOR_SOI968 2
52 #define SENSOR_OV7660 3
53 #define SENSOR_OV7670 4
54 #define SENSOR_MT9V011 5
55 #define SENSOR_MT9V111 6
56 #define SENSOR_MT9V112 7
57 #define SENSOR_MT9M001 8
58 #define SENSOR_MT9M111 9
59 #define SENSOR_MT9M112 10
60 #define SENSOR_HV7131R 11
61 #define SENSOR_MT9VPRB 12
64 #define HAS_NO_BUTTON 0x1
65 #define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
66 #define FLIP_DETECT 0x4
68 /* specific webcam descriptor */
70 struct gspca_dev gspca_dev
;
72 struct { /* color control cluster */
73 struct v4l2_ctrl
*brightness
;
74 struct v4l2_ctrl
*contrast
;
75 struct v4l2_ctrl
*saturation
;
76 struct v4l2_ctrl
*hue
;
78 struct { /* blue/red balance control cluster */
79 struct v4l2_ctrl
*blue
;
80 struct v4l2_ctrl
*red
;
82 struct { /* h/vflip control cluster */
83 struct v4l2_ctrl
*hflip
;
84 struct v4l2_ctrl
*vflip
;
86 struct v4l2_ctrl
*gamma
;
87 struct { /* autogain and exposure or gain control cluster */
88 struct v4l2_ctrl
*autogain
;
89 struct v4l2_ctrl
*exposure
;
90 struct v4l2_ctrl
*gain
;
92 struct v4l2_ctrl
*jpegqual
;
94 struct work_struct work
;
96 u32 pktsz
; /* (used by pkt_scan) */
99 u8 fmt
; /* (used for JPEG QTAB update */
101 #define MIN_AVG_LUM 80
102 #define MAX_AVG_LUM 130
114 u8 jpeg_hdr
[JPEG_HDR_SZ
];
119 static void qual_upd(struct work_struct
*work
);
131 static const struct dmi_system_id flip_dmi_table
[] = {
133 .ident
= "MSI MS-1034",
135 DMI_MATCH(DMI_SYS_VENDOR
, "MICRO-STAR INT'L CO.,LTD."),
136 DMI_MATCH(DMI_PRODUCT_NAME
, "MS-1034"),
137 DMI_MATCH(DMI_PRODUCT_VERSION
, "0341")
141 .ident
= "MSI MS-1632",
143 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
144 DMI_MATCH(DMI_BOARD_NAME
, "MS-1632")
148 .ident
= "MSI MS-1633X",
150 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
151 DMI_MATCH(DMI_BOARD_NAME
, "MS-1633X")
155 .ident
= "MSI MS-1635X",
157 DMI_MATCH(DMI_BOARD_VENDOR
, "MSI"),
158 DMI_MATCH(DMI_BOARD_NAME
, "MS-1635X")
162 .ident
= "ASUSTeK W7J",
164 DMI_MATCH(DMI_BOARD_VENDOR
, "ASUSTeK Computer Inc."),
165 DMI_MATCH(DMI_BOARD_NAME
, "W7J ")
171 static const struct v4l2_pix_format vga_mode
[] = {
172 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
174 .sizeimage
= 160 * 120 * 4 / 8 + 590,
175 .colorspace
= V4L2_COLORSPACE_JPEG
,
176 .priv
= SCALE_160x120
| MODE_JPEG
},
177 {160, 120, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
179 .sizeimage
= 160 * 120,
180 .colorspace
= V4L2_COLORSPACE_SRGB
,
181 .priv
= SCALE_160x120
| MODE_RAW
},
182 {160, 120, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
184 .sizeimage
= 240 * 120,
185 .colorspace
= V4L2_COLORSPACE_SRGB
,
186 .priv
= SCALE_160x120
},
187 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
189 .sizeimage
= 320 * 240 * 4 / 8 + 590,
190 .colorspace
= V4L2_COLORSPACE_JPEG
,
191 .priv
= SCALE_320x240
| MODE_JPEG
},
192 {320, 240, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
194 .sizeimage
= 320 * 240 ,
195 .colorspace
= V4L2_COLORSPACE_SRGB
,
196 .priv
= SCALE_320x240
| MODE_RAW
},
197 {320, 240, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
199 .sizeimage
= 480 * 240 ,
200 .colorspace
= V4L2_COLORSPACE_SRGB
,
201 .priv
= SCALE_320x240
},
202 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
204 .sizeimage
= 640 * 480 * 4 / 8 + 590,
205 .colorspace
= V4L2_COLORSPACE_JPEG
,
206 .priv
= SCALE_640x480
| MODE_JPEG
},
207 {640, 480, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
209 .sizeimage
= 640 * 480,
210 .colorspace
= V4L2_COLORSPACE_SRGB
,
211 .priv
= SCALE_640x480
| MODE_RAW
},
212 {640, 480, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
214 .sizeimage
= 960 * 480,
215 .colorspace
= V4L2_COLORSPACE_SRGB
,
216 .priv
= SCALE_640x480
},
219 static const struct v4l2_pix_format sxga_mode
[] = {
220 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
222 .sizeimage
= 160 * 120 * 4 / 8 + 590,
223 .colorspace
= V4L2_COLORSPACE_JPEG
,
224 .priv
= SCALE_160x120
| MODE_JPEG
},
225 {160, 120, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
227 .sizeimage
= 160 * 120,
228 .colorspace
= V4L2_COLORSPACE_SRGB
,
229 .priv
= SCALE_160x120
| MODE_RAW
},
230 {160, 120, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
232 .sizeimage
= 240 * 120,
233 .colorspace
= V4L2_COLORSPACE_SRGB
,
234 .priv
= SCALE_160x120
},
235 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
237 .sizeimage
= 320 * 240 * 4 / 8 + 590,
238 .colorspace
= V4L2_COLORSPACE_JPEG
,
239 .priv
= SCALE_320x240
| MODE_JPEG
},
240 {320, 240, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
242 .sizeimage
= 320 * 240 ,
243 .colorspace
= V4L2_COLORSPACE_SRGB
,
244 .priv
= SCALE_320x240
| MODE_RAW
},
245 {320, 240, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
247 .sizeimage
= 480 * 240 ,
248 .colorspace
= V4L2_COLORSPACE_SRGB
,
249 .priv
= SCALE_320x240
},
250 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
252 .sizeimage
= 640 * 480 * 4 / 8 + 590,
253 .colorspace
= V4L2_COLORSPACE_JPEG
,
254 .priv
= SCALE_640x480
| MODE_JPEG
},
255 {640, 480, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
257 .sizeimage
= 640 * 480,
258 .colorspace
= V4L2_COLORSPACE_SRGB
,
259 .priv
= SCALE_640x480
| MODE_RAW
},
260 {640, 480, V4L2_PIX_FMT_SN9C20X_I420
, V4L2_FIELD_NONE
,
262 .sizeimage
= 960 * 480,
263 .colorspace
= V4L2_COLORSPACE_SRGB
,
264 .priv
= SCALE_640x480
},
265 {1280, 1024, V4L2_PIX_FMT_SBGGR8
, V4L2_FIELD_NONE
,
266 .bytesperline
= 1280,
267 .sizeimage
= 1280 * 1024,
268 .colorspace
= V4L2_COLORSPACE_SRGB
,
269 .priv
= SCALE_1280x1024
| MODE_RAW
| MODE_SXGA
},
272 static const struct v4l2_pix_format mono_mode
[] = {
273 {160, 120, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
275 .sizeimage
= 160 * 120,
276 .colorspace
= V4L2_COLORSPACE_SRGB
,
277 .priv
= SCALE_160x120
| MODE_RAW
},
278 {320, 240, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
280 .sizeimage
= 320 * 240 ,
281 .colorspace
= V4L2_COLORSPACE_SRGB
,
282 .priv
= SCALE_320x240
| MODE_RAW
},
283 {640, 480, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
285 .sizeimage
= 640 * 480,
286 .colorspace
= V4L2_COLORSPACE_SRGB
,
287 .priv
= SCALE_640x480
| MODE_RAW
},
288 {1280, 1024, V4L2_PIX_FMT_GREY
, V4L2_FIELD_NONE
,
289 .bytesperline
= 1280,
290 .sizeimage
= 1280 * 1024,
291 .colorspace
= V4L2_COLORSPACE_SRGB
,
292 .priv
= SCALE_1280x1024
| MODE_RAW
| MODE_SXGA
},
295 static const s16 hsv_red_x
[] = {
296 41, 44, 46, 48, 50, 52, 54, 56,
297 58, 60, 62, 64, 66, 68, 70, 72,
298 74, 76, 78, 80, 81, 83, 85, 87,
299 88, 90, 92, 93, 95, 97, 98, 100,
300 101, 102, 104, 105, 107, 108, 109, 110,
301 112, 113, 114, 115, 116, 117, 118, 119,
302 120, 121, 122, 123, 123, 124, 125, 125,
303 126, 127, 127, 128, 128, 129, 129, 129,
304 130, 130, 130, 130, 131, 131, 131, 131,
305 131, 131, 131, 131, 130, 130, 130, 130,
306 129, 129, 129, 128, 128, 127, 127, 126,
307 125, 125, 124, 123, 122, 122, 121, 120,
308 119, 118, 117, 116, 115, 114, 112, 111,
309 110, 109, 107, 106, 105, 103, 102, 101,
310 99, 98, 96, 94, 93, 91, 90, 88,
311 86, 84, 83, 81, 79, 77, 75, 74,
312 72, 70, 68, 66, 64, 62, 60, 58,
313 56, 54, 52, 49, 47, 45, 43, 41,
314 39, 36, 34, 32, 30, 28, 25, 23,
315 21, 19, 16, 14, 12, 9, 7, 5,
316 3, 0, -1, -3, -6, -8, -10, -12,
317 -15, -17, -19, -22, -24, -26, -28, -30,
318 -33, -35, -37, -39, -41, -44, -46, -48,
319 -50, -52, -54, -56, -58, -60, -62, -64,
320 -66, -68, -70, -72, -74, -76, -78, -80,
321 -81, -83, -85, -87, -88, -90, -92, -93,
322 -95, -97, -98, -100, -101, -102, -104, -105,
323 -107, -108, -109, -110, -112, -113, -114, -115,
324 -116, -117, -118, -119, -120, -121, -122, -123,
325 -123, -124, -125, -125, -126, -127, -127, -128,
326 -128, -128, -128, -128, -128, -128, -128, -128,
327 -128, -128, -128, -128, -128, -128, -128, -128,
328 -128, -128, -128, -128, -128, -128, -128, -128,
329 -128, -127, -127, -126, -125, -125, -124, -123,
330 -122, -122, -121, -120, -119, -118, -117, -116,
331 -115, -114, -112, -111, -110, -109, -107, -106,
332 -105, -103, -102, -101, -99, -98, -96, -94,
333 -93, -91, -90, -88, -86, -84, -83, -81,
334 -79, -77, -75, -74, -72, -70, -68, -66,
335 -64, -62, -60, -58, -56, -54, -52, -49,
336 -47, -45, -43, -41, -39, -36, -34, -32,
337 -30, -28, -25, -23, -21, -19, -16, -14,
338 -12, -9, -7, -5, -3, 0, 1, 3,
339 6, 8, 10, 12, 15, 17, 19, 22,
340 24, 26, 28, 30, 33, 35, 37, 39, 41
343 static const s16 hsv_red_y
[] = {
344 82, 80, 78, 76, 74, 73, 71, 69,
345 67, 65, 63, 61, 58, 56, 54, 52,
346 50, 48, 46, 44, 41, 39, 37, 35,
347 32, 30, 28, 26, 23, 21, 19, 16,
348 14, 12, 10, 7, 5, 3, 0, -1,
349 -3, -6, -8, -10, -13, -15, -17, -19,
350 -22, -24, -26, -29, -31, -33, -35, -38,
351 -40, -42, -44, -46, -48, -51, -53, -55,
352 -57, -59, -61, -63, -65, -67, -69, -71,
353 -73, -75, -77, -79, -81, -82, -84, -86,
354 -88, -89, -91, -93, -94, -96, -98, -99,
355 -101, -102, -104, -105, -106, -108, -109, -110,
356 -112, -113, -114, -115, -116, -117, -119, -120,
357 -120, -121, -122, -123, -124, -125, -126, -126,
358 -127, -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 -128, -128, -128, -128, -128, -128, -128, -128,
362 -127, -127, -126, -125, -125, -124, -123, -122,
363 -121, -120, -119, -118, -117, -116, -115, -114,
364 -113, -111, -110, -109, -107, -106, -105, -103,
365 -102, -100, -99, -97, -96, -94, -92, -91,
366 -89, -87, -85, -84, -82, -80, -78, -76,
367 -74, -73, -71, -69, -67, -65, -63, -61,
368 -58, -56, -54, -52, -50, -48, -46, -44,
369 -41, -39, -37, -35, -32, -30, -28, -26,
370 -23, -21, -19, -16, -14, -12, -10, -7,
371 -5, -3, 0, 1, 3, 6, 8, 10,
372 13, 15, 17, 19, 22, 24, 26, 29,
373 31, 33, 35, 38, 40, 42, 44, 46,
374 48, 51, 53, 55, 57, 59, 61, 63,
375 65, 67, 69, 71, 73, 75, 77, 79,
376 81, 82, 84, 86, 88, 89, 91, 93,
377 94, 96, 98, 99, 101, 102, 104, 105,
378 106, 108, 109, 110, 112, 113, 114, 115,
379 116, 117, 119, 120, 120, 121, 122, 123,
380 124, 125, 126, 126, 127, 128, 128, 129,
381 129, 130, 130, 131, 131, 131, 131, 132,
382 132, 132, 132, 132, 132, 132, 132, 132,
383 132, 132, 132, 131, 131, 131, 130, 130,
384 130, 129, 129, 128, 127, 127, 126, 125,
385 125, 124, 123, 122, 121, 120, 119, 118,
386 117, 116, 115, 114, 113, 111, 110, 109,
387 107, 106, 105, 103, 102, 100, 99, 97,
388 96, 94, 92, 91, 89, 87, 85, 84, 82
391 static const s16 hsv_green_x
[] = {
392 -124, -124, -125, -125, -125, -125, -125, -125,
393 -125, -126, -126, -125, -125, -125, -125, -125,
394 -125, -124, -124, -124, -123, -123, -122, -122,
395 -121, -121, -120, -120, -119, -118, -117, -117,
396 -116, -115, -114, -113, -112, -111, -110, -109,
397 -108, -107, -105, -104, -103, -102, -100, -99,
398 -98, -96, -95, -93, -92, -91, -89, -87,
399 -86, -84, -83, -81, -79, -77, -76, -74,
400 -72, -70, -69, -67, -65, -63, -61, -59,
401 -57, -55, -53, -51, -49, -47, -45, -43,
402 -41, -39, -37, -35, -33, -30, -28, -26,
403 -24, -22, -20, -18, -15, -13, -11, -9,
404 -7, -4, -2, 0, 1, 3, 6, 8,
405 10, 12, 14, 17, 19, 21, 23, 25,
406 27, 29, 32, 34, 36, 38, 40, 42,
407 44, 46, 48, 50, 52, 54, 56, 58,
408 60, 62, 64, 66, 68, 70, 71, 73,
409 75, 77, 78, 80, 82, 83, 85, 87,
410 88, 90, 91, 93, 94, 96, 97, 98,
411 100, 101, 102, 104, 105, 106, 107, 108,
412 109, 111, 112, 113, 113, 114, 115, 116,
413 117, 118, 118, 119, 120, 120, 121, 122,
414 122, 123, 123, 124, 124, 124, 125, 125,
415 125, 125, 125, 125, 125, 126, 126, 125,
416 125, 125, 125, 125, 125, 124, 124, 124,
417 123, 123, 122, 122, 121, 121, 120, 120,
418 119, 118, 117, 117, 116, 115, 114, 113,
419 112, 111, 110, 109, 108, 107, 105, 104,
420 103, 102, 100, 99, 98, 96, 95, 93,
421 92, 91, 89, 87, 86, 84, 83, 81,
422 79, 77, 76, 74, 72, 70, 69, 67,
423 65, 63, 61, 59, 57, 55, 53, 51,
424 49, 47, 45, 43, 41, 39, 37, 35,
425 33, 30, 28, 26, 24, 22, 20, 18,
426 15, 13, 11, 9, 7, 4, 2, 0,
427 -1, -3, -6, -8, -10, -12, -14, -17,
428 -19, -21, -23, -25, -27, -29, -32, -34,
429 -36, -38, -40, -42, -44, -46, -48, -50,
430 -52, -54, -56, -58, -60, -62, -64, -66,
431 -68, -70, -71, -73, -75, -77, -78, -80,
432 -82, -83, -85, -87, -88, -90, -91, -93,
433 -94, -96, -97, -98, -100, -101, -102, -104,
434 -105, -106, -107, -108, -109, -111, -112, -113,
435 -113, -114, -115, -116, -117, -118, -118, -119,
436 -120, -120, -121, -122, -122, -123, -123, -124, -124
439 static const s16 hsv_green_y
[] = {
440 -100, -99, -98, -97, -95, -94, -93, -91,
441 -90, -89, -87, -86, -84, -83, -81, -80,
442 -78, -76, -75, -73, -71, -70, -68, -66,
443 -64, -63, -61, -59, -57, -55, -53, -51,
444 -49, -48, -46, -44, -42, -40, -38, -36,
445 -34, -32, -30, -27, -25, -23, -21, -19,
446 -17, -15, -13, -11, -9, -7, -4, -2,
447 0, 1, 3, 5, 7, 9, 11, 14,
448 16, 18, 20, 22, 24, 26, 28, 30,
449 32, 34, 36, 38, 40, 42, 44, 46,
450 48, 50, 52, 54, 56, 58, 59, 61,
451 63, 65, 67, 68, 70, 72, 74, 75,
452 77, 78, 80, 82, 83, 85, 86, 88,
453 89, 90, 92, 93, 95, 96, 97, 98,
454 100, 101, 102, 103, 104, 105, 106, 107,
455 108, 109, 110, 111, 112, 112, 113, 114,
456 115, 115, 116, 116, 117, 117, 118, 118,
457 119, 119, 119, 120, 120, 120, 120, 120,
458 121, 121, 121, 121, 121, 121, 120, 120,
459 120, 120, 120, 119, 119, 119, 118, 118,
460 117, 117, 116, 116, 115, 114, 114, 113,
461 112, 111, 111, 110, 109, 108, 107, 106,
462 105, 104, 103, 102, 100, 99, 98, 97,
463 95, 94, 93, 91, 90, 89, 87, 86,
464 84, 83, 81, 80, 78, 76, 75, 73,
465 71, 70, 68, 66, 64, 63, 61, 59,
466 57, 55, 53, 51, 49, 48, 46, 44,
467 42, 40, 38, 36, 34, 32, 30, 27,
468 25, 23, 21, 19, 17, 15, 13, 11,
469 9, 7, 4, 2, 0, -1, -3, -5,
470 -7, -9, -11, -14, -16, -18, -20, -22,
471 -24, -26, -28, -30, -32, -34, -36, -38,
472 -40, -42, -44, -46, -48, -50, -52, -54,
473 -56, -58, -59, -61, -63, -65, -67, -68,
474 -70, -72, -74, -75, -77, -78, -80, -82,
475 -83, -85, -86, -88, -89, -90, -92, -93,
476 -95, -96, -97, -98, -100, -101, -102, -103,
477 -104, -105, -106, -107, -108, -109, -110, -111,
478 -112, -112, -113, -114, -115, -115, -116, -116,
479 -117, -117, -118, -118, -119, -119, -119, -120,
480 -120, -120, -120, -120, -121, -121, -121, -121,
481 -121, -121, -120, -120, -120, -120, -120, -119,
482 -119, -119, -118, -118, -117, -117, -116, -116,
483 -115, -114, -114, -113, -112, -111, -111, -110,
484 -109, -108, -107, -106, -105, -104, -103, -102, -100
487 static const s16 hsv_blue_x
[] = {
488 112, 113, 114, 114, 115, 116, 117, 117,
489 118, 118, 119, 119, 120, 120, 120, 121,
490 121, 121, 122, 122, 122, 122, 122, 122,
491 122, 122, 122, 122, 122, 122, 121, 121,
492 121, 120, 120, 120, 119, 119, 118, 118,
493 117, 116, 116, 115, 114, 113, 113, 112,
494 111, 110, 109, 108, 107, 106, 105, 104,
495 103, 102, 100, 99, 98, 97, 95, 94,
496 93, 91, 90, 88, 87, 85, 84, 82,
497 80, 79, 77, 76, 74, 72, 70, 69,
498 67, 65, 63, 61, 60, 58, 56, 54,
499 52, 50, 48, 46, 44, 42, 40, 38,
500 36, 34, 32, 30, 28, 26, 24, 22,
501 19, 17, 15, 13, 11, 9, 7, 5,
502 2, 0, -1, -3, -5, -7, -9, -12,
503 -14, -16, -18, -20, -22, -24, -26, -28,
504 -31, -33, -35, -37, -39, -41, -43, -45,
505 -47, -49, -51, -53, -54, -56, -58, -60,
506 -62, -64, -66, -67, -69, -71, -73, -74,
507 -76, -78, -79, -81, -83, -84, -86, -87,
508 -89, -90, -92, -93, -94, -96, -97, -98,
509 -99, -101, -102, -103, -104, -105, -106, -107,
510 -108, -109, -110, -111, -112, -113, -114, -114,
511 -115, -116, -117, -117, -118, -118, -119, -119,
512 -120, -120, -120, -121, -121, -121, -122, -122,
513 -122, -122, -122, -122, -122, -122, -122, -122,
514 -122, -122, -121, -121, -121, -120, -120, -120,
515 -119, -119, -118, -118, -117, -116, -116, -115,
516 -114, -113, -113, -112, -111, -110, -109, -108,
517 -107, -106, -105, -104, -103, -102, -100, -99,
518 -98, -97, -95, -94, -93, -91, -90, -88,
519 -87, -85, -84, -82, -80, -79, -77, -76,
520 -74, -72, -70, -69, -67, -65, -63, -61,
521 -60, -58, -56, -54, -52, -50, -48, -46,
522 -44, -42, -40, -38, -36, -34, -32, -30,
523 -28, -26, -24, -22, -19, -17, -15, -13,
524 -11, -9, -7, -5, -2, 0, 1, 3,
525 5, 7, 9, 12, 14, 16, 18, 20,
526 22, 24, 26, 28, 31, 33, 35, 37,
527 39, 41, 43, 45, 47, 49, 51, 53,
528 54, 56, 58, 60, 62, 64, 66, 67,
529 69, 71, 73, 74, 76, 78, 79, 81,
530 83, 84, 86, 87, 89, 90, 92, 93,
531 94, 96, 97, 98, 99, 101, 102, 103,
532 104, 105, 106, 107, 108, 109, 110, 111, 112
535 static const s16 hsv_blue_y
[] = {
536 -11, -13, -15, -17, -19, -21, -23, -25,
537 -27, -29, -31, -33, -35, -37, -39, -41,
538 -43, -45, -46, -48, -50, -52, -54, -55,
539 -57, -59, -61, -62, -64, -66, -67, -69,
540 -71, -72, -74, -75, -77, -78, -80, -81,
541 -83, -84, -86, -87, -88, -90, -91, -92,
542 -93, -95, -96, -97, -98, -99, -100, -101,
543 -102, -103, -104, -105, -106, -106, -107, -108,
544 -109, -109, -110, -111, -111, -112, -112, -113,
545 -113, -114, -114, -114, -115, -115, -115, -115,
546 -116, -116, -116, -116, -116, -116, -116, -116,
547 -116, -115, -115, -115, -115, -114, -114, -114,
548 -113, -113, -112, -112, -111, -111, -110, -110,
549 -109, -108, -108, -107, -106, -105, -104, -103,
550 -102, -101, -100, -99, -98, -97, -96, -95,
551 -94, -93, -91, -90, -89, -88, -86, -85,
552 -84, -82, -81, -79, -78, -76, -75, -73,
553 -71, -70, -68, -67, -65, -63, -62, -60,
554 -58, -56, -55, -53, -51, -49, -47, -45,
555 -44, -42, -40, -38, -36, -34, -32, -30,
556 -28, -26, -24, -22, -20, -18, -16, -14,
557 -12, -10, -8, -6, -4, -2, 0, 1,
558 3, 5, 7, 9, 11, 13, 15, 17,
559 19, 21, 23, 25, 27, 29, 31, 33,
560 35, 37, 39, 41, 43, 45, 46, 48,
561 50, 52, 54, 55, 57, 59, 61, 62,
562 64, 66, 67, 69, 71, 72, 74, 75,
563 77, 78, 80, 81, 83, 84, 86, 87,
564 88, 90, 91, 92, 93, 95, 96, 97,
565 98, 99, 100, 101, 102, 103, 104, 105,
566 106, 106, 107, 108, 109, 109, 110, 111,
567 111, 112, 112, 113, 113, 114, 114, 114,
568 115, 115, 115, 115, 116, 116, 116, 116,
569 116, 116, 116, 116, 116, 115, 115, 115,
570 115, 114, 114, 114, 113, 113, 112, 112,
571 111, 111, 110, 110, 109, 108, 108, 107,
572 106, 105, 104, 103, 102, 101, 100, 99,
573 98, 97, 96, 95, 94, 93, 91, 90,
574 89, 88, 86, 85, 84, 82, 81, 79,
575 78, 76, 75, 73, 71, 70, 68, 67,
576 65, 63, 62, 60, 58, 56, 55, 53,
577 51, 49, 47, 45, 44, 42, 40, 38,
578 36, 34, 32, 30, 28, 26, 24, 22,
579 20, 18, 16, 14, 12, 10, 8, 6,
580 4, 2, 0, -1, -3, -5, -7, -9, -11
583 static const u16 bridge_init
[][2] = {
584 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
585 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
586 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
587 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
588 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
589 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
590 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
591 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
592 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
593 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
594 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
595 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
596 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
597 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
598 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
599 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
600 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
601 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
602 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
606 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
607 static const u8 ov_gain
[] = {
608 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
609 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
610 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
611 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
612 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
613 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
614 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
618 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
619 static const u16 micron1_gain
[] = {
620 /* 1x 1.25x 1.5x 1.75x */
621 0x0020, 0x0028, 0x0030, 0x0038,
622 /* 2x 2.25x 2.5x 2.75x */
623 0x00a0, 0x00a4, 0x00a8, 0x00ac,
624 /* 3x 3.25x 3.5x 3.75x */
625 0x00b0, 0x00b4, 0x00b8, 0x00bc,
626 /* 4x 4.25x 4.5x 4.75x */
627 0x00c0, 0x00c4, 0x00c8, 0x00cc,
628 /* 5x 5.25x 5.5x 5.75x */
629 0x00d0, 0x00d4, 0x00d8, 0x00dc,
630 /* 6x 6.25x 6.5x 6.75x */
631 0x00e0, 0x00e4, 0x00e8, 0x00ec,
632 /* 7x 7.25x 7.5x 7.75x */
633 0x00f0, 0x00f4, 0x00f8, 0x00fc,
638 /* mt9m001 sensor uses a different gain formula then other micron sensors */
639 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
640 static const u16 micron2_gain
[] = {
641 /* 1x 1.25x 1.5x 1.75x */
642 0x0008, 0x000a, 0x000c, 0x000e,
643 /* 2x 2.25x 2.5x 2.75x */
644 0x0010, 0x0012, 0x0014, 0x0016,
645 /* 3x 3.25x 3.5x 3.75x */
646 0x0018, 0x001a, 0x001c, 0x001e,
647 /* 4x 4.25x 4.5x 4.75x */
648 0x0020, 0x0051, 0x0052, 0x0053,
649 /* 5x 5.25x 5.5x 5.75x */
650 0x0054, 0x0055, 0x0056, 0x0057,
651 /* 6x 6.25x 6.5x 6.75x */
652 0x0058, 0x0059, 0x005a, 0x005b,
653 /* 7x 7.25x 7.5x 7.75x */
654 0x005c, 0x005d, 0x005e, 0x005f,
659 /* Gain = .5 + bit[7:0] / 16 */
660 static const u8 hv7131r_gain
[] = {
661 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
662 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
663 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
664 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
665 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
666 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
667 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
671 static const struct i2c_reg_u8 soi968_init
[] = {
672 {0x0c, 0x00}, {0x0f, 0x1f},
673 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
674 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
675 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
676 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
677 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
678 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
679 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
680 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
681 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
682 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
685 static const struct i2c_reg_u8 ov7660_init
[] = {
686 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
687 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
688 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
689 /* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using
690 0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
691 {0x17, 0x10}, {0x18, 0x61},
692 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
693 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0x00},
694 {0x2e, 0x00}, {0x01, 0x78}, {0x02, 0x50},
697 static const struct i2c_reg_u8 ov7670_init
[] = {
698 {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
699 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
700 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
701 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
702 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
703 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
704 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
705 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
706 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
707 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
708 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
709 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
710 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
711 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
712 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
713 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
714 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
715 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
716 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
717 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
718 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
719 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
720 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
721 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
722 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
723 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
724 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
725 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
726 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
727 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
728 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
729 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
730 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
731 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
732 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
733 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
734 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
735 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
736 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
737 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
738 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
739 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
740 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
741 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
742 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
743 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
744 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
745 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
746 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
747 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
748 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
749 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
750 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
754 static const struct i2c_reg_u8 ov9650_init
[] = {
755 {0x00, 0x00}, {0x01, 0x78},
756 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
757 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
758 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
759 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
760 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
761 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
762 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
763 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
764 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
765 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
766 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
767 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
768 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
769 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
770 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
771 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
772 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
773 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
774 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
775 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
776 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
777 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
778 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
779 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
780 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
781 {0xaa, 0x92}, {0xab, 0x0a},
784 static const struct i2c_reg_u8 ov9655_init
[] = {
785 {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
786 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
787 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
788 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
789 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
790 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
791 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
792 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
793 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
794 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
795 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
796 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
797 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
798 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
799 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
800 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
801 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
802 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
803 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
804 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
805 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
806 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
807 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
808 {0x04, 0x03}, {0x00, 0x13},
811 static const struct i2c_reg_u16 mt9v112_init
[] = {
812 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
813 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
814 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
815 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
816 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
817 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
818 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
819 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
820 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
821 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
822 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
823 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
824 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
825 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
826 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
827 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
830 static const struct i2c_reg_u16 mt9v111_init
[] = {
831 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
832 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
833 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
834 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
835 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
836 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
837 {0x0e, 0x0008}, {0x20, 0x0000}
840 static const struct i2c_reg_u16 mt9v011_init
[] = {
841 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
842 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
843 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
844 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
845 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
846 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
847 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
848 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
849 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
850 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
851 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
852 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
853 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
854 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
855 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
856 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
857 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
858 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
859 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
860 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
861 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
862 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
863 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
864 {0x06, 0x0029}, {0x05, 0x0009},
867 static const struct i2c_reg_u16 mt9m001_init
[] = {
870 {0x04, 0x0500}, /* hres = 1280 */
871 {0x03, 0x0400}, /* vres = 1024 */
883 static const struct i2c_reg_u16 mt9m111_init
[] = {
884 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
885 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
886 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
890 static const struct i2c_reg_u16 mt9m112_init
[] = {
891 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
892 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
893 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
897 static const struct i2c_reg_u8 hv7131r_init
[] = {
898 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
899 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
900 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
901 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
902 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
903 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
904 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
905 {0x23, 0x09}, {0x01, 0x08},
908 static void reg_r(struct gspca_dev
*gspca_dev
, u16 reg
, u16 length
)
910 struct usb_device
*dev
= gspca_dev
->dev
;
913 if (gspca_dev
->usb_err
< 0)
915 result
= usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
917 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
923 if (unlikely(result
< 0 || result
!= length
)) {
924 pr_err("Read register %02x failed %d\n", reg
, result
);
925 gspca_dev
->usb_err
= result
;
929 static void reg_w(struct gspca_dev
*gspca_dev
, u16 reg
,
930 const u8
*buffer
, int length
)
932 struct usb_device
*dev
= gspca_dev
->dev
;
935 if (gspca_dev
->usb_err
< 0)
937 memcpy(gspca_dev
->usb_buf
, buffer
, length
);
938 result
= usb_control_msg(dev
, usb_sndctrlpipe(dev
, 0),
940 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
946 if (unlikely(result
< 0 || result
!= length
)) {
947 pr_err("Write register %02x failed %d\n", reg
, result
);
948 gspca_dev
->usb_err
= result
;
952 static void reg_w1(struct gspca_dev
*gspca_dev
, u16 reg
, const u8 value
)
954 reg_w(gspca_dev
, reg
, &value
, 1);
957 static void i2c_w(struct gspca_dev
*gspca_dev
, const u8
*buffer
)
961 reg_w(gspca_dev
, 0x10c0, buffer
, 8);
962 for (i
= 0; i
< 5; i
++) {
963 reg_r(gspca_dev
, 0x10c0, 1);
964 if (gspca_dev
->usb_err
< 0)
966 if (gspca_dev
->usb_buf
[0] & 0x04) {
967 if (gspca_dev
->usb_buf
[0] & 0x08) {
968 pr_err("i2c_w error\n");
969 gspca_dev
->usb_err
= -EIO
;
975 pr_err("i2c_w reg %02x no response\n", buffer
[2]);
976 /* gspca_dev->usb_err = -EIO; fixme: may occur */
979 static void i2c_w1(struct gspca_dev
*gspca_dev
, u8 reg
, u8 val
)
981 struct sd
*sd
= (struct sd
*) gspca_dev
;
985 * from the point of view of the bridge, the length
986 * includes the address
988 row
[0] = sd
->i2c_intf
| (2 << 4);
989 row
[1] = sd
->i2c_addr
;
997 i2c_w(gspca_dev
, row
);
1000 static void i2c_w1_buf(struct gspca_dev
*gspca_dev
,
1001 const struct i2c_reg_u8
*buf
, int sz
)
1004 i2c_w1(gspca_dev
, buf
->reg
, buf
->val
);
1009 static void i2c_w2(struct gspca_dev
*gspca_dev
, u8 reg
, u16 val
)
1011 struct sd
*sd
= (struct sd
*) gspca_dev
;
1015 * from the point of view of the bridge, the length
1016 * includes the address
1018 row
[0] = sd
->i2c_intf
| (3 << 4);
1019 row
[1] = sd
->i2c_addr
;
1027 i2c_w(gspca_dev
, row
);
1030 static void i2c_w2_buf(struct gspca_dev
*gspca_dev
,
1031 const struct i2c_reg_u16
*buf
, int sz
)
1034 i2c_w2(gspca_dev
, buf
->reg
, buf
->val
);
1039 static void i2c_r1(struct gspca_dev
*gspca_dev
, u8 reg
, u8
*val
)
1041 struct sd
*sd
= (struct sd
*) gspca_dev
;
1044 row
[0] = sd
->i2c_intf
| (1 << 4);
1045 row
[1] = sd
->i2c_addr
;
1052 i2c_w(gspca_dev
, row
);
1053 row
[0] = sd
->i2c_intf
| (1 << 4) | 0x02;
1055 i2c_w(gspca_dev
, row
);
1056 reg_r(gspca_dev
, 0x10c2, 5);
1057 *val
= gspca_dev
->usb_buf
[4];
1060 static void i2c_r2(struct gspca_dev
*gspca_dev
, u8 reg
, u16
*val
)
1062 struct sd
*sd
= (struct sd
*) gspca_dev
;
1065 row
[0] = sd
->i2c_intf
| (1 << 4);
1066 row
[1] = sd
->i2c_addr
;
1073 i2c_w(gspca_dev
, row
);
1074 row
[0] = sd
->i2c_intf
| (2 << 4) | 0x02;
1076 i2c_w(gspca_dev
, row
);
1077 reg_r(gspca_dev
, 0x10c2, 5);
1078 *val
= (gspca_dev
->usb_buf
[3] << 8) | gspca_dev
->usb_buf
[4];
1081 static void ov9650_init_sensor(struct gspca_dev
*gspca_dev
)
1084 struct sd
*sd
= (struct sd
*) gspca_dev
;
1086 i2c_r2(gspca_dev
, 0x1c, &id
);
1087 if (gspca_dev
->usb_err
< 0)
1091 pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id
);
1092 gspca_dev
->usb_err
= -ENODEV
;
1096 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1098 i2c_w1_buf(gspca_dev
, ov9650_init
, ARRAY_SIZE(ov9650_init
));
1099 if (gspca_dev
->usb_err
< 0)
1100 pr_err("OV9650 sensor initialization failed\n");
1105 static void ov9655_init_sensor(struct gspca_dev
*gspca_dev
)
1107 struct sd
*sd
= (struct sd
*) gspca_dev
;
1109 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1111 i2c_w1_buf(gspca_dev
, ov9655_init
, ARRAY_SIZE(ov9655_init
));
1112 if (gspca_dev
->usb_err
< 0)
1113 pr_err("OV9655 sensor initialization failed\n");
1119 static void soi968_init_sensor(struct gspca_dev
*gspca_dev
)
1121 struct sd
*sd
= (struct sd
*) gspca_dev
;
1123 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1125 i2c_w1_buf(gspca_dev
, soi968_init
, ARRAY_SIZE(soi968_init
));
1126 if (gspca_dev
->usb_err
< 0)
1127 pr_err("SOI968 sensor initialization failed\n");
1133 static void ov7660_init_sensor(struct gspca_dev
*gspca_dev
)
1135 struct sd
*sd
= (struct sd
*) gspca_dev
;
1137 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1139 i2c_w1_buf(gspca_dev
, ov7660_init
, ARRAY_SIZE(ov7660_init
));
1140 if (gspca_dev
->usb_err
< 0)
1141 pr_err("OV7660 sensor initialization failed\n");
1146 static void ov7670_init_sensor(struct gspca_dev
*gspca_dev
)
1148 struct sd
*sd
= (struct sd
*) gspca_dev
;
1150 i2c_w1(gspca_dev
, 0x12, 0x80); /* sensor reset */
1152 i2c_w1_buf(gspca_dev
, ov7670_init
, ARRAY_SIZE(ov7670_init
));
1153 if (gspca_dev
->usb_err
< 0)
1154 pr_err("OV7670 sensor initialization failed\n");
1160 static void mt9v_init_sensor(struct gspca_dev
*gspca_dev
)
1162 struct sd
*sd
= (struct sd
*) gspca_dev
;
1165 sd
->i2c_addr
= 0x5d;
1166 i2c_r2(gspca_dev
, 0xff, &value
);
1167 if (gspca_dev
->usb_err
>= 0
1168 && value
== 0x8243) {
1169 i2c_w2_buf(gspca_dev
, mt9v011_init
, ARRAY_SIZE(mt9v011_init
));
1170 if (gspca_dev
->usb_err
< 0) {
1171 pr_err("MT9V011 sensor initialization failed\n");
1176 sd
->sensor
= SENSOR_MT9V011
;
1177 pr_info("MT9V011 sensor detected\n");
1181 gspca_dev
->usb_err
= 0;
1182 sd
->i2c_addr
= 0x5c;
1183 i2c_w2(gspca_dev
, 0x01, 0x0004);
1184 i2c_r2(gspca_dev
, 0xff, &value
);
1185 if (gspca_dev
->usb_err
>= 0
1186 && value
== 0x823a) {
1187 i2c_w2_buf(gspca_dev
, mt9v111_init
, ARRAY_SIZE(mt9v111_init
));
1188 if (gspca_dev
->usb_err
< 0) {
1189 pr_err("MT9V111 sensor initialization failed\n");
1194 sd
->sensor
= SENSOR_MT9V111
;
1195 pr_info("MT9V111 sensor detected\n");
1199 gspca_dev
->usb_err
= 0;
1200 sd
->i2c_addr
= 0x5d;
1201 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1202 if (gspca_dev
->usb_err
< 0) {
1203 gspca_dev
->usb_err
= 0;
1204 sd
->i2c_addr
= 0x48;
1205 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1207 i2c_r2(gspca_dev
, 0x00, &value
);
1208 if (gspca_dev
->usb_err
>= 0
1209 && value
== 0x1229) {
1210 i2c_w2_buf(gspca_dev
, mt9v112_init
, ARRAY_SIZE(mt9v112_init
));
1211 if (gspca_dev
->usb_err
< 0) {
1212 pr_err("MT9V112 sensor initialization failed\n");
1217 sd
->sensor
= SENSOR_MT9V112
;
1218 pr_info("MT9V112 sensor detected\n");
1222 gspca_dev
->usb_err
= -ENODEV
;
1225 static void mt9m112_init_sensor(struct gspca_dev
*gspca_dev
)
1227 struct sd
*sd
= (struct sd
*) gspca_dev
;
1229 i2c_w2_buf(gspca_dev
, mt9m112_init
, ARRAY_SIZE(mt9m112_init
));
1230 if (gspca_dev
->usb_err
< 0)
1231 pr_err("MT9M112 sensor initialization failed\n");
1237 static void mt9m111_init_sensor(struct gspca_dev
*gspca_dev
)
1239 struct sd
*sd
= (struct sd
*) gspca_dev
;
1241 i2c_w2_buf(gspca_dev
, mt9m111_init
, ARRAY_SIZE(mt9m111_init
));
1242 if (gspca_dev
->usb_err
< 0)
1243 pr_err("MT9M111 sensor initialization failed\n");
1249 static void mt9m001_init_sensor(struct gspca_dev
*gspca_dev
)
1251 struct sd
*sd
= (struct sd
*) gspca_dev
;
1254 i2c_r2(gspca_dev
, 0x00, &id
);
1255 if (gspca_dev
->usb_err
< 0)
1258 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
1262 pr_info("MT9M001 color sensor detected\n");
1265 pr_info("MT9M001 mono sensor detected\n");
1268 pr_err("No MT9M001 chip detected, ID = %x\n\n", id
);
1269 gspca_dev
->usb_err
= -ENODEV
;
1273 i2c_w2_buf(gspca_dev
, mt9m001_init
, ARRAY_SIZE(mt9m001_init
));
1274 if (gspca_dev
->usb_err
< 0)
1275 pr_err("MT9M001 sensor initialization failed\n");
1281 static void hv7131r_init_sensor(struct gspca_dev
*gspca_dev
)
1283 struct sd
*sd
= (struct sd
*) gspca_dev
;
1285 i2c_w1_buf(gspca_dev
, hv7131r_init
, ARRAY_SIZE(hv7131r_init
));
1286 if (gspca_dev
->usb_err
< 0)
1287 pr_err("HV7131R Sensor initialization failed\n");
1293 static void set_cmatrix(struct gspca_dev
*gspca_dev
,
1294 s32 brightness
, s32 contrast
, s32 satur
, s32 hue
)
1296 s32 hue_coord
, hue_index
= 180 + hue
;
1299 memset(cmatrix
, 0, sizeof(cmatrix
));
1300 cmatrix
[2] = (contrast
* 0x25 / 0x100) + 0x26;
1301 cmatrix
[0] = 0x13 + (cmatrix
[2] - 0x26) * 0x13 / 0x25;
1302 cmatrix
[4] = 0x07 + (cmatrix
[2] - 0x26) * 0x07 / 0x25;
1303 cmatrix
[18] = brightness
- 0x80;
1305 hue_coord
= (hsv_red_x
[hue_index
] * satur
) >> 8;
1306 cmatrix
[6] = hue_coord
;
1307 cmatrix
[7] = (hue_coord
>> 8) & 0x0f;
1309 hue_coord
= (hsv_red_y
[hue_index
] * satur
) >> 8;
1310 cmatrix
[8] = hue_coord
;
1311 cmatrix
[9] = (hue_coord
>> 8) & 0x0f;
1313 hue_coord
= (hsv_green_x
[hue_index
] * satur
) >> 8;
1314 cmatrix
[10] = hue_coord
;
1315 cmatrix
[11] = (hue_coord
>> 8) & 0x0f;
1317 hue_coord
= (hsv_green_y
[hue_index
] * satur
) >> 8;
1318 cmatrix
[12] = hue_coord
;
1319 cmatrix
[13] = (hue_coord
>> 8) & 0x0f;
1321 hue_coord
= (hsv_blue_x
[hue_index
] * satur
) >> 8;
1322 cmatrix
[14] = hue_coord
;
1323 cmatrix
[15] = (hue_coord
>> 8) & 0x0f;
1325 hue_coord
= (hsv_blue_y
[hue_index
] * satur
) >> 8;
1326 cmatrix
[16] = hue_coord
;
1327 cmatrix
[17] = (hue_coord
>> 8) & 0x0f;
1329 reg_w(gspca_dev
, 0x10e1, cmatrix
, 21);
1332 static void set_gamma(struct gspca_dev
*gspca_dev
, s32 val
)
1335 u8 gval
= val
* 0xb8 / 0x100;
1338 gamma
[1] = 0x13 + (gval
* (0xcb - 0x13) / 0xb8);
1339 gamma
[2] = 0x25 + (gval
* (0xee - 0x25) / 0xb8);
1340 gamma
[3] = 0x37 + (gval
* (0xfa - 0x37) / 0xb8);
1341 gamma
[4] = 0x45 + (gval
* (0xfc - 0x45) / 0xb8);
1342 gamma
[5] = 0x55 + (gval
* (0xfb - 0x55) / 0xb8);
1343 gamma
[6] = 0x65 + (gval
* (0xfc - 0x65) / 0xb8);
1344 gamma
[7] = 0x74 + (gval
* (0xfd - 0x74) / 0xb8);
1345 gamma
[8] = 0x83 + (gval
* (0xfe - 0x83) / 0xb8);
1346 gamma
[9] = 0x92 + (gval
* (0xfc - 0x92) / 0xb8);
1347 gamma
[10] = 0xa1 + (gval
* (0xfc - 0xa1) / 0xb8);
1348 gamma
[11] = 0xb0 + (gval
* (0xfc - 0xb0) / 0xb8);
1349 gamma
[12] = 0xbf + (gval
* (0xfb - 0xbf) / 0xb8);
1350 gamma
[13] = 0xce + (gval
* (0xfb - 0xce) / 0xb8);
1351 gamma
[14] = 0xdf + (gval
* (0xfd - 0xdf) / 0xb8);
1352 gamma
[15] = 0xea + (gval
* (0xf9 - 0xea) / 0xb8);
1355 reg_w(gspca_dev
, 0x1190, gamma
, 17);
1358 static void set_redblue(struct gspca_dev
*gspca_dev
, s32 blue
, s32 red
)
1360 reg_w1(gspca_dev
, 0x118c, red
);
1361 reg_w1(gspca_dev
, 0x118f, blue
);
1364 static void set_hvflip(struct gspca_dev
*gspca_dev
, s32 hflip
, s32 vflip
)
1368 struct sd
*sd
= (struct sd
*) gspca_dev
;
1370 if ((sd
->flags
& FLIP_DETECT
) && dmi_check_system(flip_dmi_table
)) {
1375 switch (sd
->sensor
) {
1386 reg_w1(gspca_dev
, 0x1182, sd
->vstart
);
1387 i2c_w1(gspca_dev
, 0x1e, value
);
1390 i2c_r1(gspca_dev
, 0x1e, &value
);
1399 i2c_w1(gspca_dev
, 0x1e, value
);
1400 i2c_w1(gspca_dev
, 0x3a, tslb
);
1402 case SENSOR_MT9V111
:
1403 case SENSOR_MT9V011
:
1404 i2c_r2(gspca_dev
, 0x20, &value2
);
1410 i2c_w2(gspca_dev
, 0x20, value2
);
1412 case SENSOR_MT9M112
:
1413 case SENSOR_MT9M111
:
1414 case SENSOR_MT9V112
:
1415 i2c_r2(gspca_dev
, 0x20, &value2
);
1421 i2c_w2(gspca_dev
, 0x20, value2
);
1423 case SENSOR_HV7131R
:
1424 i2c_r1(gspca_dev
, 0x01, &value
);
1430 i2c_w1(gspca_dev
, 0x01, value
);
1435 static void set_exposure(struct gspca_dev
*gspca_dev
, s32 expo
)
1437 struct sd
*sd
= (struct sd
*) gspca_dev
;
1438 u8 exp
[8] = {sd
->i2c_intf
, sd
->i2c_addr
,
1439 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1442 if (gspca_dev
->streaming
)
1445 switch (sd
->sensor
) {
1455 exp
[2] = 0x10; /* AECH */
1456 exp
[3] = expo2
>> 2;
1458 i2c_w(gspca_dev
, exp
);
1459 exp
[2] = 0x04; /* COM1 */
1460 exp
[3] = expo2
& 0x0003;
1462 i2c_w(gspca_dev
, exp
);
1466 exp
[2] = 0x2d; /* ADVFL & ADVFH */
1470 case SENSOR_MT9M001
:
1471 case SENSOR_MT9V112
:
1472 case SENSOR_MT9V011
:
1478 case SENSOR_HV7131R
:
1488 i2c_w(gspca_dev
, exp
);
1491 static void set_gain(struct gspca_dev
*gspca_dev
, s32 g
)
1493 struct sd
*sd
= (struct sd
*) gspca_dev
;
1494 u8 gain
[8] = {sd
->i2c_intf
, sd
->i2c_addr
,
1495 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1497 if (gspca_dev
->streaming
)
1498 gain
[7] = 0x15; /* or 1d ? */
1500 switch (sd
->sensor
) {
1506 gain
[0] |= (2 << 4);
1507 gain
[3] = ov_gain
[g
];
1509 case SENSOR_MT9V011
:
1510 gain
[0] |= (3 << 4);
1512 gain
[3] = micron1_gain
[g
] >> 8;
1513 gain
[4] = micron1_gain
[g
];
1515 case SENSOR_MT9V112
:
1516 gain
[0] |= (3 << 4);
1518 gain
[3] = micron1_gain
[g
] >> 8;
1519 gain
[4] = micron1_gain
[g
];
1521 case SENSOR_MT9M001
:
1522 gain
[0] |= (3 << 4);
1524 gain
[3] = micron2_gain
[g
] >> 8;
1525 gain
[4] = micron2_gain
[g
];
1527 case SENSOR_HV7131R
:
1528 gain
[0] |= (2 << 4);
1530 gain
[3] = hv7131r_gain
[g
];
1535 i2c_w(gspca_dev
, gain
);
1538 static void set_quality(struct gspca_dev
*gspca_dev
, s32 val
)
1540 struct sd
*sd
= (struct sd
*) gspca_dev
;
1542 jpeg_set_qual(sd
->jpeg_hdr
, val
);
1543 reg_w1(gspca_dev
, 0x1061, 0x01); /* stop transfer */
1544 reg_w1(gspca_dev
, 0x10e0, sd
->fmt
| 0x20); /* write QTAB */
1545 reg_w(gspca_dev
, 0x1100, &sd
->jpeg_hdr
[JPEG_QT0_OFFSET
], 64);
1546 reg_w(gspca_dev
, 0x1140, &sd
->jpeg_hdr
[JPEG_QT1_OFFSET
], 64);
1547 reg_w1(gspca_dev
, 0x1061, 0x03); /* restart transfer */
1548 reg_w1(gspca_dev
, 0x10e0, sd
->fmt
);
1549 sd
->fmt
^= 0x0c; /* invert QTAB use + write */
1550 reg_w1(gspca_dev
, 0x10e0, sd
->fmt
);
1553 #ifdef CONFIG_VIDEO_ADV_DEBUG
1554 static int sd_dbg_g_register(struct gspca_dev
*gspca_dev
,
1555 struct v4l2_dbg_register
*reg
)
1557 struct sd
*sd
= (struct sd
*) gspca_dev
;
1560 switch (reg
->match
.addr
) {
1562 if (reg
->reg
< 0x1000 || reg
->reg
> 0x11ff)
1564 reg_r(gspca_dev
, reg
->reg
, 1);
1565 reg
->val
= gspca_dev
->usb_buf
[0];
1566 return gspca_dev
->usb_err
;
1568 if (sd
->sensor
>= SENSOR_MT9V011
&&
1569 sd
->sensor
<= SENSOR_MT9M112
) {
1570 i2c_r2(gspca_dev
, reg
->reg
, (u16
*) ®
->val
);
1573 i2c_r1(gspca_dev
, reg
->reg
, (u8
*) ®
->val
);
1575 return gspca_dev
->usb_err
;
1580 static int sd_dbg_s_register(struct gspca_dev
*gspca_dev
,
1581 const struct v4l2_dbg_register
*reg
)
1583 struct sd
*sd
= (struct sd
*) gspca_dev
;
1585 switch (reg
->match
.addr
) {
1587 if (reg
->reg
< 0x1000 || reg
->reg
> 0x11ff)
1589 reg_w1(gspca_dev
, reg
->reg
, reg
->val
);
1590 return gspca_dev
->usb_err
;
1592 if (sd
->sensor
>= SENSOR_MT9V011
&&
1593 sd
->sensor
<= SENSOR_MT9M112
) {
1594 i2c_w2(gspca_dev
, reg
->reg
, reg
->val
);
1596 i2c_w1(gspca_dev
, reg
->reg
, reg
->val
);
1598 return gspca_dev
->usb_err
;
1603 static int sd_chip_info(struct gspca_dev
*gspca_dev
,
1604 struct v4l2_dbg_chip_info
*chip
)
1606 if (chip
->match
.addr
> 1)
1608 if (chip
->match
.addr
== 1)
1609 strlcpy(chip
->name
, "sensor", sizeof(chip
->name
));
1614 static int sd_config(struct gspca_dev
*gspca_dev
,
1615 const struct usb_device_id
*id
)
1617 struct sd
*sd
= (struct sd
*) gspca_dev
;
1620 cam
= &gspca_dev
->cam
;
1621 cam
->needs_full_bandwidth
= 1;
1623 sd
->sensor
= id
->driver_info
>> 8;
1624 sd
->i2c_addr
= id
->driver_info
;
1625 sd
->flags
= id
->driver_info
>> 16;
1626 sd
->i2c_intf
= 0x80; /* i2c 100 Kb/s */
1628 switch (sd
->sensor
) {
1629 case SENSOR_MT9M112
:
1630 case SENSOR_MT9M111
:
1633 cam
->cam_mode
= sxga_mode
;
1634 cam
->nmodes
= ARRAY_SIZE(sxga_mode
);
1636 case SENSOR_MT9M001
:
1637 cam
->cam_mode
= mono_mode
;
1638 cam
->nmodes
= ARRAY_SIZE(mono_mode
);
1640 case SENSOR_HV7131R
:
1641 sd
->i2c_intf
= 0x81; /* i2c 400 Kb/s */
1644 cam
->cam_mode
= vga_mode
;
1645 cam
->nmodes
= ARRAY_SIZE(vga_mode
);
1651 sd
->exposure_step
= 16;
1653 INIT_WORK(&sd
->work
, qual_upd
);
1658 static int sd_s_ctrl(struct v4l2_ctrl
*ctrl
)
1660 struct gspca_dev
*gspca_dev
=
1661 container_of(ctrl
->handler
, struct gspca_dev
, ctrl_handler
);
1662 struct sd
*sd
= (struct sd
*)gspca_dev
;
1664 gspca_dev
->usb_err
= 0;
1666 if (!gspca_dev
->streaming
)
1670 /* color control cluster */
1671 case V4L2_CID_BRIGHTNESS
:
1672 set_cmatrix(gspca_dev
, sd
->brightness
->val
,
1673 sd
->contrast
->val
, sd
->saturation
->val
, sd
->hue
->val
);
1675 case V4L2_CID_GAMMA
:
1676 set_gamma(gspca_dev
, ctrl
->val
);
1678 /* blue/red balance cluster */
1679 case V4L2_CID_BLUE_BALANCE
:
1680 set_redblue(gspca_dev
, sd
->blue
->val
, sd
->red
->val
);
1682 /* h/vflip cluster */
1683 case V4L2_CID_HFLIP
:
1684 set_hvflip(gspca_dev
, sd
->hflip
->val
, sd
->vflip
->val
);
1686 /* standalone exposure control */
1687 case V4L2_CID_EXPOSURE
:
1688 set_exposure(gspca_dev
, ctrl
->val
);
1690 /* standalone gain control */
1692 set_gain(gspca_dev
, ctrl
->val
);
1694 /* autogain + exposure or gain control cluster */
1695 case V4L2_CID_AUTOGAIN
:
1696 if (sd
->sensor
== SENSOR_SOI968
)
1697 set_gain(gspca_dev
, sd
->gain
->val
);
1699 set_exposure(gspca_dev
, sd
->exposure
->val
);
1701 case V4L2_CID_JPEG_COMPRESSION_QUALITY
:
1702 set_quality(gspca_dev
, ctrl
->val
);
1705 return gspca_dev
->usb_err
;
1708 static const struct v4l2_ctrl_ops sd_ctrl_ops
= {
1709 .s_ctrl
= sd_s_ctrl
,
1712 static int sd_init_controls(struct gspca_dev
*gspca_dev
)
1714 struct sd
*sd
= (struct sd
*) gspca_dev
;
1715 struct v4l2_ctrl_handler
*hdl
= &gspca_dev
->ctrl_handler
;
1717 gspca_dev
->vdev
.ctrl_handler
= hdl
;
1718 v4l2_ctrl_handler_init(hdl
, 13);
1720 sd
->brightness
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1721 V4L2_CID_BRIGHTNESS
, 0, 255, 1, 127);
1722 sd
->contrast
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1723 V4L2_CID_CONTRAST
, 0, 255, 1, 127);
1724 sd
->saturation
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1725 V4L2_CID_SATURATION
, 0, 255, 1, 127);
1726 sd
->hue
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1727 V4L2_CID_HUE
, -180, 180, 1, 0);
1729 sd
->gamma
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1730 V4L2_CID_GAMMA
, 0, 255, 1, 0x10);
1732 sd
->blue
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1733 V4L2_CID_BLUE_BALANCE
, 0, 127, 1, 0x28);
1734 sd
->red
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1735 V4L2_CID_RED_BALANCE
, 0, 127, 1, 0x28);
1737 if (sd
->sensor
!= SENSOR_OV9655
&& sd
->sensor
!= SENSOR_SOI968
&&
1738 sd
->sensor
!= SENSOR_OV7670
&& sd
->sensor
!= SENSOR_MT9M001
&&
1739 sd
->sensor
!= SENSOR_MT9VPRB
) {
1740 sd
->hflip
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1741 V4L2_CID_HFLIP
, 0, 1, 1, 0);
1742 sd
->vflip
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1743 V4L2_CID_VFLIP
, 0, 1, 1, 0);
1746 if (sd
->sensor
!= SENSOR_SOI968
&& sd
->sensor
!= SENSOR_MT9VPRB
&&
1747 sd
->sensor
!= SENSOR_MT9M112
&& sd
->sensor
!= SENSOR_MT9M111
&&
1748 sd
->sensor
!= SENSOR_MT9V111
)
1749 sd
->exposure
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1750 V4L2_CID_EXPOSURE
, 0, 0x1780, 1, 0x33);
1752 if (sd
->sensor
!= SENSOR_MT9VPRB
&& sd
->sensor
!= SENSOR_MT9M112
&&
1753 sd
->sensor
!= SENSOR_MT9M111
&& sd
->sensor
!= SENSOR_MT9V111
) {
1754 sd
->gain
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1755 V4L2_CID_GAIN
, 0, 28, 1, 0);
1756 sd
->autogain
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1757 V4L2_CID_AUTOGAIN
, 0, 1, 1, 1);
1760 sd
->jpegqual
= v4l2_ctrl_new_std(hdl
, &sd_ctrl_ops
,
1761 V4L2_CID_JPEG_COMPRESSION_QUALITY
, 50, 90, 1, 80);
1763 pr_err("Could not initialize controls\n");
1767 v4l2_ctrl_cluster(4, &sd
->brightness
);
1768 v4l2_ctrl_cluster(2, &sd
->blue
);
1770 v4l2_ctrl_cluster(2, &sd
->hflip
);
1772 if (sd
->sensor
== SENSOR_SOI968
)
1773 /* this sensor doesn't have the exposure control and
1774 autogain is clustered with gain instead. This works
1775 because sd->exposure == NULL. */
1776 v4l2_ctrl_auto_cluster(3, &sd
->autogain
, 0, false);
1778 /* Otherwise autogain is clustered with exposure. */
1779 v4l2_ctrl_auto_cluster(2, &sd
->autogain
, 0, false);
1784 static int sd_init(struct gspca_dev
*gspca_dev
)
1786 struct sd
*sd
= (struct sd
*) gspca_dev
;
1790 0x80, sd
->i2c_addr
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
1793 for (i
= 0; i
< ARRAY_SIZE(bridge_init
); i
++) {
1794 value
= bridge_init
[i
][1];
1795 reg_w(gspca_dev
, bridge_init
[i
][0], &value
, 1);
1796 if (gspca_dev
->usb_err
< 0) {
1797 pr_err("Device initialization failed\n");
1798 return gspca_dev
->usb_err
;
1802 if (sd
->flags
& LED_REVERSE
)
1803 reg_w1(gspca_dev
, 0x1006, 0x00);
1805 reg_w1(gspca_dev
, 0x1006, 0x20);
1807 reg_w(gspca_dev
, 0x10c0, i2c_init
, 9);
1808 if (gspca_dev
->usb_err
< 0) {
1809 pr_err("Device initialization failed\n");
1810 return gspca_dev
->usb_err
;
1813 switch (sd
->sensor
) {
1815 ov9650_init_sensor(gspca_dev
);
1816 if (gspca_dev
->usb_err
< 0)
1818 pr_info("OV9650 sensor detected\n");
1821 ov9655_init_sensor(gspca_dev
);
1822 if (gspca_dev
->usb_err
< 0)
1824 pr_info("OV9655 sensor detected\n");
1827 soi968_init_sensor(gspca_dev
);
1828 if (gspca_dev
->usb_err
< 0)
1830 pr_info("SOI968 sensor detected\n");
1833 ov7660_init_sensor(gspca_dev
);
1834 if (gspca_dev
->usb_err
< 0)
1836 pr_info("OV7660 sensor detected\n");
1839 ov7670_init_sensor(gspca_dev
);
1840 if (gspca_dev
->usb_err
< 0)
1842 pr_info("OV7670 sensor detected\n");
1844 case SENSOR_MT9VPRB
:
1845 mt9v_init_sensor(gspca_dev
);
1846 if (gspca_dev
->usb_err
< 0)
1848 pr_info("MT9VPRB sensor detected\n");
1850 case SENSOR_MT9M111
:
1851 mt9m111_init_sensor(gspca_dev
);
1852 if (gspca_dev
->usb_err
< 0)
1854 pr_info("MT9M111 sensor detected\n");
1856 case SENSOR_MT9M112
:
1857 mt9m112_init_sensor(gspca_dev
);
1858 if (gspca_dev
->usb_err
< 0)
1860 pr_info("MT9M112 sensor detected\n");
1862 case SENSOR_MT9M001
:
1863 mt9m001_init_sensor(gspca_dev
);
1864 if (gspca_dev
->usb_err
< 0)
1867 case SENSOR_HV7131R
:
1868 hv7131r_init_sensor(gspca_dev
);
1869 if (gspca_dev
->usb_err
< 0)
1871 pr_info("HV7131R sensor detected\n");
1874 pr_err("Unsupported sensor\n");
1875 gspca_dev
->usb_err
= -ENODEV
;
1877 return gspca_dev
->usb_err
;
1880 static void configure_sensor_output(struct gspca_dev
*gspca_dev
, int mode
)
1882 struct sd
*sd
= (struct sd
*) gspca_dev
;
1885 switch (sd
->sensor
) {
1887 if (mode
& MODE_SXGA
) {
1888 i2c_w1(gspca_dev
, 0x17, 0x1d);
1889 i2c_w1(gspca_dev
, 0x18, 0xbd);
1890 i2c_w1(gspca_dev
, 0x19, 0x01);
1891 i2c_w1(gspca_dev
, 0x1a, 0x81);
1892 i2c_w1(gspca_dev
, 0x12, 0x00);
1896 i2c_w1(gspca_dev
, 0x17, 0x13);
1897 i2c_w1(gspca_dev
, 0x18, 0x63);
1898 i2c_w1(gspca_dev
, 0x19, 0x01);
1899 i2c_w1(gspca_dev
, 0x1a, 0x79);
1900 i2c_w1(gspca_dev
, 0x12, 0x40);
1906 if (mode
& MODE_SXGA
) {
1907 i2c_w1(gspca_dev
, 0x17, 0x1b);
1908 i2c_w1(gspca_dev
, 0x18, 0xbc);
1909 i2c_w1(gspca_dev
, 0x19, 0x01);
1910 i2c_w1(gspca_dev
, 0x1a, 0x82);
1911 i2c_r1(gspca_dev
, 0x12, &value
);
1912 i2c_w1(gspca_dev
, 0x12, value
& 0x07);
1914 i2c_w1(gspca_dev
, 0x17, 0x24);
1915 i2c_w1(gspca_dev
, 0x18, 0xc5);
1916 i2c_w1(gspca_dev
, 0x19, 0x00);
1917 i2c_w1(gspca_dev
, 0x1a, 0x3c);
1918 i2c_r1(gspca_dev
, 0x12, &value
);
1919 i2c_w1(gspca_dev
, 0x12, (value
& 0x7) | 0x40);
1922 case SENSOR_MT9M112
:
1923 case SENSOR_MT9M111
:
1924 if (mode
& MODE_SXGA
) {
1925 i2c_w2(gspca_dev
, 0xf0, 0x0002);
1926 i2c_w2(gspca_dev
, 0xc8, 0x970b);
1927 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1929 i2c_w2(gspca_dev
, 0xf0, 0x0002);
1930 i2c_w2(gspca_dev
, 0xc8, 0x8000);
1931 i2c_w2(gspca_dev
, 0xf0, 0x0000);
1937 static int sd_isoc_init(struct gspca_dev
*gspca_dev
)
1939 struct usb_interface
*intf
;
1940 u32 flags
= gspca_dev
->cam
.cam_mode
[(int)gspca_dev
->curr_mode
].priv
;
1943 * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth
1944 * than our regular bandwidth calculations reserve, so we force the
1945 * use of a specific altsetting when using the SN9C20X_I420 fmt.
1947 if (!(flags
& (MODE_RAW
| MODE_JPEG
))) {
1948 intf
= usb_ifnum_to_if(gspca_dev
->dev
, gspca_dev
->iface
);
1950 if (intf
->num_altsetting
!= 9) {
1951 pr_warn("sn9c20x camera with unknown number of alt "
1952 "settings (%d), please report!\n",
1953 intf
->num_altsetting
);
1954 gspca_dev
->alt
= intf
->num_altsetting
;
1958 switch (gspca_dev
->pixfmt
.width
) {
1959 case 160: /* 160x120 */
1962 case 320: /* 320x240 */
1965 default: /* >= 640x480 */
1974 #define HW_WIN(mode, hstart, vstart) \
1975 ((const u8 []){hstart, 0, vstart, 0, \
1976 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
1977 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
1979 #define CLR_WIN(width, height) \
1981 {0, width >> 2, 0, height >> 1,\
1982 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
1984 static int sd_start(struct gspca_dev
*gspca_dev
)
1986 struct sd
*sd
= (struct sd
*) gspca_dev
;
1987 int mode
= gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
;
1988 int width
= gspca_dev
->pixfmt
.width
;
1989 int height
= gspca_dev
->pixfmt
.height
;
1992 jpeg_define(sd
->jpeg_hdr
, height
, width
,
1994 jpeg_set_qual(sd
->jpeg_hdr
, v4l2_ctrl_g_ctrl(sd
->jpegqual
));
1996 if (mode
& MODE_RAW
)
1998 else if (mode
& MODE_JPEG
)
2001 fmt
= 0x2f; /* YUV 420 */
2004 switch (mode
& SCALE_MASK
) {
2005 case SCALE_1280x1024
:
2007 pr_info("Set 1280x1024\n");
2011 pr_info("Set 640x480\n");
2015 pr_info("Set 320x240\n");
2019 pr_info("Set 160x120\n");
2023 configure_sensor_output(gspca_dev
, mode
);
2024 reg_w(gspca_dev
, 0x1100, &sd
->jpeg_hdr
[JPEG_QT0_OFFSET
], 64);
2025 reg_w(gspca_dev
, 0x1140, &sd
->jpeg_hdr
[JPEG_QT1_OFFSET
], 64);
2026 reg_w(gspca_dev
, 0x10fb, CLR_WIN(width
, height
), 5);
2027 reg_w(gspca_dev
, 0x1180, HW_WIN(mode
, sd
->hstart
, sd
->vstart
), 6);
2028 reg_w1(gspca_dev
, 0x1189, scale
);
2029 reg_w1(gspca_dev
, 0x10e0, fmt
);
2031 set_cmatrix(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->brightness
),
2032 v4l2_ctrl_g_ctrl(sd
->contrast
),
2033 v4l2_ctrl_g_ctrl(sd
->saturation
),
2034 v4l2_ctrl_g_ctrl(sd
->hue
));
2035 set_gamma(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->gamma
));
2036 set_redblue(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->blue
),
2037 v4l2_ctrl_g_ctrl(sd
->red
));
2039 set_gain(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->gain
));
2041 set_exposure(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->exposure
));
2043 set_hvflip(gspca_dev
, v4l2_ctrl_g_ctrl(sd
->hflip
),
2044 v4l2_ctrl_g_ctrl(sd
->vflip
));
2046 reg_w1(gspca_dev
, 0x1007, 0x20);
2047 reg_w1(gspca_dev
, 0x1061, 0x03);
2049 /* if JPEG, prepare the compression quality update */
2050 if (mode
& MODE_JPEG
) {
2051 sd
->pktsz
= sd
->npkt
= 0;
2055 return gspca_dev
->usb_err
;
2058 static void sd_stopN(struct gspca_dev
*gspca_dev
)
2060 reg_w1(gspca_dev
, 0x1007, 0x00);
2061 reg_w1(gspca_dev
, 0x1061, 0x01);
2064 /* called on streamoff with alt==0 and on disconnect */
2065 /* the usb_lock is held at entry - restore on exit */
2066 static void sd_stop0(struct gspca_dev
*gspca_dev
)
2068 struct sd
*sd
= (struct sd
*) gspca_dev
;
2070 mutex_unlock(&gspca_dev
->usb_lock
);
2071 flush_work(&sd
->work
);
2072 mutex_lock(&gspca_dev
->usb_lock
);
2075 static void do_autoexposure(struct gspca_dev
*gspca_dev
, u16 avg_lum
)
2077 struct sd
*sd
= (struct sd
*) gspca_dev
;
2078 s32 cur_exp
= v4l2_ctrl_g_ctrl(sd
->exposure
);
2079 s32 max
= sd
->exposure
->maximum
- sd
->exposure_step
;
2080 s32 min
= sd
->exposure
->minimum
+ sd
->exposure_step
;
2084 * some hardcoded values are present
2085 * like those for maximal/minimal exposure
2086 * and exposure steps
2088 if (avg_lum
< MIN_AVG_LUM
) {
2092 new_exp
= cur_exp
+ sd
->exposure_step
;
2097 v4l2_ctrl_s_ctrl(sd
->exposure
, new_exp
);
2099 sd
->older_step
= sd
->old_step
;
2102 if (sd
->old_step
^ sd
->older_step
)
2103 sd
->exposure_step
/= 2;
2105 sd
->exposure_step
+= 2;
2107 if (avg_lum
> MAX_AVG_LUM
) {
2110 new_exp
= cur_exp
- sd
->exposure_step
;
2115 v4l2_ctrl_s_ctrl(sd
->exposure
, new_exp
);
2116 sd
->older_step
= sd
->old_step
;
2119 if (sd
->old_step
^ sd
->older_step
)
2120 sd
->exposure_step
/= 2;
2122 sd
->exposure_step
+= 2;
2126 static void do_autogain(struct gspca_dev
*gspca_dev
, u16 avg_lum
)
2128 struct sd
*sd
= (struct sd
*) gspca_dev
;
2129 s32 cur_gain
= v4l2_ctrl_g_ctrl(sd
->gain
);
2131 if (avg_lum
< MIN_AVG_LUM
&& cur_gain
< sd
->gain
->maximum
)
2132 v4l2_ctrl_s_ctrl(sd
->gain
, cur_gain
+ 1);
2133 if (avg_lum
> MAX_AVG_LUM
&& cur_gain
> sd
->gain
->minimum
)
2134 v4l2_ctrl_s_ctrl(sd
->gain
, cur_gain
- 1);
2137 static void sd_dqcallback(struct gspca_dev
*gspca_dev
)
2139 struct sd
*sd
= (struct sd
*) gspca_dev
;
2142 if (sd
->autogain
== NULL
|| !v4l2_ctrl_g_ctrl(sd
->autogain
))
2145 avg_lum
= atomic_read(&sd
->avg_lum
);
2146 if (sd
->sensor
== SENSOR_SOI968
)
2147 do_autogain(gspca_dev
, avg_lum
);
2149 do_autoexposure(gspca_dev
, avg_lum
);
2152 /* JPEG quality update */
2153 /* This function is executed from a work queue. */
2154 static void qual_upd(struct work_struct
*work
)
2156 struct sd
*sd
= container_of(work
, struct sd
, work
);
2157 struct gspca_dev
*gspca_dev
= &sd
->gspca_dev
;
2158 s32 qual
= v4l2_ctrl_g_ctrl(sd
->jpegqual
);
2160 /* To protect gspca_dev->usb_buf and gspca_dev->usb_err */
2161 mutex_lock(&gspca_dev
->usb_lock
);
2162 PDEBUG(D_STREAM
, "qual_upd %d%%", qual
);
2163 gspca_dev
->usb_err
= 0;
2164 set_quality(gspca_dev
, qual
);
2165 mutex_unlock(&gspca_dev
->usb_lock
);
2168 #if IS_ENABLED(CONFIG_INPUT)
2169 static int sd_int_pkt_scan(struct gspca_dev
*gspca_dev
,
2170 u8
*data
, /* interrupt packet */
2171 int len
) /* interrupt packet length */
2173 struct sd
*sd
= (struct sd
*) gspca_dev
;
2175 if (!(sd
->flags
& HAS_NO_BUTTON
) && len
== 1) {
2176 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 1);
2177 input_sync(gspca_dev
->input_dev
);
2178 input_report_key(gspca_dev
->input_dev
, KEY_CAMERA
, 0);
2179 input_sync(gspca_dev
->input_dev
);
2186 /* check the JPEG compression */
2187 static void transfer_check(struct gspca_dev
*gspca_dev
,
2190 struct sd
*sd
= (struct sd
*) gspca_dev
;
2195 /* if USB error, discard the frame and decrease the quality */
2196 if (data
[6] & 0x08) { /* USB FIFO full */
2197 gspca_dev
->last_packet_type
= DISCARD_PACKET
;
2201 /* else, compute the filling rate and a new JPEG quality */
2202 r
= (sd
->pktsz
* 100) /
2204 gspca_dev
->urb
[0]->iso_frame_desc
[0].length
);
2210 if (new_qual
!= 0) {
2211 sd
->nchg
+= new_qual
;
2212 if (sd
->nchg
< -6 || sd
->nchg
>= 12) {
2213 /* Note: we are in interrupt context, so we can't
2214 use v4l2_ctrl_g/s_ctrl here. Access the value
2215 directly instead. */
2216 s32 curqual
= sd
->jpegqual
->cur
.val
;
2218 new_qual
+= curqual
;
2219 if (new_qual
< sd
->jpegqual
->minimum
)
2220 new_qual
= sd
->jpegqual
->minimum
;
2221 else if (new_qual
> sd
->jpegqual
->maximum
)
2222 new_qual
= sd
->jpegqual
->maximum
;
2223 if (new_qual
!= curqual
) {
2224 sd
->jpegqual
->cur
.val
= new_qual
;
2225 schedule_work(&sd
->work
);
2231 sd
->pktsz
= sd
->npkt
= 0;
2234 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
2235 u8
*data
, /* isoc packet */
2236 int len
) /* iso packet length */
2238 struct sd
*sd
= (struct sd
*) gspca_dev
;
2239 int avg_lum
, is_jpeg
;
2240 static const u8 frame_header
[] = {
2241 0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96
2244 is_jpeg
= (sd
->fmt
& 0x03) == 0;
2245 if (len
>= 64 && memcmp(data
, frame_header
, 6) == 0) {
2246 avg_lum
= ((data
[35] >> 2) & 3) |
2249 avg_lum
+= ((data
[35] >> 4) & 3) |
2252 avg_lum
+= ((data
[35] >> 6) & 3) |
2255 avg_lum
+= (data
[36] & 3) |
2258 avg_lum
+= ((data
[36] >> 2) & 3) |
2261 avg_lum
+= ((data
[36] >> 4) & 3) |
2264 avg_lum
+= ((data
[36] >> 6) & 3) |
2267 avg_lum
+= ((data
[44] >> 4) & 3) |
2271 atomic_set(&sd
->avg_lum
, avg_lum
);
2274 transfer_check(gspca_dev
, data
);
2276 gspca_frame_add(gspca_dev
, LAST_PACKET
, NULL
, 0);
2282 if (gspca_dev
->last_packet_type
== LAST_PACKET
) {
2284 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
2285 sd
->jpeg_hdr
, JPEG_HDR_SZ
);
2286 gspca_frame_add(gspca_dev
, INTER_PACKET
,
2289 gspca_frame_add(gspca_dev
, FIRST_PACKET
,
2293 /* if JPEG, count the packets and their size */
2298 gspca_frame_add(gspca_dev
, INTER_PACKET
, data
, len
);
2302 /* sub-driver description */
2303 static const struct sd_desc sd_desc
= {
2304 .name
= KBUILD_MODNAME
,
2305 .config
= sd_config
,
2307 .init_controls
= sd_init_controls
,
2308 .isoc_init
= sd_isoc_init
,
2312 .pkt_scan
= sd_pkt_scan
,
2313 #if IS_ENABLED(CONFIG_INPUT)
2314 .int_pkt_scan
= sd_int_pkt_scan
,
2316 .dq_callback
= sd_dqcallback
,
2317 #ifdef CONFIG_VIDEO_ADV_DEBUG
2318 .set_register
= sd_dbg_s_register
,
2319 .get_register
= sd_dbg_g_register
,
2320 .get_chip_info
= sd_chip_info
,
2324 #define SN9C20X(sensor, i2c_addr, flags) \
2325 .driver_info = ((flags & 0xff) << 16) \
2326 | (SENSOR_ ## sensor << 8) \
2329 static const struct usb_device_id device_table
[] = {
2330 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001
, 0x5d, 0)},
2331 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111
, 0x5d, 0)},
2332 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655
, 0x30, 0)},
2333 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112
, 0x5d, 0)},
2334 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968
, 0x30, LED_REVERSE
)},
2335 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650
, 0x30,
2336 (FLIP_DETECT
| HAS_NO_BUTTON
))},
2337 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650
, 0x30, 0)},
2338 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650
, 0x30, 0)},
2339 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670
, 0x21, 0)},
2340 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB
, 0x00, 0)},
2341 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660
, 0x21, FLIP_DETECT
)},
2342 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R
, 0x11, 0)},
2343 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650
, 0x30, 0)},
2344 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001
, 0x5d, 0)},
2345 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111
, 0x5d, 0)},
2346 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655
, 0x30, 0)},
2347 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112
, 0x5d, 0)},
2348 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968
, 0x30, 0)},
2349 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650
, 0x30, 0)},
2350 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670
, 0x21, 0)},
2351 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB
, 0x00, 0)},
2352 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655
, 0x30, LED_REVERSE
)},
2353 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660
, 0x21, LED_REVERSE
)},
2354 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R
, 0x11, 0)},
2355 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650
, 0x30, 0)},
2356 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660
, 0x21, 0)},
2357 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R
, 0x11, 0)},
2358 {USB_DEVICE(0x0458, 0x7045), SN9C20X(MT9M112
, 0x5d, LED_REVERSE
)},
2359 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112
, 0x5d, 0)},
2360 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112
, 0x5d, 0)},
2361 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R
, 0x11, 0)},
2362 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R
, 0x11, 0)},
2363 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R
, 0x11, 0)},
2364 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R
, 0x11, 0)},
2365 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111
, 0x5d, 0)},
2366 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111
, 0x5d, 0)},
2367 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111
, 0x5d, 0)},
2370 MODULE_DEVICE_TABLE(usb
, device_table
);
2372 /* -- device connect -- */
2373 static int sd_probe(struct usb_interface
*intf
,
2374 const struct usb_device_id
*id
)
2376 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
2380 static struct usb_driver sd_driver
= {
2381 .name
= KBUILD_MODNAME
,
2382 .id_table
= device_table
,
2384 .disconnect
= gspca_disconnect
,
2386 .suspend
= gspca_suspend
,
2387 .resume
= gspca_resume
,
2388 .reset_resume
= gspca_resume
,
2392 module_usb_driver(sd_driver
);