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