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