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