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