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