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