• 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.36/drivers/media/video/gspca/
1/*
2 * Sonix sn9c102p sn9c105 sn9c120 (jpeg) subdriver
3 *
4 * Copyright (C) 2009-2010 Jean-Fran��ois Moine <http://moinejf.free.fr>
5 * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#define MODULE_NAME "sonixj"
23
24#include <linux/input.h>
25#include "gspca.h"
26#include "jpeg.h"
27
28#define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
29
30MODULE_AUTHOR("Jean-Fran��ois Moine <http://moinejf.free.fr>");
31MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
32MODULE_LICENSE("GPL");
33
34/* specific webcam descriptor */
35struct sd {
36	struct gspca_dev gspca_dev;	/* !! must be the first item */
37
38	atomic_t avg_lum;
39	u32 exposure;
40
41	u16 brightness;
42	u8 contrast;
43	u8 colors;
44	u8 autogain;
45	u8 blue;
46	u8 red;
47	u8 gamma;
48	u8 vflip;			/* ov7630/ov7648 only */
49	u8 sharpness;
50	u8 infrared;			/* mt9v111 only */
51	u8 freq;			/* ov76xx only */
52	u8 quality;			/* image quality */
53#define QUALITY_MIN 60
54#define QUALITY_MAX 95
55#define QUALITY_DEF 80
56	u8 jpegqual;			/* webcam quality */
57
58	u8 reg18;
59	u8 flags;
60
61	s8 ag_cnt;
62#define AG_CNT_START 13
63
64	u8 bridge;
65#define BRIDGE_SN9C102P 0
66#define BRIDGE_SN9C105 1
67#define BRIDGE_SN9C110 2
68#define BRIDGE_SN9C120 3
69	u8 sensor;			/* Type of image sensor chip */
70	u8 i2c_addr;
71
72	u8 jpeg_hdr[JPEG_HDR_SZ];
73};
74enum sensors {
75	SENSOR_ADCM1700,
76	SENSOR_GC0307,
77	SENSOR_HV7131R,
78	SENSOR_MI0360,
79	SENSOR_MO4000,
80	SENSOR_MT9V111,
81	SENSOR_OM6802,
82	SENSOR_OV7630,
83	SENSOR_OV7648,
84	SENSOR_OV7660,
85	SENSOR_PO1030,
86	SENSOR_PO2030N,
87	SENSOR_SOI768,
88	SENSOR_SP80708,
89};
90
91/* device flags */
92#define PDN_INV	1		/* inverse pin S_PWR_DN / sn_xxx tables */
93
94/* V4L2 controls supported by the driver */
95static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
96static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
97static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
98static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
99static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
100static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
101static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
102static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
103static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
104static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
105static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
106static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
107static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
108static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
109static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
110static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
111static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
112static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
113static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
114static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
115static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
116static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
117
118static const struct ctrl sd_ctrls[] = {
119#define BRIGHTNESS_IDX 0
120	{
121	    {
122		.id      = V4L2_CID_BRIGHTNESS,
123		.type    = V4L2_CTRL_TYPE_INTEGER,
124		.name    = "Brightness",
125		.minimum = 0,
126#define BRIGHTNESS_MAX 0xffff
127		.maximum = BRIGHTNESS_MAX,
128		.step    = 1,
129#define BRIGHTNESS_DEF 0x8000
130		.default_value = BRIGHTNESS_DEF,
131	    },
132	    .set = sd_setbrightness,
133	    .get = sd_getbrightness,
134	},
135#define CONTRAST_IDX 1
136	{
137	    {
138		.id      = V4L2_CID_CONTRAST,
139		.type    = V4L2_CTRL_TYPE_INTEGER,
140		.name    = "Contrast",
141		.minimum = 0,
142#define CONTRAST_MAX 127
143		.maximum = CONTRAST_MAX,
144		.step    = 1,
145#define CONTRAST_DEF 63
146		.default_value = CONTRAST_DEF,
147	    },
148	    .set = sd_setcontrast,
149	    .get = sd_getcontrast,
150	},
151#define COLOR_IDX 2
152	{
153	    {
154		.id      = V4L2_CID_SATURATION,
155		.type    = V4L2_CTRL_TYPE_INTEGER,
156		.name    = "Saturation",
157		.minimum = 0,
158		.maximum = 40,
159		.step    = 1,
160#define COLOR_DEF 25
161		.default_value = COLOR_DEF,
162	    },
163	    .set = sd_setcolors,
164	    .get = sd_getcolors,
165	},
166#define BLUE_BALANCE_IDX 3
167	{
168	    {
169		.id      = V4L2_CID_BLUE_BALANCE,
170		.type    = V4L2_CTRL_TYPE_INTEGER,
171		.name    = "Blue Balance",
172		.minimum = 24,
173		.maximum = 40,
174		.step    = 1,
175#define BLUE_BALANCE_DEF 32
176		.default_value = BLUE_BALANCE_DEF,
177	    },
178	    .set = sd_setblue_balance,
179	    .get = sd_getblue_balance,
180	},
181#define RED_BALANCE_IDX 4
182	{
183	    {
184		.id      = V4L2_CID_RED_BALANCE,
185		.type    = V4L2_CTRL_TYPE_INTEGER,
186		.name    = "Red Balance",
187		.minimum = 24,
188		.maximum = 40,
189		.step    = 1,
190#define RED_BALANCE_DEF 32
191		.default_value = RED_BALANCE_DEF,
192	    },
193	    .set = sd_setred_balance,
194	    .get = sd_getred_balance,
195	},
196#define GAMMA_IDX 5
197	{
198	    {
199		.id      = V4L2_CID_GAMMA,
200		.type    = V4L2_CTRL_TYPE_INTEGER,
201		.name    = "Gamma",
202		.minimum = 0,
203		.maximum = 40,
204		.step    = 1,
205#define GAMMA_DEF 20
206		.default_value = GAMMA_DEF,
207	    },
208	    .set = sd_setgamma,
209	    .get = sd_getgamma,
210	},
211#define AUTOGAIN_IDX 6
212	{
213	    {
214		.id      = V4L2_CID_AUTOGAIN,
215		.type    = V4L2_CTRL_TYPE_BOOLEAN,
216		.name    = "Auto Gain",
217		.minimum = 0,
218		.maximum = 1,
219		.step    = 1,
220#define AUTOGAIN_DEF 1
221		.default_value = AUTOGAIN_DEF,
222	    },
223	    .set = sd_setautogain,
224	    .get = sd_getautogain,
225	},
226/* ov7630/ov7648 only */
227#define VFLIP_IDX 7
228	{
229	    {
230		.id      = V4L2_CID_VFLIP,
231		.type    = V4L2_CTRL_TYPE_BOOLEAN,
232		.name    = "Vflip",
233		.minimum = 0,
234		.maximum = 1,
235		.step    = 1,
236#define VFLIP_DEF 0
237		.default_value = VFLIP_DEF,
238	    },
239	    .set = sd_setvflip,
240	    .get = sd_getvflip,
241	},
242#define SHARPNESS_IDX 8
243	{
244	    {
245		.id	 = V4L2_CID_SHARPNESS,
246		.type    = V4L2_CTRL_TYPE_INTEGER,
247		.name    = "Sharpness",
248		.minimum = 0,
249		.maximum = 255,
250		.step    = 1,
251#define SHARPNESS_DEF 90
252		.default_value = SHARPNESS_DEF,
253	    },
254	    .set = sd_setsharpness,
255	    .get = sd_getsharpness,
256	},
257/* mt9v111 only */
258#define INFRARED_IDX 9
259	{
260	    {
261		.id      = V4L2_CID_INFRARED,
262		.type    = V4L2_CTRL_TYPE_BOOLEAN,
263		.name    = "Infrared",
264		.minimum = 0,
265		.maximum = 1,
266		.step    = 1,
267#define INFRARED_DEF 0
268		.default_value = INFRARED_DEF,
269	    },
270	    .set = sd_setinfrared,
271	    .get = sd_getinfrared,
272	},
273/* ov7630/ov7648/ov7660 only */
274#define FREQ_IDX 10
275	{
276	    {
277		.id	 = V4L2_CID_POWER_LINE_FREQUENCY,
278		.type    = V4L2_CTRL_TYPE_MENU,
279		.name    = "Light frequency filter",
280		.minimum = 0,
281		.maximum = 2,	/* 0: 0, 1: 50Hz, 2:60Hz */
282		.step    = 1,
283#define FREQ_DEF 1
284		.default_value = FREQ_DEF,
285	    },
286	    .set = sd_setfreq,
287	    .get = sd_getfreq,
288	},
289};
290
291/* table of the disabled controls */
292static const __u32 ctrl_dis[] = {
293[SENSOR_ADCM1700] =	(1 << AUTOGAIN_IDX) |
294			(1 << INFRARED_IDX) |
295			(1 << VFLIP_IDX) |
296			(1 << FREQ_IDX),
297
298[SENSOR_GC0307] =	(1 << INFRARED_IDX) |
299			(1 << VFLIP_IDX) |
300			(1 << FREQ_IDX),
301
302[SENSOR_HV7131R] =	(1 << INFRARED_IDX) |
303			(1 << FREQ_IDX),
304
305[SENSOR_MI0360] =	(1 << INFRARED_IDX) |
306			(1 << VFLIP_IDX) |
307			(1 << FREQ_IDX),
308
309[SENSOR_MO4000] =	(1 << INFRARED_IDX) |
310			(1 << VFLIP_IDX) |
311			(1 << FREQ_IDX),
312
313[SENSOR_MT9V111] =	(1 << VFLIP_IDX) |
314			(1 << FREQ_IDX),
315
316[SENSOR_OM6802] =	(1 << INFRARED_IDX) |
317			(1 << VFLIP_IDX) |
318			(1 << FREQ_IDX),
319
320[SENSOR_OV7630] =	(1 << INFRARED_IDX),
321
322[SENSOR_OV7648] =	(1 << INFRARED_IDX),
323
324[SENSOR_OV7660] =	(1 << AUTOGAIN_IDX) |
325			(1 << INFRARED_IDX) |
326			(1 << VFLIP_IDX),
327
328[SENSOR_PO1030] =	(1 << AUTOGAIN_IDX) |
329			(1 << INFRARED_IDX) |
330			(1 << VFLIP_IDX) |
331			(1 << FREQ_IDX),
332
333[SENSOR_PO2030N] =	(1 << AUTOGAIN_IDX) |
334			(1 << INFRARED_IDX) |
335			(1 << VFLIP_IDX) |
336			(1 << FREQ_IDX),
337[SENSOR_SOI768] =	(1 << AUTOGAIN_IDX) |
338			(1 << INFRARED_IDX) |
339			(1 << VFLIP_IDX) |
340			(1 << FREQ_IDX),
341
342[SENSOR_SP80708] =	(1 << AUTOGAIN_IDX) |
343			(1 << INFRARED_IDX) |
344			(1 << VFLIP_IDX) |
345			(1 << FREQ_IDX),
346};
347
348static const struct v4l2_pix_format cif_mode[] = {
349	{352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
350		.bytesperline = 352,
351		.sizeimage = 352 * 288 * 4 / 8 + 590,
352		.colorspace = V4L2_COLORSPACE_JPEG,
353		.priv = 0},
354};
355static const struct v4l2_pix_format vga_mode[] = {
356	{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
357		.bytesperline = 160,
358		.sizeimage = 160 * 120 * 4 / 8 + 590,
359		.colorspace = V4L2_COLORSPACE_JPEG,
360		.priv = 2},
361	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
362		.bytesperline = 320,
363		.sizeimage = 320 * 240 * 3 / 8 + 590,
364		.colorspace = V4L2_COLORSPACE_JPEG,
365		.priv = 1},
366	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
367		.bytesperline = 640,
368		/* Note 3 / 8 is not large enough, not even 5 / 8 is ?! */
369		.sizeimage = 640 * 480 * 3 / 4 + 590,
370		.colorspace = V4L2_COLORSPACE_JPEG,
371		.priv = 0},
372};
373
374static const u8 sn_adcm1700[0x1c] = {
375/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
376	0x00,	0x43,	0x60,	0x00,	0x1a,	0x00,	0x00,	0x00,
377/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
378	0x80,	0x51,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
379/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
380	0x03,	0x00,	0x05,	0x01,	0x05,	0x16,	0x12,	0x42,
381/*	reg18	reg19	reg1a	reg1b */
382	0x06,	0x00,	0x00,	0x00
383};
384
385static const u8 sn_gc0307[0x1c] = {
386/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
387	0x00,	0x61,	0x62,	0x00,	0x1a,	0x00,	0x00,	0x00,
388/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
389	0x80,	0x21,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
390/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
391	0x03,	0x00,	0x03,	0x01,	0x08,	0x28,	0x1e,	0x02,
392/*	reg18	reg19	reg1a	reg1b */
393	0x06,	0x00,	0x00,	0x00
394};
395
396static const u8 sn_hv7131[0x1c] = {
397/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
398	0x00,	0x03,	0x60,	0x00,	0x1a,	0x20,	0x20,	0x20,
399/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
400	0x81,	0x11,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
401/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
402	0x03,	0x00,	0x00,	0x01,	0x03,	0x28,	0x1e,	0x41,
403/*	reg18	reg19	reg1a	reg1b */
404	0x0a,	0x00,	0x00,	0x00
405};
406
407static const u8 sn_mi0360[0x1c] = {
408/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
409	0x00,	0x61,	0x40,	0x00,	0x1a,	0x20,	0x20,	0x20,
410/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
411	0x81,	0x5d,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
412/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
413	0x03,	0x00,	0x00,	0x02,	0x0a,	0x28,	0x1e,	0x61,
414/*	reg18	reg19	reg1a	reg1b */
415	0x06,	0x00,	0x00,	0x00
416};
417
418static const u8 sn_mo4000[0x1c] = {
419/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
420	0x00,	0x23,	0x60,	0x00,	0x1a,	0x00,	0x20,	0x18,
421/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
422	0x81,	0x21,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
423/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
424	0x03,	 0x00,	0x0b,	0x0f,	0x14,	0x28,	0x1e,	0x40,
425/*	reg18	reg19	reg1a	reg1b */
426	0x08,	0x00,	0x00,	0x00
427};
428
429static const u8 sn_mt9v111[0x1c] = {
430/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
431	0x00,	0x61,	0x40,	0x00,	0x1a,	0x20,	0x20,	0x20,
432/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
433	0x81,	0x5c,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
434/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
435	0x03,	0x00,	0x00,	0x02,	0x1c,	0x28,	0x1e,	0x40,
436/*	reg18	reg19	reg1a	reg1b */
437	0x06,	0x00,	0x00,	0x00
438};
439
440static const u8 sn_om6802[0x1c] = {
441/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
442	0x00,	0x23,	0x72,	0x00,	0x1a,	0x20,	0x20,	0x19,
443/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
444	0x80,	0x34,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
445/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
446	0x03,	0x00,	0x51,	0x01,	0x00,	0x28,	0x1e,	0x40,
447/*	reg18	reg19	reg1a	reg1b */
448	0x05,	0x00,	0x00,	0x00
449};
450
451static const u8 sn_ov7630[0x1c] = {
452/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
453	0x00,	0x21,	0x40,	0x00,	0x1a,	0x00,	0x00,	0x00,
454/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
455	0x81,	0x21,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
456/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
457	0x03,	0x00,	0x04,	0x01,	0x0a,	0x28,	0x1e,	0xc2,
458/*	reg18	reg19	reg1a	reg1b */
459	0x0b,	0x00,	0x00,	0x00
460};
461
462static const u8 sn_ov7648[0x1c] = {
463/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
464	0x00,	0x63,	0x40,	0x00,	0x1a,	0x20,	0x20,	0x20,
465/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
466	0x81,	0x21,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
467/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
468	0x03,	0x00,	0x00,	0x01,	0x00,	0x28,	0x1e,	0x00,
469/*	reg18	reg19	reg1a	reg1b */
470	0x0b,	0x00,	0x00,	0x00
471};
472
473static const u8 sn_ov7660[0x1c] = {
474/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
475	0x00,	0x61,	0x40,	0x00,	0x1a,	0x00,	0x00,	0x00,
476/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
477	0x81,	0x21,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
478/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
479	0x03,	0x00,	0x01,	0x01,	0x08,	0x28,	0x1e,	0x20,
480/*	reg18	reg19	reg1a	reg1b */
481	0x07,	0x00,	0x00,	0x00
482};
483
484static const u8 sn_po1030[0x1c] = {
485/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
486	0x00,	0x21,	0x62,	0x00,	0x1a,	0x20,	0x20,	0x20,
487/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
488	0x81,	0x6e,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
489/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
490	0x03,	0x00,	0x00,	0x06,	0x06,	0x28,	0x1e,	0x00,
491/*	reg18	reg19	reg1a	reg1b */
492	0x07,	0x00,	0x00,	0x00
493};
494
495static const u8 sn_po2030n[0x1c] = {
496/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
497	0x00,	0x63,	0x40,	0x00,	0x1a,	0x00,	0x00,	0x00,
498/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
499	0x81,	0x6e,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
500/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
501	0x03,	0x00,	0x00,	0x01,	0x14,	0x28,	0x1e,	0x00,
502/*	reg18	reg19	reg1a	reg1b */
503	0x07,	0x00,	0x00,	0x00
504};
505
506static const u8 sn_soi768[0x1c] = {
507/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
508	0x00,	0x21,	0x40,	0x00,	0x1a,	0x00,	0x00,	0x00,
509/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
510	0x81,	0x21,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
511/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
512	0x03,	0x00,	0x00,	0x01,	0x08,	0x28,	0x1e,	0x00,
513/*	reg18	reg19	reg1a	reg1b */
514	0x07,	0x00,	0x00,	0x00
515};
516
517static const u8 sn_sp80708[0x1c] = {
518/*	reg0	reg1	reg2	reg3	reg4	reg5	reg6	reg7 */
519	0x00,	0x63,	0x60,	0x00,	0x1a,	0x20,	0x20,	0x20,
520/*	reg8	reg9	rega	regb	regc	regd	rege	regf */
521	0x81,	0x18,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
522/*	reg10	reg11	reg12	reg13	reg14	reg15	reg16	reg17 */
523	0x03,	0x00,	0x00,	0x03,	0x04,	0x28,	0x1e,	0x00,
524/*	reg18	reg19	reg1a	reg1b */
525	0x07,	0x00,	0x00,	0x00
526};
527
528/* sequence specific to the sensors - !! index = SENSOR_xxx */
529static const u8 *sn_tb[] = {
530[SENSOR_ADCM1700] =	sn_adcm1700,
531[SENSOR_GC0307] =	sn_gc0307,
532[SENSOR_HV7131R] =	sn_hv7131,
533[SENSOR_MI0360] =	sn_mi0360,
534[SENSOR_MO4000] =	sn_mo4000,
535[SENSOR_MT9V111] =	sn_mt9v111,
536[SENSOR_OM6802] =	sn_om6802,
537[SENSOR_OV7630] =	sn_ov7630,
538[SENSOR_OV7648] =	sn_ov7648,
539[SENSOR_OV7660] =	sn_ov7660,
540[SENSOR_PO1030] =	sn_po1030,
541[SENSOR_PO2030N] =	sn_po2030n,
542[SENSOR_SOI768] =	sn_soi768,
543[SENSOR_SP80708] =	sn_sp80708,
544};
545
546/* default gamma table */
547static const u8 gamma_def[17] = {
548	0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
549	0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
550};
551/* gamma for sensor ADCM1700 */
552static const u8 gamma_spec_0[17] = {
553	0x0f, 0x39, 0x5a, 0x74, 0x86, 0x95, 0xa6, 0xb4,
554	0xbd, 0xc4, 0xcc, 0xd4, 0xd5, 0xde, 0xe4, 0xed, 0xf5
555};
556/* gamma for sensors HV7131R and MT9V111 */
557static const u8 gamma_spec_1[17] = {
558	0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
559	0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
560};
561/* gamma for sensor GC0307 */
562static const u8 gamma_spec_2[17] = {
563	0x14, 0x37, 0x50, 0x6a, 0x7c, 0x8d, 0x9d, 0xab,
564	0xb5, 0xbf, 0xc2, 0xcb, 0xd1, 0xd6, 0xdb, 0xe1, 0xeb
565};
566/* gamma for sensor SP80708 */
567static const u8 gamma_spec_3[17] = {
568	0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
569	0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
570};
571
572/* color matrix and offsets */
573static const u8 reg84[] = {
574	0x14, 0x00, 0x27, 0x00, 0x07, 0x00,	/* YR YG YB gains */
575	0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00,	/* UR UG UB */
576	0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f,	/* VR VG VB */
577	0x00, 0x00, 0x00			/* YUV offsets */
578};
579static const u8 adcm1700_sensor_init[][8] = {
580	{0xa0, 0x51, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x10},
581	{0xb0, 0x51, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10},	/* reset */
582	{0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
583	{0xb0, 0x51, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
584	{0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
585	{0xb0, 0x51, 0x0c, 0xe0, 0x2e, 0x00, 0x00, 0x10},
586	{0xb0, 0x51, 0x10, 0x02, 0x02, 0x00, 0x00, 0x10},
587	{0xb0, 0x51, 0x14, 0x0e, 0x0e, 0x00, 0x00, 0x10},
588	{0xb0, 0x51, 0x1c, 0x00, 0x80, 0x00, 0x00, 0x10},
589	{0xb0, 0x51, 0x20, 0x01, 0x00, 0x00, 0x00, 0x10},
590	{0xdd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
591	{0xb0, 0x51, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10},
592	{0xdd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
593	{0xb0, 0x51, 0x04, 0x01, 0x00, 0x00, 0x00, 0x10},
594	{0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
595	{0xb0, 0x51, 0x14, 0x01, 0x00, 0x00, 0x00, 0x10},
596	{0xb0, 0x51, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
597	{}
598};
599static const u8 adcm1700_sensor_param1[][8] = {
600	{0xb0, 0x51, 0x26, 0xf9, 0x01, 0x00, 0x00, 0x10},	/* exposure? */
601	{0xd0, 0x51, 0x1e, 0x8e, 0x8e, 0x8e, 0x8e, 0x10},
602
603	{0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
604	{0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
605	{0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
606	{0xb0, 0x51, 0x32, 0x00, 0x72, 0x00, 0x00, 0x10},
607	{0xd0, 0x51, 0x1e, 0xbe, 0xd7, 0xe8, 0xbe, 0x10},	/* exposure? */
608
609	{0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
610	{0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
611	{0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
612	{0xb0, 0x51, 0x32, 0x00, 0xa2, 0x00, 0x00, 0x10},
613	{}
614};
615static const u8 gc0307_sensor_init[][8] = {
616	{0xa0, 0x21, 0x43, 0x00, 0x00, 0x00, 0x00, 0x10},
617	{0xa0, 0x21, 0x44, 0xa2, 0x00, 0x00, 0x00, 0x10},
618	{0xa0, 0x21, 0x01, 0x6a, 0x00, 0x00, 0x00, 0x10},
619	{0xa0, 0x21, 0x02, 0x70, 0x00, 0x00, 0x00, 0x10},
620	{0xa0, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
621	{0xa0, 0x21, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
622	{0xa0, 0x21, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
623	{0xa0, 0x21, 0x11, 0x05, 0x00, 0x00, 0x00, 0x10},
624	{0xa0, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
625	{0xa0, 0x21, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
626	{0xa0, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10},
627	{0xa0, 0x21, 0x08, 0x02, 0x00, 0x00, 0x00, 0x10},
628	{0xa0, 0x21, 0x09, 0x01, 0x00, 0x00, 0x00, 0x10},
629	{0xa0, 0x21, 0x0a, 0xe8, 0x00, 0x00, 0x00, 0x10},
630	{0xa0, 0x21, 0x0b, 0x02, 0x00, 0x00, 0x00, 0x10},
631	{0xa0, 0x21, 0x0c, 0x80, 0x00, 0x00, 0x00, 0x10},
632	{0xa0, 0x21, 0x0d, 0x22, 0x00, 0x00, 0x00, 0x10},
633	{0xa0, 0x21, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x10},
634	{0xa0, 0x21, 0x0f, 0xb2, 0x00, 0x00, 0x00, 0x10},
635	{0xa0, 0x21, 0x12, 0x70, 0x00, 0x00, 0x00, 0x10},
636	{0xdd, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 10ms*/
637	{0xa0, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, 0x10},
638	{0xa0, 0x21, 0x15, 0xb8, 0x00, 0x00, 0x00, 0x10},
639	{0xa0, 0x21, 0x16, 0x13, 0x00, 0x00, 0x00, 0x10},
640	{0xa0, 0x21, 0x17, 0x52, 0x00, 0x00, 0x00, 0x10},
641	{0xa0, 0x21, 0x18, 0x50, 0x00, 0x00, 0x00, 0x10},
642	{0xa0, 0x21, 0x1e, 0x0d, 0x00, 0x00, 0x00, 0x10},
643	{0xa0, 0x21, 0x1f, 0x32, 0x00, 0x00, 0x00, 0x10},
644	{0xa0, 0x21, 0x61, 0x90, 0x00, 0x00, 0x00, 0x10},
645	{0xa0, 0x21, 0x63, 0x70, 0x00, 0x00, 0x00, 0x10},
646	{0xa0, 0x21, 0x65, 0x98, 0x00, 0x00, 0x00, 0x10},
647	{0xa0, 0x21, 0x67, 0x90, 0x00, 0x00, 0x00, 0x10},
648	{0xa0, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
649	{0xa0, 0x21, 0x04, 0x96, 0x00, 0x00, 0x00, 0x10},
650	{0xa0, 0x21, 0x45, 0x27, 0x00, 0x00, 0x00, 0x10},
651	{0xa0, 0x21, 0x47, 0x2c, 0x00, 0x00, 0x00, 0x10},
652	{0xa0, 0x21, 0x43, 0x47, 0x00, 0x00, 0x00, 0x10},
653	{0xa0, 0x21, 0x44, 0xd8, 0x00, 0x00, 0x00, 0x10},
654	{}
655};
656static const u8 gc0307_sensor_param1[][8] = {
657	{0xa0, 0x21, 0x68, 0x13, 0x00, 0x00, 0x00, 0x10},
658	{0xd0, 0x21, 0x61, 0x80, 0x00, 0x80, 0x00, 0x10},
659	{0xc0, 0x21, 0x65, 0x80, 0x00, 0x80, 0x00, 0x10},
660	{0xc0, 0x21, 0x63, 0xa0, 0x00, 0xa6, 0x00, 0x10},
661/*param3*/
662	{0xa0, 0x21, 0x01, 0x6e, 0x00, 0x00, 0x00, 0x10},
663	{0xa0, 0x21, 0x02, 0x88, 0x00, 0x00, 0x00, 0x10},
664	{}
665};
666
667static const u8 hv7131r_sensor_init[][8] = {
668	{0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
669	{0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
670	{0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
671/*	{0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
672	{0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
673	{0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
674/*	{0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
675
676	{0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
677	{0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
678	{0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
679	{0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
680	{0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
681	{0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
682	{0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
683	{0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
684
685	{0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
686	{0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
687	{0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
688	{0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
689	{0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
690
691	{0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
692	{0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
693	{0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
694	{0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
695	{0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
696	{0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10},
697							/* set sensor clock */
698	{}
699};
700static const u8 mi0360_sensor_init[][8] = {
701	{0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
702	{0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
703	{0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
704	{0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
705	{0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
706	{0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
707	{0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
708	{0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
709	{0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
710	{0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
711	{0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
712	{0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
713	{0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
714	{0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
715	{0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
716	{0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
717	{0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
718	{0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
719	{0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
720	{0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
721	{0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
722	{0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
723	{0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10},
724	{0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
725	{0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
726	{0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
727	{0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
728	{0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
729	{0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
730	{0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
731	{0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
732	{0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
733	{0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
734
735	{0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
736	{0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
737	{0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
738	{0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
739	{0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
740
741	{0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
742	{0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
743	{0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
744	{0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
745
746	{0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
747	{0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
748/*	{0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
749/*	{0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
750	{0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
751	{0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
752	{}
753};
754static const u8 mo4000_sensor_init[][8] = {
755	{0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
756	{0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
757	{0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
758	{0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
759	{0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
760	{0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
761	{0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
762	{0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
763	{0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
764	{0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
765	{0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
766	{0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
767	{0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
768	{0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
769	{0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
770	{0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
771	{0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
772	{0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
773	{0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
774	{0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
775	{}
776};
777static const u8 mt9v111_sensor_init[][8] = {
778	{0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
779	{0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
780	{0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
781	{0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
782	{0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
783	{0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
784	{0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
785	{0xb1, 0x5c, 0x03, 0x01, 0xe1, 0x00, 0x00, 0x10},
786	{0xb1, 0x5c, 0x04, 0x02, 0x81, 0x00, 0x00, 0x10},
787	{0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
788	{0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
789	{0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
790	{0xb1, 0x5c, 0x03, 0x01, 0xe6, 0x00, 0x00, 0x10},
791	{0xb1, 0x5c, 0x04, 0x02, 0x86, 0x00, 0x00, 0x10},
792	{0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
793	{0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
794	{0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
795	{0xb1, 0x5c, 0x0e, 0x00, 0x08, 0x00, 0x00, 0x10},
796	{0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
797	{0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
798	{0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
799	{0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
800	{0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
801	{0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
802	{0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
803	{0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
804	{0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
805	{0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
806	{}
807};
808static const u8 mt9v111_sensor_param1[][8] = {
809	{0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
810	{0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
811	{0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10},
812	{0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */
813	{0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
814	/*******/
815	{0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
816	{0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
817	{0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
818	{0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
819	{}
820};
821static const u8 om6802_init0[2][8] = {
822	{0xa0, 0x34, 0x29, 0x0e, 0x00, 0x00, 0x00, 0x10},
823	{0xa0, 0x34, 0x23, 0xb0, 0x00, 0x00, 0x00, 0x10},
824};
825static const u8 om6802_sensor_init[][8] = {
826	{0xa0, 0x34, 0xdf, 0x6d, 0x00, 0x00, 0x00, 0x10},
827						/* factory mode */
828	{0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
829						/* output raw RGB */
830	{0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
831/*	{0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
832	{0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
833		/* auto-exposure speed (0) / white balance mode (auto RGB) */
834/*	{0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
835							 * set color mode */
836/*	{0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
837						 * max AGC value in AE */
838/*	{0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
839							 * preset AGC */
840/*	{0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
841						 * preset brightness */
842/*	{0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
843							 * preset contrast */
844/*	{0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
845							 * preset gamma */
846	{0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
847				/* luminance mode (0x4f -> AutoExpo on) */
848	{0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
849							/* preset shutter */
850/*	{0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
851							 * auto frame rate */
852/*	{0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
853	{0xa0, 0x34, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
854	{}
855};
856static const u8 om6802_sensor_param1[][8] = {
857	{0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10},
858	{0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10},
859	{0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10},
860	{0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10},
861	{}
862};
863static const u8 ov7630_sensor_init[][8] = {
864	{0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
865	{0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
866	{0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
867	{0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
868	{0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
869	{0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
870	{0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
871/* win: i2c_r from 00 to 80 */
872	{0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
873	{0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
874/* HDG: 0x11 was 0x00 change to 0x01 for better exposure (15 fps instead of 30)
875	0x13 was 0xc0 change to 0xc3 for auto gain and exposure */
876	{0xd1, 0x21, 0x11, 0x01, 0x48, 0xc3, 0x00, 0x10},
877	{0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
878	{0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
879	{0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
880	{0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
881	{0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
882	{0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
883	{0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
884	{0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
885	{0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
886	{0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
887	{0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
888	{0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
889	{0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
890	{0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
891	{0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
892	{0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
893	{0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
894	{0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
895	{0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
896	{0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
897	{0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
898	{0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
899	{0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
900	{}
901};
902static const u8 ov7630_sensor_param1[][8] = {
903	{0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
904	{0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
905/*	{0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10},  * COMN
906							 * set by setvflip */
907	{0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
908	{0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
909	{0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
910/* */
911/*	{0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
912/*	{0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
913/* */
914	{0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
915/*	{0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
916	{}
917};
918
919static const u8 ov7648_sensor_init[][8] = {
920	{0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
921	{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},	/* reset */
922	{0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
923	{0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
924	{0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
925	{0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
926	{0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
927	{0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
928	{0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
929	{0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
930	{0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
931	{0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
932	{0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
933	{0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
934	{0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
935	{0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
936	{0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
937	{0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
938	{0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
939	{0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
940	{0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
941	{0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
942
943	{0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
944/*	{0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
945/*	{0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
946/*	{0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */
947	{}
948};
949static const u8 ov7648_sensor_param1[][8] = {
950/*	{0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
951/*	{0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10},   * COMN
952							 * set by setvflip */
953	{0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
954	{0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
955/*	{0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
956/*	{0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},  * GAIN - def */
957/*	{0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10},  * B R - def: 80 */
958/*...*/
959	{0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
960/*	{0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
961/*	{0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
962/*	{0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
963/*	{0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
964/*	{0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10},  * B R - def: 80 */
965
966	{}
967};
968
969static const u8 ov7660_sensor_init[][8] = {
970	{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
971	{0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
972	{0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
973						/* Outformat = rawRGB */
974	{0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
975	{0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10},
976						/* GAIN BLUE RED VREF */
977	{0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
978						/* COM 1 BAVE GEAVE AECHH */
979	{0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
980	{0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
981	{0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
982						/* AECH CLKRC COM7 COM8 */
983	{0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
984	{0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
985						/* HSTART HSTOP VSTRT VSTOP */
986	{0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
987	{0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
988	{0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
989					/* BOS GBOS GROS ROS (BGGR offset) */
990/*	{0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
991	{0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
992						/* AEW AEB VPT BBIAS */
993	{0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
994						/* GbBIAS RSVD EXHCH EXHCL */
995	{0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
996						/* RBIAS ADVFL ASDVFH YAVE */
997	{0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
998						/* HSYST HSYEN HREF */
999	{0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
1000	{0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
1001						/* ADC ACOM OFON TSLB */
1002	{0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
1003						/* COM11 COM12 COM13 COM14 */
1004	{0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
1005						/* EDGE COM15 COM16 COM17 */
1006	{0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
1007	{0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
1008	{0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
1009	{0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
1010	{0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
1011	{0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
1012	{0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
1013	{0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
1014	{0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
1015	{0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
1016						/* LCC1 LCC2 LCC3 LCC4 */
1017	{0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
1018	{0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
1019	{0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
1020					/* band gap reference [0:3] DBLV */
1021	{0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
1022	{0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
1023	{0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
1024	{0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
1025	{0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
1026	{0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
1027	{0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
1028	{0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
1029	{0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
1030	{0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
1031/* not in all ms-win traces*/
1032	{0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
1033	{}
1034};
1035static const u8 ov7660_sensor_param1[][8] = {
1036	{0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
1037						/* bits[3..0]reserved */
1038	{0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
1039	{0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
1040						/* VREF vertical frame ctrl */
1041	{0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
1042	{0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
1043	{0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
1044	{0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
1045	{0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
1046/*	{0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
1047/****** (some exchanges in the win trace) ******/
1048	{0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
1049	{0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
1050	{0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
1051	{0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
1052/*	{0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10},  * RED */
1053/****** (some exchanges in the win trace) ******/
1054/******!! startsensor KO if changed !!****/
1055	{0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
1056	{0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
1057	{0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
1058	{0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
1059	{}
1060};
1061
1062static const u8 po1030_sensor_init[][8] = {
1063/* the sensor registers are described in m5602/m5602_po1030.h */
1064	{0xa1, 0x6e, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x10}, /* sensor reset */
1065	{0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
1066	{0xa1, 0x6e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x10},
1067	{0xa1, 0x6e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10},
1068	{0xd1, 0x6e, 0x04, 0x02, 0xb1, 0x02, 0x39, 0x10},
1069	{0xd1, 0x6e, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
1070	{0xd1, 0x6e, 0x0c, 0x02, 0x7f, 0x01, 0xe0, 0x10},
1071	{0xd1, 0x6e, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
1072	{0xd1, 0x6e, 0x16, 0x85, 0x40, 0x4a, 0x40, 0x10}, /* r/g1/b/g2 gains */
1073	{0xc1, 0x6e, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10},
1074	{0xd1, 0x6e, 0x1d, 0x08, 0x03, 0x00, 0x00, 0x10},
1075	{0xd1, 0x6e, 0x23, 0x00, 0xb0, 0x00, 0x94, 0x10},
1076	{0xd1, 0x6e, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
1077	{0xb1, 0x6e, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
1078	{0xd1, 0x6e, 0x2d, 0x14, 0x35, 0x61, 0x84, 0x10}, /* gamma corr */
1079	{0xd1, 0x6e, 0x31, 0xa2, 0xbd, 0xd8, 0xff, 0x10},
1080	{0xd1, 0x6e, 0x35, 0x06, 0x1e, 0x12, 0x02, 0x10}, /* color matrix */
1081	{0xd1, 0x6e, 0x39, 0xaa, 0x53, 0x37, 0xd5, 0x10},
1082	{0xa1, 0x6e, 0x3d, 0xf2, 0x00, 0x00, 0x00, 0x10},
1083	{0xd1, 0x6e, 0x3e, 0x00, 0x00, 0x80, 0x03, 0x10},
1084	{0xd1, 0x6e, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
1085	{0xc1, 0x6e, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
1086	{0xd1, 0x6e, 0x4b, 0x02, 0xef, 0x08, 0xcd, 0x10},
1087	{0xd1, 0x6e, 0x4f, 0x00, 0xd0, 0x00, 0xa0, 0x10},
1088	{0xd1, 0x6e, 0x53, 0x01, 0xaa, 0x01, 0x40, 0x10},
1089	{0xd1, 0x6e, 0x5a, 0x50, 0x04, 0x30, 0x03, 0x10}, /* raw rgb bayer */
1090	{0xa1, 0x6e, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x10},
1091	{0xd1, 0x6e, 0x5f, 0x10, 0x40, 0xff, 0x00, 0x10},
1092
1093	{0xd1, 0x6e, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
1094	{0xd1, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
1095	{0xd1, 0x6e, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x10},
1096	{0xd1, 0x6e, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x10},
1097	{0xc1, 0x6e, 0x73, 0x10, 0x80, 0xeb, 0x00, 0x10},
1098	{}
1099};
1100static const u8 po1030_sensor_param1[][8] = {
1101/* from ms-win traces - these values change with auto gain/expo/wb.. */
1102	{0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
1103	{0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
1104/* mean values */
1105	{0xc1, 0x6e, 0x1a, 0x02, 0xd4, 0xa4, 0x00, 0x10}, /* integlines */
1106	{0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, /* global gain */
1107	{0xc1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, /* r/g1/b gains */
1108
1109	{0xa1, 0x6e, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x10}, /* control1 */
1110	{0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, /* frameheight */
1111	{0xa1, 0x6e, 0x07, 0xd5, 0x00, 0x00, 0x00, 0x10},
1112/*	{0xc1, 0x6e, 0x16, 0x49, 0x40, 0x45, 0x00, 0x10}, */
1113	{}
1114};
1115
1116static const u8 po2030n_sensor_init[][8] = {
1117	{0xa1, 0x6e, 0x1e, 0x1a, 0x00, 0x00, 0x00, 0x10},
1118	{0xa1, 0x6e, 0x1f, 0x99, 0x00, 0x00, 0x00, 0x10},
1119	{0xdd, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
1120	{0xa1, 0x6e, 0x1e, 0x0a, 0x00, 0x00, 0x00, 0x10},
1121	{0xa1, 0x6e, 0x1f, 0x19, 0x00, 0x00, 0x00, 0x10},
1122	{0xdd, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
1123	{0xa1, 0x6e, 0x20, 0x44, 0x00, 0x00, 0x00, 0x10},
1124	{0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
1125	{0xa1, 0x6e, 0x05, 0x70, 0x00, 0x00, 0x00, 0x10},
1126	{0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
1127	{0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
1128	{0xd1, 0x6e, 0x08, 0x00, 0xd0, 0x00, 0x08, 0x10},
1129	{0xd1, 0x6e, 0x0c, 0x03, 0x50, 0x01, 0xe8, 0x10},
1130	{0xd1, 0x6e, 0x1d, 0x20, 0x0a, 0x19, 0x44, 0x10},
1131	{0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
1132	{0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x00, 0x10},
1133	{0xd1, 0x6e, 0x29, 0x00, 0x00, 0x00, 0x00, 0x10},
1134	{0xd1, 0x6e, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
1135	{0xd1, 0x6e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
1136	{0xd1, 0x6e, 0x35, 0x00, 0x00, 0x00, 0x00, 0x10},
1137	{0xd1, 0x6e, 0x39, 0x00, 0x00, 0x00, 0x00, 0x10},
1138	{0xd1, 0x6e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x10},
1139	{0xd1, 0x6e, 0x41, 0x00, 0x00, 0x00, 0x00, 0x10},
1140	{0xd1, 0x6e, 0x45, 0x00, 0x00, 0x00, 0x00, 0x10},
1141	{0xd1, 0x6e, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10},
1142	{0xd1, 0x6e, 0x4d, 0x00, 0x00, 0x00, 0xed, 0x10},
1143	{0xd1, 0x6e, 0x51, 0x17, 0x4a, 0x2f, 0xc0, 0x10},
1144	{0xd1, 0x6e, 0x55, 0x00, 0x00, 0x00, 0x00, 0x10},
1145	{0xd1, 0x6e, 0x59, 0x00, 0x00, 0x00, 0x00, 0x10},
1146	{0xd1, 0x6e, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x10},
1147	{0xd1, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x00, 0x10},
1148	{0xd1, 0x6e, 0x65, 0x00, 0x00, 0x00, 0x00, 0x10},
1149	{0xd1, 0x6e, 0x69, 0x00, 0x00, 0x00, 0x00, 0x10},
1150	{0xd1, 0x6e, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x10},
1151	{0xd1, 0x6e, 0x71, 0x00, 0x00, 0x00, 0x00, 0x10},
1152	{0xd1, 0x6e, 0x75, 0x00, 0x00, 0x00, 0x00, 0x10},
1153	{0xd1, 0x6e, 0x79, 0x00, 0x00, 0x00, 0x00, 0x10},
1154	{0xd1, 0x6e, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x10},
1155	{0xd1, 0x6e, 0x81, 0x00, 0x00, 0x00, 0x00, 0x10},
1156	{0xd1, 0x6e, 0x85, 0x00, 0x00, 0x00, 0x08, 0x10},
1157	{0xd1, 0x6e, 0x89, 0x01, 0xe8, 0x00, 0x01, 0x10},
1158	{0xa1, 0x6e, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x10},
1159	{0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
1160	{0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x01, 0x10},
1161	{0xd1, 0x6e, 0x29, 0xe6, 0x00, 0xbd, 0x03, 0x10},
1162	{0xd1, 0x6e, 0x2d, 0x41, 0x38, 0x68, 0x40, 0x10},
1163	{0xd1, 0x6e, 0x31, 0x2b, 0x00, 0x36, 0x00, 0x10},
1164	{0xd1, 0x6e, 0x35, 0x30, 0x30, 0x08, 0x00, 0x10},
1165	{0xd1, 0x6e, 0x39, 0x00, 0x00, 0x33, 0x06, 0x10},
1166	{0xb1, 0x6e, 0x3d, 0x06, 0x02, 0x00, 0x00, 0x10},
1167	{}
1168};
1169static const u8 po2030n_sensor_param1[][8] = {
1170	{0xa1, 0x6e, 0x1a, 0x01, 0x00, 0x00, 0x00, 0x10},
1171	{0xdd, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 8ms */
1172	{0xa1, 0x6e, 0x1b, 0xf4, 0x00, 0x00, 0x00, 0x10},
1173	{0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10},
1174	{0xd1, 0x6e, 0x16, 0x50, 0x40, 0x49, 0x40, 0x10},
1175/*param2*/
1176	{0xa1, 0x6e, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
1177	{0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
1178	{0xa1, 0x6e, 0x05, 0x6f, 0x00, 0x00, 0x00, 0x10},
1179	{0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
1180	{0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
1181	{0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10},
1182	{0xc1, 0x6e, 0x16, 0x52, 0x40, 0x48, 0x00, 0x10},
1183/*after start*/
1184	{0xa1, 0x6e, 0x15, 0x0f, 0x00, 0x00, 0x00, 0x10},
1185	{0xdd, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */
1186	{0xa1, 0x6e, 0x1a, 0x05, 0x00, 0x00, 0x00, 0x10},
1187	{0xdd, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */
1188	{0xa1, 0x6e, 0x1b, 0x53, 0x00, 0x00, 0x00, 0x10},
1189	{}
1190};
1191
1192static const u8 soi768_sensor_init[][8] = {
1193	{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
1194	{0xdd, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 96ms */
1195	{0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
1196	{0xa1, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10},
1197	{0xa1, 0x21, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x10},
1198	{0xa1, 0x21, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10},
1199	{}
1200};
1201static const u8 soi768_sensor_param1[][8] = {
1202	{0xa1, 0x21, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10},
1203	{0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
1204	{0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
1205	{0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1206	{0xb1, 0x21, 0x01, 0x7f, 0x7f, 0x00, 0x00, 0x10},
1207/* */
1208/*	{0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, */
1209/*	{0xa1, 0x21, 0x2d, 0x25, 0x00, 0x00, 0x00, 0x10}, */
1210	{0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
1211/*	{0xb1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, */
1212	{0xa1, 0x21, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x10},
1213/* the next sequence should be used for auto gain */
1214	{0xa1, 0x21, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10},
1215			/* global gain ? : 07 - change with 0x15 at the end */
1216	{0xa1, 0x21, 0x10, 0x3f, 0x00, 0x00, 0x00, 0x10}, /* ???? : 063f */
1217	{0xa1, 0x21, 0x04, 0x06, 0x00, 0x00, 0x00, 0x10},
1218	{0xb1, 0x21, 0x2d, 0x00, 0x02, 0x00, 0x00, 0x10},
1219			/* exposure ? : 0200 - change with 0x1e at the end */
1220	{}
1221};
1222
1223static const u8 sp80708_sensor_init[][8] = {
1224	{0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
1225	{0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
1226	{0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
1227	{0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
1228	{0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1229	{0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
1230	{0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
1231	{0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
1232	{0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
1233	{0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
1234	{0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
1235	{0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
1236	{0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
1237	{0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
1238	{0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
1239	{0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
1240	{0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
1241	{0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
1242	{0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
1243	{0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
1244	{0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
1245	{0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
1246	{0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
1247	{0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
1248	{0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
1249	{0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
1250	{0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
1251	{0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
1252	{0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
1253	{0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
1254	{0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
1255	{0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
1256	{0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
1257	{0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
1258	{0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
1259	{0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
1260	{0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
1261	{0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
1262	{0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
1263	{0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
1264	{0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
1265	{0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
1266	{0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
1267	{0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
1268	{0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
1269	{0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
1270	{0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
1271	{0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
1272	{0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
1273	{0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
1274	{0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
1275	{0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
1276	{0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
1277	{0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
1278	{0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
1279	{0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
1280	{0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
1281	{0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
1282	{0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
1283	{0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
1284	{0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
1285	{0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
1286	{0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
1287	{0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
1288	{0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
1289	{0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
1290	{0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
1291	{0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
1292	{0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
1293	{0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
1294	{0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
1295	{}
1296};
1297static const u8 sp80708_sensor_param1[][8] = {
1298	{0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1299	{0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1300	{0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
1301	{0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
1302	{0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
1303	{0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
1304	{0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
1305	{}
1306};
1307
1308static const u8 (*sensor_init[])[8] = {
1309[SENSOR_ADCM1700] =	adcm1700_sensor_init,
1310[SENSOR_GC0307] =	gc0307_sensor_init,
1311[SENSOR_HV7131R] =	hv7131r_sensor_init,
1312[SENSOR_MI0360] =	mi0360_sensor_init,
1313[SENSOR_MO4000] =	mo4000_sensor_init,
1314[SENSOR_MT9V111] =	mt9v111_sensor_init,
1315[SENSOR_OM6802] =	om6802_sensor_init,
1316[SENSOR_OV7630] =	ov7630_sensor_init,
1317[SENSOR_OV7648] =	ov7648_sensor_init,
1318[SENSOR_OV7660] =	ov7660_sensor_init,
1319[SENSOR_PO1030] =	po1030_sensor_init,
1320[SENSOR_PO2030N] =	po2030n_sensor_init,
1321[SENSOR_SOI768] =	soi768_sensor_init,
1322[SENSOR_SP80708] =	sp80708_sensor_init,
1323};
1324
1325/* read <len> bytes to gspca_dev->usb_buf */
1326static void reg_r(struct gspca_dev *gspca_dev,
1327		  u16 value, int len)
1328{
1329#ifdef GSPCA_DEBUG
1330	if (len > USB_BUF_SZ) {
1331		err("reg_r: buffer overflow");
1332		return;
1333	}
1334#endif
1335	usb_control_msg(gspca_dev->dev,
1336			usb_rcvctrlpipe(gspca_dev->dev, 0),
1337			0,
1338			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1339			value, 0,
1340			gspca_dev->usb_buf, len,
1341			500);
1342	PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
1343}
1344
1345static void reg_w1(struct gspca_dev *gspca_dev,
1346		   u16 value,
1347		   u8 data)
1348{
1349	PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
1350	gspca_dev->usb_buf[0] = data;
1351	usb_control_msg(gspca_dev->dev,
1352			usb_sndctrlpipe(gspca_dev->dev, 0),
1353			0x08,
1354			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1355			value,
1356			0,
1357			gspca_dev->usb_buf, 1,
1358			500);
1359}
1360static void reg_w(struct gspca_dev *gspca_dev,
1361			  u16 value,
1362			  const u8 *buffer,
1363			  int len)
1364{
1365	PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
1366		value, buffer[0], buffer[1]);
1367#ifdef GSPCA_DEBUG
1368	if (len > USB_BUF_SZ) {
1369		err("reg_w: buffer overflow");
1370		return;
1371	}
1372#endif
1373	memcpy(gspca_dev->usb_buf, buffer, len);
1374	usb_control_msg(gspca_dev->dev,
1375			usb_sndctrlpipe(gspca_dev->dev, 0),
1376			0x08,
1377			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1378			value, 0,
1379			gspca_dev->usb_buf, len,
1380			500);
1381}
1382
1383/* I2C write 1 byte */
1384static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1385{
1386	struct sd *sd = (struct sd *) gspca_dev;
1387
1388	PDEBUG(D_USBO, "i2c_w1 [%02x] = %02x", reg, val);
1389	switch (sd->sensor) {
1390	case SENSOR_ADCM1700:
1391	case SENSOR_OM6802:
1392	case SENSOR_GC0307:		/* i2c command = a0 (100 kHz) */
1393		gspca_dev->usb_buf[0] = 0x80 | (2 << 4);
1394		break;
1395	default:			/* i2c command = a1 (400 kHz) */
1396		gspca_dev->usb_buf[0] = 0x81 | (2 << 4);
1397		break;
1398	}
1399	gspca_dev->usb_buf[1] = sd->i2c_addr;
1400	gspca_dev->usb_buf[2] = reg;
1401	gspca_dev->usb_buf[3] = val;
1402	gspca_dev->usb_buf[4] = 0;
1403	gspca_dev->usb_buf[5] = 0;
1404	gspca_dev->usb_buf[6] = 0;
1405	gspca_dev->usb_buf[7] = 0x10;
1406	usb_control_msg(gspca_dev->dev,
1407			usb_sndctrlpipe(gspca_dev->dev, 0),
1408			0x08,
1409			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1410			0x08,			/* value = i2c */
1411			0,
1412			gspca_dev->usb_buf, 8,
1413			500);
1414}
1415
1416/* I2C write 8 bytes */
1417static void i2c_w8(struct gspca_dev *gspca_dev,
1418		   const u8 *buffer)
1419{
1420	PDEBUG(D_USBO, "i2c_w8 [%02x] = %02x ..",
1421		buffer[2], buffer[3]);
1422	memcpy(gspca_dev->usb_buf, buffer, 8);
1423	usb_control_msg(gspca_dev->dev,
1424			usb_sndctrlpipe(gspca_dev->dev, 0),
1425			0x08,
1426			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1427			0x08, 0,		/* value, index */
1428			gspca_dev->usb_buf, 8,
1429			500);
1430	msleep(2);
1431}
1432
1433/* sensor read 'len' (1..5) bytes in gspca_dev->usb_buf */
1434static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len)
1435{
1436	struct sd *sd = (struct sd *) gspca_dev;
1437	u8 mode[8];
1438
1439	switch (sd->sensor) {
1440	case SENSOR_ADCM1700:
1441	case SENSOR_OM6802:
1442	case SENSOR_GC0307:		/* i2c command = a0 (100 kHz) */
1443		mode[0] = 0x80 | 0x10;
1444		break;
1445	default:			/* i2c command = 91 (400 kHz) */
1446		mode[0] = 0x81 | 0x10;
1447		break;
1448	}
1449	mode[1] = sd->i2c_addr;
1450	mode[2] = reg;
1451	mode[3] = 0;
1452	mode[4] = 0;
1453	mode[5] = 0;
1454	mode[6] = 0;
1455	mode[7] = 0x10;
1456	i2c_w8(gspca_dev, mode);
1457	msleep(2);
1458	mode[0] = (mode[0] & 0x81) | (len << 4) | 0x02;
1459	mode[2] = 0;
1460	i2c_w8(gspca_dev, mode);
1461	msleep(2);
1462	reg_r(gspca_dev, 0x0a, 5);
1463}
1464
1465static void i2c_w_seq(struct gspca_dev *gspca_dev,
1466			const u8 (*data)[8])
1467{
1468	while ((*data)[0] != 0) {
1469		if ((*data)[0] != 0xdd)
1470			i2c_w8(gspca_dev, *data);
1471		else
1472			msleep((*data)[1]);
1473		data++;
1474	}
1475}
1476
1477static void hv7131r_probe(struct gspca_dev *gspca_dev)
1478{
1479	i2c_w1(gspca_dev, 0x02, 0);			/* sensor wakeup */
1480	msleep(10);
1481	reg_w1(gspca_dev, 0x02, 0x66);			/* Gpio on */
1482	msleep(10);
1483	i2c_r(gspca_dev, 0, 5);				/* read sensor id */
1484	if (gspca_dev->usb_buf[0] == 0x02
1485	    && gspca_dev->usb_buf[1] == 0x09
1486	    && gspca_dev->usb_buf[2] == 0x01
1487	    && gspca_dev->usb_buf[3] == 0x00
1488	    && gspca_dev->usb_buf[4] == 0x00) {
1489		PDEBUG(D_PROBE, "Sensor sn9c102P HV7131R found");
1490		return;
1491	}
1492	PDEBUG(D_PROBE, "Sensor 0x%02x 0x%02x 0x%02x - sn9c102P not found",
1493		gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
1494		gspca_dev->usb_buf[2]);
1495}
1496
1497static void mi0360_probe(struct gspca_dev *gspca_dev)
1498{
1499	struct sd *sd = (struct sd *) gspca_dev;
1500	int i, j;
1501	u16 val = 0;
1502	static const u8 probe_tb[][4][8] = {
1503	    {					/* mi0360 */
1504		{0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1505		{0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1506		{0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1507		{0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1508	    },
1509	    {					/* mt9v111 */
1510		{0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1511		{0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1512		{0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1513		{}
1514	    },
1515	};
1516
1517	for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1518		reg_w1(gspca_dev, 0x17, 0x62);
1519		reg_w1(gspca_dev, 0x01, 0x08);
1520		for (j = 0; j < 3; j++)
1521			i2c_w8(gspca_dev, probe_tb[i][j]);
1522		msleep(2);
1523		reg_r(gspca_dev, 0x0a, 5);
1524		val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1525		if (probe_tb[i][3][0] != 0)
1526			i2c_w8(gspca_dev, probe_tb[i][3]);
1527		reg_w1(gspca_dev, 0x01, 0x29);
1528		reg_w1(gspca_dev, 0x17, 0x42);
1529		if (val != 0xffff)
1530			break;
1531	}
1532	switch (val) {
1533	case 0x823a:
1534		PDEBUG(D_PROBE, "Sensor mt9v111");
1535		sd->sensor = SENSOR_MT9V111;
1536		break;
1537	case 0x8243:
1538		PDEBUG(D_PROBE, "Sensor mi0360");
1539		break;
1540	default:
1541		PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
1542		break;
1543	}
1544}
1545
1546static void ov7630_probe(struct gspca_dev *gspca_dev)
1547{
1548	struct sd *sd = (struct sd *) gspca_dev;
1549	u16 val;
1550
1551	/* check ov76xx */
1552	reg_w1(gspca_dev, 0x17, 0x62);
1553	reg_w1(gspca_dev, 0x01, 0x08);
1554	sd->i2c_addr = 0x21;
1555	i2c_r(gspca_dev, 0x0a, 2);
1556	val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1557	reg_w1(gspca_dev, 0x01, 0x29);
1558	reg_w1(gspca_dev, 0x17, 0x42);
1559	if (val == 0x7628) {			/* soi768 */
1560		sd->sensor = SENSOR_SOI768;
1561		gspca_dev->cam.input_flags =
1562				V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP;
1563		PDEBUG(D_PROBE, "Sensor soi768");
1564		return;
1565	}
1566	PDEBUG(D_PROBE, "Sensor ov%04x", val);
1567}
1568
1569static void ov7648_probe(struct gspca_dev *gspca_dev)
1570{
1571	struct sd *sd = (struct sd *) gspca_dev;
1572	u16 val;
1573
1574	/* check ov76xx */
1575	reg_w1(gspca_dev, 0x17, 0x62);
1576	reg_w1(gspca_dev, 0x01, 0x08);
1577	sd->i2c_addr = 0x21;
1578	i2c_r(gspca_dev, 0x0a, 2);
1579	val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1580	reg_w1(gspca_dev, 0x01, 0x29);
1581	reg_w1(gspca_dev, 0x17, 0x42);
1582	if ((val & 0xff00) == 0x7600) {		/* ov76xx */
1583		PDEBUG(D_PROBE, "Sensor ov%04x", val);
1584		return;
1585	}
1586
1587	/* check po1030 */
1588	reg_w1(gspca_dev, 0x17, 0x62);
1589	reg_w1(gspca_dev, 0x01, 0x08);
1590	sd->i2c_addr = 0x6e;
1591	i2c_r(gspca_dev, 0x00, 2);
1592	val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1593	reg_w1(gspca_dev, 0x01, 0x29);
1594	reg_w1(gspca_dev, 0x17, 0x42);
1595	if (val == 0x1030) {			/* po1030 */
1596		PDEBUG(D_PROBE, "Sensor po1030");
1597		sd->sensor = SENSOR_PO1030;
1598		return;
1599	}
1600
1601	PDEBUG(D_PROBE, "Unknown sensor %04x", val);
1602}
1603
1604/* 0c45:6142 sensor may be po2030n, gc0305 or gc0307 */
1605static void po2030n_probe(struct gspca_dev *gspca_dev)
1606{
1607	struct sd *sd = (struct sd *) gspca_dev;
1608	u16 val;
1609
1610	/* check gc0307 */
1611	reg_w1(gspca_dev, 0x17, 0x62);
1612	reg_w1(gspca_dev, 0x01, 0x08);
1613	reg_w1(gspca_dev, 0x02, 0x22);
1614	sd->i2c_addr = 0x21;
1615	i2c_r(gspca_dev, 0x00, 1);
1616	val = gspca_dev->usb_buf[4];
1617	reg_w1(gspca_dev, 0x01, 0x29);		/* reset */
1618	reg_w1(gspca_dev, 0x17, 0x42);
1619	if (val == 0x99) {			/* gc0307 (?) */
1620		PDEBUG(D_PROBE, "Sensor gc0307");
1621		sd->sensor = SENSOR_GC0307;
1622		return;
1623	}
1624
1625	/* check po2030n */
1626	reg_w1(gspca_dev, 0x17, 0x62);
1627	reg_w1(gspca_dev, 0x01, 0x0a);
1628	sd->i2c_addr = 0x6e;
1629	i2c_r(gspca_dev, 0x00, 2);
1630	val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1631	reg_w1(gspca_dev, 0x01, 0x29);
1632	reg_w1(gspca_dev, 0x17, 0x42);
1633	if (val == 0x2030) {
1634		PDEBUG(D_PROBE, "Sensor po2030n");
1635/*		sd->sensor = SENSOR_PO2030N; */
1636	} else {
1637		PDEBUG(D_PROBE, "Unknown sensor ID %04x", val);
1638	}
1639}
1640
1641static void bridge_init(struct gspca_dev *gspca_dev,
1642			  const u8 *sn9c1xx)
1643{
1644	struct sd *sd = (struct sd *) gspca_dev;
1645	u8 reg0102[2];
1646	const u8 *reg9a;
1647	static const u8 reg9a_def[] =
1648		{0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
1649	static const u8 reg9a_spec[] =
1650		{0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
1651	static const u8 regd4[] = {0x60, 0x00, 0x00};
1652
1653	/* sensor clock already enabled in sd_init */
1654	/* reg_w1(gspca_dev, 0xf1, 0x00); */
1655	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1656
1657	/* configure gpio */
1658	reg0102[0] = sn9c1xx[1];
1659	reg0102[1] = sn9c1xx[2];
1660	if (gspca_dev->audio)
1661		reg0102[1] |= 0x04;	/* keep the audio connection */
1662	reg_w(gspca_dev, 0x01, reg0102, 2);
1663	reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
1664	reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
1665	switch (sd->sensor) {
1666	case SENSOR_GC0307:
1667	case SENSOR_OV7660:
1668	case SENSOR_PO1030:
1669	case SENSOR_PO2030N:
1670	case SENSOR_SOI768:
1671	case SENSOR_SP80708:
1672		reg9a = reg9a_spec;
1673		break;
1674	default:
1675		reg9a = reg9a_def;
1676		break;
1677	}
1678	reg_w(gspca_dev, 0x9a, reg9a, 6);
1679
1680	reg_w(gspca_dev, 0xd4, regd4, sizeof regd4);
1681
1682	reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
1683
1684	switch (sd->sensor) {
1685	case SENSOR_ADCM1700:
1686		reg_w1(gspca_dev, 0x01, 0x43);
1687		reg_w1(gspca_dev, 0x17, 0x62);
1688		reg_w1(gspca_dev, 0x01, 0x42);
1689		reg_w1(gspca_dev, 0x01, 0x42);
1690		break;
1691	case SENSOR_GC0307:
1692		msleep(50);
1693		reg_w1(gspca_dev, 0x01, 0x61);
1694		reg_w1(gspca_dev, 0x17, 0x22);
1695		reg_w1(gspca_dev, 0x01, 0x60);
1696		reg_w1(gspca_dev, 0x01, 0x40);
1697		msleep(50);
1698		break;
1699	case SENSOR_MT9V111:
1700		reg_w1(gspca_dev, 0x01, 0x61);
1701		reg_w1(gspca_dev, 0x17, 0x61);
1702		reg_w1(gspca_dev, 0x01, 0x60);
1703		reg_w1(gspca_dev, 0x01, 0x40);
1704		break;
1705	case SENSOR_OM6802:
1706		msleep(10);
1707		reg_w1(gspca_dev, 0x02, 0x73);
1708		reg_w1(gspca_dev, 0x17, 0x60);
1709		reg_w1(gspca_dev, 0x01, 0x22);
1710		msleep(100);
1711		reg_w1(gspca_dev, 0x01, 0x62);
1712		reg_w1(gspca_dev, 0x17, 0x64);
1713		reg_w1(gspca_dev, 0x17, 0x64);
1714		reg_w1(gspca_dev, 0x01, 0x42);
1715		msleep(10);
1716		reg_w1(gspca_dev, 0x01, 0x42);
1717		i2c_w8(gspca_dev, om6802_init0[0]);
1718		i2c_w8(gspca_dev, om6802_init0[1]);
1719		msleep(15);
1720		reg_w1(gspca_dev, 0x02, 0x71);
1721		msleep(150);
1722		break;
1723	case SENSOR_OV7630:
1724		reg_w1(gspca_dev, 0x01, 0x61);
1725		reg_w1(gspca_dev, 0x17, 0xe2);
1726		reg_w1(gspca_dev, 0x01, 0x60);
1727		reg_w1(gspca_dev, 0x01, 0x40);
1728		break;
1729	case SENSOR_OV7648:
1730		reg_w1(gspca_dev, 0x01, 0x63);
1731		reg_w1(gspca_dev, 0x17, 0x20);
1732		reg_w1(gspca_dev, 0x01, 0x62);
1733		reg_w1(gspca_dev, 0x01, 0x42);
1734		break;
1735	case SENSOR_PO1030:
1736	case SENSOR_SOI768:
1737		reg_w1(gspca_dev, 0x01, 0x61);
1738		reg_w1(gspca_dev, 0x17, 0x20);
1739		reg_w1(gspca_dev, 0x01, 0x60);
1740		reg_w1(gspca_dev, 0x01, 0x40);
1741		break;
1742	case SENSOR_PO2030N:
1743	case SENSOR_OV7660:
1744		reg_w1(gspca_dev, 0x01, 0x63);
1745		reg_w1(gspca_dev, 0x17, 0x20);
1746		reg_w1(gspca_dev, 0x01, 0x62);
1747		reg_w1(gspca_dev, 0x01, 0x42);
1748		break;
1749	case SENSOR_SP80708:
1750		reg_w1(gspca_dev, 0x01, 0x63);
1751		reg_w1(gspca_dev, 0x17, 0x20);
1752		reg_w1(gspca_dev, 0x01, 0x62);
1753		reg_w1(gspca_dev, 0x01, 0x42);
1754		msleep(100);
1755		reg_w1(gspca_dev, 0x02, 0x62);
1756		break;
1757	default:
1758/*	case SENSOR_HV7131R: */
1759/*	case SENSOR_MI0360: */
1760/*	case SENSOR_MO4000: */
1761		reg_w1(gspca_dev, 0x01, 0x43);
1762		reg_w1(gspca_dev, 0x17, 0x61);
1763		reg_w1(gspca_dev, 0x01, 0x42);
1764		if (sd->sensor == SENSOR_HV7131R
1765		    && sd->bridge == BRIDGE_SN9C102P)
1766			hv7131r_probe(gspca_dev);
1767		break;
1768	}
1769}
1770
1771/* this function is called at probe time */
1772static int sd_config(struct gspca_dev *gspca_dev,
1773			const struct usb_device_id *id)
1774{
1775	struct sd *sd = (struct sd *) gspca_dev;
1776	struct cam *cam;
1777
1778	sd->bridge = id->driver_info >> 16;
1779	sd->sensor = id->driver_info >> 8;
1780	sd->flags = id->driver_info;
1781
1782	cam = &gspca_dev->cam;
1783	if (sd->sensor == SENSOR_ADCM1700) {
1784		cam->cam_mode = cif_mode;
1785		cam->nmodes = ARRAY_SIZE(cif_mode);
1786	} else {
1787		cam->cam_mode = vga_mode;
1788		cam->nmodes = ARRAY_SIZE(vga_mode);
1789	}
1790	cam->npkt = 24;			/* 24 packets per ISOC message */
1791
1792	sd->brightness = BRIGHTNESS_DEF;
1793	sd->contrast = CONTRAST_DEF;
1794	sd->colors = COLOR_DEF;
1795	sd->blue = BLUE_BALANCE_DEF;
1796	sd->red = RED_BALANCE_DEF;
1797	sd->gamma = GAMMA_DEF;
1798	sd->autogain = AUTOGAIN_DEF;
1799	sd->ag_cnt = -1;
1800	sd->vflip = VFLIP_DEF;
1801	switch (sd->sensor) {
1802	case SENSOR_OM6802:
1803		sd->sharpness = 0x10;
1804		break;
1805	default:
1806		sd->sharpness = SHARPNESS_DEF;
1807		break;
1808	}
1809	sd->infrared = INFRARED_DEF;
1810	sd->freq = FREQ_DEF;
1811	sd->quality = QUALITY_DEF;
1812	sd->jpegqual = 80;
1813
1814	return 0;
1815}
1816
1817/* this function is called at probe and resume time */
1818static int sd_init(struct gspca_dev *gspca_dev)
1819{
1820	struct sd *sd = (struct sd *) gspca_dev;
1821	const u8 *sn9c1xx;
1822	u8 regGpio[] = { 0x29, 0x74 };		/* with audio */
1823	u8 regF1;
1824
1825	/* setup a selector by bridge */
1826	reg_w1(gspca_dev, 0xf1, 0x01);
1827	reg_r(gspca_dev, 0x00, 1);
1828	reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1829	reg_r(gspca_dev, 0x00, 1);		/* get sonix chip id */
1830	regF1 = gspca_dev->usb_buf[0];
1831	PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
1832	switch (sd->bridge) {
1833	case BRIDGE_SN9C102P:
1834		if (regF1 != 0x11)
1835			return -ENODEV;
1836		reg_w1(gspca_dev, 0x02, regGpio[1]);
1837		break;
1838	case BRIDGE_SN9C105:
1839		if (regF1 != 0x11)
1840			return -ENODEV;
1841		if (sd->sensor == SENSOR_MI0360)
1842			mi0360_probe(gspca_dev);
1843		reg_w(gspca_dev, 0x01, regGpio, 2);
1844		break;
1845	case BRIDGE_SN9C120:
1846		if (regF1 != 0x12)
1847			return -ENODEV;
1848		switch (sd->sensor) {
1849		case SENSOR_MI0360:
1850			mi0360_probe(gspca_dev);
1851			break;
1852		case SENSOR_OV7630:
1853			ov7630_probe(gspca_dev);
1854			break;
1855		case SENSOR_OV7648:
1856			ov7648_probe(gspca_dev);
1857			break;
1858		case SENSOR_PO2030N:
1859			po2030n_probe(gspca_dev);
1860			break;
1861		}
1862		regGpio[1] = 0x70;		/* no audio */
1863		reg_w(gspca_dev, 0x01, regGpio, 2);
1864		break;
1865	default:
1866/*	case BRIDGE_SN9C110: */
1867/*	case BRIDGE_SN9C325: */
1868		if (regF1 != 0x12)
1869			return -ENODEV;
1870		reg_w1(gspca_dev, 0x02, 0x62);
1871		break;
1872	}
1873
1874	/* Note we do not disable the sensor clock here (power saving mode),
1875	   as that also disables the button on the cam. */
1876	reg_w1(gspca_dev, 0xf1, 0x00);
1877
1878	/* set the i2c address */
1879	sn9c1xx = sn_tb[sd->sensor];
1880	sd->i2c_addr = sn9c1xx[9];
1881
1882	gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
1883
1884	return 0;
1885}
1886
1887static u32 setexposure(struct gspca_dev *gspca_dev,
1888			u32 expo)
1889{
1890	struct sd *sd = (struct sd *) gspca_dev;
1891
1892	switch (sd->sensor) {
1893	case SENSOR_GC0307: {
1894		int a, b;
1895
1896		/* expo = 0..255 -> a = 19..43 */
1897		a = 19 + expo * 25 / 256;
1898		i2c_w1(gspca_dev, 0x68, a);
1899		a -= 12;
1900		b = a * a * 4;			/* heuristic */
1901		i2c_w1(gspca_dev, 0x03, b >> 8);
1902		i2c_w1(gspca_dev, 0x04, b);
1903		break;
1904	    }
1905	case SENSOR_HV7131R: {
1906		u8 Expodoit[] =
1907			{ 0xc1, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16 };
1908
1909		Expodoit[3] = expo >> 16;
1910		Expodoit[4] = expo >> 8;
1911		Expodoit[5] = expo;
1912		i2c_w8(gspca_dev, Expodoit);
1913		break;
1914	    }
1915	case SENSOR_MI0360: {
1916		u8 expoMi[] =		/* exposure 0x0635 -> 4 fp/s 0x10 */
1917			{ 0xb1, 0x5d, 0x09, 0x00, 0x00, 0x00, 0x00, 0x16 };
1918		static const u8 doit[] =		/* update sensor */
1919			{ 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1920		static const u8 sensorgo[] =		/* sensor on */
1921			{ 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1922
1923		if (expo > 0x0635)
1924			expo = 0x0635;
1925		else if (expo < 0x0001)
1926			expo = 0x0001;
1927		expoMi[3] = expo >> 8;
1928		expoMi[4] = expo;
1929		i2c_w8(gspca_dev, expoMi);
1930		i2c_w8(gspca_dev, doit);
1931		i2c_w8(gspca_dev, sensorgo);
1932		break;
1933	    }
1934	case SENSOR_MO4000: {
1935		u8 expoMof[] =
1936			{ 0xa1, 0x21, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x10 };
1937		u8 expoMo10[] =
1938			{ 0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10 };
1939		static const u8 gainMo[] =
1940			{ 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1941
1942		if (expo > 0x1fff)
1943			expo = 0x1fff;
1944		else if (expo < 0x0001)
1945			expo = 0x0001;
1946		expoMof[3] = (expo & 0x03fc) >> 2;
1947		i2c_w8(gspca_dev, expoMof);
1948		expoMo10[3] = ((expo & 0x1c00) >> 10)
1949				| ((expo & 0x0003) << 4);
1950		i2c_w8(gspca_dev, expoMo10);
1951		i2c_w8(gspca_dev, gainMo);
1952		PDEBUG(D_FRAM, "set exposure %d",
1953			((expoMo10[3] & 0x07) << 10)
1954			| (expoMof[3] << 2)
1955			| ((expoMo10[3] & 0x30) >> 4));
1956		break;
1957	    }
1958	case SENSOR_MT9V111: {
1959		u8 expo_c1[] =
1960			{ 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1961
1962		if (expo > 0x0280)
1963			expo = 0x0280;
1964		else if (expo < 0x0040)
1965			expo = 0x0040;
1966		expo_c1[3] = expo >> 8;
1967		expo_c1[4] = expo;
1968		i2c_w8(gspca_dev, expo_c1);
1969		break;
1970	    }
1971	case SENSOR_OM6802: {
1972		u8 gainOm[] =
1973			{ 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1974				/* preset AGC - works when AutoExpo = off */
1975
1976		if (expo > 0x03ff)
1977			expo = 0x03ff;
1978		 if (expo < 0x0001)
1979			expo = 0x0001;
1980		gainOm[3] = expo >> 2;
1981		i2c_w8(gspca_dev, gainOm);
1982		reg_w1(gspca_dev, 0x96, expo >> 5);
1983		PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
1984		break;
1985	    }
1986	}
1987	return expo;
1988}
1989
1990static void setbrightness(struct gspca_dev *gspca_dev)
1991{
1992	struct sd *sd = (struct sd *) gspca_dev;
1993	unsigned int expo;
1994	u8 k2;
1995
1996	k2 = ((int) sd->brightness - 0x8000) >> 10;
1997	switch (sd->sensor) {
1998	case SENSOR_ADCM1700:
1999		if (k2 > 0x1f)
2000			k2 = 0;		/* only positive Y offset */
2001		break;
2002	case SENSOR_HV7131R:
2003		expo = sd->brightness << 4;
2004		if (expo > 0x002dc6c0)
2005			expo = 0x002dc6c0;
2006		else if (expo < 0x02a0)
2007			expo = 0x02a0;
2008		sd->exposure = setexposure(gspca_dev, expo);
2009		break;
2010	case SENSOR_MI0360:
2011	case SENSOR_MO4000:
2012		expo = sd->brightness >> 4;
2013		sd->exposure = setexposure(gspca_dev, expo);
2014		break;
2015	case SENSOR_GC0307:
2016	case SENSOR_MT9V111:
2017		expo = sd->brightness >> 8;
2018		sd->exposure = setexposure(gspca_dev, expo);
2019		return;			/* don't set the Y offset */
2020	case SENSOR_OM6802:
2021		expo = sd->brightness >> 6;
2022		sd->exposure = setexposure(gspca_dev, expo);
2023		k2 = sd->brightness >> 11;
2024		break;
2025	}
2026
2027	reg_w1(gspca_dev, 0x96, k2);	/* color matrix Y offset */
2028}
2029
2030static void setcontrast(struct gspca_dev *gspca_dev)
2031{
2032	struct sd *sd = (struct sd *) gspca_dev;
2033	u8 k2;
2034	u8 contrast[6];
2035
2036	k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10;	/* 10..40 */
2037	contrast[0] = (k2 + 1) / 2;		/* red */
2038	contrast[1] = 0;
2039	contrast[2] = k2;			/* green */
2040	contrast[3] = 0;
2041	contrast[4] = (k2 + 1) / 5;		/* blue */
2042	contrast[5] = 0;
2043	reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
2044}
2045
2046static void setcolors(struct gspca_dev *gspca_dev)
2047{
2048	struct sd *sd = (struct sd *) gspca_dev;
2049	int i, v;
2050	u8 reg8a[12];			/* U & V gains */
2051	static const s16 uv[6] = {	/* same as reg84 in signed decimal */
2052		-24, -38, 64,		/* UR UG UB */
2053		 62, -51, -9		/* VR VG VB */
2054	};
2055
2056	for (i = 0; i < 6; i++) {
2057		v = uv[i] * sd->colors / COLOR_DEF;
2058		reg8a[i * 2] = v;
2059		reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
2060	}
2061	reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
2062}
2063
2064static void setredblue(struct gspca_dev *gspca_dev)
2065{
2066	struct sd *sd = (struct sd *) gspca_dev;
2067
2068	reg_w1(gspca_dev, 0x05, sd->red);
2069/*	reg_w1(gspca_dev, 0x07, 32); */
2070	reg_w1(gspca_dev, 0x06, sd->blue);
2071}
2072
2073static void setgamma(struct gspca_dev *gspca_dev)
2074{
2075	struct sd *sd = (struct sd *) gspca_dev;
2076	int i;
2077	u8 gamma[17];
2078	const u8 *gamma_base;
2079	static const u8 delta[17] = {
2080		0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
2081		0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
2082	};
2083
2084	switch (sd->sensor) {
2085	case SENSOR_ADCM1700:
2086		gamma_base = gamma_spec_0;
2087		break;
2088	case SENSOR_HV7131R:
2089	case SENSOR_MT9V111:
2090		gamma_base = gamma_spec_1;
2091		break;
2092	case SENSOR_GC0307:
2093		gamma_base = gamma_spec_2;
2094		break;
2095	case SENSOR_SP80708:
2096		gamma_base = gamma_spec_3;
2097		break;
2098	default:
2099		gamma_base = gamma_def;
2100		break;
2101	}
2102
2103	for (i = 0; i < sizeof gamma; i++)
2104		gamma[i] = gamma_base[i]
2105			+ delta[i] * (sd->gamma - GAMMA_DEF) / 32;
2106	reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
2107}
2108
2109static void setautogain(struct gspca_dev *gspca_dev)
2110{
2111	struct sd *sd = (struct sd *) gspca_dev;
2112
2113	if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
2114		return;
2115	switch (sd->sensor) {
2116	case SENSOR_OV7630:
2117	case SENSOR_OV7648: {
2118		u8 comb;
2119
2120		if (sd->sensor == SENSOR_OV7630)
2121			comb = 0xc0;
2122		else
2123			comb = 0xa0;
2124		if (sd->autogain)
2125			comb |= 0x03;
2126		i2c_w1(&sd->gspca_dev, 0x13, comb);
2127		return;
2128	    }
2129	}
2130	if (sd->autogain)
2131		sd->ag_cnt = AG_CNT_START;
2132	else
2133		sd->ag_cnt = -1;
2134}
2135
2136/* hv7131r/ov7630/ov7648 only */
2137static void setvflip(struct sd *sd)
2138{
2139	u8 comn;
2140
2141	if (sd->gspca_dev.ctrl_dis & (1 << VFLIP_IDX))
2142		return;
2143	switch (sd->sensor) {
2144	case SENSOR_HV7131R:
2145		comn = 0x18;			/* clkdiv = 1, ablcen = 1 */
2146		if (sd->vflip)
2147			comn |= 0x01;
2148		i2c_w1(&sd->gspca_dev, 0x01, comn);	/* sctra */
2149		break;
2150	case SENSOR_OV7630:
2151		comn = 0x02;
2152		if (!sd->vflip)
2153			comn |= 0x80;
2154		i2c_w1(&sd->gspca_dev, 0x75, comn);
2155		break;
2156	default:
2157/*	case SENSOR_OV7648: */
2158		comn = 0x06;
2159		if (sd->vflip)
2160			comn |= 0x80;
2161		i2c_w1(&sd->gspca_dev, 0x75, comn);
2162		break;
2163	}
2164}
2165
2166static void setsharpness(struct sd *sd)
2167{
2168	reg_w1(&sd->gspca_dev, 0x99, sd->sharpness);
2169}
2170
2171static void setinfrared(struct sd *sd)
2172{
2173	if (sd->gspca_dev.ctrl_dis & (1 << INFRARED_IDX))
2174		return;
2175/* Clip */
2176	i2c_w1(&sd->gspca_dev, 0x02,			/* gpio */
2177		sd->infrared ? 0x66 : 0x64);
2178}
2179
2180static void setfreq(struct gspca_dev *gspca_dev)
2181{
2182	struct sd *sd = (struct sd *) gspca_dev;
2183
2184	if (gspca_dev->ctrl_dis & (1 << FREQ_IDX))
2185		return;
2186	if (sd->sensor == SENSOR_OV7660) {
2187		u8 com8;
2188
2189		com8 = 0xdf;		/* auto gain/wb/expo */
2190		switch (sd->freq) {
2191		case 0: /* Banding filter disabled */
2192			i2c_w1(gspca_dev, 0x13, com8 | 0x20);
2193			break;
2194		case 1: /* 50 hz */
2195			i2c_w1(gspca_dev, 0x13, com8);
2196			i2c_w1(gspca_dev, 0x3b, 0x0a);
2197			break;
2198		case 2: /* 60 hz */
2199			i2c_w1(gspca_dev, 0x13, com8);
2200			i2c_w1(gspca_dev, 0x3b, 0x02);
2201			break;
2202		}
2203	} else {
2204		u8 reg2a = 0, reg2b = 0, reg2d = 0;
2205
2206		/* Get reg2a / reg2d base values */
2207		switch (sd->sensor) {
2208		case SENSOR_OV7630:
2209			reg2a = 0x08;
2210			reg2d = 0x01;
2211			break;
2212		case SENSOR_OV7648:
2213			reg2a = 0x11;
2214			reg2d = 0x81;
2215			break;
2216		}
2217
2218		switch (sd->freq) {
2219		case 0: /* Banding filter disabled */
2220			break;
2221		case 1: /* 50 hz (filter on and framerate adj) */
2222			reg2a |= 0x80;
2223			reg2b = 0xac;
2224			reg2d |= 0x04;
2225			break;
2226		case 2: /* 60 hz (filter on, no framerate adj) */
2227			reg2a |= 0x80;
2228			reg2d |= 0x04;
2229			break;
2230		}
2231		i2c_w1(gspca_dev, 0x2a, reg2a);
2232		i2c_w1(gspca_dev, 0x2b, reg2b);
2233		i2c_w1(gspca_dev, 0x2d, reg2d);
2234	}
2235}
2236
2237static void setjpegqual(struct gspca_dev *gspca_dev)
2238{
2239	struct sd *sd = (struct sd *) gspca_dev;
2240	int i, sc;
2241
2242	if (sd->jpegqual < 50)
2243		sc = 5000 / sd->jpegqual;
2244	else
2245		sc = 200 - sd->jpegqual * 2;
2246#if USB_BUF_SZ < 64
2247#error "No room enough in usb_buf for quantization table"
2248#endif
2249	for (i = 0; i < 64; i++)
2250		gspca_dev->usb_buf[i] =
2251			(jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100;
2252	usb_control_msg(gspca_dev->dev,
2253			usb_sndctrlpipe(gspca_dev->dev, 0),
2254			0x08,
2255			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
2256			0x0100, 0,
2257			gspca_dev->usb_buf, 64,
2258			500);
2259	for (i = 0; i < 64; i++)
2260		gspca_dev->usb_buf[i] =
2261			(jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100;
2262	usb_control_msg(gspca_dev->dev,
2263			usb_sndctrlpipe(gspca_dev->dev, 0),
2264			0x08,
2265			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
2266			0x0140, 0,
2267			gspca_dev->usb_buf, 64,
2268			500);
2269
2270	sd->reg18 ^= 0x40;
2271	reg_w1(gspca_dev, 0x18, sd->reg18);
2272}
2273
2274/* -- start the camera -- */
2275static int sd_start(struct gspca_dev *gspca_dev)
2276{
2277	struct sd *sd = (struct sd *) gspca_dev;
2278	int i;
2279	u8 reg1, reg17;
2280	const u8 *sn9c1xx;
2281	const u8 (*init)[8];
2282	int mode;
2283	static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
2284	static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
2285	static const u8 CA_adcm1700[] =
2286				{ 0x14, 0xec, 0x0a, 0xf6 };
2287	static const u8 CA_po2030n[] =
2288				{ 0x1e, 0xe2, 0x14, 0xec };
2289	static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd };	/* MI0360 */
2290	static const u8 CE_gc0307[] =
2291				{ 0x32, 0xce, 0x2d, 0xd3 };
2292	static const u8 CE_ov76xx[] =
2293				{ 0x32, 0xdd, 0x32, 0xdd };
2294	static const u8 CE_po2030n[] =
2295				{ 0x14, 0xe7, 0x1e, 0xdd };
2296
2297	/* create the JPEG header */
2298	jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
2299			0x21);		/* JPEG 422 */
2300	jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2301
2302	/* initialize the bridge */
2303	sn9c1xx = sn_tb[sd->sensor];
2304	bridge_init(gspca_dev, sn9c1xx);
2305
2306	/* initialize the sensor */
2307	i2c_w_seq(gspca_dev, sensor_init[sd->sensor]);
2308
2309	reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
2310	reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
2311	reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
2312	reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
2313	reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
2314	if (sd->sensor == SENSOR_ADCM1700) {
2315		reg_w1(gspca_dev, 0xd2, 0x3a);	/* AE_H_SIZE = 116 */
2316		reg_w1(gspca_dev, 0xd3, 0x30);	/* AE_V_SIZE = 96 */
2317	} else {
2318		reg_w1(gspca_dev, 0xd2, 0x6a);	/* AE_H_SIZE = 212 */
2319		reg_w1(gspca_dev, 0xd3, 0x50);	/* AE_V_SIZE = 160 */
2320	}
2321	reg_w1(gspca_dev, 0xc6, 0x00);
2322	reg_w1(gspca_dev, 0xc7, 0x00);
2323	if (sd->sensor == SENSOR_ADCM1700) {
2324		reg_w1(gspca_dev, 0xc8, 0x2c);	/* AW_H_STOP = 352 */
2325		reg_w1(gspca_dev, 0xc9, 0x24);	/* AW_V_STOP = 288 */
2326	} else {
2327		reg_w1(gspca_dev, 0xc8, 0x50);	/* AW_H_STOP = 640 */
2328		reg_w1(gspca_dev, 0xc9, 0x3c);	/* AW_V_STOP = 480 */
2329	}
2330	reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
2331	switch (sd->sensor) {
2332	case SENSOR_GC0307:
2333		reg17 = 0xa2;
2334		break;
2335	case SENSOR_MT9V111:
2336		reg17 = 0xe0;
2337		break;
2338	case SENSOR_ADCM1700:
2339	case SENSOR_OV7630:
2340		reg17 = 0xe2;
2341		break;
2342	case SENSOR_OV7648:
2343		reg17 = 0x20;
2344		break;
2345	case SENSOR_OV7660:
2346	case SENSOR_SOI768:
2347		reg17 = 0xa0;
2348		break;
2349	case SENSOR_PO1030:
2350	case SENSOR_PO2030N:
2351		reg17 = 0xa0;
2352		break;
2353	default:
2354		reg17 = 0x60;
2355		break;
2356	}
2357	reg_w1(gspca_dev, 0x17, reg17);
2358
2359	reg_w1(gspca_dev, 0x05, 0x00);		/* red */
2360	reg_w1(gspca_dev, 0x07, 0x00);		/* green */
2361	reg_w1(gspca_dev, 0x06, 0x00);		/* blue */
2362	reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
2363
2364	setgamma(gspca_dev);
2365
2366	for (i = 0; i < 8; i++)
2367		reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
2368	switch (sd->sensor) {
2369	case SENSOR_ADCM1700:
2370	case SENSOR_OV7660:
2371	case SENSOR_SP80708:
2372		reg_w1(gspca_dev, 0x9a, 0x05);
2373		break;
2374	case SENSOR_GC0307:
2375	case SENSOR_MT9V111:
2376		reg_w1(gspca_dev, 0x9a, 0x07);
2377		break;
2378	case SENSOR_OV7630:
2379	case SENSOR_OV7648:
2380		reg_w1(gspca_dev, 0x9a, 0x0a);
2381		break;
2382	case SENSOR_PO2030N:
2383	case SENSOR_SOI768:
2384		reg_w1(gspca_dev, 0x9a, 0x06);
2385		break;
2386	default:
2387		reg_w1(gspca_dev, 0x9a, 0x08);
2388		break;
2389	}
2390	setsharpness(sd);
2391
2392	reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
2393	reg_w1(gspca_dev, 0x05, 0x20);		/* red */
2394	reg_w1(gspca_dev, 0x07, 0x20);		/* green */
2395	reg_w1(gspca_dev, 0x06, 0x20);		/* blue */
2396
2397	init = NULL;
2398	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
2399	if (mode)
2400		reg1 = 0x46;	/* 320x240: clk 48Mhz, video trf enable */
2401	else
2402		reg1 = 0x06;	/* 640x480: clk 24Mhz, video trf enable */
2403	reg17 = 0x61;		/* 0x:20: enable sensor clock */
2404	switch (sd->sensor) {
2405	case SENSOR_ADCM1700:
2406		init = adcm1700_sensor_param1;
2407		reg1 = 0x46;
2408		reg17 = 0xe2;
2409		break;
2410	case SENSOR_GC0307:
2411		init = gc0307_sensor_param1;
2412		reg17 = 0xa2;
2413		reg1 = 0x44;
2414		break;
2415	case SENSOR_MO4000:
2416		if (mode) {
2417/*			reg1 = 0x46;	 * 320 clk 48Mhz 60fp/s */
2418			reg1 = 0x06;	/* clk 24Mz */
2419		} else {
2420			reg17 = 0x22;	/* 640 MCKSIZE */
2421/*			reg1 = 0x06;	 * 640 clk 24Mz (done) */
2422		}
2423		break;
2424	case SENSOR_MT9V111:
2425		init = mt9v111_sensor_param1;
2426		if (mode) {
2427			reg1 = 0x04;	/* 320 clk 48Mhz */
2428		} else {
2429/*			reg1 = 0x06;	 * 640 clk 24Mz (done) */
2430			reg17 = 0xc2;
2431		}
2432		break;
2433	case SENSOR_OM6802:
2434		init = om6802_sensor_param1;
2435		reg17 = 0x64;		/* 640 MCKSIZE */
2436		break;
2437	case SENSOR_OV7630:
2438		init = ov7630_sensor_param1;
2439		reg17 = 0xe2;
2440		reg1 = 0x44;
2441		break;
2442	case SENSOR_OV7648:
2443		init = ov7648_sensor_param1;
2444		reg17 = 0x21;
2445/*		reg1 = 0x42;		 * 42 - 46? */
2446		break;
2447	case SENSOR_OV7660:
2448		init = ov7660_sensor_param1;
2449		if (sd->bridge == BRIDGE_SN9C120) {
2450			if (mode) {		/* 320x240 - 160x120 */
2451				reg17 = 0xa2;
2452				reg1 = 0x44;	/* 48 Mhz, video trf eneble */
2453			}
2454		} else {
2455			reg17 = 0x22;
2456			reg1 = 0x06;	/* 24 Mhz, video trf eneble
2457					 * inverse power down */
2458		}
2459		break;
2460	case SENSOR_PO1030:
2461		init = po1030_sensor_param1;
2462		reg17 = 0xa2;
2463		reg1 = 0x44;
2464		break;
2465	case SENSOR_PO2030N:
2466		init = po2030n_sensor_param1;
2467		reg1 = 0x46;
2468		reg17 = 0xa2;
2469		break;
2470	case SENSOR_SOI768:
2471		init = soi768_sensor_param1;
2472		reg1 = 0x44;
2473		reg17 = 0xa2;
2474		break;
2475	case SENSOR_SP80708:
2476		init = sp80708_sensor_param1;
2477		if (mode) {
2478/*??			reg1 = 0x04;	 * 320 clk 48Mhz */
2479		} else {
2480			reg1 = 0x46;	 /* 640 clk 48Mz */
2481			reg17 = 0xa2;
2482		}
2483		break;
2484	}
2485
2486	/* more sensor initialization - param1 */
2487	if (init != NULL) {
2488		i2c_w_seq(gspca_dev, init);
2489/*		init = NULL; */
2490	}
2491
2492	reg_w(gspca_dev, 0xc0, C0, 6);
2493	switch (sd->sensor) {
2494	case SENSOR_ADCM1700:
2495	case SENSOR_GC0307:
2496	case SENSOR_SOI768:
2497		reg_w(gspca_dev, 0xca, CA_adcm1700, 4);
2498		break;
2499	case SENSOR_PO2030N:
2500		reg_w(gspca_dev, 0xca, CA_po2030n, 4);
2501		break;
2502	default:
2503		reg_w(gspca_dev, 0xca, CA, 4);
2504		break;
2505	}
2506	switch (sd->sensor) {
2507	case SENSOR_ADCM1700:
2508	case SENSOR_OV7630:
2509	case SENSOR_OV7648:
2510	case SENSOR_OV7660:
2511	case SENSOR_SOI768:
2512		reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
2513		break;
2514	case SENSOR_GC0307:
2515		reg_w(gspca_dev, 0xce, CE_gc0307, 4);
2516		break;
2517	case SENSOR_PO2030N:
2518		reg_w(gspca_dev, 0xce, CE_po2030n, 4);
2519		break;
2520	default:
2521		reg_w(gspca_dev, 0xce, CE, 4);
2522					/* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
2523		break;
2524	}
2525
2526
2527	/* here change size mode 0 -> VGA; 1 -> CIF */
2528	sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40;
2529	reg_w1(gspca_dev, 0x18, sd->reg18);
2530	setjpegqual(gspca_dev);
2531
2532	reg_w1(gspca_dev, 0x17, reg17);
2533	reg_w1(gspca_dev, 0x01, reg1);
2534
2535	setvflip(sd);
2536	setbrightness(gspca_dev);
2537	setcontrast(gspca_dev);
2538	setcolors(gspca_dev);
2539	setautogain(gspca_dev);
2540	setfreq(gspca_dev);
2541	return 0;
2542}
2543
2544static void sd_stopN(struct gspca_dev *gspca_dev)
2545{
2546	struct sd *sd = (struct sd *) gspca_dev;
2547	static const u8 stophv7131[] =
2548		{ 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
2549	static const u8 stopmi0360[] =
2550		{ 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
2551	static const u8 stopov7648[] =
2552		{ 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
2553	static const u8 stopsoi768[] =
2554		{ 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 };
2555	u8 data;
2556	const u8 *sn9c1xx;
2557
2558	data = 0x0b;
2559	switch (sd->sensor) {
2560	case SENSOR_GC0307:
2561		data = 0x29;
2562		break;
2563	case SENSOR_HV7131R:
2564		i2c_w8(gspca_dev, stophv7131);
2565		data = 0x2b;
2566		break;
2567	case SENSOR_MI0360:
2568		i2c_w8(gspca_dev, stopmi0360);
2569		data = 0x29;
2570		break;
2571	case SENSOR_OV7648:
2572		i2c_w8(gspca_dev, stopov7648);
2573		/* fall thru */
2574	case SENSOR_MT9V111:
2575	case SENSOR_OV7630:
2576	case SENSOR_PO1030:
2577		data = 0x29;
2578		break;
2579	case SENSOR_SOI768:
2580		i2c_w8(gspca_dev, stopsoi768);
2581		data = 0x29;
2582		break;
2583	}
2584	sn9c1xx = sn_tb[sd->sensor];
2585	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
2586	reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
2587	reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
2588	reg_w1(gspca_dev, 0x01, data);
2589	/* Don't disable sensor clock as that disables the button on the cam */
2590	/* reg_w1(gspca_dev, 0xf1, 0x01); */
2591}
2592
2593static void do_autogain(struct gspca_dev *gspca_dev)
2594{
2595	struct sd *sd = (struct sd *) gspca_dev;
2596	int delta;
2597	int expotimes;
2598	u8 luma_mean = 130;
2599	u8 luma_delta = 20;
2600
2601	/* Thanks S., without your advice, autobright should not work :) */
2602	if (sd->ag_cnt < 0)
2603		return;
2604	if (--sd->ag_cnt >= 0)
2605		return;
2606	sd->ag_cnt = AG_CNT_START;
2607
2608	delta = atomic_read(&sd->avg_lum);
2609	PDEBUG(D_FRAM, "mean lum %d", delta);
2610	if (delta < luma_mean - luma_delta ||
2611	    delta > luma_mean + luma_delta) {
2612		switch (sd->sensor) {
2613		case SENSOR_GC0307:
2614			expotimes = sd->exposure;
2615			expotimes += (luma_mean - delta) >> 6;
2616			if (expotimes < 0)
2617				expotimes = 0;
2618			sd->exposure = setexposure(gspca_dev,
2619						   (unsigned int) expotimes);
2620			break;
2621		case SENSOR_HV7131R:
2622			expotimes = sd->exposure >> 8;
2623			expotimes += (luma_mean - delta) >> 4;
2624			if (expotimes < 0)
2625				expotimes = 0;
2626			sd->exposure = setexposure(gspca_dev,
2627					(unsigned int) (expotimes << 8));
2628			break;
2629		case SENSOR_OM6802:
2630			expotimes = sd->exposure;
2631			expotimes += (luma_mean - delta) >> 2;
2632			if (expotimes < 0)
2633				expotimes = 0;
2634			sd->exposure = setexposure(gspca_dev,
2635						   (unsigned int) expotimes);
2636			setredblue(gspca_dev);
2637			break;
2638		default:
2639/*		case SENSOR_MO4000: */
2640/*		case SENSOR_MI0360: */
2641/*		case SENSOR_MT9V111: */
2642			expotimes = sd->exposure;
2643			expotimes += (luma_mean - delta) >> 6;
2644			if (expotimes < 0)
2645				expotimes = 0;
2646			sd->exposure = setexposure(gspca_dev,
2647						   (unsigned int) expotimes);
2648			setredblue(gspca_dev);
2649			break;
2650		}
2651	}
2652}
2653
2654/* scan the URB packets */
2655/* This function is run at interrupt level. */
2656static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2657			u8 *data,			/* isoc packet */
2658			int len)			/* iso packet length */
2659{
2660	struct sd *sd = (struct sd *) gspca_dev;
2661	int sof, avg_lum;
2662
2663	sof = len - 64;
2664	if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
2665
2666		/* end of frame */
2667		gspca_frame_add(gspca_dev, LAST_PACKET,
2668				data, sof + 2);
2669		if (sd->ag_cnt < 0)
2670			return;
2671/* w1 w2 w3 */
2672/* w4 w5 w6 */
2673/* w7 w8 */
2674/* w4 */
2675		avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
2676/* w6 */
2677		avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
2678/* w2 */
2679		avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
2680/* w8 */
2681		avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
2682/* w5 */
2683		avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
2684		avg_lum >>= 4;
2685		atomic_set(&sd->avg_lum, avg_lum);
2686		return;
2687	}
2688	if (gspca_dev->last_packet_type == LAST_PACKET) {
2689
2690		/* put the JPEG 422 header */
2691		gspca_frame_add(gspca_dev, FIRST_PACKET,
2692			sd->jpeg_hdr, JPEG_HDR_SZ);
2693	}
2694	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2695}
2696
2697static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
2698{
2699	struct sd *sd = (struct sd *) gspca_dev;
2700
2701	sd->brightness = val;
2702	if (gspca_dev->streaming)
2703		setbrightness(gspca_dev);
2704	return 0;
2705}
2706
2707static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
2708{
2709	struct sd *sd = (struct sd *) gspca_dev;
2710
2711	*val = sd->brightness;
2712	return 0;
2713}
2714
2715static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
2716{
2717	struct sd *sd = (struct sd *) gspca_dev;
2718
2719	sd->contrast = val;
2720	if (gspca_dev->streaming)
2721		setcontrast(gspca_dev);
2722	return 0;
2723}
2724
2725static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
2726{
2727	struct sd *sd = (struct sd *) gspca_dev;
2728
2729	*val = sd->contrast;
2730	return 0;
2731}
2732
2733static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
2734{
2735	struct sd *sd = (struct sd *) gspca_dev;
2736
2737	sd->colors = val;
2738	if (gspca_dev->streaming)
2739		setcolors(gspca_dev);
2740	return 0;
2741}
2742
2743static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
2744{
2745	struct sd *sd = (struct sd *) gspca_dev;
2746
2747	*val = sd->colors;
2748	return 0;
2749}
2750
2751static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
2752{
2753	struct sd *sd = (struct sd *) gspca_dev;
2754
2755	sd->blue = val;
2756	if (gspca_dev->streaming)
2757		setredblue(gspca_dev);
2758	return 0;
2759}
2760
2761static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
2762{
2763	struct sd *sd = (struct sd *) gspca_dev;
2764
2765	*val = sd->blue;
2766	return 0;
2767}
2768
2769static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
2770{
2771	struct sd *sd = (struct sd *) gspca_dev;
2772
2773	sd->red = val;
2774	if (gspca_dev->streaming)
2775		setredblue(gspca_dev);
2776	return 0;
2777}
2778
2779static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
2780{
2781	struct sd *sd = (struct sd *) gspca_dev;
2782
2783	*val = sd->red;
2784	return 0;
2785}
2786
2787static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
2788{
2789	struct sd *sd = (struct sd *) gspca_dev;
2790
2791	sd->gamma = val;
2792	if (gspca_dev->streaming)
2793		setgamma(gspca_dev);
2794	return 0;
2795}
2796
2797static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
2798{
2799	struct sd *sd = (struct sd *) gspca_dev;
2800
2801	*val = sd->gamma;
2802	return 0;
2803}
2804
2805static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2806{
2807	struct sd *sd = (struct sd *) gspca_dev;
2808
2809	sd->autogain = val;
2810	if (gspca_dev->streaming)
2811		setautogain(gspca_dev);
2812	return 0;
2813}
2814
2815static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
2816{
2817	struct sd *sd = (struct sd *) gspca_dev;
2818
2819	*val = sd->autogain;
2820	return 0;
2821}
2822
2823static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
2824{
2825	struct sd *sd = (struct sd *) gspca_dev;
2826
2827	sd->sharpness = val;
2828	if (gspca_dev->streaming)
2829		setsharpness(sd);
2830	return 0;
2831}
2832
2833static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
2834{
2835	struct sd *sd = (struct sd *) gspca_dev;
2836
2837	*val = sd->sharpness;
2838	return 0;
2839}
2840
2841static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2842{
2843	struct sd *sd = (struct sd *) gspca_dev;
2844
2845	sd->vflip = val;
2846	if (gspca_dev->streaming)
2847		setvflip(sd);
2848	return 0;
2849}
2850
2851static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2852{
2853	struct sd *sd = (struct sd *) gspca_dev;
2854
2855	*val = sd->vflip;
2856	return 0;
2857}
2858
2859static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
2860{
2861	struct sd *sd = (struct sd *) gspca_dev;
2862
2863	sd->infrared = val;
2864	if (gspca_dev->streaming)
2865		setinfrared(sd);
2866	return 0;
2867}
2868
2869static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
2870{
2871	struct sd *sd = (struct sd *) gspca_dev;
2872
2873	*val = sd->infrared;
2874	return 0;
2875}
2876
2877static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
2878{
2879	struct sd *sd = (struct sd *) gspca_dev;
2880
2881	sd->freq = val;
2882	if (gspca_dev->streaming)
2883		setfreq(gspca_dev);
2884	return 0;
2885}
2886
2887static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
2888{
2889	struct sd *sd = (struct sd *) gspca_dev;
2890
2891	*val = sd->freq;
2892	return 0;
2893}
2894
2895static int sd_set_jcomp(struct gspca_dev *gspca_dev,
2896			struct v4l2_jpegcompression *jcomp)
2897{
2898	struct sd *sd = (struct sd *) gspca_dev;
2899
2900	if (jcomp->quality < QUALITY_MIN)
2901		sd->quality = QUALITY_MIN;
2902	else if (jcomp->quality > QUALITY_MAX)
2903		sd->quality = QUALITY_MAX;
2904	else
2905		sd->quality = jcomp->quality;
2906	if (gspca_dev->streaming)
2907		jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2908	return 0;
2909}
2910
2911static int sd_get_jcomp(struct gspca_dev *gspca_dev,
2912			struct v4l2_jpegcompression *jcomp)
2913{
2914	struct sd *sd = (struct sd *) gspca_dev;
2915
2916	memset(jcomp, 0, sizeof *jcomp);
2917	jcomp->quality = sd->quality;
2918	jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
2919			| V4L2_JPEG_MARKER_DQT;
2920	return 0;
2921}
2922
2923static int sd_querymenu(struct gspca_dev *gspca_dev,
2924			struct v4l2_querymenu *menu)
2925{
2926	switch (menu->id) {
2927	case V4L2_CID_POWER_LINE_FREQUENCY:
2928		switch (menu->index) {
2929		case 0:		/* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
2930			strcpy((char *) menu->name, "NoFliker");
2931			return 0;
2932		case 1:		/* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2933			strcpy((char *) menu->name, "50 Hz");
2934			return 0;
2935		case 2:		/* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2936			strcpy((char *) menu->name, "60 Hz");
2937			return 0;
2938		}
2939		break;
2940	}
2941	return -EINVAL;
2942}
2943
2944#ifdef CONFIG_INPUT
2945static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2946			u8 *data,		/* interrupt packet data */
2947			int len)		/* interrupt packet length */
2948{
2949	int ret = -EINVAL;
2950
2951	if (len == 1 && data[0] == 1) {
2952		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2953		input_sync(gspca_dev->input_dev);
2954		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2955		input_sync(gspca_dev->input_dev);
2956		ret = 0;
2957	}
2958
2959	return ret;
2960}
2961#endif
2962
2963/* sub-driver description */
2964static const struct sd_desc sd_desc = {
2965	.name = MODULE_NAME,
2966	.ctrls = sd_ctrls,
2967	.nctrls = ARRAY_SIZE(sd_ctrls),
2968	.config = sd_config,
2969	.init = sd_init,
2970	.start = sd_start,
2971	.stopN = sd_stopN,
2972	.pkt_scan = sd_pkt_scan,
2973	.dq_callback = do_autogain,
2974	.get_jcomp = sd_get_jcomp,
2975	.set_jcomp = sd_set_jcomp,
2976	.querymenu = sd_querymenu,
2977#ifdef CONFIG_INPUT
2978	.int_pkt_scan = sd_int_pkt_scan,
2979#endif
2980};
2981
2982/* -- module initialisation -- */
2983#define BS(bridge, sensor) \
2984	.driver_info = (BRIDGE_ ## bridge << 16) \
2985			| (SENSOR_ ## sensor << 8)
2986#define BSF(bridge, sensor, flags) \
2987	.driver_info = (BRIDGE_ ## bridge << 16) \
2988			| (SENSOR_ ## sensor << 8) \
2989			| (flags)
2990static const __devinitdata struct usb_device_id device_table[] = {
2991#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2992	{USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)},
2993	{USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)},
2994#endif
2995	{USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, PDN_INV)},
2996	{USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, PDN_INV)},
2997	{USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)},
2998	{USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)},
2999	{USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)},
3000	{USB_DEVICE(0x06f8, 0x3004), BS(SN9C105, OV7660)},
3001	{USB_DEVICE(0x06f8, 0x3008), BS(SN9C105, OV7660)},
3002/*	{USB_DEVICE(0x0c45, 0x603a), BS(SN9C102P, OV7648)}, */
3003	{USB_DEVICE(0x0c45, 0x6040), BS(SN9C102P, HV7131R)},
3004/*	{USB_DEVICE(0x0c45, 0x607a), BS(SN9C102P, OV7648)}, */
3005/*	{USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */
3006	{USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)},
3007/*	{USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */
3008	{USB_DEVICE(0x0c45, 0x60c0), BS(SN9C105, MI0360)},
3009/*	{USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
3010/*	{USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
3011/*	{USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */
3012	{USB_DEVICE(0x0c45, 0x60ce), BS(SN9C105, SP80708)},
3013	{USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)},
3014/*	{USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */
3015/*	{USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */
3016/*	{USB_DEVICE(0x0c45, 0x60f2), BS(SN9C105, OV7660)}, */
3017	{USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)},
3018#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
3019	{USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)},
3020	{USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)},
3021#endif
3022	{USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)},	/*sn9c128*/
3023/*	{USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, PO2030N)}, * / GC0305*/
3024/*	{USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */
3025	{USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)},	/*sn9c128*/
3026	{USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)},	/*sn9c128*/
3027	{USB_DEVICE(0x0c45, 0x610c), BS(SN9C120, HV7131R)},	/*sn9c128*/
3028	{USB_DEVICE(0x0c45, 0x610e), BS(SN9C120, OV7630)},	/*sn9c128*/
3029/*	{USB_DEVICE(0x0c45, 0x610f), BS(SN9C120, S5K53BEB)}, */
3030/*	{USB_DEVICE(0x0c45, 0x6122), BS(SN9C110, ICM105C)}, */
3031/*	{USB_DEVICE(0x0c45, 0x6123), BS(SN9C110, SanyoCCD)}, */
3032	{USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)},	/*sn9c325?*/
3033/*bw600.inf:*/
3034	{USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)},	/*sn9c325?*/
3035	{USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)},
3036	{USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)},
3037/*	{USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */
3038#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
3039	{USB_DEVICE(0x0c45, 0x6130), BS(SN9C120, MI0360)},
3040#endif
3041/*	{USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */
3042	{USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)},
3043	{USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)},
3044#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
3045	{USB_DEVICE(0x0c45, 0x613b), BS(SN9C120, OV7660)},
3046#endif
3047	{USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)},
3048	{USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)},
3049	{USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)},	/*sn9c120b*/
3050						/* or GC0305 / GC0307 */
3051	{USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)},	/*sn9c120b*/
3052	{USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)},	/*sn9c120b*/
3053	{USB_DEVICE(0x0c45, 0x614a), BS(SN9C120, ADCM1700)},	/*sn9c120b*/
3054	{}
3055};
3056MODULE_DEVICE_TABLE(usb, device_table);
3057
3058/* -- device connect -- */
3059static int sd_probe(struct usb_interface *intf,
3060		    const struct usb_device_id *id)
3061{
3062	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
3063				THIS_MODULE);
3064}
3065
3066static struct usb_driver sd_driver = {
3067	.name = MODULE_NAME,
3068	.id_table = device_table,
3069	.probe = sd_probe,
3070	.disconnect = gspca_disconnect,
3071#ifdef CONFIG_PM
3072	.suspend = gspca_suspend,
3073	.resume = gspca_resume,
3074#endif
3075};
3076
3077/* -- module insert / remove -- */
3078static int __init sd_mod_init(void)
3079{
3080	int ret;
3081	ret = usb_register(&sd_driver);
3082	if (ret < 0)
3083		return ret;
3084	info("registered");
3085	return 0;
3086}
3087static void __exit sd_mod_exit(void)
3088{
3089	usb_deregister(&sd_driver);
3090	info("deregistered");
3091}
3092
3093module_init(sd_mod_init);
3094module_exit(sd_mod_exit);
3095