[go: nahoru, domu]

1/*
2 *	Sonix sn9c201 sn9c202 library
3 *
4 * Copyright (C) 2012 Jean-Francois Moine <http://moinejf.free.fr>
5 *	Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com>
6 *	Copyright (C) 2009 Brian Johnson <brijohn@gmail.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * 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
23#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
24
25#include <linux/input.h>
26
27#include "gspca.h"
28#include "jpeg.h"
29
30#include <linux/dmi.h>
31
32MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, "
33		"microdia project <microdia@googlegroups.com>");
34MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
35MODULE_LICENSE("GPL");
36
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
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
59#define SENSOR_MT9M112  10
60#define SENSOR_HV7131R	11
61#define SENSOR_MT9VPRB	12
62
63/* camera flags */
64#define HAS_NO_BUTTON	0x1
65#define LED_REVERSE	0x2 /* some cameras unset gpio to turn on leds */
66#define FLIP_DETECT	0x4
67
68/* specific webcam descriptor */
69struct sd {
70	struct gspca_dev gspca_dev;
71
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;
93
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;
100	u8 fmt;				/* (used for JPEG QTAB update */
101
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
109	u8 i2c_addr;
110	u8 i2c_intf;
111	u8 sensor;
112	u8 hstart;
113	u8 vstart;
114
115	u8 jpeg_hdr[JPEG_HDR_SZ];
116
117	u8 flags;
118};
119
120static void qual_upd(struct work_struct *work);
121
122struct i2c_reg_u8 {
123	u8 reg;
124	u8 val;
125};
126
127struct i2c_reg_u16 {
128	u8 reg;
129	u16 val;
130};
131
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	},
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	},
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	},
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	},
169	{}
170};
171
172static const struct v4l2_pix_format vga_mode[] = {
173	{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
174		.bytesperline = 160,
175		.sizeimage = 160 * 120 * 4 / 8 + 590,
176		.colorspace = V4L2_COLORSPACE_JPEG,
177		.priv = SCALE_160x120 | MODE_JPEG},
178	{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
179		.bytesperline = 160,
180		.sizeimage = 160 * 120,
181		.colorspace = V4L2_COLORSPACE_SRGB,
182		.priv = SCALE_160x120 | MODE_RAW},
183	{160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
184		.bytesperline = 160,
185		.sizeimage = 240 * 120,
186		.colorspace = V4L2_COLORSPACE_SRGB,
187		.priv = SCALE_160x120},
188	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
189		.bytesperline = 320,
190		.sizeimage = 320 * 240 * 4 / 8 + 590,
191		.colorspace = V4L2_COLORSPACE_JPEG,
192		.priv = SCALE_320x240 | MODE_JPEG},
193	{320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
194		.bytesperline = 320,
195		.sizeimage = 320 * 240 ,
196		.colorspace = V4L2_COLORSPACE_SRGB,
197		.priv = SCALE_320x240 | MODE_RAW},
198	{320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
199		.bytesperline = 320,
200		.sizeimage = 480 * 240 ,
201		.colorspace = V4L2_COLORSPACE_SRGB,
202		.priv = SCALE_320x240},
203	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
204		.bytesperline = 640,
205		.sizeimage = 640 * 480 * 4 / 8 + 590,
206		.colorspace = V4L2_COLORSPACE_JPEG,
207		.priv = SCALE_640x480 | MODE_JPEG},
208	{640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
209		.bytesperline = 640,
210		.sizeimage = 640 * 480,
211		.colorspace = V4L2_COLORSPACE_SRGB,
212		.priv = SCALE_640x480 | MODE_RAW},
213	{640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
214		.bytesperline = 640,
215		.sizeimage = 960 * 480,
216		.colorspace = V4L2_COLORSPACE_SRGB,
217		.priv = SCALE_640x480},
218};
219
220static const struct v4l2_pix_format sxga_mode[] = {
221	{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
222		.bytesperline = 160,
223		.sizeimage = 160 * 120 * 4 / 8 + 590,
224		.colorspace = V4L2_COLORSPACE_JPEG,
225		.priv = SCALE_160x120 | MODE_JPEG},
226	{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
227		.bytesperline = 160,
228		.sizeimage = 160 * 120,
229		.colorspace = V4L2_COLORSPACE_SRGB,
230		.priv = SCALE_160x120 | MODE_RAW},
231	{160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
232		.bytesperline = 160,
233		.sizeimage = 240 * 120,
234		.colorspace = V4L2_COLORSPACE_SRGB,
235		.priv = SCALE_160x120},
236	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
237		.bytesperline = 320,
238		.sizeimage = 320 * 240 * 4 / 8 + 590,
239		.colorspace = V4L2_COLORSPACE_JPEG,
240		.priv = SCALE_320x240 | MODE_JPEG},
241	{320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
242		.bytesperline = 320,
243		.sizeimage = 320 * 240 ,
244		.colorspace = V4L2_COLORSPACE_SRGB,
245		.priv = SCALE_320x240 | MODE_RAW},
246	{320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
247		.bytesperline = 320,
248		.sizeimage = 480 * 240 ,
249		.colorspace = V4L2_COLORSPACE_SRGB,
250		.priv = SCALE_320x240},
251	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
252		.bytesperline = 640,
253		.sizeimage = 640 * 480 * 4 / 8 + 590,
254		.colorspace = V4L2_COLORSPACE_JPEG,
255		.priv = SCALE_640x480 | MODE_JPEG},
256	{640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
257		.bytesperline = 640,
258		.sizeimage = 640 * 480,
259		.colorspace = V4L2_COLORSPACE_SRGB,
260		.priv = SCALE_640x480 | MODE_RAW},
261	{640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
262		.bytesperline = 640,
263		.sizeimage = 960 * 480,
264		.colorspace = V4L2_COLORSPACE_SRGB,
265		.priv = SCALE_640x480},
266	{1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
267		.bytesperline = 1280,
268		.sizeimage = 1280 * 1024,
269		.colorspace = V4L2_COLORSPACE_SRGB,
270		.priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
271};
272
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
296static const s16 hsv_red_x[] = {
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
344static const s16 hsv_red_y[] = {
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
392static const s16 hsv_green_x[] = {
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
440static const s16 hsv_green_y[] = {
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
488static const s16 hsv_blue_x[] = {
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
536static const s16 hsv_blue_y[] = {
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
584static const u16 bridge_init[][2] = {
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},
603	{0x1183, 0x00},	{0x1184, 0x50},	{0x1185, 0x80},
604	{0x1007, 0x00}
605};
606
607/* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
608static const u8 ov_gain[] = {
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) */
620static const u16 micron1_gain[] = {
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) */
641static const u16 micron2_gain[] = {
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 */
661static const u8 hv7131r_gain[] = {
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
672static const struct i2c_reg_u8 soi968_init[] = {
673	{0x0c, 0x00}, {0x0f, 0x1f},
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},
679	{0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
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
686static const struct i2c_reg_u8 ov7660_init[] = {
687	{0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
688	{0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
689	{0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
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},
693	{0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
694	{0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0x00},
695	{0x2e, 0x00}, {0x01, 0x78}, {0x02, 0x50},
696};
697
698static const struct i2c_reg_u8 ov7670_init[] = {
699	{0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
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
755static const struct i2c_reg_u8 ov9650_init[] = {
756	{0x00, 0x00}, {0x01, 0x78},
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
785static const struct i2c_reg_u8 ov9655_init[] = {
786	{0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
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},
802	{0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
803	{0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
804	{0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
805	{0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
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},
810};
811
812static const struct i2c_reg_u16 mt9v112_init[] = {
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
831static const struct i2c_reg_u16 mt9v111_init[] = {
832	{0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
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}
839};
840
841static const struct i2c_reg_u16 mt9v011_init[] = {
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
868static const struct i2c_reg_u16 mt9m001_init[] = {
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},
882};
883
884static const struct i2c_reg_u16 mt9m111_init[] = {
885	{0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
886	{0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
887	{0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
888	{0xf0, 0x0000},
889};
890
891static const struct i2c_reg_u16 mt9m112_init[] = {
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
898static const struct i2c_reg_u8 hv7131r_init[] = {
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
909static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
910{
911	struct usb_device *dev = gspca_dev->dev;
912	int result;
913
914	if (gspca_dev->usb_err < 0)
915		return;
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)) {
925		pr_err("Read register %02x failed %d\n", reg, result);
926		gspca_dev->usb_err = result;
927	}
928}
929
930static void reg_w(struct gspca_dev *gspca_dev, u16 reg,
931		 const u8 *buffer, int length)
932{
933	struct usb_device *dev = gspca_dev->dev;
934	int result;
935
936	if (gspca_dev->usb_err < 0)
937		return;
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)) {
948		pr_err("Write register %02x failed %d\n", reg, result);
949		gspca_dev->usb_err = result;
950	}
951}
952
953static void reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
954{
955	reg_w(gspca_dev, reg, &value, 1);
956}
957
958static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
959{
960	int i;
961
962	reg_w(gspca_dev, 0x10c0, buffer, 8);
963	for (i = 0; i < 5; i++) {
964		reg_r(gspca_dev, 0x10c0, 1);
965		if (gspca_dev->usb_err < 0)
966			return;
967		if (gspca_dev->usb_buf[0] & 0x04) {
968			if (gspca_dev->usb_buf[0] & 0x08) {
969				pr_err("i2c_w error\n");
970				gspca_dev->usb_err = -EIO;
971			}
972			return;
973		}
974		msleep(10);
975	}
976	pr_err("i2c_w reg %02x no response\n", buffer[2]);
977/*	gspca_dev->usb_err = -EIO;	fixme: may occur */
978}
979
980static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
981{
982	struct sd *sd = (struct sd *) gspca_dev;
983	u8 row[8];
984
985	/*
986	 * from the point of view of the bridge, the length
987	 * includes the address
988	 */
989	row[0] = sd->i2c_intf | (2 << 4);
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
998	i2c_w(gspca_dev, row);
999}
1000
1001static void i2c_w1_buf(struct gspca_dev *gspca_dev,
1002			const struct i2c_reg_u8 *buf, int sz)
1003{
1004	while (--sz >= 0) {
1005		i2c_w1(gspca_dev, buf->reg, buf->val);
1006		buf++;
1007	}
1008}
1009
1010static void i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
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	 */
1019	row[0] = sd->i2c_intf | (3 << 4);
1020	row[1] = sd->i2c_addr;
1021	row[2] = reg;
1022	row[3] = val >> 8;
1023	row[4] = val;
1024	row[5] = 0x00;
1025	row[6] = 0x00;
1026	row[7] = 0x10;
1027
1028	i2c_w(gspca_dev, row);
1029}
1030
1031static void i2c_w2_buf(struct gspca_dev *gspca_dev,
1032			const struct i2c_reg_u16 *buf, int sz)
1033{
1034	while (--sz >= 0) {
1035		i2c_w2(gspca_dev, buf->reg, buf->val);
1036		buf++;
1037	}
1038}
1039
1040static void i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1041{
1042	struct sd *sd = (struct sd *) gspca_dev;
1043	u8 row[8];
1044
1045	row[0] = sd->i2c_intf | (1 << 4);
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;
1053	i2c_w(gspca_dev, row);
1054	row[0] = sd->i2c_intf | (1 << 4) | 0x02;
1055	row[2] = 0;
1056	i2c_w(gspca_dev, row);
1057	reg_r(gspca_dev, 0x10c2, 5);
1058	*val = gspca_dev->usb_buf[4];
1059}
1060
1061static void i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1062{
1063	struct sd *sd = (struct sd *) gspca_dev;
1064	u8 row[8];
1065
1066	row[0] = sd->i2c_intf | (1 << 4);
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;
1074	i2c_w(gspca_dev, row);
1075	row[0] = sd->i2c_intf | (2 << 4) | 0x02;
1076	row[2] = 0;
1077	i2c_w(gspca_dev, row);
1078	reg_r(gspca_dev, 0x10c2, 5);
1079	*val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1080}
1081
1082static void ov9650_init_sensor(struct gspca_dev *gspca_dev)
1083{
1084	u16 id;
1085	struct sd *sd = (struct sd *) gspca_dev;
1086
1087	i2c_r2(gspca_dev, 0x1c, &id);
1088	if (gspca_dev->usb_err < 0)
1089		return;
1090
1091	if (id != 0x7fa2) {
1092		pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id);
1093		gspca_dev->usb_err = -ENODEV;
1094		return;
1095	}
1096
1097	i2c_w1(gspca_dev, 0x12, 0x80);		/* sensor reset */
1098	msleep(200);
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");
1102	sd->hstart = 1;
1103	sd->vstart = 7;
1104}
1105
1106static void ov9655_init_sensor(struct gspca_dev *gspca_dev)
1107{
1108	struct sd *sd = (struct sd *) gspca_dev;
1109
1110	i2c_w1(gspca_dev, 0x12, 0x80);		/* sensor reset */
1111	msleep(200);
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
1116	sd->hstart = 1;
1117	sd->vstart = 2;
1118}
1119
1120static void soi968_init_sensor(struct gspca_dev *gspca_dev)
1121{
1122	struct sd *sd = (struct sd *) gspca_dev;
1123
1124	i2c_w1(gspca_dev, 0x12, 0x80);		/* sensor reset */
1125	msleep(200);
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
1130	sd->hstart = 60;
1131	sd->vstart = 11;
1132}
1133
1134static void ov7660_init_sensor(struct gspca_dev *gspca_dev)
1135{
1136	struct sd *sd = (struct sd *) gspca_dev;
1137
1138	i2c_w1(gspca_dev, 0x12, 0x80);		/* sensor reset */
1139	msleep(200);
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");
1143	sd->hstart = 3;
1144	sd->vstart = 3;
1145}
1146
1147static void ov7670_init_sensor(struct gspca_dev *gspca_dev)
1148{
1149	struct sd *sd = (struct sd *) gspca_dev;
1150
1151	i2c_w1(gspca_dev, 0x12, 0x80);		/* sensor reset */
1152	msleep(200);
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
1157	sd->hstart = 0;
1158	sd->vstart = 1;
1159}
1160
1161static void mt9v_init_sensor(struct gspca_dev *gspca_dev)
1162{
1163	struct sd *sd = (struct sd *) gspca_dev;
1164	u16 value;
1165
1166	sd->i2c_addr = 0x5d;
1167	i2c_r2(gspca_dev, 0xff, &value);
1168	if (gspca_dev->usb_err >= 0
1169	 && value == 0x8243) {
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;
1174		}
1175		sd->hstart = 2;
1176		sd->vstart = 2;
1177		sd->sensor = SENSOR_MT9V011;
1178		pr_info("MT9V011 sensor detected\n");
1179		return;
1180	}
1181
1182	gspca_dev->usb_err = 0;
1183	sd->i2c_addr = 0x5c;
1184	i2c_w2(gspca_dev, 0x01, 0x0004);
1185	i2c_r2(gspca_dev, 0xff, &value);
1186	if (gspca_dev->usb_err >= 0
1187	 && value == 0x823a) {
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;
1192		}
1193		sd->hstart = 2;
1194		sd->vstart = 2;
1195		sd->sensor = SENSOR_MT9V111;
1196		pr_info("MT9V111 sensor detected\n");
1197		return;
1198	}
1199
1200	gspca_dev->usb_err = 0;
1201	sd->i2c_addr = 0x5d;
1202	i2c_w2(gspca_dev, 0xf0, 0x0000);
1203	if (gspca_dev->usb_err < 0) {
1204		gspca_dev->usb_err = 0;
1205		sd->i2c_addr = 0x48;
1206		i2c_w2(gspca_dev, 0xf0, 0x0000);
1207	}
1208	i2c_r2(gspca_dev, 0x00, &value);
1209	if (gspca_dev->usb_err >= 0
1210	 && value == 0x1229) {
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;
1215		}
1216		sd->hstart = 6;
1217		sd->vstart = 2;
1218		sd->sensor = SENSOR_MT9V112;
1219		pr_info("MT9V112 sensor detected\n");
1220		return;
1221	}
1222
1223	gspca_dev->usb_err = -ENODEV;
1224}
1225
1226static void mt9m112_init_sensor(struct gspca_dev *gspca_dev)
1227{
1228	struct sd *sd = (struct sd *) gspca_dev;
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
1234	sd->hstart = 0;
1235	sd->vstart = 2;
1236}
1237
1238static void mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1239{
1240	struct sd *sd = (struct sd *) gspca_dev;
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
1246	sd->hstart = 0;
1247	sd->vstart = 2;
1248}
1249
1250static void mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1251{
1252	struct sd *sd = (struct sd *) gspca_dev;
1253	u16 id;
1254
1255	i2c_r2(gspca_dev, 0x00, &id);
1256	if (gspca_dev->usb_err < 0)
1257		return;
1258
1259	/* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
1260	switch (id) {
1261	case 0x8411:
1262	case 0x8421:
1263		pr_info("MT9M001 color sensor detected\n");
1264		break;
1265	case 0x8431:
1266		pr_info("MT9M001 mono sensor detected\n");
1267		break;
1268	default:
1269		pr_err("No MT9M001 chip detected, ID = %x\n\n", id);
1270		gspca_dev->usb_err = -ENODEV;
1271		return;
1272	}
1273
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
1278	sd->hstart = 1;
1279	sd->vstart = 1;
1280}
1281
1282static void hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1283{
1284	struct sd *sd = (struct sd *) gspca_dev;
1285
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
1290	sd->hstart = 0;
1291	sd->vstart = 1;
1292}
1293
1294static void set_cmatrix(struct gspca_dev *gspca_dev,
1295		s32 brightness, s32 contrast, s32 satur, s32 hue)
1296{
1297	s32 hue_coord, hue_index = 180 + hue;
1298	u8 cmatrix[21];
1299
1300	memset(cmatrix, 0, sizeof(cmatrix));
1301	cmatrix[2] = (contrast * 0x25 / 0x100) + 0x26;
1302	cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1303	cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1304	cmatrix[18] = brightness - 0x80;
1305
1306	hue_coord = (hsv_red_x[hue_index] * satur) >> 8;
1307	cmatrix[6] = hue_coord;
1308	cmatrix[7] = (hue_coord >> 8) & 0x0f;
1309
1310	hue_coord = (hsv_red_y[hue_index] * satur) >> 8;
1311	cmatrix[8] = hue_coord;
1312	cmatrix[9] = (hue_coord >> 8) & 0x0f;
1313
1314	hue_coord = (hsv_green_x[hue_index] * satur) >> 8;
1315	cmatrix[10] = hue_coord;
1316	cmatrix[11] = (hue_coord >> 8) & 0x0f;
1317
1318	hue_coord = (hsv_green_y[hue_index] * satur) >> 8;
1319	cmatrix[12] = hue_coord;
1320	cmatrix[13] = (hue_coord >> 8) & 0x0f;
1321
1322	hue_coord = (hsv_blue_x[hue_index] * satur) >> 8;
1323	cmatrix[14] = hue_coord;
1324	cmatrix[15] = (hue_coord >> 8) & 0x0f;
1325
1326	hue_coord = (hsv_blue_y[hue_index] * satur) >> 8;
1327	cmatrix[16] = hue_coord;
1328	cmatrix[17] = (hue_coord >> 8) & 0x0f;
1329
1330	reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1331}
1332
1333static void set_gamma(struct gspca_dev *gspca_dev, s32 val)
1334{
1335	u8 gamma[17];
1336	u8 gval = val * 0xb8 / 0x100;
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
1356	reg_w(gspca_dev, 0x1190, gamma, 17);
1357}
1358
1359static void set_redblue(struct gspca_dev *gspca_dev, s32 blue, s32 red)
1360{
1361	reg_w1(gspca_dev, 0x118c, red);
1362	reg_w1(gspca_dev, 0x118f, blue);
1363}
1364
1365static void set_hvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip)
1366{
1367	u8 value, tslb;
1368	u16 value2;
1369	struct sd *sd = (struct sd *) gspca_dev;
1370
1371	if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1372		hflip = !hflip;
1373		vflip = !vflip;
1374	}
1375
1376	switch (sd->sensor) {
1377	case SENSOR_OV7660:
1378		value = 0x01;
1379		if (hflip)
1380			value |= 0x20;
1381		if (vflip) {
1382			value |= 0x10;
1383			sd->vstart = 2;
1384		} else {
1385			sd->vstart = 3;
1386		}
1387		reg_w1(gspca_dev, 0x1182, sd->vstart);
1388		i2c_w1(gspca_dev, 0x1e, value);
1389		break;
1390	case SENSOR_OV9650:
1391		i2c_r1(gspca_dev, 0x1e, &value);
1392		value &= ~0x30;
1393		tslb = 0x01;
1394		if (hflip)
1395			value |= 0x20;
1396		if (vflip) {
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;
1407		if (hflip)
1408			value2 |= 0x8080;
1409		if (vflip)
1410			value2 |= 0x4020;
1411		i2c_w2(gspca_dev, 0x20, value2);
1412		break;
1413	case SENSOR_MT9M112:
1414	case SENSOR_MT9M111:
1415	case SENSOR_MT9V112:
1416		i2c_r2(gspca_dev, 0x20, &value2);
1417		value2 &= ~0x0003;
1418		if (hflip)
1419			value2 |= 0x0002;
1420		if (vflip)
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;
1427		if (vflip)
1428			value |= 0x01;
1429		if (hflip)
1430			value |= 0x02;
1431		i2c_w1(gspca_dev, 0x01, value);
1432		break;
1433	}
1434}
1435
1436static void set_exposure(struct gspca_dev *gspca_dev, s32 expo)
1437{
1438	struct sd *sd = (struct sd *) gspca_dev;
1439	u8 exp[8] = {sd->i2c_intf, sd->i2c_addr,
1440				0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1441	int expo2;
1442
1443	if (gspca_dev->streaming)
1444		exp[7] = 0x1e;
1445
1446	switch (sd->sensor) {
1447	case SENSOR_OV7660:
1448	case SENSOR_OV7670:
1449	case SENSOR_OV9655:
1450	case SENSOR_OV9650:
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;
1466		exp[0] |= (3 << 4);
1467		exp[2] = 0x2d;			/* ADVFL & ADVFH */
1468		exp[3] = expo;
1469		exp[4] = expo >> 8;
1470		break;
1471	case SENSOR_MT9M001:
1472	case SENSOR_MT9V112:
1473	case SENSOR_MT9V011:
1474		exp[0] |= (3 << 4);
1475		exp[2] = 0x09;
1476		exp[3] = expo >> 8;
1477		exp[4] = expo;
1478		break;
1479	case SENSOR_HV7131R:
1480		exp[0] |= (4 << 4);
1481		exp[2] = 0x25;
1482		exp[3] = expo >> 5;
1483		exp[4] = expo << 3;
1484		exp[5] = 0;
1485		break;
1486	default:
1487		return;
1488	}
1489	i2c_w(gspca_dev, exp);
1490}
1491
1492static void set_gain(struct gspca_dev *gspca_dev, s32 g)
1493{
1494	struct sd *sd = (struct sd *) gspca_dev;
1495	u8 gain[8] = {sd->i2c_intf, sd->i2c_addr,
1496				0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1497
1498	if (gspca_dev->streaming)
1499		gain[7] = 0x15;		/* or 1d ? */
1500
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);
1508		gain[3] = ov_gain[g];
1509		break;
1510	case SENSOR_MT9V011:
1511		gain[0] |= (3 << 4);
1512		gain[2] = 0x35;
1513		gain[3] = micron1_gain[g] >> 8;
1514		gain[4] = micron1_gain[g];
1515		break;
1516	case SENSOR_MT9V112:
1517		gain[0] |= (3 << 4);
1518		gain[2] = 0x2f;
1519		gain[3] = micron1_gain[g] >> 8;
1520		gain[4] = micron1_gain[g];
1521		break;
1522	case SENSOR_MT9M001:
1523		gain[0] |= (3 << 4);
1524		gain[2] = 0x2f;
1525		gain[3] = micron2_gain[g] >> 8;
1526		gain[4] = micron2_gain[g];
1527		break;
1528	case SENSOR_HV7131R:
1529		gain[0] |= (2 << 4);
1530		gain[2] = 0x30;
1531		gain[3] = hv7131r_gain[g];
1532		break;
1533	default:
1534		return;
1535	}
1536	i2c_w(gspca_dev, gain);
1537}
1538
1539static void set_quality(struct gspca_dev *gspca_dev, s32 val)
1540{
1541	struct sd *sd = (struct sd *) gspca_dev;
1542
1543	jpeg_set_qual(sd->jpeg_hdr, val);
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
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;
1559
1560	reg->size = 1;
1561	switch (reg->match.addr) {
1562	case 0:
1563		if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1564			return -EINVAL;
1565		reg_r(gspca_dev, reg->reg, 1);
1566		reg->val = gspca_dev->usb_buf[0];
1567		return gspca_dev->usb_err;
1568	case 1:
1569		if (sd->sensor >= SENSOR_MT9V011 &&
1570		    sd->sensor <= SENSOR_MT9M112) {
1571			i2c_r2(gspca_dev, reg->reg, (u16 *) &reg->val);
1572			reg->size = 2;
1573		} else {
1574			i2c_r1(gspca_dev, reg->reg, (u8 *) &reg->val);
1575		}
1576		return gspca_dev->usb_err;
1577	}
1578	return -EINVAL;
1579}
1580
1581static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1582			const struct v4l2_dbg_register *reg)
1583{
1584	struct sd *sd = (struct sd *) gspca_dev;
1585
1586	switch (reg->match.addr) {
1587	case 0:
1588		if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1589			return -EINVAL;
1590		reg_w1(gspca_dev, reg->reg, reg->val);
1591		return gspca_dev->usb_err;
1592	case 1:
1593		if (sd->sensor >= SENSOR_MT9V011 &&
1594		    sd->sensor <= SENSOR_MT9M112) {
1595			i2c_w2(gspca_dev, reg->reg, reg->val);
1596		} else {
1597			i2c_w1(gspca_dev, reg->reg, reg->val);
1598		}
1599		return gspca_dev->usb_err;
1600	}
1601	return -EINVAL;
1602}
1603
1604static int sd_chip_info(struct gspca_dev *gspca_dev,
1605			struct v4l2_dbg_chip_info *chip)
1606{
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;
1612}
1613#endif
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;
1622	cam->needs_full_bandwidth = 1;
1623
1624	sd->sensor = id->driver_info >> 8;
1625	sd->i2c_addr = id->driver_info;
1626	sd->flags = id->driver_info >> 16;
1627	sd->i2c_intf = 0x80;			/* i2c 100 Kb/s */
1628
1629	switch (sd->sensor) {
1630	case SENSOR_MT9M112:
1631	case SENSOR_MT9M111:
1632	case SENSOR_OV9650:
1633	case SENSOR_SOI968:
1634		cam->cam_mode = sxga_mode;
1635		cam->nmodes = ARRAY_SIZE(sxga_mode);
1636		break;
1637	case SENSOR_MT9M001:
1638		cam->cam_mode = mono_mode;
1639		cam->nmodes = ARRAY_SIZE(mono_mode);
1640		break;
1641	case SENSOR_HV7131R:
1642		sd->i2c_intf = 0x81;			/* i2c 400 Kb/s */
1643		/* fall thru */
1644	default:
1645		cam->cam_mode = vga_mode;
1646		cam->nmodes = ARRAY_SIZE(vga_mode);
1647		break;
1648	}
1649
1650	sd->old_step = 0;
1651	sd->older_step = 0;
1652	sd->exposure_step = 16;
1653
1654	INIT_WORK(&sd->work, qual_upd);
1655
1656	return 0;
1657}
1658
1659static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
1660{
1661	struct gspca_dev *gspca_dev =
1662		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
1663	struct sd *sd = (struct sd *)gspca_dev;
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:
1673		set_cmatrix(gspca_dev, sd->brightness->val,
1674			sd->contrast->val, sd->saturation->val, sd->hue->val);
1675		break;
1676	case V4L2_CID_GAMMA:
1677		set_gamma(gspca_dev, ctrl->val);
1678		break;
1679	/* blue/red balance cluster */
1680	case V4L2_CID_BLUE_BALANCE:
1681		set_redblue(gspca_dev, sd->blue->val, sd->red->val);
1682		break;
1683	/* h/vflip cluster */
1684	case V4L2_CID_HFLIP:
1685		set_hvflip(gspca_dev, sd->hflip->val, sd->vflip->val);
1686		break;
1687	/* standalone exposure control */
1688	case V4L2_CID_EXPOSURE:
1689		set_exposure(gspca_dev, ctrl->val);
1690		break;
1691	/* standalone gain control */
1692	case V4L2_CID_GAIN:
1693		set_gain(gspca_dev, ctrl->val);
1694		break;
1695	/* autogain + exposure or gain control cluster */
1696	case V4L2_CID_AUTOGAIN:
1697		if (sd->sensor == SENSOR_SOI968)
1698			set_gain(gspca_dev, sd->gain->val);
1699		else
1700			set_exposure(gspca_dev, sd->exposure->val);
1701		break;
1702	case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1703		set_quality(gspca_dev, ctrl->val);
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;
1716	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
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);
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);
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);
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);
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) {
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	}
1782	return 0;
1783}
1784
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
1794	for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
1795		value = bridge_init[i][1];
1796		reg_w(gspca_dev, bridge_init[i][0], &value, 1);
1797		if (gspca_dev->usb_err < 0) {
1798			pr_err("Device initialization failed\n");
1799			return gspca_dev->usb_err;
1800		}
1801	}
1802
1803	if (sd->flags & LED_REVERSE)
1804		reg_w1(gspca_dev, 0x1006, 0x00);
1805	else
1806		reg_w1(gspca_dev, 0x1006, 0x20);
1807
1808	reg_w(gspca_dev, 0x10c0, i2c_init, 9);
1809	if (gspca_dev->usb_err < 0) {
1810		pr_err("Device initialization failed\n");
1811		return gspca_dev->usb_err;
1812	}
1813
1814	switch (sd->sensor) {
1815	case SENSOR_OV9650:
1816		ov9650_init_sensor(gspca_dev);
1817		if (gspca_dev->usb_err < 0)
1818			break;
1819		pr_info("OV9650 sensor detected\n");
1820		break;
1821	case SENSOR_OV9655:
1822		ov9655_init_sensor(gspca_dev);
1823		if (gspca_dev->usb_err < 0)
1824			break;
1825		pr_info("OV9655 sensor detected\n");
1826		break;
1827	case SENSOR_SOI968:
1828		soi968_init_sensor(gspca_dev);
1829		if (gspca_dev->usb_err < 0)
1830			break;
1831		pr_info("SOI968 sensor detected\n");
1832		break;
1833	case SENSOR_OV7660:
1834		ov7660_init_sensor(gspca_dev);
1835		if (gspca_dev->usb_err < 0)
1836			break;
1837		pr_info("OV7660 sensor detected\n");
1838		break;
1839	case SENSOR_OV7670:
1840		ov7670_init_sensor(gspca_dev);
1841		if (gspca_dev->usb_err < 0)
1842			break;
1843		pr_info("OV7670 sensor detected\n");
1844		break;
1845	case SENSOR_MT9VPRB:
1846		mt9v_init_sensor(gspca_dev);
1847		if (gspca_dev->usb_err < 0)
1848			break;
1849		pr_info("MT9VPRB sensor detected\n");
1850		break;
1851	case SENSOR_MT9M111:
1852		mt9m111_init_sensor(gspca_dev);
1853		if (gspca_dev->usb_err < 0)
1854			break;
1855		pr_info("MT9M111 sensor detected\n");
1856		break;
1857	case SENSOR_MT9M112:
1858		mt9m112_init_sensor(gspca_dev);
1859		if (gspca_dev->usb_err < 0)
1860			break;
1861		pr_info("MT9M112 sensor detected\n");
1862		break;
1863	case SENSOR_MT9M001:
1864		mt9m001_init_sensor(gspca_dev);
1865		if (gspca_dev->usb_err < 0)
1866			break;
1867		break;
1868	case SENSOR_HV7131R:
1869		hv7131r_init_sensor(gspca_dev);
1870		if (gspca_dev->usb_err < 0)
1871			break;
1872		pr_info("HV7131R sensor detected\n");
1873		break;
1874	default:
1875		pr_err("Unsupported sensor\n");
1876		gspca_dev->usb_err = -ENODEV;
1877	}
1878	return gspca_dev->usb_err;
1879}
1880
1881static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
1882{
1883	struct sd *sd = (struct sd *) gspca_dev;
1884	u8 value;
1885
1886	switch (sd->sensor) {
1887	case SENSOR_SOI968:
1888		if (mode & MODE_SXGA) {
1889			i2c_w1(gspca_dev, 0x17, 0x1d);
1890			i2c_w1(gspca_dev, 0x18, 0xbd);
1891			i2c_w1(gspca_dev, 0x19, 0x01);
1892			i2c_w1(gspca_dev, 0x1a, 0x81);
1893			i2c_w1(gspca_dev, 0x12, 0x00);
1894			sd->hstart = 140;
1895			sd->vstart = 19;
1896		} else {
1897			i2c_w1(gspca_dev, 0x17, 0x13);
1898			i2c_w1(gspca_dev, 0x18, 0x63);
1899			i2c_w1(gspca_dev, 0x19, 0x01);
1900			i2c_w1(gspca_dev, 0x1a, 0x79);
1901			i2c_w1(gspca_dev, 0x12, 0x40);
1902			sd->hstart = 60;
1903			sd->vstart = 11;
1904		}
1905		break;
1906	case SENSOR_OV9650:
1907		if (mode & MODE_SXGA) {
1908			i2c_w1(gspca_dev, 0x17, 0x1b);
1909			i2c_w1(gspca_dev, 0x18, 0xbc);
1910			i2c_w1(gspca_dev, 0x19, 0x01);
1911			i2c_w1(gspca_dev, 0x1a, 0x82);
1912			i2c_r1(gspca_dev, 0x12, &value);
1913			i2c_w1(gspca_dev, 0x12, value & 0x07);
1914		} else {
1915			i2c_w1(gspca_dev, 0x17, 0x24);
1916			i2c_w1(gspca_dev, 0x18, 0xc5);
1917			i2c_w1(gspca_dev, 0x19, 0x00);
1918			i2c_w1(gspca_dev, 0x1a, 0x3c);
1919			i2c_r1(gspca_dev, 0x12, &value);
1920			i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
1921		}
1922		break;
1923	case SENSOR_MT9M112:
1924	case SENSOR_MT9M111:
1925		if (mode & MODE_SXGA) {
1926			i2c_w2(gspca_dev, 0xf0, 0x0002);
1927			i2c_w2(gspca_dev, 0xc8, 0x970b);
1928			i2c_w2(gspca_dev, 0xf0, 0x0000);
1929		} else {
1930			i2c_w2(gspca_dev, 0xf0, 0x0002);
1931			i2c_w2(gspca_dev, 0xc8, 0x8000);
1932			i2c_w2(gspca_dev, 0xf0, 0x0000);
1933		}
1934		break;
1935	}
1936}
1937
1938static int sd_isoc_init(struct gspca_dev *gspca_dev)
1939{
1940	struct usb_interface *intf;
1941	u32 flags = gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv;
1942
1943	/*
1944	 * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth
1945	 * than our regular bandwidth calculations reserve, so we force the
1946	 * use of a specific altsetting when using the SN9C20X_I420 fmt.
1947	 */
1948	if (!(flags & (MODE_RAW | MODE_JPEG))) {
1949		intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
1950
1951		if (intf->num_altsetting != 9) {
1952			pr_warn("sn9c20x camera with unknown number of alt "
1953				"settings (%d), please report!\n",
1954				intf->num_altsetting);
1955			gspca_dev->alt = intf->num_altsetting;
1956			return 0;
1957		}
1958
1959		switch (gspca_dev->pixfmt.width) {
1960		case 160: /* 160x120 */
1961			gspca_dev->alt = 2;
1962			break;
1963		case 320: /* 320x240 */
1964			gspca_dev->alt = 6;
1965			break;
1966		default:  /* >= 640x480 */
1967			gspca_dev->alt = 9;
1968			break;
1969		}
1970	}
1971
1972	return 0;
1973}
1974
1975#define HW_WIN(mode, hstart, vstart) \
1976((const u8 []){hstart, 0, vstart, 0, \
1977(mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
1978(mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
1979
1980#define CLR_WIN(width, height) \
1981((const u8 [])\
1982{0, width >> 2, 0, height >> 1,\
1983((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
1984
1985static int sd_start(struct gspca_dev *gspca_dev)
1986{
1987	struct sd *sd = (struct sd *) gspca_dev;
1988	int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1989	int width = gspca_dev->pixfmt.width;
1990	int height = gspca_dev->pixfmt.height;
1991	u8 fmt, scale = 0;
1992
1993	jpeg_define(sd->jpeg_hdr, height, width,
1994			0x21);
1995	jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual));
1996
1997	if (mode & MODE_RAW)
1998		fmt = 0x2d;
1999	else if (mode & MODE_JPEG)
2000		fmt = 0x24;
2001	else
2002		fmt = 0x2f;	/* YUV 420 */
2003	sd->fmt = fmt;
2004
2005	switch (mode & SCALE_MASK) {
2006	case SCALE_1280x1024:
2007		scale = 0xc0;
2008		pr_info("Set 1280x1024\n");
2009		break;
2010	case SCALE_640x480:
2011		scale = 0x80;
2012		pr_info("Set 640x480\n");
2013		break;
2014	case SCALE_320x240:
2015		scale = 0x90;
2016		pr_info("Set 320x240\n");
2017		break;
2018	case SCALE_160x120:
2019		scale = 0xa0;
2020		pr_info("Set 160x120\n");
2021		break;
2022	}
2023
2024	configure_sensor_output(gspca_dev, mode);
2025	reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2026	reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2027	reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2028	reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2029	reg_w1(gspca_dev, 0x1189, scale);
2030	reg_w1(gspca_dev, 0x10e0, fmt);
2031
2032	set_cmatrix(gspca_dev, v4l2_ctrl_g_ctrl(sd->brightness),
2033			v4l2_ctrl_g_ctrl(sd->contrast),
2034			v4l2_ctrl_g_ctrl(sd->saturation),
2035			v4l2_ctrl_g_ctrl(sd->hue));
2036	set_gamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma));
2037	set_redblue(gspca_dev, v4l2_ctrl_g_ctrl(sd->blue),
2038			v4l2_ctrl_g_ctrl(sd->red));
2039	if (sd->gain)
2040		set_gain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain));
2041	if (sd->exposure)
2042		set_exposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure));
2043	if (sd->hflip)
2044		set_hvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip),
2045				v4l2_ctrl_g_ctrl(sd->vflip));
2046
2047	reg_w1(gspca_dev, 0x1007, 0x20);
2048	reg_w1(gspca_dev, 0x1061, 0x03);
2049
2050	/* if JPEG, prepare the compression quality update */
2051	if (mode & MODE_JPEG) {
2052		sd->pktsz = sd->npkt = 0;
2053		sd->nchg = 0;
2054		sd->work_thread =
2055			create_singlethread_workqueue(KBUILD_MODNAME);
2056	}
2057
2058	return gspca_dev->usb_err;
2059}
2060
2061static void sd_stopN(struct gspca_dev *gspca_dev)
2062{
2063	reg_w1(gspca_dev, 0x1007, 0x00);
2064	reg_w1(gspca_dev, 0x1061, 0x01);
2065}
2066
2067/* called on streamoff with alt==0 and on disconnect */
2068/* the usb_lock is held at entry - restore on exit */
2069static void sd_stop0(struct gspca_dev *gspca_dev)
2070{
2071	struct sd *sd = (struct sd *) gspca_dev;
2072
2073	if (sd->work_thread != NULL) {
2074		mutex_unlock(&gspca_dev->usb_lock);
2075		destroy_workqueue(sd->work_thread);
2076		mutex_lock(&gspca_dev->usb_lock);
2077		sd->work_thread = NULL;
2078	}
2079}
2080
2081static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2082{
2083	struct sd *sd = (struct sd *) gspca_dev;
2084	s32 cur_exp = v4l2_ctrl_g_ctrl(sd->exposure);
2085	s32 max = sd->exposure->maximum - sd->exposure_step;
2086	s32 min = sd->exposure->minimum + sd->exposure_step;
2087	s16 new_exp;
2088
2089	/*
2090	 * some hardcoded values are present
2091	 * like those for maximal/minimal exposure
2092	 * and exposure steps
2093	 */
2094	if (avg_lum < MIN_AVG_LUM) {
2095		if (cur_exp > max)
2096			return;
2097
2098		new_exp = cur_exp + sd->exposure_step;
2099		if (new_exp > max)
2100			new_exp = max;
2101		if (new_exp < min)
2102			new_exp = min;
2103		v4l2_ctrl_s_ctrl(sd->exposure, new_exp);
2104
2105		sd->older_step = sd->old_step;
2106		sd->old_step = 1;
2107
2108		if (sd->old_step ^ sd->older_step)
2109			sd->exposure_step /= 2;
2110		else
2111			sd->exposure_step += 2;
2112	}
2113	if (avg_lum > MAX_AVG_LUM) {
2114		if (cur_exp < min)
2115			return;
2116		new_exp = cur_exp - sd->exposure_step;
2117		if (new_exp > max)
2118			new_exp = max;
2119		if (new_exp < min)
2120			new_exp = min;
2121		v4l2_ctrl_s_ctrl(sd->exposure, new_exp);
2122		sd->older_step = sd->old_step;
2123		sd->old_step = 0;
2124
2125		if (sd->old_step ^ sd->older_step)
2126			sd->exposure_step /= 2;
2127		else
2128			sd->exposure_step += 2;
2129	}
2130}
2131
2132static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2133{
2134	struct sd *sd = (struct sd *) gspca_dev;
2135	s32 cur_gain = v4l2_ctrl_g_ctrl(sd->gain);
2136
2137	if (avg_lum < MIN_AVG_LUM && cur_gain < sd->gain->maximum)
2138		v4l2_ctrl_s_ctrl(sd->gain, cur_gain + 1);
2139	if (avg_lum > MAX_AVG_LUM && cur_gain > sd->gain->minimum)
2140		v4l2_ctrl_s_ctrl(sd->gain, cur_gain - 1);
2141}
2142
2143static void sd_dqcallback(struct gspca_dev *gspca_dev)
2144{
2145	struct sd *sd = (struct sd *) gspca_dev;
2146	int avg_lum;
2147
2148	if (sd->autogain == NULL || !v4l2_ctrl_g_ctrl(sd->autogain))
2149		return;
2150
2151	avg_lum = atomic_read(&sd->avg_lum);
2152	if (sd->sensor == SENSOR_SOI968)
2153		do_autogain(gspca_dev, avg_lum);
2154	else
2155		do_autoexposure(gspca_dev, avg_lum);
2156}
2157
2158/* JPEG quality update */
2159/* This function is executed from a work queue. */
2160static void qual_upd(struct work_struct *work)
2161{
2162	struct sd *sd = container_of(work, struct sd, work);
2163	struct gspca_dev *gspca_dev = &sd->gspca_dev;
2164	s32 qual = v4l2_ctrl_g_ctrl(sd->jpegqual);
2165
2166	/* To protect gspca_dev->usb_buf and gspca_dev->usb_err */
2167	mutex_lock(&gspca_dev->usb_lock);
2168	PDEBUG(D_STREAM, "qual_upd %d%%", qual);
2169	gspca_dev->usb_err = 0;
2170	set_quality(gspca_dev, qual);
2171	mutex_unlock(&gspca_dev->usb_lock);
2172}
2173
2174#if IS_ENABLED(CONFIG_INPUT)
2175static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2176			u8 *data,		/* interrupt packet */
2177			int len)		/* interrupt packet length */
2178{
2179	struct sd *sd = (struct sd *) gspca_dev;
2180
2181	if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
2182		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2183		input_sync(gspca_dev->input_dev);
2184		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2185		input_sync(gspca_dev->input_dev);
2186		return 0;
2187	}
2188	return -EINVAL;
2189}
2190#endif
2191
2192/* check the JPEG compression */
2193static void transfer_check(struct gspca_dev *gspca_dev,
2194			u8 *data)
2195{
2196	struct sd *sd = (struct sd *) gspca_dev;
2197	int new_qual, r;
2198
2199	new_qual = 0;
2200
2201	/* if USB error, discard the frame and decrease the quality */
2202	if (data[6] & 0x08) {				/* USB FIFO full */
2203		gspca_dev->last_packet_type = DISCARD_PACKET;
2204		new_qual = -5;
2205	} else {
2206
2207		/* else, compute the filling rate and a new JPEG quality */
2208		r = (sd->pktsz * 100) /
2209			(sd->npkt *
2210				gspca_dev->urb[0]->iso_frame_desc[0].length);
2211		if (r >= 85)
2212			new_qual = -3;
2213		else if (r < 75)
2214			new_qual = 2;
2215	}
2216	if (new_qual != 0) {
2217		sd->nchg += new_qual;
2218		if (sd->nchg < -6 || sd->nchg >= 12) {
2219			/* Note: we are in interrupt context, so we can't
2220			   use v4l2_ctrl_g/s_ctrl here. Access the value
2221			   directly instead. */
2222			s32 curqual = sd->jpegqual->cur.val;
2223			sd->nchg = 0;
2224			new_qual += curqual;
2225			if (new_qual < sd->jpegqual->minimum)
2226				new_qual = sd->jpegqual->minimum;
2227			else if (new_qual > sd->jpegqual->maximum)
2228				new_qual = sd->jpegqual->maximum;
2229			if (new_qual != curqual) {
2230				sd->jpegqual->cur.val = new_qual;
2231				queue_work(sd->work_thread, &sd->work);
2232			}
2233		}
2234	} else {
2235		sd->nchg = 0;
2236	}
2237	sd->pktsz = sd->npkt = 0;
2238}
2239
2240static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2241			u8 *data,			/* isoc packet */
2242			int len)			/* iso packet length */
2243{
2244	struct sd *sd = (struct sd *) gspca_dev;
2245	int avg_lum, is_jpeg;
2246	static const u8 frame_header[] = {
2247		0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96
2248	};
2249
2250	is_jpeg = (sd->fmt & 0x03) == 0;
2251	if (len >= 64 && memcmp(data, frame_header, 6) == 0) {
2252		avg_lum = ((data[35] >> 2) & 3) |
2253			   (data[20] << 2) |
2254			   (data[19] << 10);
2255		avg_lum += ((data[35] >> 4) & 3) |
2256			    (data[22] << 2) |
2257			    (data[21] << 10);
2258		avg_lum += ((data[35] >> 6) & 3) |
2259			    (data[24] << 2) |
2260			    (data[23] << 10);
2261		avg_lum += (data[36] & 3) |
2262			   (data[26] << 2) |
2263			   (data[25] << 10);
2264		avg_lum += ((data[36] >> 2) & 3) |
2265			    (data[28] << 2) |
2266			    (data[27] << 10);
2267		avg_lum += ((data[36] >> 4) & 3) |
2268			    (data[30] << 2) |
2269			    (data[29] << 10);
2270		avg_lum += ((data[36] >> 6) & 3) |
2271			    (data[32] << 2) |
2272			    (data[31] << 10);
2273		avg_lum += ((data[44] >> 4) & 3) |
2274			    (data[34] << 2) |
2275			    (data[33] << 10);
2276		avg_lum >>= 9;
2277		atomic_set(&sd->avg_lum, avg_lum);
2278
2279		if (is_jpeg)
2280			transfer_check(gspca_dev, data);
2281
2282		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2283		len -= 64;
2284		if (len == 0)
2285			return;
2286		data += 64;
2287	}
2288	if (gspca_dev->last_packet_type == LAST_PACKET) {
2289		if (is_jpeg) {
2290			gspca_frame_add(gspca_dev, FIRST_PACKET,
2291				sd->jpeg_hdr, JPEG_HDR_SZ);
2292			gspca_frame_add(gspca_dev, INTER_PACKET,
2293				data, len);
2294		} else {
2295			gspca_frame_add(gspca_dev, FIRST_PACKET,
2296				data, len);
2297		}
2298	} else {
2299		/* if JPEG, count the packets and their size */
2300		if (is_jpeg) {
2301			sd->npkt++;
2302			sd->pktsz += len;
2303		}
2304		gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2305	}
2306}
2307
2308/* sub-driver description */
2309static const struct sd_desc sd_desc = {
2310	.name = KBUILD_MODNAME,
2311	.config = sd_config,
2312	.init = sd_init,
2313	.init_controls = sd_init_controls,
2314	.isoc_init = sd_isoc_init,
2315	.start = sd_start,
2316	.stopN = sd_stopN,
2317	.stop0 = sd_stop0,
2318	.pkt_scan = sd_pkt_scan,
2319#if IS_ENABLED(CONFIG_INPUT)
2320	.int_pkt_scan = sd_int_pkt_scan,
2321#endif
2322	.dq_callback = sd_dqcallback,
2323#ifdef CONFIG_VIDEO_ADV_DEBUG
2324	.set_register = sd_dbg_s_register,
2325	.get_register = sd_dbg_g_register,
2326	.get_chip_info = sd_chip_info,
2327#endif
2328};
2329
2330#define SN9C20X(sensor, i2c_addr, flags) \
2331	.driver_info =  ((flags & 0xff) << 16) \
2332			| (SENSOR_ ## sensor << 8) \
2333			| (i2c_addr)
2334
2335static const struct usb_device_id device_table[] = {
2336	{USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2337	{USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
2338	{USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2339	{USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
2340	{USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
2341	{USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
2342					     (FLIP_DETECT | HAS_NO_BUTTON))},
2343	{USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2344	{USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2345	{USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2346	{USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2347	{USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, FLIP_DETECT)},
2348	{USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2349	{USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2350	{USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2351	{USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2352	{USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
2353	{USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
2354	{USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2355	{USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2356	{USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2357	{USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2358	{USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, LED_REVERSE)},
2359	{USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, LED_REVERSE)},
2360	{USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2361	{USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2362	{USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2363	{USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2364	{USB_DEVICE(0x0458, 0x7045), SN9C20X(MT9M112, 0x5d, LED_REVERSE)},
2365	{USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
2366	{USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
2367	{USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2368	{USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2369	{USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2370	{USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2371	{USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
2372	{USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2373	{USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2374	{}
2375};
2376MODULE_DEVICE_TABLE(usb, device_table);
2377
2378/* -- device connect -- */
2379static int sd_probe(struct usb_interface *intf,
2380		    const struct usb_device_id *id)
2381{
2382	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2383				THIS_MODULE);
2384}
2385
2386static struct usb_driver sd_driver = {
2387	.name = KBUILD_MODNAME,
2388	.id_table = device_table,
2389	.probe = sd_probe,
2390	.disconnect = gspca_disconnect,
2391#ifdef CONFIG_PM
2392	.suspend = gspca_suspend,
2393	.resume = gspca_resume,
2394	.reset_resume = gspca_resume,
2395#endif
2396};
2397
2398module_usb_driver(sd_driver);
2399