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