]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/media/usb/gspca/sn9c20x.c
Merge branches 'for-4.11/upstream-fixes', 'for-4.12/accutouch', 'for-4.12/cp2112...
[mirror_ubuntu-artful-kernel.git] / drivers / media / usb / gspca / sn9c20x.c
CommitLineData
26e744b6
BJ
1/*
2 * Sonix sn9c201 sn9c202 library
ff38d58e
JFM
3 *
4 * Copyright (C) 2012 Jean-Francois Moine <http://moinejf.free.fr>
26e744b6
BJ
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.
26e744b6
BJ
17 */
18
91f5842b
JP
19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
26e744b6 21#include <linux/input.h>
26e744b6 22
c15b95ed
MCC
23#include "gspca.h"
24#include "jpeg.h"
25
7ddaac7f 26#include <linux/dmi.h>
c15b95ed 27
1ddc9f75 28MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, microdia project <microdia@googlegroups.com>");
26e744b6
BJ
29MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
30MODULE_LICENSE("GPL");
31
86701c1d
MCC
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
26e744b6
BJ
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
e99ac54d
BJ
54#define SENSOR_MT9M112 10
55#define SENSOR_HV7131R 11
9637c652 56#define SENSOR_MT9VPRB 12
26e744b6 57
a39db27a 58/* camera flags */
33ddc16f 59#define HAS_NO_BUTTON 0x1
0c045eb7 60#define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
7ddaac7f 61#define FLIP_DETECT 0x4
a39db27a 62
26e744b6
BJ
63/* specific webcam descriptor */
64struct sd {
65 struct gspca_dev gspca_dev;
66
63069da1
HV
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;
c5224d81 88
92dcffcf 89 struct work_struct work;
92dcffcf
JFM
90
91 u32 pktsz; /* (used by pkt_scan) */
92 u16 npkt;
93 s8 nchg;
4c632e4e
JFM
94 u8 fmt; /* (used for JPEG QTAB update */
95
26e744b6
BJ
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
26e744b6 103 u8 i2c_addr;
c4407fe8 104 u8 i2c_intf;
26e744b6
BJ
105 u8 sensor;
106 u8 hstart;
107 u8 vstart;
108
9a731a32 109 u8 jpeg_hdr[JPEG_HDR_SZ];
26e744b6 110
a39db27a 111 u8 flags;
26e744b6
BJ
112};
113
92dcffcf
JFM
114static void qual_upd(struct work_struct *work);
115
58aa68c2
JP
116struct i2c_reg_u8 {
117 u8 reg;
118 u8 val;
119};
120
121struct i2c_reg_u16 {
122 u8 reg;
123 u16 val;
124};
125
7ddaac7f
BJ
126static 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 },
bcc6f669
HG
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 },
5d26ed91
BJ
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 },
e077f86b
BJ
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 },
7ddaac7f
BJ
163 {}
164};
165
26e744b6
BJ
166static const struct v4l2_pix_format vga_mode[] = {
167 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
b1e4665b 168 .bytesperline = 160,
9b1d3cae 169 .sizeimage = 160 * 120 * 4 / 8 + 590,
26e744b6 170 .colorspace = V4L2_COLORSPACE_JPEG,
86701c1d 171 .priv = SCALE_160x120 | MODE_JPEG},
26e744b6
BJ
172 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
173 .bytesperline = 160,
174 .sizeimage = 160 * 120,
175 .colorspace = V4L2_COLORSPACE_SRGB,
86701c1d 176 .priv = SCALE_160x120 | MODE_RAW},
26e744b6 177 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
b1e4665b 178 .bytesperline = 160,
26e744b6
BJ
179 .sizeimage = 240 * 120,
180 .colorspace = V4L2_COLORSPACE_SRGB,
86701c1d 181 .priv = SCALE_160x120},
26e744b6 182 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
b1e4665b 183 .bytesperline = 320,
6899a9c7 184 .sizeimage = 320 * 240 * 4 / 8 + 590,
26e744b6 185 .colorspace = V4L2_COLORSPACE_JPEG,
86701c1d 186 .priv = SCALE_320x240 | MODE_JPEG},
26e744b6
BJ
187 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
188 .bytesperline = 320,
189 .sizeimage = 320 * 240 ,
190 .colorspace = V4L2_COLORSPACE_SRGB,
86701c1d 191 .priv = SCALE_320x240 | MODE_RAW},
26e744b6 192 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
b1e4665b 193 .bytesperline = 320,
26e744b6
BJ
194 .sizeimage = 480 * 240 ,
195 .colorspace = V4L2_COLORSPACE_SRGB,
86701c1d 196 .priv = SCALE_320x240},
26e744b6 197 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
b1e4665b 198 .bytesperline = 640,
6899a9c7 199 .sizeimage = 640 * 480 * 4 / 8 + 590,
26e744b6 200 .colorspace = V4L2_COLORSPACE_JPEG,
86701c1d 201 .priv = SCALE_640x480 | MODE_JPEG},
26e744b6
BJ
202 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
203 .bytesperline = 640,
204 .sizeimage = 640 * 480,
205 .colorspace = V4L2_COLORSPACE_SRGB,
86701c1d 206 .priv = SCALE_640x480 | MODE_RAW},
26e744b6 207 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
b1e4665b 208 .bytesperline = 640,
26e744b6
BJ
209 .sizeimage = 960 * 480,
210 .colorspace = V4L2_COLORSPACE_SRGB,
86701c1d 211 .priv = SCALE_640x480},
26e744b6
BJ
212};
213
214static const struct v4l2_pix_format sxga_mode[] = {
215 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
b1e4665b 216 .bytesperline = 160,
9b1d3cae 217 .sizeimage = 160 * 120 * 4 / 8 + 590,
26e744b6 218 .colorspace = V4L2_COLORSPACE_JPEG,
86701c1d 219 .priv = SCALE_160x120 | MODE_JPEG},
26e744b6
BJ
220 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
221 .bytesperline = 160,
222 .sizeimage = 160 * 120,
223 .colorspace = V4L2_COLORSPACE_SRGB,
86701c1d 224 .priv = SCALE_160x120 | MODE_RAW},
26e744b6 225 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
b1e4665b 226 .bytesperline = 160,
26e744b6
BJ
227 .sizeimage = 240 * 120,
228 .colorspace = V4L2_COLORSPACE_SRGB,
86701c1d 229 .priv = SCALE_160x120},
26e744b6 230 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
b1e4665b 231 .bytesperline = 320,
6899a9c7 232 .sizeimage = 320 * 240 * 4 / 8 + 590,
26e744b6 233 .colorspace = V4L2_COLORSPACE_JPEG,
86701c1d 234 .priv = SCALE_320x240 | MODE_JPEG},
26e744b6
BJ
235 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
236 .bytesperline = 320,
237 .sizeimage = 320 * 240 ,
238 .colorspace = V4L2_COLORSPACE_SRGB,
86701c1d 239 .priv = SCALE_320x240 | MODE_RAW},
26e744b6 240 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
b1e4665b 241 .bytesperline = 320,
26e744b6
BJ
242 .sizeimage = 480 * 240 ,
243 .colorspace = V4L2_COLORSPACE_SRGB,
86701c1d 244 .priv = SCALE_320x240},
26e744b6 245 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
b1e4665b 246 .bytesperline = 640,
6899a9c7 247 .sizeimage = 640 * 480 * 4 / 8 + 590,
26e744b6 248 .colorspace = V4L2_COLORSPACE_JPEG,
86701c1d 249 .priv = SCALE_640x480 | MODE_JPEG},
26e744b6
BJ
250 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
251 .bytesperline = 640,
252 .sizeimage = 640 * 480,
253 .colorspace = V4L2_COLORSPACE_SRGB,
86701c1d 254 .priv = SCALE_640x480 | MODE_RAW},
26e744b6 255 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
b1e4665b 256 .bytesperline = 640,
26e744b6
BJ
257 .sizeimage = 960 * 480,
258 .colorspace = V4L2_COLORSPACE_SRGB,
86701c1d 259 .priv = SCALE_640x480},
26e744b6
BJ
260 {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
261 .bytesperline = 1280,
9b1d3cae 262 .sizeimage = 1280 * 1024,
26e744b6 263 .colorspace = V4L2_COLORSPACE_SRGB,
86701c1d 264 .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
26e744b6
BJ
265};
266
d162e7aa
MCC
267static 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
58aa68c2 290static const s16 hsv_red_x[] = {
26e744b6
BJ
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
58aa68c2 338static const s16 hsv_red_y[] = {
26e744b6
BJ
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
58aa68c2 386static const s16 hsv_green_x[] = {
26e744b6
BJ
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
58aa68c2 434static const s16 hsv_green_y[] = {
26e744b6
BJ
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
58aa68c2 482static const s16 hsv_blue_x[] = {
26e744b6
BJ
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
58aa68c2 530static const s16 hsv_blue_y[] = {
26e744b6
BJ
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
dae1de64 578static const u16 bridge_init[][2] = {
26e744b6
BJ
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},
0c045eb7
BJ
597 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
598 {0x1007, 0x00}
26e744b6
BJ
599};
600
601/* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
dae1de64 602static const u8 ov_gain[] = {
26e744b6
BJ
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) */
dae1de64 614static const u16 micron1_gain[] = {
26e744b6
BJ
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) */
dae1de64 635static const u16 micron2_gain[] = {
26e744b6
BJ
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 */
dae1de64 655static const u8 hv7131r_gain[] = {
26e744b6
BJ
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
dae1de64 666static const struct i2c_reg_u8 soi968_init[] = {
92884f80 667 {0x0c, 0x00}, {0x0f, 0x1f},
26e744b6
BJ
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},
e1430471 673 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
26e744b6
BJ
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
dae1de64 680static const struct i2c_reg_u8 ov7660_init[] = {
26e744b6
BJ
681 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
682 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
683 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
8bc50f35
HG
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},
26e744b6 687 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
a1ac5dc2
JFM
688 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0x00},
689 {0x2e, 0x00}, {0x01, 0x78}, {0x02, 0x50},
26e744b6
BJ
690};
691
dae1de64 692static const struct i2c_reg_u8 ov7670_init[] = {
92884f80 693 {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
26e744b6
BJ
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
dae1de64 749static const struct i2c_reg_u8 ov9650_init[] = {
92884f80 750 {0x00, 0x00}, {0x01, 0x78},
26e744b6
BJ
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
dae1de64 779static const struct i2c_reg_u8 ov9655_init[] = {
92884f80 780 {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
cc2a8335
BJ
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},
26e744b6 796 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
cc2a8335
BJ
797 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
798 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
26e744b6 799 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
cc2a8335
BJ
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},
26e744b6
BJ
804};
805
dae1de64 806static const struct i2c_reg_u16 mt9v112_init[] = {
26e744b6
BJ
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
dae1de64 825static const struct i2c_reg_u16 mt9v111_init[] = {
26e744b6 826 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
6ea23bd0
BJ
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}
26e744b6
BJ
833};
834
dae1de64 835static const struct i2c_reg_u16 mt9v011_init[] = {
26e744b6
BJ
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
dae1de64 862static const struct i2c_reg_u16 mt9m001_init[] = {
d162e7aa
MCC
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},
26e744b6
BJ
876};
877
dae1de64 878static const struct i2c_reg_u16 mt9m111_init[] = {
13a84fa4
BJ
879 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
880 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
4d708a5e
BJ
881 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
882 {0xf0, 0x0000},
26e744b6
BJ
883};
884
dae1de64 885static const struct i2c_reg_u16 mt9m112_init[] = {
e99ac54d
BJ
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
dae1de64 892static const struct i2c_reg_u8 hv7131r_init[] = {
26e744b6
BJ
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
fe86ec75 903static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
26e744b6
BJ
904{
905 struct usb_device *dev = gspca_dev->dev;
906 int result;
fe86ec75
JFM
907
908 if (gspca_dev->usb_err < 0)
909 return;
26e744b6
BJ
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)) {
fe86ec75
JFM
919 pr_err("Read register %02x failed %d\n", reg, result);
920 gspca_dev->usb_err = result;
26e744b6 921 }
26e744b6
BJ
922}
923
fe86ec75 924static void reg_w(struct gspca_dev *gspca_dev, u16 reg,
58aa68c2 925 const u8 *buffer, int length)
26e744b6
BJ
926{
927 struct usb_device *dev = gspca_dev->dev;
928 int result;
fe86ec75
JFM
929
930 if (gspca_dev->usb_err < 0)
931 return;
26e744b6
BJ
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)) {
fe86ec75
JFM
942 pr_err("Write register %02x failed %d\n", reg, result);
943 gspca_dev->usb_err = result;
26e744b6 944 }
26e744b6
BJ
945}
946
fe86ec75 947static void reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
26e744b6 948{
ff38d58e 949 reg_w(gspca_dev, reg, &value, 1);
26e744b6
BJ
950}
951
fe86ec75 952static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
26e744b6
BJ
953{
954 int i;
ff38d58e 955
26e744b6
BJ
956 reg_w(gspca_dev, 0x10c0, buffer, 8);
957 for (i = 0; i < 5; i++) {
958 reg_r(gspca_dev, 0x10c0, 1);
fe86ec75
JFM
959 if (gspca_dev->usb_err < 0)
960 return;
26e744b6 961 if (gspca_dev->usb_buf[0] & 0x04) {
fe86ec75
JFM
962 if (gspca_dev->usb_buf[0] & 0x08) {
963 pr_err("i2c_w error\n");
964 gspca_dev->usb_err = -EIO;
965 }
966 return;
26e744b6 967 }
e71389be 968 msleep(10);
26e744b6 969 }
fe86ec75
JFM
970 pr_err("i2c_w reg %02x no response\n", buffer[2]);
971/* gspca_dev->usb_err = -EIO; fixme: may occur */
26e744b6
BJ
972}
973
fe86ec75 974static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
26e744b6
BJ
975{
976 struct sd *sd = (struct sd *) gspca_dev;
26e744b6
BJ
977 u8 row[8];
978
979 /*
980 * from the point of view of the bridge, the length
981 * includes the address
982 */
c4407fe8 983 row[0] = sd->i2c_intf | (2 << 4);
26e744b6
BJ
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
fe86ec75 992 i2c_w(gspca_dev, row);
26e744b6
BJ
993}
994
d4689b74 995static void i2c_w1_buf(struct gspca_dev *gspca_dev,
dae1de64 996 const struct i2c_reg_u8 *buf, int sz)
d4689b74
JFM
997{
998 while (--sz >= 0) {
999 i2c_w1(gspca_dev, buf->reg, buf->val);
1000 buf++;
1001 }
1002}
1003
fe86ec75 1004static void i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
26e744b6
BJ
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 */
c4407fe8 1013 row[0] = sd->i2c_intf | (3 << 4);
26e744b6
BJ
1014 row[1] = sd->i2c_addr;
1015 row[2] = reg;
ff38d58e
JFM
1016 row[3] = val >> 8;
1017 row[4] = val;
26e744b6
BJ
1018 row[5] = 0x00;
1019 row[6] = 0x00;
1020 row[7] = 0x10;
1021
fe86ec75 1022 i2c_w(gspca_dev, row);
26e744b6
BJ
1023}
1024
d4689b74 1025static void i2c_w2_buf(struct gspca_dev *gspca_dev,
dae1de64 1026 const struct i2c_reg_u16 *buf, int sz)
d4689b74
JFM
1027{
1028 while (--sz >= 0) {
1029 i2c_w2(gspca_dev, buf->reg, buf->val);
1030 buf++;
1031 }
1032}
1033
fe86ec75 1034static void i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
26e744b6
BJ
1035{
1036 struct sd *sd = (struct sd *) gspca_dev;
1037 u8 row[8];
1038
c4407fe8 1039 row[0] = sd->i2c_intf | (1 << 4);
26e744b6
BJ
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;
fe86ec75 1047 i2c_w(gspca_dev, row);
c4407fe8 1048 row[0] = sd->i2c_intf | (1 << 4) | 0x02;
26e744b6 1049 row[2] = 0;
fe86ec75
JFM
1050 i2c_w(gspca_dev, row);
1051 reg_r(gspca_dev, 0x10c2, 5);
00b581ef 1052 *val = gspca_dev->usb_buf[4];
26e744b6
BJ
1053}
1054
fe86ec75 1055static void i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
26e744b6
BJ
1056{
1057 struct sd *sd = (struct sd *) gspca_dev;
1058 u8 row[8];
1059
c4407fe8 1060 row[0] = sd->i2c_intf | (1 << 4);
26e744b6
BJ
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;
fe86ec75 1068 i2c_w(gspca_dev, row);
c4407fe8 1069 row[0] = sd->i2c_intf | (2 << 4) | 0x02;
26e744b6 1070 row[2] = 0;
fe86ec75
JFM
1071 i2c_w(gspca_dev, row);
1072 reg_r(gspca_dev, 0x10c2, 5);
00b581ef 1073 *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
26e744b6
BJ
1074}
1075
fe86ec75 1076static void ov9650_init_sensor(struct gspca_dev *gspca_dev)
26e744b6 1077{
e78567d2 1078 u16 id;
26e744b6
BJ
1079 struct sd *sd = (struct sd *) gspca_dev;
1080
fe86ec75
JFM
1081 i2c_r2(gspca_dev, 0x1c, &id);
1082 if (gspca_dev->usb_err < 0)
1083 return;
e78567d2
MCC
1084
1085 if (id != 0x7fa2) {
91f5842b 1086 pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id);
fe86ec75
JFM
1087 gspca_dev->usb_err = -ENODEV;
1088 return;
e78567d2
MCC
1089 }
1090
92884f80
JFM
1091 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1092 msleep(200);
d4689b74
JFM
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");
26e744b6
BJ
1096 sd->hstart = 1;
1097 sd->vstart = 7;
26e744b6
BJ
1098}
1099
fe86ec75 1100static void ov9655_init_sensor(struct gspca_dev *gspca_dev)
26e744b6 1101{
26e744b6
BJ
1102 struct sd *sd = (struct sd *) gspca_dev;
1103
92884f80
JFM
1104 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1105 msleep(200);
d4689b74
JFM
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
cc2a8335
BJ
1110 sd->hstart = 1;
1111 sd->vstart = 2;
26e744b6
BJ
1112}
1113
fe86ec75 1114static void soi968_init_sensor(struct gspca_dev *gspca_dev)
26e744b6 1115{
26e744b6
BJ
1116 struct sd *sd = (struct sd *) gspca_dev;
1117
92884f80
JFM
1118 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1119 msleep(200);
d4689b74
JFM
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
26e744b6
BJ
1124 sd->hstart = 60;
1125 sd->vstart = 11;
26e744b6
BJ
1126}
1127
fe86ec75 1128static void ov7660_init_sensor(struct gspca_dev *gspca_dev)
26e744b6 1129{
26e744b6
BJ
1130 struct sd *sd = (struct sd *) gspca_dev;
1131
92884f80
JFM
1132 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1133 msleep(200);
d4689b74
JFM
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");
8bc50f35
HG
1137 sd->hstart = 3;
1138 sd->vstart = 3;
26e744b6
BJ
1139}
1140
fe86ec75 1141static void ov7670_init_sensor(struct gspca_dev *gspca_dev)
26e744b6 1142{
26e744b6
BJ
1143 struct sd *sd = (struct sd *) gspca_dev;
1144
92884f80
JFM
1145 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */
1146 msleep(200);
d4689b74
JFM
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
26e744b6
BJ
1151 sd->hstart = 0;
1152 sd->vstart = 1;
26e744b6
BJ
1153}
1154
fe86ec75 1155static void mt9v_init_sensor(struct gspca_dev *gspca_dev)
26e744b6
BJ
1156{
1157 struct sd *sd = (struct sd *) gspca_dev;
26e744b6 1158 u16 value;
26e744b6
BJ
1159
1160 sd->i2c_addr = 0x5d;
fe86ec75
JFM
1161 i2c_r2(gspca_dev, 0xff, &value);
1162 if (gspca_dev->usb_err >= 0
1163 && value == 0x8243) {
d4689b74
JFM
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;
26e744b6
BJ
1168 }
1169 sd->hstart = 2;
1170 sd->vstart = 2;
1171 sd->sensor = SENSOR_MT9V011;
91f5842b 1172 pr_info("MT9V011 sensor detected\n");
fe86ec75 1173 return;
26e744b6
BJ
1174 }
1175
fe86ec75 1176 gspca_dev->usb_err = 0;
26e744b6
BJ
1177 sd->i2c_addr = 0x5c;
1178 i2c_w2(gspca_dev, 0x01, 0x0004);
fe86ec75
JFM
1179 i2c_r2(gspca_dev, 0xff, &value);
1180 if (gspca_dev->usb_err >= 0
1181 && value == 0x823a) {
d4689b74
JFM
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;
26e744b6
BJ
1186 }
1187 sd->hstart = 2;
1188 sd->vstart = 2;
1189 sd->sensor = SENSOR_MT9V111;
91f5842b 1190 pr_info("MT9V111 sensor detected\n");
fe86ec75 1191 return;
26e744b6
BJ
1192 }
1193
fe86ec75 1194 gspca_dev->usb_err = 0;
26e744b6 1195 sd->i2c_addr = 0x5d;
fe86ec75
JFM
1196 i2c_w2(gspca_dev, 0xf0, 0x0000);
1197 if (gspca_dev->usb_err < 0) {
1198 gspca_dev->usb_err = 0;
26e744b6
BJ
1199 sd->i2c_addr = 0x48;
1200 i2c_w2(gspca_dev, 0xf0, 0x0000);
1201 }
fe86ec75
JFM
1202 i2c_r2(gspca_dev, 0x00, &value);
1203 if (gspca_dev->usb_err >= 0
1204 && value == 0x1229) {
d4689b74
JFM
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;
26e744b6
BJ
1209 }
1210 sd->hstart = 6;
1211 sd->vstart = 2;
1212 sd->sensor = SENSOR_MT9V112;
91f5842b 1213 pr_info("MT9V112 sensor detected\n");
fe86ec75 1214 return;
26e744b6
BJ
1215 }
1216
fe86ec75 1217 gspca_dev->usb_err = -ENODEV;
26e744b6
BJ
1218}
1219
fe86ec75 1220static void mt9m112_init_sensor(struct gspca_dev *gspca_dev)
e99ac54d
BJ
1221{
1222 struct sd *sd = (struct sd *) gspca_dev;
d4689b74
JFM
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
e99ac54d
BJ
1228 sd->hstart = 0;
1229 sd->vstart = 2;
e99ac54d
BJ
1230}
1231
fe86ec75 1232static void mt9m111_init_sensor(struct gspca_dev *gspca_dev)
26e744b6
BJ
1233{
1234 struct sd *sd = (struct sd *) gspca_dev;
d4689b74
JFM
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
26e744b6
BJ
1240 sd->hstart = 0;
1241 sd->vstart = 2;
26e744b6
BJ
1242}
1243
fe86ec75 1244static void mt9m001_init_sensor(struct gspca_dev *gspca_dev)
26e744b6
BJ
1245{
1246 struct sd *sd = (struct sd *) gspca_dev;
d162e7aa
MCC
1247 u16 id;
1248
fe86ec75
JFM
1249 i2c_r2(gspca_dev, 0x00, &id);
1250 if (gspca_dev->usb_err < 0)
1251 return;
d162e7aa
MCC
1252
1253 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
1254 switch (id) {
1255 case 0x8411:
1256 case 0x8421:
91f5842b 1257 pr_info("MT9M001 color sensor detected\n");
d162e7aa
MCC
1258 break;
1259 case 0x8431:
91f5842b 1260 pr_info("MT9M001 mono sensor detected\n");
d162e7aa
MCC
1261 break;
1262 default:
91f5842b 1263 pr_err("No MT9M001 chip detected, ID = %x\n\n", id);
fe86ec75
JFM
1264 gspca_dev->usb_err = -ENODEV;
1265 return;
d162e7aa
MCC
1266 }
1267
d4689b74
JFM
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
d162e7aa
MCC
1272 sd->hstart = 1;
1273 sd->vstart = 1;
26e744b6
BJ
1274}
1275
fe86ec75 1276static void hv7131r_init_sensor(struct gspca_dev *gspca_dev)
26e744b6 1277{
26e744b6
BJ
1278 struct sd *sd = (struct sd *) gspca_dev;
1279
d4689b74
JFM
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
26e744b6
BJ
1284 sd->hstart = 0;
1285 sd->vstart = 1;
26e744b6
BJ
1286}
1287
63069da1
HV
1288static void set_cmatrix(struct gspca_dev *gspca_dev,
1289 s32 brightness, s32 contrast, s32 satur, s32 hue)
26e744b6 1290{
63069da1 1291 s32 hue_coord, hue_index = 180 + hue;
26e744b6 1292 u8 cmatrix[21];
26e744b6 1293
e0aa2b28 1294 memset(cmatrix, 0, sizeof(cmatrix));
63069da1 1295 cmatrix[2] = (contrast * 0x25 / 0x100) + 0x26;
26e744b6
BJ
1296 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1297 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
63069da1 1298 cmatrix[18] = brightness - 0x80;
26e744b6 1299
c5224d81 1300 hue_coord = (hsv_red_x[hue_index] * satur) >> 8;
de2d1549
JFM
1301 cmatrix[6] = hue_coord;
1302 cmatrix[7] = (hue_coord >> 8) & 0x0f;
26e744b6 1303
c5224d81 1304 hue_coord = (hsv_red_y[hue_index] * satur) >> 8;
de2d1549
JFM
1305 cmatrix[8] = hue_coord;
1306 cmatrix[9] = (hue_coord >> 8) & 0x0f;
26e744b6 1307
c5224d81 1308 hue_coord = (hsv_green_x[hue_index] * satur) >> 8;
de2d1549
JFM
1309 cmatrix[10] = hue_coord;
1310 cmatrix[11] = (hue_coord >> 8) & 0x0f;
26e744b6 1311
c5224d81 1312 hue_coord = (hsv_green_y[hue_index] * satur) >> 8;
de2d1549
JFM
1313 cmatrix[12] = hue_coord;
1314 cmatrix[13] = (hue_coord >> 8) & 0x0f;
26e744b6 1315
c5224d81 1316 hue_coord = (hsv_blue_x[hue_index] * satur) >> 8;
de2d1549
JFM
1317 cmatrix[14] = hue_coord;
1318 cmatrix[15] = (hue_coord >> 8) & 0x0f;
26e744b6 1319
c5224d81 1320 hue_coord = (hsv_blue_y[hue_index] * satur) >> 8;
de2d1549
JFM
1321 cmatrix[16] = hue_coord;
1322 cmatrix[17] = (hue_coord >> 8) & 0x0f;
26e744b6 1323
c5224d81 1324 reg_w(gspca_dev, 0x10e1, cmatrix, 21);
26e744b6
BJ
1325}
1326
63069da1 1327static void set_gamma(struct gspca_dev *gspca_dev, s32 val)
26e744b6 1328{
26e744b6 1329 u8 gamma[17];
63069da1 1330 u8 gval = val * 0xb8 / 0x100;
26e744b6
BJ
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
c5224d81 1350 reg_w(gspca_dev, 0x1190, gamma, 17);
26e744b6
BJ
1351}
1352
63069da1 1353static void set_redblue(struct gspca_dev *gspca_dev, s32 blue, s32 red)
26e744b6 1354{
63069da1
HV
1355 reg_w1(gspca_dev, 0x118c, red);
1356 reg_w1(gspca_dev, 0x118f, blue);
26e744b6
BJ
1357}
1358
63069da1 1359static void set_hvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip)
26e744b6 1360{
63069da1 1361 u8 value, tslb;
26e744b6
BJ
1362 u16 value2;
1363 struct sd *sd = (struct sd *) gspca_dev;
7ddaac7f
BJ
1364
1365 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
63069da1
HV
1366 hflip = !hflip;
1367 vflip = !vflip;
7ddaac7f
BJ
1368 }
1369
26e744b6 1370 switch (sd->sensor) {
779b51f7
HG
1371 case SENSOR_OV7660:
1372 value = 0x01;
1373 if (hflip)
1374 value |= 0x20;
1375 if (vflip) {
1376 value |= 0x10;
1377 sd->vstart = 2;
ff38d58e 1378 } else {
779b51f7 1379 sd->vstart = 3;
ff38d58e 1380 }
779b51f7
HG
1381 reg_w1(gspca_dev, 0x1182, sd->vstart);
1382 i2c_w1(gspca_dev, 0x1e, value);
1383 break;
26e744b6
BJ
1384 case SENSOR_OV9650:
1385 i2c_r1(gspca_dev, 0x1e, &value);
1386 value &= ~0x30;
1387 tslb = 0x01;
7ddaac7f 1388 if (hflip)
26e744b6 1389 value |= 0x20;
7ddaac7f 1390 if (vflip) {
26e744b6
BJ
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;
7ddaac7f 1401 if (hflip)
26e744b6 1402 value2 |= 0x8080;
7ddaac7f 1403 if (vflip)
26e744b6
BJ
1404 value2 |= 0x4020;
1405 i2c_w2(gspca_dev, 0x20, value2);
1406 break;
e99ac54d 1407 case SENSOR_MT9M112:
26e744b6
BJ
1408 case SENSOR_MT9M111:
1409 case SENSOR_MT9V112:
1410 i2c_r2(gspca_dev, 0x20, &value2);
1411 value2 &= ~0x0003;
7ddaac7f 1412 if (hflip)
26e744b6 1413 value2 |= 0x0002;
7ddaac7f 1414 if (vflip)
26e744b6
BJ
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;
7ddaac7f 1421 if (vflip)
26e744b6 1422 value |= 0x01;
7ddaac7f 1423 if (hflip)
26e744b6
BJ
1424 value |= 0x02;
1425 i2c_w1(gspca_dev, 0x01, value);
1426 break;
1427 }
26e744b6
BJ
1428}
1429
63069da1 1430static void set_exposure(struct gspca_dev *gspca_dev, s32 expo)
26e744b6
BJ
1431{
1432 struct sd *sd = (struct sd *) gspca_dev;
c4407fe8 1433 u8 exp[8] = {sd->i2c_intf, sd->i2c_addr,
4fb8137c 1434 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
63069da1 1435 int expo2;
c5224d81 1436
4fb8137c
JFM
1437 if (gspca_dev->streaming)
1438 exp[7] = 0x1e;
1439
26e744b6
BJ
1440 switch (sd->sensor) {
1441 case SENSOR_OV7660:
1442 case SENSOR_OV7670:
26e744b6
BJ
1443 case SENSOR_OV9655:
1444 case SENSOR_OV9650:
a1ac5dc2
JFM
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;
26e744b6 1460 exp[0] |= (3 << 4);
a1ac5dc2 1461 exp[2] = 0x2d; /* ADVFL & ADVFH */
c5224d81
JFM
1462 exp[3] = expo;
1463 exp[4] = expo >> 8;
26e744b6
BJ
1464 break;
1465 case SENSOR_MT9M001:
26e744b6 1466 case SENSOR_MT9V112:
26e744b6
BJ
1467 case SENSOR_MT9V011:
1468 exp[0] |= (3 << 4);
1469 exp[2] = 0x09;
c5224d81
JFM
1470 exp[3] = expo >> 8;
1471 exp[4] = expo;
26e744b6
BJ
1472 break;
1473 case SENSOR_HV7131R:
1474 exp[0] |= (4 << 4);
1475 exp[2] = 0x25;
c5224d81
JFM
1476 exp[3] = expo >> 5;
1477 exp[4] = expo << 3;
e10f7319 1478 exp[5] = 0;
26e744b6 1479 break;
e1430471 1480 default:
c5224d81 1481 return;
26e744b6
BJ
1482 }
1483 i2c_w(gspca_dev, exp);
26e744b6
BJ
1484}
1485
63069da1 1486static void set_gain(struct gspca_dev *gspca_dev, s32 g)
26e744b6
BJ
1487{
1488 struct sd *sd = (struct sd *) gspca_dev;
c4407fe8 1489 u8 gain[8] = {sd->i2c_intf, sd->i2c_addr,
4fb8137c 1490 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
c5224d81 1491
4fb8137c
JFM
1492 if (gspca_dev->streaming)
1493 gain[7] = 0x15; /* or 1d ? */
1494
26e744b6
BJ
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);
c5224d81 1502 gain[3] = ov_gain[g];
26e744b6
BJ
1503 break;
1504 case SENSOR_MT9V011:
26e744b6
BJ
1505 gain[0] |= (3 << 4);
1506 gain[2] = 0x35;
c5224d81
JFM
1507 gain[3] = micron1_gain[g] >> 8;
1508 gain[4] = micron1_gain[g];
26e744b6
BJ
1509 break;
1510 case SENSOR_MT9V112:
26e744b6
BJ
1511 gain[0] |= (3 << 4);
1512 gain[2] = 0x2f;
c5224d81
JFM
1513 gain[3] = micron1_gain[g] >> 8;
1514 gain[4] = micron1_gain[g];
26e744b6
BJ
1515 break;
1516 case SENSOR_MT9M001:
1517 gain[0] |= (3 << 4);
1518 gain[2] = 0x2f;
c5224d81
JFM
1519 gain[3] = micron2_gain[g] >> 8;
1520 gain[4] = micron2_gain[g];
26e744b6
BJ
1521 break;
1522 case SENSOR_HV7131R:
1523 gain[0] |= (2 << 4);
1524 gain[2] = 0x30;
c5224d81 1525 gain[3] = hv7131r_gain[g];
26e744b6 1526 break;
e1430471 1527 default:
c5224d81 1528 return;
26e744b6
BJ
1529 }
1530 i2c_w(gspca_dev, gain);
26e744b6
BJ
1531}
1532
63069da1 1533static void set_quality(struct gspca_dev *gspca_dev, s32 val)
4c632e4e
JFM
1534{
1535 struct sd *sd = (struct sd *) gspca_dev;
1536
63069da1 1537 jpeg_set_qual(sd->jpeg_hdr, val);
4c632e4e
JFM
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
26e744b6
BJ
1548#ifdef CONFIG_VIDEO_ADV_DEBUG
1549static 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;
ff38d58e 1553
f82fadcf 1554 reg->size = 1;
b1c85cc0
HV
1555 switch (reg->match.addr) {
1556 case 0:
26e744b6
BJ
1557 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1558 return -EINVAL;
fe86ec75 1559 reg_r(gspca_dev, reg->reg, 1);
26e744b6 1560 reg->val = gspca_dev->usb_buf[0];
fe86ec75 1561 return gspca_dev->usb_err;
b1c85cc0 1562 case 1:
26e744b6 1563 if (sd->sensor >= SENSOR_MT9V011 &&
e99ac54d 1564 sd->sensor <= SENSOR_MT9M112) {
fe86ec75 1565 i2c_r2(gspca_dev, reg->reg, (u16 *) &reg->val);
f82fadcf 1566 reg->size = 2;
26e744b6 1567 } else {
fe86ec75 1568 i2c_r1(gspca_dev, reg->reg, (u8 *) &reg->val);
26e744b6 1569 }
fe86ec75 1570 return gspca_dev->usb_err;
26e744b6
BJ
1571 }
1572 return -EINVAL;
1573}
1574
1575static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
977ba3b1 1576 const struct v4l2_dbg_register *reg)
26e744b6
BJ
1577{
1578 struct sd *sd = (struct sd *) gspca_dev;
ff38d58e 1579
b1c85cc0
HV
1580 switch (reg->match.addr) {
1581 case 0:
26e744b6
BJ
1582 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1583 return -EINVAL;
fe86ec75
JFM
1584 reg_w1(gspca_dev, reg->reg, reg->val);
1585 return gspca_dev->usb_err;
b1c85cc0 1586 case 1:
26e744b6 1587 if (sd->sensor >= SENSOR_MT9V011 &&
e99ac54d 1588 sd->sensor <= SENSOR_MT9M112) {
fe86ec75 1589 i2c_w2(gspca_dev, reg->reg, reg->val);
26e744b6 1590 } else {
fe86ec75 1591 i2c_w1(gspca_dev, reg->reg, reg->val);
26e744b6 1592 }
fe86ec75 1593 return gspca_dev->usb_err;
26e744b6
BJ
1594 }
1595 return -EINVAL;
1596}
26e744b6 1597
b1c85cc0
HV
1598static int sd_chip_info(struct gspca_dev *gspca_dev,
1599 struct v4l2_dbg_chip_info *chip)
26e744b6 1600{
b1c85cc0
HV
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;
26e744b6 1606}
b1c85cc0 1607#endif
26e744b6
BJ
1608
1609static 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;
eb3fb7c9 1616 cam->needs_full_bandwidth = 1;
26e744b6 1617
ff38d58e
JFM
1618 sd->sensor = id->driver_info >> 8;
1619 sd->i2c_addr = id->driver_info;
1620 sd->flags = id->driver_info >> 16;
c4407fe8 1621 sd->i2c_intf = 0x80; /* i2c 100 Kb/s */
26e744b6
BJ
1622
1623 switch (sd->sensor) {
e99ac54d 1624 case SENSOR_MT9M112:
4d708a5e 1625 case SENSOR_MT9M111:
26e744b6 1626 case SENSOR_OV9650:
e8b7acc1 1627 case SENSOR_SOI968:
26e744b6
BJ
1628 cam->cam_mode = sxga_mode;
1629 cam->nmodes = ARRAY_SIZE(sxga_mode);
1630 break;
d162e7aa
MCC
1631 case SENSOR_MT9M001:
1632 cam->cam_mode = mono_mode;
1633 cam->nmodes = ARRAY_SIZE(mono_mode);
1634 break;
c4407fe8
JFM
1635 case SENSOR_HV7131R:
1636 sd->i2c_intf = 0x81; /* i2c 400 Kb/s */
1637 /* fall thru */
26e744b6
BJ
1638 default:
1639 cam->cam_mode = vga_mode;
1640 cam->nmodes = ARRAY_SIZE(vga_mode);
de2d1549 1641 break;
26e744b6
BJ
1642 }
1643
1644 sd->old_step = 0;
1645 sd->older_step = 0;
1646 sd->exposure_step = 16;
1647
92dcffcf 1648 INIT_WORK(&sd->work, qual_upd);
26e744b6 1649
26e744b6
BJ
1650 return 0;
1651}
1652
63069da1
HV
1653static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
1654{
a8a47860
HG
1655 struct gspca_dev *gspca_dev =
1656 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
1657 struct sd *sd = (struct sd *)gspca_dev;
63069da1
HV
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:
a8a47860 1667 set_cmatrix(gspca_dev, sd->brightness->val,
63069da1
HV
1668 sd->contrast->val, sd->saturation->val, sd->hue->val);
1669 break;
1670 case V4L2_CID_GAMMA:
a8a47860 1671 set_gamma(gspca_dev, ctrl->val);
63069da1
HV
1672 break;
1673 /* blue/red balance cluster */
1674 case V4L2_CID_BLUE_BALANCE:
a8a47860 1675 set_redblue(gspca_dev, sd->blue->val, sd->red->val);
63069da1
HV
1676 break;
1677 /* h/vflip cluster */
1678 case V4L2_CID_HFLIP:
a8a47860 1679 set_hvflip(gspca_dev, sd->hflip->val, sd->vflip->val);
63069da1
HV
1680 break;
1681 /* standalone exposure control */
1682 case V4L2_CID_EXPOSURE:
a8a47860 1683 set_exposure(gspca_dev, ctrl->val);
63069da1
HV
1684 break;
1685 /* standalone gain control */
1686 case V4L2_CID_GAIN:
a8a47860 1687 set_gain(gspca_dev, ctrl->val);
63069da1
HV
1688 break;
1689 /* autogain + exposure or gain control cluster */
1690 case V4L2_CID_AUTOGAIN:
1691 if (sd->sensor == SENSOR_SOI968)
a8a47860 1692 set_gain(gspca_dev, sd->gain->val);
63069da1 1693 else
a8a47860 1694 set_exposure(gspca_dev, sd->exposure->val);
63069da1
HV
1695 break;
1696 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
a8a47860 1697 set_quality(gspca_dev, ctrl->val);
63069da1
HV
1698 break;
1699 }
1700 return gspca_dev->usb_err;
1701}
1702
1703static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1704 .s_ctrl = sd_s_ctrl,
1705};
1706
1707static int sd_init_controls(struct gspca_dev *gspca_dev)
1708{
1709 struct sd *sd = (struct sd *) gspca_dev;
a8a47860 1710 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
63069da1
HV
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);
63069da1
HV
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);
63069da1
HV
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);
63069da1
HV
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);
bc378fee
HG
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) {
63069da1
HV
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 }
63069da1
HV
1776 return 0;
1777}
1778
26e744b6
BJ
1779static int sd_init(struct gspca_dev *gspca_dev)
1780{
1781 struct sd *sd = (struct sd *) gspca_dev;
1782 int i;
1783 u8 value;
312487cc
MP
1784 u8 i2c_init[9] = {
1785 0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
1786 };
26e744b6
BJ
1787
1788 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
1789 value = bridge_init[i][1];
fe86ec75
JFM
1790 reg_w(gspca_dev, bridge_init[i][0], &value, 1);
1791 if (gspca_dev->usb_err < 0) {
91f5842b 1792 pr_err("Device initialization failed\n");
fe86ec75 1793 return gspca_dev->usb_err;
26e744b6
BJ
1794 }
1795 }
1796
0c045eb7
BJ
1797 if (sd->flags & LED_REVERSE)
1798 reg_w1(gspca_dev, 0x1006, 0x00);
1799 else
1800 reg_w1(gspca_dev, 0x1006, 0x20);
1801
fe86ec75
JFM
1802 reg_w(gspca_dev, 0x10c0, i2c_init, 9);
1803 if (gspca_dev->usb_err < 0) {
91f5842b 1804 pr_err("Device initialization failed\n");
fe86ec75 1805 return gspca_dev->usb_err;
26e744b6
BJ
1806 }
1807
1808 switch (sd->sensor) {
1809 case SENSOR_OV9650:
fe86ec75
JFM
1810 ov9650_init_sensor(gspca_dev);
1811 if (gspca_dev->usb_err < 0)
1812 break;
91f5842b 1813 pr_info("OV9650 sensor detected\n");
26e744b6
BJ
1814 break;
1815 case SENSOR_OV9655:
fe86ec75
JFM
1816 ov9655_init_sensor(gspca_dev);
1817 if (gspca_dev->usb_err < 0)
1818 break;
91f5842b 1819 pr_info("OV9655 sensor detected\n");
26e744b6
BJ
1820 break;
1821 case SENSOR_SOI968:
fe86ec75
JFM
1822 soi968_init_sensor(gspca_dev);
1823 if (gspca_dev->usb_err < 0)
1824 break;
91f5842b 1825 pr_info("SOI968 sensor detected\n");
26e744b6
BJ
1826 break;
1827 case SENSOR_OV7660:
fe86ec75
JFM
1828 ov7660_init_sensor(gspca_dev);
1829 if (gspca_dev->usb_err < 0)
1830 break;
91f5842b 1831 pr_info("OV7660 sensor detected\n");
26e744b6
BJ
1832 break;
1833 case SENSOR_OV7670:
fe86ec75
JFM
1834 ov7670_init_sensor(gspca_dev);
1835 if (gspca_dev->usb_err < 0)
1836 break;
91f5842b 1837 pr_info("OV7670 sensor detected\n");
26e744b6
BJ
1838 break;
1839 case SENSOR_MT9VPRB:
fe86ec75
JFM
1840 mt9v_init_sensor(gspca_dev);
1841 if (gspca_dev->usb_err < 0)
1842 break;
ff38d58e 1843 pr_info("MT9VPRB sensor detected\n");
26e744b6
BJ
1844 break;
1845 case SENSOR_MT9M111:
fe86ec75
JFM
1846 mt9m111_init_sensor(gspca_dev);
1847 if (gspca_dev->usb_err < 0)
1848 break;
91f5842b 1849 pr_info("MT9M111 sensor detected\n");
26e744b6 1850 break;
e99ac54d 1851 case SENSOR_MT9M112:
fe86ec75
JFM
1852 mt9m112_init_sensor(gspca_dev);
1853 if (gspca_dev->usb_err < 0)
1854 break;
91f5842b 1855 pr_info("MT9M112 sensor detected\n");
e99ac54d 1856 break;
26e744b6 1857 case SENSOR_MT9M001:
fe86ec75
JFM
1858 mt9m001_init_sensor(gspca_dev);
1859 if (gspca_dev->usb_err < 0)
1860 break;
26e744b6
BJ
1861 break;
1862 case SENSOR_HV7131R:
fe86ec75
JFM
1863 hv7131r_init_sensor(gspca_dev);
1864 if (gspca_dev->usb_err < 0)
1865 break;
91f5842b 1866 pr_info("HV7131R sensor detected\n");
26e744b6
BJ
1867 break;
1868 default:
ff38d58e 1869 pr_err("Unsupported sensor\n");
fe86ec75 1870 gspca_dev->usb_err = -ENODEV;
26e744b6 1871 }
fe86ec75 1872 return gspca_dev->usb_err;
26e744b6
BJ
1873}
1874
1875static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
1876{
1877 struct sd *sd = (struct sd *) gspca_dev;
1878 u8 value;
ff38d58e 1879
26e744b6 1880 switch (sd->sensor) {
e8b7acc1
BJ
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;
26e744b6
BJ
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;
e99ac54d 1917 case SENSOR_MT9M112:
4d708a5e
BJ
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;
26e744b6
BJ
1929 }
1930}
1931
d80dd5d0
HG
1932static 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) {
1ddc9f75 1946 pr_warn("sn9c20x camera with unknown number of alt settings (%d), please report!\n",
7135d884 1947 intf->num_altsetting);
d80dd5d0
HG
1948 gspca_dev->alt = intf->num_altsetting;
1949 return 0;
1950 }
1951
1966bc2a 1952 switch (gspca_dev->pixfmt.width) {
d80dd5d0
HG
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;
ff38d58e 1961 break;
d80dd5d0
HG
1962 }
1963 }
1964
1965 return 0;
1966}
1967
26e744b6 1968#define HW_WIN(mode, hstart, vstart) \
83955556 1969((const u8 []){hstart, 0, vstart, 0, \
26e744b6
BJ
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
1978static 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;
1966bc2a
OZ
1982 int width = gspca_dev->pixfmt.width;
1983 int height = gspca_dev->pixfmt.height;
26e744b6
BJ
1984 u8 fmt, scale = 0;
1985
26e744b6
BJ
1986 jpeg_define(sd->jpeg_hdr, height, width,
1987 0x21);
63069da1 1988 jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual));
26e744b6
BJ
1989
1990 if (mode & MODE_RAW)
1991 fmt = 0x2d;
1992 else if (mode & MODE_JPEG)
4c632e4e 1993 fmt = 0x24;
26e744b6 1994 else
86701c1d 1995 fmt = 0x2f; /* YUV 420 */
4c632e4e 1996 sd->fmt = fmt;
26e744b6 1997
86701c1d
MCC
1998 switch (mode & SCALE_MASK) {
1999 case SCALE_1280x1024:
26e744b6 2000 scale = 0xc0;
91f5842b 2001 pr_info("Set 1280x1024\n");
26e744b6 2002 break;
86701c1d 2003 case SCALE_640x480:
26e744b6 2004 scale = 0x80;
91f5842b 2005 pr_info("Set 640x480\n");
26e744b6 2006 break;
86701c1d 2007 case SCALE_320x240:
26e744b6 2008 scale = 0x90;
91f5842b 2009 pr_info("Set 320x240\n");
26e744b6 2010 break;
86701c1d 2011 case SCALE_160x120:
26e744b6 2012 scale = 0xa0;
91f5842b 2013 pr_info("Set 160x120\n");
26e744b6
BJ
2014 break;
2015 }
2016
2017 configure_sensor_output(gspca_dev, mode);
9a731a32
JFM
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);
26e744b6
BJ
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
63069da1
HV
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));
6c6ee53c
HG
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));
26e744b6 2039
0c045eb7 2040 reg_w1(gspca_dev, 0x1007, 0x20);
ccbaba43 2041 reg_w1(gspca_dev, 0x1061, 0x03);
92dcffcf
JFM
2042
2043 /* if JPEG, prepare the compression quality update */
2044 if (mode & MODE_JPEG) {
2045 sd->pktsz = sd->npkt = 0;
2046 sd->nchg = 0;
92dcffcf
JFM
2047 }
2048
fe86ec75 2049 return gspca_dev->usb_err;
26e744b6
BJ
2050}
2051
2052static void sd_stopN(struct gspca_dev *gspca_dev)
2053{
0c045eb7 2054 reg_w1(gspca_dev, 0x1007, 0x00);
ccbaba43 2055 reg_w1(gspca_dev, 0x1061, 0x01);
26e744b6
BJ
2056}
2057
92dcffcf
JFM
2058/* called on streamoff with alt==0 and on disconnect */
2059/* the usb_lock is held at entry - restore on exit */
2060static void sd_stop0(struct gspca_dev *gspca_dev)
2061{
2062 struct sd *sd = (struct sd *) gspca_dev;
2063
edf096be
BS
2064 mutex_unlock(&gspca_dev->usb_lock);
2065 flush_work(&sd->work);
2066 mutex_lock(&gspca_dev->usb_lock);
92dcffcf
JFM
2067}
2068
e1430471 2069static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
26e744b6
BJ
2070{
2071 struct sd *sd = (struct sd *) gspca_dev;
63069da1
HV
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;
e1430471 2075 s16 new_exp;
26e744b6
BJ
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) {
63069da1 2083 if (cur_exp > max)
26e744b6
BJ
2084 return;
2085
63069da1
HV
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);
26e744b6
BJ
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) {
63069da1 2102 if (cur_exp < min)
26e744b6 2103 return;
63069da1
HV
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);
26e744b6
BJ
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
e1430471
BJ
2120static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2121{
2122 struct sd *sd = (struct sd *) gspca_dev;
63069da1 2123 s32 cur_gain = v4l2_ctrl_g_ctrl(sd->gain);
e1430471 2124
63069da1
HV
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);
e1430471
BJ
2129}
2130
2131static void sd_dqcallback(struct gspca_dev *gspca_dev)
2132{
2133 struct sd *sd = (struct sd *) gspca_dev;
2134 int avg_lum;
2135
6c6ee53c 2136 if (sd->autogain == NULL || !v4l2_ctrl_g_ctrl(sd->autogain))
e1430471
BJ
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
92dcffcf
JFM
2146/* JPEG quality update */
2147/* This function is executed from a work queue. */
2148static 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;
63069da1 2152 s32 qual = v4l2_ctrl_g_ctrl(sd->jpegqual);
92dcffcf 2153
844db450 2154 /* To protect gspca_dev->usb_buf and gspca_dev->usb_err */
92dcffcf 2155 mutex_lock(&gspca_dev->usb_lock);
63069da1 2156 PDEBUG(D_STREAM, "qual_upd %d%%", qual);
844db450 2157 gspca_dev->usb_err = 0;
63069da1 2158 set_quality(gspca_dev, qual);
92dcffcf
JFM
2159 mutex_unlock(&gspca_dev->usb_lock);
2160}
2161
8099affa 2162#if IS_ENABLED(CONFIG_INPUT)
a39db27a
MCC
2163static 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;
ff38d58e 2168
33ddc16f 2169 if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
ff38d58e
JFM
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;
a39db27a 2175 }
ff38d58e 2176 return -EINVAL;
a39db27a
MCC
2177}
2178#endif
2179
92dcffcf
JFM
2180/* check the JPEG compression */
2181static 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) {
63069da1
HV
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;
92dcffcf 2211 sd->nchg = 0;
63069da1
HV
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;
edf096be 2219 schedule_work(&sd->work);
92dcffcf
JFM
2220 }
2221 }
2222 } else {
2223 sd->nchg = 0;
2224 }
2225 sd->pktsz = sd->npkt = 0;
2226}
2227
26e744b6 2228static void sd_pkt_scan(struct gspca_dev *gspca_dev,
26e744b6
BJ
2229 u8 *data, /* isoc packet */
2230 int len) /* iso packet length */
2231{
2232 struct sd *sd = (struct sd *) gspca_dev;
ff38d58e 2233 int avg_lum, is_jpeg;
312487cc
MP
2234 static const u8 frame_header[] = {
2235 0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96
2236 };
ff38d58e
JFM
2237
2238 is_jpeg = (sd->fmt & 0x03) == 0;
1f42df0d 2239 if (len >= 64 && memcmp(data, frame_header, 6) == 0) {
26e744b6
BJ
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);
92dcffcf 2266
ff38d58e 2267 if (is_jpeg)
92dcffcf
JFM
2268 transfer_check(gspca_dev, data);
2269
04d174e9 2270 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
1f42df0d
JFM
2271 len -= 64;
2272 if (len == 0)
2273 return;
2274 data += 64;
26e744b6
BJ
2275 }
2276 if (gspca_dev->last_packet_type == LAST_PACKET) {
ff38d58e 2277 if (is_jpeg) {
76dd272b 2278 gspca_frame_add(gspca_dev, FIRST_PACKET,
26e744b6 2279 sd->jpeg_hdr, JPEG_HDR_SZ);
76dd272b 2280 gspca_frame_add(gspca_dev, INTER_PACKET,
26e744b6
BJ
2281 data, len);
2282 } else {
76dd272b 2283 gspca_frame_add(gspca_dev, FIRST_PACKET,
26e744b6
BJ
2284 data, len);
2285 }
2286 } else {
92dcffcf 2287 /* if JPEG, count the packets and their size */
ff38d58e 2288 if (is_jpeg) {
92dcffcf
JFM
2289 sd->npkt++;
2290 sd->pktsz += len;
2291 }
76dd272b 2292 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
26e744b6
BJ
2293 }
2294}
2295
2296/* sub-driver description */
2297static const struct sd_desc sd_desc = {
ff38d58e 2298 .name = KBUILD_MODNAME,
26e744b6
BJ
2299 .config = sd_config,
2300 .init = sd_init,
63069da1 2301 .init_controls = sd_init_controls,
d80dd5d0 2302 .isoc_init = sd_isoc_init,
26e744b6
BJ
2303 .start = sd_start,
2304 .stopN = sd_stopN,
92dcffcf 2305 .stop0 = sd_stop0,
26e744b6 2306 .pkt_scan = sd_pkt_scan,
8099affa 2307#if IS_ENABLED(CONFIG_INPUT)
a39db27a
MCC
2308 .int_pkt_scan = sd_int_pkt_scan,
2309#endif
e1430471 2310 .dq_callback = sd_dqcallback,
26e744b6
BJ
2311#ifdef CONFIG_VIDEO_ADV_DEBUG
2312 .set_register = sd_dbg_s_register,
2313 .get_register = sd_dbg_g_register,
b1c85cc0 2314 .get_chip_info = sd_chip_info,
26e744b6 2315#endif
26e744b6
BJ
2316};
2317
a39db27a 2318#define SN9C20X(sensor, i2c_addr, flags) \
0c045eb7 2319 .driver_info = ((flags & 0xff) << 16) \
26e744b6
BJ
2320 | (SENSOR_ ## sensor << 8) \
2321 | (i2c_addr)
2322
95c967c1 2323static const struct usb_device_id device_table[] = {
26e744b6
BJ
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)},
e99ac54d 2327 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
33ddc16f
BJ
2328 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
2329 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
2330 (FLIP_DETECT | HAS_NO_BUTTON))},
26e744b6
BJ
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)},
779b51f7 2335 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, FLIP_DETECT)},
26e744b6
BJ
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)},
33ddc16f 2340 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
e99ac54d 2341 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
26e744b6
BJ
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)},
114cfbdf 2346 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, LED_REVERSE)},
b39e0cb9 2347 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, LED_REVERSE)},
26e744b6
BJ
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)},
61f03191 2352 {USB_DEVICE(0x0458, 0x7045), SN9C20X(MT9M112, 0x5d, LED_REVERSE)},
e99ac54d
BJ
2353 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
2354 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
26e744b6
BJ
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)},
33ddc16f 2359 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
26e744b6
BJ
2360 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2361 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2362 {}
2363};
2364MODULE_DEVICE_TABLE(usb, device_table);
2365
2366/* -- device connect -- */
2367static 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
26e744b6 2374static struct usb_driver sd_driver = {
ff38d58e 2375 .name = KBUILD_MODNAME,
26e744b6
BJ
2376 .id_table = device_table,
2377 .probe = sd_probe,
a39db27a 2378 .disconnect = gspca_disconnect,
26e744b6
BJ
2379#ifdef CONFIG_PM
2380 .suspend = gspca_suspend,
2381 .resume = gspca_resume,
2382 .reset_resume = gspca_resume,
2383#endif
2384};
2385
ecb3b2b3 2386module_usb_driver(sd_driver);