xref: /OK3568_Linux_fs/kernel/drivers/media/usb/gspca/spca508.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * SPCA508 chip based cameras subdriver
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2009 Jean-Francois Moine <http://moinejf.free.fr>
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #define MODULE_NAME "spca508"
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include "gspca.h"
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
15*4882a593Smuzhiyun MODULE_DESCRIPTION("GSPCA/SPCA508 USB Camera Driver");
16*4882a593Smuzhiyun MODULE_LICENSE("GPL");
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun /* specific webcam descriptor */
19*4882a593Smuzhiyun struct sd {
20*4882a593Smuzhiyun 	struct gspca_dev gspca_dev;		/* !! must be the first item */
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun 	u8 subtype;
23*4882a593Smuzhiyun #define CreativeVista 0
24*4882a593Smuzhiyun #define HamaUSBSightcam 1
25*4882a593Smuzhiyun #define HamaUSBSightcam2 2
26*4882a593Smuzhiyun #define IntelEasyPCCamera 3
27*4882a593Smuzhiyun #define MicroInnovationIC200 4
28*4882a593Smuzhiyun #define ViewQuestVQ110 5
29*4882a593Smuzhiyun };
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun static const struct v4l2_pix_format sif_mode[] = {
32*4882a593Smuzhiyun 	{160, 120, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
33*4882a593Smuzhiyun 		.bytesperline = 160,
34*4882a593Smuzhiyun 		.sizeimage = 160 * 120 * 3 / 2,
35*4882a593Smuzhiyun 		.colorspace = V4L2_COLORSPACE_SRGB,
36*4882a593Smuzhiyun 		.priv = 3},
37*4882a593Smuzhiyun 	{176, 144, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
38*4882a593Smuzhiyun 		.bytesperline = 176,
39*4882a593Smuzhiyun 		.sizeimage = 176 * 144 * 3 / 2,
40*4882a593Smuzhiyun 		.colorspace = V4L2_COLORSPACE_SRGB,
41*4882a593Smuzhiyun 		.priv = 2},
42*4882a593Smuzhiyun 	{320, 240, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
43*4882a593Smuzhiyun 		.bytesperline = 320,
44*4882a593Smuzhiyun 		.sizeimage = 320 * 240 * 3 / 2,
45*4882a593Smuzhiyun 		.colorspace = V4L2_COLORSPACE_SRGB,
46*4882a593Smuzhiyun 		.priv = 1},
47*4882a593Smuzhiyun 	{352, 288, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
48*4882a593Smuzhiyun 		.bytesperline = 352,
49*4882a593Smuzhiyun 		.sizeimage = 352 * 288 * 3 / 2,
50*4882a593Smuzhiyun 		.colorspace = V4L2_COLORSPACE_SRGB,
51*4882a593Smuzhiyun 		.priv = 0},
52*4882a593Smuzhiyun };
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun /* Frame packet header offsets for the spca508 */
55*4882a593Smuzhiyun #define SPCA508_OFFSET_DATA 37
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun /*
58*4882a593Smuzhiyun  * Initialization data: this is the first set-up data written to the
59*4882a593Smuzhiyun  * device (before the open data).
60*4882a593Smuzhiyun  */
61*4882a593Smuzhiyun static const u16 spca508_init_data[][2] = {
62*4882a593Smuzhiyun 	{0x0000, 0x870b},
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun 	{0x0020, 0x8112},	/* Video drop enable, ISO streaming disable */
65*4882a593Smuzhiyun 	{0x0003, 0x8111},	/* Reset compression & memory */
66*4882a593Smuzhiyun 	{0x0000, 0x8110},	/* Disable all outputs */
67*4882a593Smuzhiyun 	/* READ {0x0000, 0x8114} -> 0000: 00  */
68*4882a593Smuzhiyun 	{0x0000, 0x8114},	/* SW GPIO data */
69*4882a593Smuzhiyun 	{0x0008, 0x8110},	/* Enable charge pump output */
70*4882a593Smuzhiyun 	{0x0002, 0x8116},	/* 200 kHz pump clock */
71*4882a593Smuzhiyun 	/* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE:) */
72*4882a593Smuzhiyun 	{0x0003, 0x8111},	/* Reset compression & memory */
73*4882a593Smuzhiyun 	{0x0000, 0x8111},	/* Normal mode (not reset) */
74*4882a593Smuzhiyun 	{0x0098, 0x8110},
75*4882a593Smuzhiyun 		/* Enable charge pump output, sync.serial,external 2x clock */
76*4882a593Smuzhiyun 	{0x000d, 0x8114},	/* SW GPIO data */
77*4882a593Smuzhiyun 	{0x0002, 0x8116},	/* 200 kHz pump clock */
78*4882a593Smuzhiyun 	{0x0020, 0x8112},	/* Video drop enable, ISO streaming disable */
79*4882a593Smuzhiyun /* --------------------------------------- */
80*4882a593Smuzhiyun 	{0x000f, 0x8402},	/* memory bank */
81*4882a593Smuzhiyun 	{0x0000, 0x8403},	/* ... address */
82*4882a593Smuzhiyun /* --------------------------------------- */
83*4882a593Smuzhiyun /* 0x88__ is Synchronous Serial Interface. */
84*4882a593Smuzhiyun /* TBD: This table could be expressed more compactly */
85*4882a593Smuzhiyun /* using spca508_write_i2c_vector(). */
86*4882a593Smuzhiyun /* TBD: Should see if the values in spca50x_i2c_data */
87*4882a593Smuzhiyun /* would work with the VQ110 instead of the values */
88*4882a593Smuzhiyun /* below. */
89*4882a593Smuzhiyun 	{0x00c0, 0x8804},	/* SSI slave addr */
90*4882a593Smuzhiyun 	{0x0008, 0x8802},	/* 375 Khz SSI clock */
91*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
92*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
93*4882a593Smuzhiyun 	{0x0008, 0x8802},	/* 375 Khz SSI clock */
94*4882a593Smuzhiyun 	{0x0012, 0x8801},	/* SSI reg addr */
95*4882a593Smuzhiyun 	{0x0080, 0x8800},	/* SSI data to write */
96*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
97*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
98*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
99*4882a593Smuzhiyun 	{0x0008, 0x8802},	/* 375 Khz SSI clock */
100*4882a593Smuzhiyun 	{0x0012, 0x8801},	/* SSI reg addr */
101*4882a593Smuzhiyun 	{0x0000, 0x8800},	/* SSI data to write */
102*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
103*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
104*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
105*4882a593Smuzhiyun 	{0x0008, 0x8802},	/* 375 Khz SSI clock */
106*4882a593Smuzhiyun 	{0x0011, 0x8801},	/* SSI reg addr */
107*4882a593Smuzhiyun 	{0x0040, 0x8800},	/* SSI data to write */
108*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
109*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
110*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
111*4882a593Smuzhiyun 	{0x0008, 0x8802},
112*4882a593Smuzhiyun 	{0x0013, 0x8801},
113*4882a593Smuzhiyun 	{0x0000, 0x8800},
114*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
115*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
116*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
117*4882a593Smuzhiyun 	{0x0008, 0x8802},
118*4882a593Smuzhiyun 	{0x0014, 0x8801},
119*4882a593Smuzhiyun 	{0x0000, 0x8800},
120*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
121*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
122*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
123*4882a593Smuzhiyun 	{0x0008, 0x8802},
124*4882a593Smuzhiyun 	{0x0015, 0x8801},
125*4882a593Smuzhiyun 	{0x0001, 0x8800},
126*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
127*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
128*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
129*4882a593Smuzhiyun 	{0x0008, 0x8802},
130*4882a593Smuzhiyun 	{0x0016, 0x8801},
131*4882a593Smuzhiyun 	{0x0003, 0x8800},
132*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
133*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
134*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
135*4882a593Smuzhiyun 	{0x0008, 0x8802},
136*4882a593Smuzhiyun 	{0x0017, 0x8801},
137*4882a593Smuzhiyun 	{0x0036, 0x8800},
138*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
139*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
140*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
141*4882a593Smuzhiyun 	{0x0008, 0x8802},
142*4882a593Smuzhiyun 	{0x0018, 0x8801},
143*4882a593Smuzhiyun 	{0x00ec, 0x8800},
144*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
145*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
146*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
147*4882a593Smuzhiyun 	{0x0008, 0x8802},
148*4882a593Smuzhiyun 	{0x001a, 0x8801},
149*4882a593Smuzhiyun 	{0x0094, 0x8800},
150*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
151*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
152*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
153*4882a593Smuzhiyun 	{0x0008, 0x8802},
154*4882a593Smuzhiyun 	{0x001b, 0x8801},
155*4882a593Smuzhiyun 	{0x0000, 0x8800},
156*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
157*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
158*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
159*4882a593Smuzhiyun 	{0x0008, 0x8802},
160*4882a593Smuzhiyun 	{0x0027, 0x8801},
161*4882a593Smuzhiyun 	{0x00a2, 0x8800},
162*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
163*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
164*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
165*4882a593Smuzhiyun 	{0x0008, 0x8802},
166*4882a593Smuzhiyun 	{0x0028, 0x8801},
167*4882a593Smuzhiyun 	{0x0040, 0x8800},
168*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
169*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
170*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
171*4882a593Smuzhiyun 	{0x0008, 0x8802},
172*4882a593Smuzhiyun 	{0x002a, 0x8801},
173*4882a593Smuzhiyun 	{0x0084, 0x8800},
174*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
175*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00 */
176*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
177*4882a593Smuzhiyun 	{0x0008, 0x8802},
178*4882a593Smuzhiyun 	{0x002b, 0x8801},
179*4882a593Smuzhiyun 	{0x00a8, 0x8800},
180*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
181*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
182*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
183*4882a593Smuzhiyun 	{0x0008, 0x8802},
184*4882a593Smuzhiyun 	{0x002c, 0x8801},
185*4882a593Smuzhiyun 	{0x00fe, 0x8800},
186*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
187*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
188*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
189*4882a593Smuzhiyun 	{0x0008, 0x8802},
190*4882a593Smuzhiyun 	{0x002d, 0x8801},
191*4882a593Smuzhiyun 	{0x0003, 0x8800},
192*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
193*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
194*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
195*4882a593Smuzhiyun 	{0x0008, 0x8802},
196*4882a593Smuzhiyun 	{0x0038, 0x8801},
197*4882a593Smuzhiyun 	{0x0083, 0x8800},
198*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
199*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
200*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
201*4882a593Smuzhiyun 	{0x0008, 0x8802},
202*4882a593Smuzhiyun 	{0x0033, 0x8801},
203*4882a593Smuzhiyun 	{0x0081, 0x8800},
204*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
205*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
206*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
207*4882a593Smuzhiyun 	{0x0008, 0x8802},
208*4882a593Smuzhiyun 	{0x0034, 0x8801},
209*4882a593Smuzhiyun 	{0x004a, 0x8800},
210*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
211*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
212*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
213*4882a593Smuzhiyun 	{0x0008, 0x8802},
214*4882a593Smuzhiyun 	{0x0039, 0x8801},
215*4882a593Smuzhiyun 	{0x0000, 0x8800},
216*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
217*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
218*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
219*4882a593Smuzhiyun 	{0x0008, 0x8802},
220*4882a593Smuzhiyun 	{0x0010, 0x8801},
221*4882a593Smuzhiyun 	{0x00a8, 0x8800},
222*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
223*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
224*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
225*4882a593Smuzhiyun 	{0x0008, 0x8802},
226*4882a593Smuzhiyun 	{0x0006, 0x8801},
227*4882a593Smuzhiyun 	{0x0058, 0x8800},
228*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
229*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00 */
230*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
231*4882a593Smuzhiyun 	{0x0008, 0x8802},
232*4882a593Smuzhiyun 	{0x0000, 0x8801},
233*4882a593Smuzhiyun 	{0x0004, 0x8800},
234*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
235*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
236*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
237*4882a593Smuzhiyun 	{0x0008, 0x8802},
238*4882a593Smuzhiyun 	{0x0040, 0x8801},
239*4882a593Smuzhiyun 	{0x0080, 0x8800},
240*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
241*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
242*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
243*4882a593Smuzhiyun 	{0x0008, 0x8802},
244*4882a593Smuzhiyun 	{0x0041, 0x8801},
245*4882a593Smuzhiyun 	{0x000c, 0x8800},
246*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
247*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
248*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
249*4882a593Smuzhiyun 	{0x0008, 0x8802},
250*4882a593Smuzhiyun 	{0x0042, 0x8801},
251*4882a593Smuzhiyun 	{0x000c, 0x8800},
252*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
253*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
254*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
255*4882a593Smuzhiyun 	{0x0008, 0x8802},
256*4882a593Smuzhiyun 	{0x0043, 0x8801},
257*4882a593Smuzhiyun 	{0x0028, 0x8800},
258*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
259*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
260*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
261*4882a593Smuzhiyun 	{0x0008, 0x8802},
262*4882a593Smuzhiyun 	{0x0044, 0x8801},
263*4882a593Smuzhiyun 	{0x0080, 0x8800},
264*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
265*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
266*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
267*4882a593Smuzhiyun 	{0x0008, 0x8802},
268*4882a593Smuzhiyun 	{0x0045, 0x8801},
269*4882a593Smuzhiyun 	{0x0020, 0x8800},
270*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
271*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
272*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
273*4882a593Smuzhiyun 	{0x0008, 0x8802},
274*4882a593Smuzhiyun 	{0x0046, 0x8801},
275*4882a593Smuzhiyun 	{0x0020, 0x8800},
276*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
277*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
278*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
279*4882a593Smuzhiyun 	{0x0008, 0x8802},
280*4882a593Smuzhiyun 	{0x0047, 0x8801},
281*4882a593Smuzhiyun 	{0x0080, 0x8800},
282*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
283*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
284*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
285*4882a593Smuzhiyun 	{0x0008, 0x8802},
286*4882a593Smuzhiyun 	{0x0048, 0x8801},
287*4882a593Smuzhiyun 	{0x004c, 0x8800},
288*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
289*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
290*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
291*4882a593Smuzhiyun 	{0x0008, 0x8802},
292*4882a593Smuzhiyun 	{0x0049, 0x8801},
293*4882a593Smuzhiyun 	{0x0084, 0x8800},
294*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
295*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
296*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
297*4882a593Smuzhiyun 	{0x0008, 0x8802},
298*4882a593Smuzhiyun 	{0x004a, 0x8801},
299*4882a593Smuzhiyun 	{0x0084, 0x8800},
300*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
301*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
302*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
303*4882a593Smuzhiyun 	{0x0008, 0x8802},
304*4882a593Smuzhiyun 	{0x004b, 0x8801},
305*4882a593Smuzhiyun 	{0x0084, 0x8800},
306*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
307*4882a593Smuzhiyun 	/* --------------------------------------- */
308*4882a593Smuzhiyun 	{0x0012, 0x8700},	/* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
309*4882a593Smuzhiyun 	{0x0000, 0x8701},	/* CKx1 clock delay adj */
310*4882a593Smuzhiyun 	{0x0000, 0x8701},	/* CKx1 clock delay adj */
311*4882a593Smuzhiyun 	{0x0001, 0x870c},	/* CKOx2 output */
312*4882a593Smuzhiyun 	/* --------------------------------------- */
313*4882a593Smuzhiyun 	{0x0080, 0x8600},	/* Line memory read counter (L) */
314*4882a593Smuzhiyun 	{0x0001, 0x8606},	/* reserved */
315*4882a593Smuzhiyun 	{0x0064, 0x8607},	/* Line memory read counter (H) 0x6480=25,728 */
316*4882a593Smuzhiyun 	{0x002a, 0x8601},	/* CDSP sharp interpolation mode,
317*4882a593Smuzhiyun 	 *			line sel for color sep, edge enhance enab */
318*4882a593Smuzhiyun 	{0x0000, 0x8602},	/* optical black level for user settng = 0 */
319*4882a593Smuzhiyun 	{0x0080, 0x8600},	/* Line memory read counter (L) */
320*4882a593Smuzhiyun 	{0x000a, 0x8603},	/* optical black level calc mode:
321*4882a593Smuzhiyun 				 * auto; optical black offset = 10 */
322*4882a593Smuzhiyun 	{0x00df, 0x865b},	/* Horiz offset for valid pixels (L)=0xdf */
323*4882a593Smuzhiyun 	{0x0012, 0x865c},	/* Vert offset for valid lines (L)=0x12 */
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun /* The following two lines seem to be the "wrong" resolution. */
326*4882a593Smuzhiyun /* But perhaps these indicate the actual size of the sensor */
327*4882a593Smuzhiyun /* rather than the size of the current video mode. */
328*4882a593Smuzhiyun 	{0x0058, 0x865d},	/* Horiz valid pixels (*4) (L) = 352 */
329*4882a593Smuzhiyun 	{0x0048, 0x865e},	/* Vert valid lines (*4) (L) = 288 */
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun 	{0x0015, 0x8608},	/* A11 Coef ... */
332*4882a593Smuzhiyun 	{0x0030, 0x8609},
333*4882a593Smuzhiyun 	{0x00fb, 0x860a},
334*4882a593Smuzhiyun 	{0x003e, 0x860b},
335*4882a593Smuzhiyun 	{0x00ce, 0x860c},
336*4882a593Smuzhiyun 	{0x00f4, 0x860d},
337*4882a593Smuzhiyun 	{0x00eb, 0x860e},
338*4882a593Smuzhiyun 	{0x00dc, 0x860f},
339*4882a593Smuzhiyun 	{0x0039, 0x8610},
340*4882a593Smuzhiyun 	{0x0001, 0x8611},	/* R offset for white balance ... */
341*4882a593Smuzhiyun 	{0x0000, 0x8612},
342*4882a593Smuzhiyun 	{0x0001, 0x8613},
343*4882a593Smuzhiyun 	{0x0000, 0x8614},
344*4882a593Smuzhiyun 	{0x005b, 0x8651},	/* R gain for white balance ... */
345*4882a593Smuzhiyun 	{0x0040, 0x8652},
346*4882a593Smuzhiyun 	{0x0060, 0x8653},
347*4882a593Smuzhiyun 	{0x0040, 0x8654},
348*4882a593Smuzhiyun 	{0x0000, 0x8655},
349*4882a593Smuzhiyun 	{0x0001, 0x863f},	/* Fixed gamma correction enable, USB control,
350*4882a593Smuzhiyun 				 * lum filter disable, lum noise clip disable */
351*4882a593Smuzhiyun 	{0x00a1, 0x8656},	/* Window1 size 256x256, Windows2 size 64x64,
352*4882a593Smuzhiyun 				 * gamma look-up disable,
353*4882a593Smuzhiyun 				 * new edge enhancement enable */
354*4882a593Smuzhiyun 	{0x0018, 0x8657},	/* Edge gain high thresh */
355*4882a593Smuzhiyun 	{0x0020, 0x8658},	/* Edge gain low thresh */
356*4882a593Smuzhiyun 	{0x000a, 0x8659},	/* Edge bandwidth high threshold */
357*4882a593Smuzhiyun 	{0x0005, 0x865a},	/* Edge bandwidth low threshold */
358*4882a593Smuzhiyun 	/* -------------------------------- */
359*4882a593Smuzhiyun 	{0x0030, 0x8112},	/* Video drop enable, ISO streaming enable */
360*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
361*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
362*4882a593Smuzhiyun 	{0xa908, 0x8802},
363*4882a593Smuzhiyun 	{0x0034, 0x8801},	/* SSI reg addr */
364*4882a593Smuzhiyun 	{0x00ca, 0x8800},
365*4882a593Smuzhiyun 	/* SSI data to write */
366*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
367*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
368*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
369*4882a593Smuzhiyun 	{0x1f08, 0x8802},
370*4882a593Smuzhiyun 	{0x0006, 0x8801},
371*4882a593Smuzhiyun 	{0x0080, 0x8800},
372*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun /* ----- Read back coefs we wrote earlier. */
375*4882a593Smuzhiyun 	/* READ { 0x0000, 0x8608 } -> 0000: 15  */
376*4882a593Smuzhiyun 	/* READ { 0x0000, 0x8609 } -> 0000: 30  */
377*4882a593Smuzhiyun 	/* READ { 0x0000, 0x860a } -> 0000: fb  */
378*4882a593Smuzhiyun 	/* READ { 0x0000, 0x860b } -> 0000: 3e  */
379*4882a593Smuzhiyun 	/* READ { 0x0000, 0x860c } -> 0000: ce  */
380*4882a593Smuzhiyun 	/* READ { 0x0000, 0x860d } -> 0000: f4  */
381*4882a593Smuzhiyun 	/* READ { 0x0000, 0x860e } -> 0000: eb  */
382*4882a593Smuzhiyun 	/* READ { 0x0000, 0x860f } -> 0000: dc  */
383*4882a593Smuzhiyun 	/* READ { 0x0000, 0x8610 } -> 0000: 39  */
384*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
385*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 08  */
386*4882a593Smuzhiyun 	{0xb008, 0x8802},
387*4882a593Smuzhiyun 	{0x0006, 0x8801},
388*4882a593Smuzhiyun 	{0x007d, 0x8800},
389*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 
392*4882a593Smuzhiyun 	/* This chunk is seemingly redundant with */
393*4882a593Smuzhiyun 	/* earlier commands (A11 Coef...), but if I disable it, */
394*4882a593Smuzhiyun 	/* the image appears too dark.  Maybe there was some kind of */
395*4882a593Smuzhiyun 	/* reset since the earlier commands, so this is necessary again. */
396*4882a593Smuzhiyun 	{0x0015, 0x8608},
397*4882a593Smuzhiyun 	{0x0030, 0x8609},
398*4882a593Smuzhiyun 	{0xfffb, 0x860a},
399*4882a593Smuzhiyun 	{0x003e, 0x860b},
400*4882a593Smuzhiyun 	{0xffce, 0x860c},
401*4882a593Smuzhiyun 	{0xfff4, 0x860d},
402*4882a593Smuzhiyun 	{0xffeb, 0x860e},
403*4882a593Smuzhiyun 	{0xffdc, 0x860f},
404*4882a593Smuzhiyun 	{0x0039, 0x8610},
405*4882a593Smuzhiyun 	{0x0018, 0x8657},
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 	{0x0000, 0x8508},	/* Disable compression. */
408*4882a593Smuzhiyun 	/* Previous line was:
409*4882a593Smuzhiyun 	{0x0021, 0x8508},	 * Enable compression. */
410*4882a593Smuzhiyun 	{0x0032, 0x850b},	/* compression stuff */
411*4882a593Smuzhiyun 	{0x0003, 0x8509},	/* compression stuff */
412*4882a593Smuzhiyun 	{0x0011, 0x850a},	/* compression stuff */
413*4882a593Smuzhiyun 	{0x0021, 0x850d},	/* compression stuff */
414*4882a593Smuzhiyun 	{0x0010, 0x850c},	/* compression stuff */
415*4882a593Smuzhiyun 	{0x0003, 0x8500},	/* *** Video mode: 160x120 */
416*4882a593Smuzhiyun 	{0x0001, 0x8501},	/* Hardware-dominated snap control */
417*4882a593Smuzhiyun 	{0x0061, 0x8656},	/* Window1 size 128x128, Windows2 size 128x128,
418*4882a593Smuzhiyun 				 * gamma look-up disable,
419*4882a593Smuzhiyun 				 * new edge enhancement enable */
420*4882a593Smuzhiyun 	{0x0018, 0x8617},	/* Window1 start X (*2) */
421*4882a593Smuzhiyun 	{0x0008, 0x8618},	/* Window1 start Y (*2) */
422*4882a593Smuzhiyun 	{0x0061, 0x8656},	/* Window1 size 128x128, Windows2 size 128x128,
423*4882a593Smuzhiyun 				 * gamma look-up disable,
424*4882a593Smuzhiyun 				 * new edge enhancement enable */
425*4882a593Smuzhiyun 	{0x0058, 0x8619},	/* Window2 start X (*2) */
426*4882a593Smuzhiyun 	{0x0008, 0x861a},	/* Window2 start Y (*2) */
427*4882a593Smuzhiyun 	{0x00ff, 0x8615},	/* High lum thresh for white balance */
428*4882a593Smuzhiyun 	{0x0000, 0x8616},	/* Low lum thresh for white balance */
429*4882a593Smuzhiyun 	{0x0012, 0x8700},	/* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
430*4882a593Smuzhiyun 	{0x0012, 0x8700},	/* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
431*4882a593Smuzhiyun 	/* READ { 0x0000, 0x8656 } -> 0000: 61  */
432*4882a593Smuzhiyun 	{0x0028, 0x8802},    /* 375 Khz SSI clock, SSI r/w sync with VSYNC */
433*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
434*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 28  */
435*4882a593Smuzhiyun 	{0x1f28, 0x8802},    /* 375 Khz SSI clock, SSI r/w sync with VSYNC */
436*4882a593Smuzhiyun 	{0x0010, 0x8801},	/* SSI reg addr */
437*4882a593Smuzhiyun 	{0x003e, 0x8800},	/* SSI data to write */
438*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
439*4882a593Smuzhiyun 	{0x0028, 0x8802},
440*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
441*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 28  */
442*4882a593Smuzhiyun 	{0x1f28, 0x8802},
443*4882a593Smuzhiyun 	{0x0000, 0x8801},
444*4882a593Smuzhiyun 	{0x001f, 0x8800},
445*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
446*4882a593Smuzhiyun 	{0x0001, 0x8602},    /* optical black level for user settning = 1 */
447*4882a593Smuzhiyun 
448*4882a593Smuzhiyun 	/* Original: */
449*4882a593Smuzhiyun 	{0x0023, 0x8700},	/* Clock speed 48Mhz/(3+2)/4= 2.4 Mhz */
450*4882a593Smuzhiyun 	{0x000f, 0x8602},    /* optical black level for user settning = 15 */
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun 	{0x0028, 0x8802},
453*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
454*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 28  */
455*4882a593Smuzhiyun 	{0x1f28, 0x8802},
456*4882a593Smuzhiyun 	{0x0010, 0x8801},
457*4882a593Smuzhiyun 	{0x007b, 0x8800},
458*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
459*4882a593Smuzhiyun 	{0x002f, 0x8651},	/* R gain for white balance ... */
460*4882a593Smuzhiyun 	{0x0080, 0x8653},
461*4882a593Smuzhiyun 	/* READ { 0x0000, 0x8655 } -> 0000: 00  */
462*4882a593Smuzhiyun 	{0x0000, 0x8655},
463*4882a593Smuzhiyun 
464*4882a593Smuzhiyun 	{0x0030, 0x8112},	/* Video drop enable, ISO streaming enable */
465*4882a593Smuzhiyun 	{0x0020, 0x8112},	/* Video drop enable, ISO streaming disable */
466*4882a593Smuzhiyun 	/* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE: (ALT=0) ) */
467*4882a593Smuzhiyun 	{}
468*4882a593Smuzhiyun };
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun /*
471*4882a593Smuzhiyun  * Initialization data for Intel EasyPC Camera CS110
472*4882a593Smuzhiyun  */
473*4882a593Smuzhiyun static const u16 spca508cs110_init_data[][2] = {
474*4882a593Smuzhiyun 	{0x0000, 0x870b},	/* Reset CTL3 */
475*4882a593Smuzhiyun 	{0x0003, 0x8111},	/* Soft Reset compression, memory, TG & CDSP */
476*4882a593Smuzhiyun 	{0x0000, 0x8111},	/* Normal operation on reset */
477*4882a593Smuzhiyun 	{0x0090, 0x8110},
478*4882a593Smuzhiyun 		 /* External Clock 2x & Synchronous Serial Interface Output */
479*4882a593Smuzhiyun 	{0x0020, 0x8112},	/* Video Drop packet enable */
480*4882a593Smuzhiyun 	{0x0000, 0x8114},	/* Software GPIO output data */
481*4882a593Smuzhiyun 	{0x0001, 0x8114},
482*4882a593Smuzhiyun 	{0x0001, 0x8114},
483*4882a593Smuzhiyun 	{0x0001, 0x8114},
484*4882a593Smuzhiyun 	{0x0003, 0x8114},
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun 	/* Initial sequence Synchronous Serial Interface */
487*4882a593Smuzhiyun 	{0x000f, 0x8402},	/* Memory bank Address */
488*4882a593Smuzhiyun 	{0x0000, 0x8403},	/* Memory bank Address */
489*4882a593Smuzhiyun 	{0x00ba, 0x8804},	/* SSI Slave address */
490*4882a593Smuzhiyun 	{0x0010, 0x8802},	/* 93.75kHz SSI Clock Two DataByte */
491*4882a593Smuzhiyun 	{0x0010, 0x8802},	/* 93.75kHz SSI Clock two DataByte */
492*4882a593Smuzhiyun 
493*4882a593Smuzhiyun 	{0x0001, 0x8801},
494*4882a593Smuzhiyun 	{0x000a, 0x8805},	/* a - NWG: Dunno what this is about */
495*4882a593Smuzhiyun 	{0x0000, 0x8800},
496*4882a593Smuzhiyun 	{0x0010, 0x8802},
497*4882a593Smuzhiyun 
498*4882a593Smuzhiyun 	{0x0002, 0x8801},
499*4882a593Smuzhiyun 	{0x0000, 0x8805},
500*4882a593Smuzhiyun 	{0x0000, 0x8800},
501*4882a593Smuzhiyun 	{0x0010, 0x8802},
502*4882a593Smuzhiyun 
503*4882a593Smuzhiyun 	{0x0003, 0x8801},
504*4882a593Smuzhiyun 	{0x0027, 0x8805},
505*4882a593Smuzhiyun 	{0x0001, 0x8800},
506*4882a593Smuzhiyun 	{0x0010, 0x8802},
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun 	{0x0004, 0x8801},
509*4882a593Smuzhiyun 	{0x0065, 0x8805},
510*4882a593Smuzhiyun 	{0x0001, 0x8800},
511*4882a593Smuzhiyun 	{0x0010, 0x8802},
512*4882a593Smuzhiyun 
513*4882a593Smuzhiyun 	{0x0005, 0x8801},
514*4882a593Smuzhiyun 	{0x0003, 0x8805},
515*4882a593Smuzhiyun 	{0x0000, 0x8800},
516*4882a593Smuzhiyun 	{0x0010, 0x8802},
517*4882a593Smuzhiyun 
518*4882a593Smuzhiyun 	{0x0006, 0x8801},
519*4882a593Smuzhiyun 	{0x001c, 0x8805},
520*4882a593Smuzhiyun 	{0x0000, 0x8800},
521*4882a593Smuzhiyun 	{0x0010, 0x8802},
522*4882a593Smuzhiyun 
523*4882a593Smuzhiyun 	{0x0007, 0x8801},
524*4882a593Smuzhiyun 	{0x002a, 0x8805},
525*4882a593Smuzhiyun 	{0x0000, 0x8800},
526*4882a593Smuzhiyun 	{0x0010, 0x8802},
527*4882a593Smuzhiyun 
528*4882a593Smuzhiyun 	{0x0002, 0x8704},	/* External input CKIx1 */
529*4882a593Smuzhiyun 	{0x0001, 0x8606},    /* 1 Line memory Read Counter (H) Result: (d)410 */
530*4882a593Smuzhiyun 	{0x009a, 0x8600},	/* Line memory Read Counter (L) */
531*4882a593Smuzhiyun 	{0x0001, 0x865b},	/* 1 Horizontal Offset for Valid Pixel(L) */
532*4882a593Smuzhiyun 	{0x0003, 0x865c},	/* 3 Vertical Offset for Valid Lines(L) */
533*4882a593Smuzhiyun 	{0x0058, 0x865d},	/* 58 Horizontal Valid Pixel Window(L) */
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun 	{0x0006, 0x8660},	/* Nibble data + input order */
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun 	{0x000a, 0x8602},	/* Optical black level set to 0x0a */
538*4882a593Smuzhiyun 	{0x0000, 0x8603},	/* Optical black level Offset */
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun /*	{0x0000, 0x8611},	 * 0 R  Offset for white Balance */
541*4882a593Smuzhiyun /*	{0x0000, 0x8612},	 * 1 Gr Offset for white Balance */
542*4882a593Smuzhiyun /*	{0x0000, 0x8613},	 * 1f B  Offset for white Balance */
543*4882a593Smuzhiyun /*	{0x0000, 0x8614},	 * f0 Gb Offset for white Balance */
544*4882a593Smuzhiyun 
545*4882a593Smuzhiyun 	{0x0040, 0x8651},   /* 2b BLUE gain for white balance  good at all 60 */
546*4882a593Smuzhiyun 	{0x0030, 0x8652},	/* 41 Gr Gain for white Balance (L) */
547*4882a593Smuzhiyun 	{0x0035, 0x8653},	/* 26 RED gain for white balance */
548*4882a593Smuzhiyun 	{0x0035, 0x8654},	/* 40Gb Gain for white Balance (L) */
549*4882a593Smuzhiyun 	{0x0041, 0x863f},
550*4882a593Smuzhiyun 	      /* Fixed Gamma correction enabled (makes colours look better) */
551*4882a593Smuzhiyun 
552*4882a593Smuzhiyun 	{0x0000, 0x8655},
553*4882a593Smuzhiyun 		/* High bits for white balance*****brightness control*** */
554*4882a593Smuzhiyun 	{}
555*4882a593Smuzhiyun };
556*4882a593Smuzhiyun 
557*4882a593Smuzhiyun static const u16 spca508_sightcam_init_data[][2] = {
558*4882a593Smuzhiyun /* This line seems to setup the frame/canvas */
559*4882a593Smuzhiyun 	{0x000f, 0x8402},
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun /* These 6 lines are needed to startup the webcam */
562*4882a593Smuzhiyun 	{0x0090, 0x8110},
563*4882a593Smuzhiyun 	{0x0001, 0x8114},
564*4882a593Smuzhiyun 	{0x0001, 0x8114},
565*4882a593Smuzhiyun 	{0x0001, 0x8114},
566*4882a593Smuzhiyun 	{0x0003, 0x8114},
567*4882a593Smuzhiyun 	{0x0080, 0x8804},
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun /* This part seems to make the pictures darker? (autobrightness?) */
570*4882a593Smuzhiyun 	{0x0001, 0x8801},
571*4882a593Smuzhiyun 	{0x0004, 0x8800},
572*4882a593Smuzhiyun 	{0x0003, 0x8801},
573*4882a593Smuzhiyun 	{0x00e0, 0x8800},
574*4882a593Smuzhiyun 	{0x0004, 0x8801},
575*4882a593Smuzhiyun 	{0x00b4, 0x8800},
576*4882a593Smuzhiyun 	{0x0005, 0x8801},
577*4882a593Smuzhiyun 	{0x0000, 0x8800},
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun 	{0x0006, 0x8801},
580*4882a593Smuzhiyun 	{0x00e0, 0x8800},
581*4882a593Smuzhiyun 	{0x0007, 0x8801},
582*4882a593Smuzhiyun 	{0x000c, 0x8800},
583*4882a593Smuzhiyun 
584*4882a593Smuzhiyun /* This section is just needed, it probably
585*4882a593Smuzhiyun  * does something like the previous section,
586*4882a593Smuzhiyun  * but the cam won't start if it's not included.
587*4882a593Smuzhiyun  */
588*4882a593Smuzhiyun 	{0x0014, 0x8801},
589*4882a593Smuzhiyun 	{0x0008, 0x8800},
590*4882a593Smuzhiyun 	{0x0015, 0x8801},
591*4882a593Smuzhiyun 	{0x0067, 0x8800},
592*4882a593Smuzhiyun 	{0x0016, 0x8801},
593*4882a593Smuzhiyun 	{0x0000, 0x8800},
594*4882a593Smuzhiyun 	{0x0017, 0x8801},
595*4882a593Smuzhiyun 	{0x0020, 0x8800},
596*4882a593Smuzhiyun 	{0x0018, 0x8801},
597*4882a593Smuzhiyun 	{0x0044, 0x8800},
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun /* Makes the picture darker - and the
600*4882a593Smuzhiyun  * cam won't start if not included
601*4882a593Smuzhiyun  */
602*4882a593Smuzhiyun 	{0x001e, 0x8801},
603*4882a593Smuzhiyun 	{0x00ea, 0x8800},
604*4882a593Smuzhiyun 	{0x001f, 0x8801},
605*4882a593Smuzhiyun 	{0x0001, 0x8800},
606*4882a593Smuzhiyun 	{0x0003, 0x8801},
607*4882a593Smuzhiyun 	{0x00e0, 0x8800},
608*4882a593Smuzhiyun 
609*4882a593Smuzhiyun /* seems to place the colors ontop of each other #1 */
610*4882a593Smuzhiyun 	{0x0006, 0x8704},
611*4882a593Smuzhiyun 	{0x0001, 0x870c},
612*4882a593Smuzhiyun 	{0x0016, 0x8600},
613*4882a593Smuzhiyun 	{0x0002, 0x8606},
614*4882a593Smuzhiyun 
615*4882a593Smuzhiyun /* if not included the pictures becomes _very_ dark */
616*4882a593Smuzhiyun 	{0x0064, 0x8607},
617*4882a593Smuzhiyun 	{0x003a, 0x8601},
618*4882a593Smuzhiyun 	{0x0000, 0x8602},
619*4882a593Smuzhiyun 
620*4882a593Smuzhiyun /* seems to place the colors ontop of each other #2 */
621*4882a593Smuzhiyun 	{0x0016, 0x8600},
622*4882a593Smuzhiyun 	{0x0018, 0x8617},
623*4882a593Smuzhiyun 	{0x0008, 0x8618},
624*4882a593Smuzhiyun 	{0x00a1, 0x8656},
625*4882a593Smuzhiyun 
626*4882a593Smuzhiyun /* webcam won't start if not included */
627*4882a593Smuzhiyun 	{0x0007, 0x865b},
628*4882a593Smuzhiyun 	{0x0001, 0x865c},
629*4882a593Smuzhiyun 	{0x0058, 0x865d},
630*4882a593Smuzhiyun 	{0x0048, 0x865e},
631*4882a593Smuzhiyun 
632*4882a593Smuzhiyun /* adjusts the colors */
633*4882a593Smuzhiyun 	{0x0049, 0x8651},
634*4882a593Smuzhiyun 	{0x0040, 0x8652},
635*4882a593Smuzhiyun 	{0x004c, 0x8653},
636*4882a593Smuzhiyun 	{0x0040, 0x8654},
637*4882a593Smuzhiyun 	{}
638*4882a593Smuzhiyun };
639*4882a593Smuzhiyun 
640*4882a593Smuzhiyun static const u16 spca508_sightcam2_init_data[][2] = {
641*4882a593Smuzhiyun 	{0x0020, 0x8112},
642*4882a593Smuzhiyun 
643*4882a593Smuzhiyun 	{0x000f, 0x8402},
644*4882a593Smuzhiyun 	{0x0000, 0x8403},
645*4882a593Smuzhiyun 
646*4882a593Smuzhiyun 	{0x0008, 0x8201},
647*4882a593Smuzhiyun 	{0x0008, 0x8200},
648*4882a593Smuzhiyun 	{0x0001, 0x8200},
649*4882a593Smuzhiyun 	{0x0009, 0x8201},
650*4882a593Smuzhiyun 	{0x0008, 0x8200},
651*4882a593Smuzhiyun 	{0x0001, 0x8200},
652*4882a593Smuzhiyun 	{0x000a, 0x8201},
653*4882a593Smuzhiyun 	{0x0008, 0x8200},
654*4882a593Smuzhiyun 	{0x0001, 0x8200},
655*4882a593Smuzhiyun 	{0x000b, 0x8201},
656*4882a593Smuzhiyun 	{0x0008, 0x8200},
657*4882a593Smuzhiyun 	{0x0001, 0x8200},
658*4882a593Smuzhiyun 	{0x000c, 0x8201},
659*4882a593Smuzhiyun 	{0x0008, 0x8200},
660*4882a593Smuzhiyun 	{0x0001, 0x8200},
661*4882a593Smuzhiyun 	{0x000d, 0x8201},
662*4882a593Smuzhiyun 	{0x0008, 0x8200},
663*4882a593Smuzhiyun 	{0x0001, 0x8200},
664*4882a593Smuzhiyun 	{0x000e, 0x8201},
665*4882a593Smuzhiyun 	{0x0008, 0x8200},
666*4882a593Smuzhiyun 	{0x0001, 0x8200},
667*4882a593Smuzhiyun 	{0x0007, 0x8201},
668*4882a593Smuzhiyun 	{0x0008, 0x8200},
669*4882a593Smuzhiyun 	{0x0001, 0x8200},
670*4882a593Smuzhiyun 	{0x000f, 0x8201},
671*4882a593Smuzhiyun 	{0x0008, 0x8200},
672*4882a593Smuzhiyun 	{0x0001, 0x8200},
673*4882a593Smuzhiyun 
674*4882a593Smuzhiyun 	{0x0018, 0x8660},
675*4882a593Smuzhiyun 	{0x0010, 0x8201},
676*4882a593Smuzhiyun 
677*4882a593Smuzhiyun 	{0x0008, 0x8200},
678*4882a593Smuzhiyun 	{0x0001, 0x8200},
679*4882a593Smuzhiyun 	{0x0011, 0x8201},
680*4882a593Smuzhiyun 	{0x0008, 0x8200},
681*4882a593Smuzhiyun 	{0x0001, 0x8200},
682*4882a593Smuzhiyun 
683*4882a593Smuzhiyun 	{0x0000, 0x86b0},
684*4882a593Smuzhiyun 	{0x0034, 0x86b1},
685*4882a593Smuzhiyun 	{0x0000, 0x86b2},
686*4882a593Smuzhiyun 	{0x0049, 0x86b3},
687*4882a593Smuzhiyun 	{0x0000, 0x86b4},
688*4882a593Smuzhiyun 	{0x0000, 0x86b4},
689*4882a593Smuzhiyun 
690*4882a593Smuzhiyun 	{0x0012, 0x8201},
691*4882a593Smuzhiyun 	{0x0008, 0x8200},
692*4882a593Smuzhiyun 	{0x0001, 0x8200},
693*4882a593Smuzhiyun 	{0x0013, 0x8201},
694*4882a593Smuzhiyun 	{0x0008, 0x8200},
695*4882a593Smuzhiyun 	{0x0001, 0x8200},
696*4882a593Smuzhiyun 
697*4882a593Smuzhiyun 	{0x0001, 0x86b0},
698*4882a593Smuzhiyun 	{0x00aa, 0x86b1},
699*4882a593Smuzhiyun 	{0x0000, 0x86b2},
700*4882a593Smuzhiyun 	{0x00e4, 0x86b3},
701*4882a593Smuzhiyun 	{0x0000, 0x86b4},
702*4882a593Smuzhiyun 	{0x0000, 0x86b4},
703*4882a593Smuzhiyun 
704*4882a593Smuzhiyun 	{0x0018, 0x8660},
705*4882a593Smuzhiyun 
706*4882a593Smuzhiyun 	{0x0090, 0x8110},
707*4882a593Smuzhiyun 	{0x0001, 0x8114},
708*4882a593Smuzhiyun 	{0x0001, 0x8114},
709*4882a593Smuzhiyun 	{0x0001, 0x8114},
710*4882a593Smuzhiyun 	{0x0003, 0x8114},
711*4882a593Smuzhiyun 
712*4882a593Smuzhiyun 	{0x0080, 0x8804},
713*4882a593Smuzhiyun 	{0x0003, 0x8801},
714*4882a593Smuzhiyun 	{0x0012, 0x8800},
715*4882a593Smuzhiyun 	{0x0004, 0x8801},
716*4882a593Smuzhiyun 	{0x0005, 0x8800},
717*4882a593Smuzhiyun 	{0x0005, 0x8801},
718*4882a593Smuzhiyun 	{0x0000, 0x8800},
719*4882a593Smuzhiyun 	{0x0006, 0x8801},
720*4882a593Smuzhiyun 	{0x0000, 0x8800},
721*4882a593Smuzhiyun 	{0x0007, 0x8801},
722*4882a593Smuzhiyun 	{0x0000, 0x8800},
723*4882a593Smuzhiyun 	{0x0008, 0x8801},
724*4882a593Smuzhiyun 	{0x0005, 0x8800},
725*4882a593Smuzhiyun 	{0x000a, 0x8700},
726*4882a593Smuzhiyun 	{0x000e, 0x8801},
727*4882a593Smuzhiyun 	{0x0004, 0x8800},
728*4882a593Smuzhiyun 	{0x0005, 0x8801},
729*4882a593Smuzhiyun 	{0x0047, 0x8800},
730*4882a593Smuzhiyun 	{0x0006, 0x8801},
731*4882a593Smuzhiyun 	{0x0000, 0x8800},
732*4882a593Smuzhiyun 	{0x0007, 0x8801},
733*4882a593Smuzhiyun 	{0x00c0, 0x8800},
734*4882a593Smuzhiyun 	{0x0008, 0x8801},
735*4882a593Smuzhiyun 	{0x0003, 0x8800},
736*4882a593Smuzhiyun 	{0x0013, 0x8801},
737*4882a593Smuzhiyun 	{0x0001, 0x8800},
738*4882a593Smuzhiyun 	{0x0009, 0x8801},
739*4882a593Smuzhiyun 	{0x0000, 0x8800},
740*4882a593Smuzhiyun 	{0x000a, 0x8801},
741*4882a593Smuzhiyun 	{0x0000, 0x8800},
742*4882a593Smuzhiyun 	{0x000b, 0x8801},
743*4882a593Smuzhiyun 	{0x0000, 0x8800},
744*4882a593Smuzhiyun 	{0x000c, 0x8801},
745*4882a593Smuzhiyun 	{0x0000, 0x8800},
746*4882a593Smuzhiyun 	{0x000e, 0x8801},
747*4882a593Smuzhiyun 	{0x0004, 0x8800},
748*4882a593Smuzhiyun 	{0x000f, 0x8801},
749*4882a593Smuzhiyun 	{0x0000, 0x8800},
750*4882a593Smuzhiyun 	{0x0010, 0x8801},
751*4882a593Smuzhiyun 	{0x0006, 0x8800},
752*4882a593Smuzhiyun 	{0x0011, 0x8801},
753*4882a593Smuzhiyun 	{0x0006, 0x8800},
754*4882a593Smuzhiyun 	{0x0012, 0x8801},
755*4882a593Smuzhiyun 	{0x0000, 0x8800},
756*4882a593Smuzhiyun 	{0x0013, 0x8801},
757*4882a593Smuzhiyun 	{0x0001, 0x8800},
758*4882a593Smuzhiyun 
759*4882a593Smuzhiyun 	{0x000a, 0x8700},
760*4882a593Smuzhiyun 	{0x0000, 0x8702},
761*4882a593Smuzhiyun 	{0x0000, 0x8703},
762*4882a593Smuzhiyun 	{0x00c2, 0x8704},
763*4882a593Smuzhiyun 	{0x0001, 0x870c},
764*4882a593Smuzhiyun 
765*4882a593Smuzhiyun 	{0x0044, 0x8600},
766*4882a593Smuzhiyun 	{0x0002, 0x8606},
767*4882a593Smuzhiyun 	{0x0064, 0x8607},
768*4882a593Smuzhiyun 	{0x003a, 0x8601},
769*4882a593Smuzhiyun 	{0x0008, 0x8602},
770*4882a593Smuzhiyun 	{0x0044, 0x8600},
771*4882a593Smuzhiyun 	{0x0018, 0x8617},
772*4882a593Smuzhiyun 	{0x0008, 0x8618},
773*4882a593Smuzhiyun 	{0x00a1, 0x8656},
774*4882a593Smuzhiyun 	{0x0004, 0x865b},
775*4882a593Smuzhiyun 	{0x0002, 0x865c},
776*4882a593Smuzhiyun 	{0x0058, 0x865d},
777*4882a593Smuzhiyun 	{0x0048, 0x865e},
778*4882a593Smuzhiyun 	{0x0012, 0x8608},
779*4882a593Smuzhiyun 	{0x002c, 0x8609},
780*4882a593Smuzhiyun 	{0x0002, 0x860a},
781*4882a593Smuzhiyun 	{0x002c, 0x860b},
782*4882a593Smuzhiyun 	{0x00db, 0x860c},
783*4882a593Smuzhiyun 	{0x00f9, 0x860d},
784*4882a593Smuzhiyun 	{0x00f1, 0x860e},
785*4882a593Smuzhiyun 	{0x00e3, 0x860f},
786*4882a593Smuzhiyun 	{0x002c, 0x8610},
787*4882a593Smuzhiyun 	{0x006c, 0x8651},
788*4882a593Smuzhiyun 	{0x0041, 0x8652},
789*4882a593Smuzhiyun 	{0x0059, 0x8653},
790*4882a593Smuzhiyun 	{0x0040, 0x8654},
791*4882a593Smuzhiyun 	{0x00fa, 0x8611},
792*4882a593Smuzhiyun 	{0x00ff, 0x8612},
793*4882a593Smuzhiyun 	{0x00f8, 0x8613},
794*4882a593Smuzhiyun 	{0x0000, 0x8614},
795*4882a593Smuzhiyun 	{0x0001, 0x863f},
796*4882a593Smuzhiyun 	{0x0000, 0x8640},
797*4882a593Smuzhiyun 	{0x0026, 0x8641},
798*4882a593Smuzhiyun 	{0x0045, 0x8642},
799*4882a593Smuzhiyun 	{0x0060, 0x8643},
800*4882a593Smuzhiyun 	{0x0075, 0x8644},
801*4882a593Smuzhiyun 	{0x0088, 0x8645},
802*4882a593Smuzhiyun 	{0x009b, 0x8646},
803*4882a593Smuzhiyun 	{0x00b0, 0x8647},
804*4882a593Smuzhiyun 	{0x00c5, 0x8648},
805*4882a593Smuzhiyun 	{0x00d2, 0x8649},
806*4882a593Smuzhiyun 	{0x00dc, 0x864a},
807*4882a593Smuzhiyun 	{0x00e5, 0x864b},
808*4882a593Smuzhiyun 	{0x00eb, 0x864c},
809*4882a593Smuzhiyun 	{0x00f0, 0x864d},
810*4882a593Smuzhiyun 	{0x00f6, 0x864e},
811*4882a593Smuzhiyun 	{0x00fa, 0x864f},
812*4882a593Smuzhiyun 	{0x00ff, 0x8650},
813*4882a593Smuzhiyun 	{0x0060, 0x8657},
814*4882a593Smuzhiyun 	{0x0010, 0x8658},
815*4882a593Smuzhiyun 	{0x0018, 0x8659},
816*4882a593Smuzhiyun 	{0x0005, 0x865a},
817*4882a593Smuzhiyun 	{0x0018, 0x8660},
818*4882a593Smuzhiyun 	{0x0003, 0x8509},
819*4882a593Smuzhiyun 	{0x0011, 0x850a},
820*4882a593Smuzhiyun 	{0x0032, 0x850b},
821*4882a593Smuzhiyun 	{0x0010, 0x850c},
822*4882a593Smuzhiyun 	{0x0021, 0x850d},
823*4882a593Smuzhiyun 	{0x0001, 0x8500},
824*4882a593Smuzhiyun 	{0x0000, 0x8508},
825*4882a593Smuzhiyun 	{0x0012, 0x8608},
826*4882a593Smuzhiyun 	{0x002c, 0x8609},
827*4882a593Smuzhiyun 	{0x0002, 0x860a},
828*4882a593Smuzhiyun 	{0x0039, 0x860b},
829*4882a593Smuzhiyun 	{0x00d0, 0x860c},
830*4882a593Smuzhiyun 	{0x00f7, 0x860d},
831*4882a593Smuzhiyun 	{0x00ed, 0x860e},
832*4882a593Smuzhiyun 	{0x00db, 0x860f},
833*4882a593Smuzhiyun 	{0x0039, 0x8610},
834*4882a593Smuzhiyun 	{0x0012, 0x8657},
835*4882a593Smuzhiyun 	{0x000c, 0x8619},
836*4882a593Smuzhiyun 	{0x0004, 0x861a},
837*4882a593Smuzhiyun 	{0x00a1, 0x8656},
838*4882a593Smuzhiyun 	{0x00c8, 0x8615},
839*4882a593Smuzhiyun 	{0x0032, 0x8616},
840*4882a593Smuzhiyun 
841*4882a593Smuzhiyun 	{0x0030, 0x8112},
842*4882a593Smuzhiyun 	{0x0020, 0x8112},
843*4882a593Smuzhiyun 	{0x0020, 0x8112},
844*4882a593Smuzhiyun 	{0x000f, 0x8402},
845*4882a593Smuzhiyun 	{0x0000, 0x8403},
846*4882a593Smuzhiyun 
847*4882a593Smuzhiyun 	{0x0090, 0x8110},
848*4882a593Smuzhiyun 	{0x0001, 0x8114},
849*4882a593Smuzhiyun 	{0x0001, 0x8114},
850*4882a593Smuzhiyun 	{0x0001, 0x8114},
851*4882a593Smuzhiyun 	{0x0003, 0x8114},
852*4882a593Smuzhiyun 	{0x0080, 0x8804},
853*4882a593Smuzhiyun 
854*4882a593Smuzhiyun 	{0x0003, 0x8801},
855*4882a593Smuzhiyun 	{0x0012, 0x8800},
856*4882a593Smuzhiyun 	{0x0004, 0x8801},
857*4882a593Smuzhiyun 	{0x0005, 0x8800},
858*4882a593Smuzhiyun 	{0x0005, 0x8801},
859*4882a593Smuzhiyun 	{0x0047, 0x8800},
860*4882a593Smuzhiyun 	{0x0006, 0x8801},
861*4882a593Smuzhiyun 	{0x0000, 0x8800},
862*4882a593Smuzhiyun 	{0x0007, 0x8801},
863*4882a593Smuzhiyun 	{0x00c0, 0x8800},
864*4882a593Smuzhiyun 	{0x0008, 0x8801},
865*4882a593Smuzhiyun 	{0x0003, 0x8800},
866*4882a593Smuzhiyun 	{0x000a, 0x8700},
867*4882a593Smuzhiyun 	{0x000e, 0x8801},
868*4882a593Smuzhiyun 	{0x0004, 0x8800},
869*4882a593Smuzhiyun 	{0x0005, 0x8801},
870*4882a593Smuzhiyun 	{0x0047, 0x8800},
871*4882a593Smuzhiyun 	{0x0006, 0x8801},
872*4882a593Smuzhiyun 	{0x0000, 0x8800},
873*4882a593Smuzhiyun 	{0x0007, 0x8801},
874*4882a593Smuzhiyun 	{0x00c0, 0x8800},
875*4882a593Smuzhiyun 	{0x0008, 0x8801},
876*4882a593Smuzhiyun 	{0x0003, 0x8800},
877*4882a593Smuzhiyun 	{0x0013, 0x8801},
878*4882a593Smuzhiyun 	{0x0001, 0x8800},
879*4882a593Smuzhiyun 	{0x0009, 0x8801},
880*4882a593Smuzhiyun 	{0x0000, 0x8800},
881*4882a593Smuzhiyun 	{0x000a, 0x8801},
882*4882a593Smuzhiyun 	{0x0000, 0x8800},
883*4882a593Smuzhiyun 	{0x000b, 0x8801},
884*4882a593Smuzhiyun 	{0x0000, 0x8800},
885*4882a593Smuzhiyun 	{0x000c, 0x8801},
886*4882a593Smuzhiyun 	{0x0000, 0x8800},
887*4882a593Smuzhiyun 	{0x000e, 0x8801},
888*4882a593Smuzhiyun 	{0x0004, 0x8800},
889*4882a593Smuzhiyun 	{0x000f, 0x8801},
890*4882a593Smuzhiyun 	{0x0000, 0x8800},
891*4882a593Smuzhiyun 	{0x0010, 0x8801},
892*4882a593Smuzhiyun 	{0x0006, 0x8800},
893*4882a593Smuzhiyun 	{0x0011, 0x8801},
894*4882a593Smuzhiyun 	{0x0006, 0x8800},
895*4882a593Smuzhiyun 	{0x0012, 0x8801},
896*4882a593Smuzhiyun 	{0x0000, 0x8800},
897*4882a593Smuzhiyun 	{0x0013, 0x8801},
898*4882a593Smuzhiyun 	{0x0001, 0x8800},
899*4882a593Smuzhiyun 	{0x000a, 0x8700},
900*4882a593Smuzhiyun 	{0x0000, 0x8702},
901*4882a593Smuzhiyun 	{0x0000, 0x8703},
902*4882a593Smuzhiyun 	{0x00c2, 0x8704},
903*4882a593Smuzhiyun 	{0x0001, 0x870c},
904*4882a593Smuzhiyun 	{0x0044, 0x8600},
905*4882a593Smuzhiyun 	{0x0002, 0x8606},
906*4882a593Smuzhiyun 	{0x0064, 0x8607},
907*4882a593Smuzhiyun 	{0x003a, 0x8601},
908*4882a593Smuzhiyun 	{0x0008, 0x8602},
909*4882a593Smuzhiyun 	{0x0044, 0x8600},
910*4882a593Smuzhiyun 	{0x0018, 0x8617},
911*4882a593Smuzhiyun 	{0x0008, 0x8618},
912*4882a593Smuzhiyun 	{0x00a1, 0x8656},
913*4882a593Smuzhiyun 	{0x0004, 0x865b},
914*4882a593Smuzhiyun 	{0x0002, 0x865c},
915*4882a593Smuzhiyun 	{0x0058, 0x865d},
916*4882a593Smuzhiyun 	{0x0048, 0x865e},
917*4882a593Smuzhiyun 	{0x0012, 0x8608},
918*4882a593Smuzhiyun 	{0x002c, 0x8609},
919*4882a593Smuzhiyun 	{0x0002, 0x860a},
920*4882a593Smuzhiyun 	{0x002c, 0x860b},
921*4882a593Smuzhiyun 	{0x00db, 0x860c},
922*4882a593Smuzhiyun 	{0x00f9, 0x860d},
923*4882a593Smuzhiyun 	{0x00f1, 0x860e},
924*4882a593Smuzhiyun 	{0x00e3, 0x860f},
925*4882a593Smuzhiyun 	{0x002c, 0x8610},
926*4882a593Smuzhiyun 	{0x006c, 0x8651},
927*4882a593Smuzhiyun 	{0x0041, 0x8652},
928*4882a593Smuzhiyun 	{0x0059, 0x8653},
929*4882a593Smuzhiyun 	{0x0040, 0x8654},
930*4882a593Smuzhiyun 	{0x00fa, 0x8611},
931*4882a593Smuzhiyun 	{0x00ff, 0x8612},
932*4882a593Smuzhiyun 	{0x00f8, 0x8613},
933*4882a593Smuzhiyun 	{0x0000, 0x8614},
934*4882a593Smuzhiyun 	{0x0001, 0x863f},
935*4882a593Smuzhiyun 	{0x0000, 0x8640},
936*4882a593Smuzhiyun 	{0x0026, 0x8641},
937*4882a593Smuzhiyun 	{0x0045, 0x8642},
938*4882a593Smuzhiyun 	{0x0060, 0x8643},
939*4882a593Smuzhiyun 	{0x0075, 0x8644},
940*4882a593Smuzhiyun 	{0x0088, 0x8645},
941*4882a593Smuzhiyun 	{0x009b, 0x8646},
942*4882a593Smuzhiyun 	{0x00b0, 0x8647},
943*4882a593Smuzhiyun 	{0x00c5, 0x8648},
944*4882a593Smuzhiyun 	{0x00d2, 0x8649},
945*4882a593Smuzhiyun 	{0x00dc, 0x864a},
946*4882a593Smuzhiyun 	{0x00e5, 0x864b},
947*4882a593Smuzhiyun 	{0x00eb, 0x864c},
948*4882a593Smuzhiyun 	{0x00f0, 0x864d},
949*4882a593Smuzhiyun 	{0x00f6, 0x864e},
950*4882a593Smuzhiyun 	{0x00fa, 0x864f},
951*4882a593Smuzhiyun 	{0x00ff, 0x8650},
952*4882a593Smuzhiyun 	{0x0060, 0x8657},
953*4882a593Smuzhiyun 	{0x0010, 0x8658},
954*4882a593Smuzhiyun 	{0x0018, 0x8659},
955*4882a593Smuzhiyun 	{0x0005, 0x865a},
956*4882a593Smuzhiyun 	{0x0018, 0x8660},
957*4882a593Smuzhiyun 	{0x0003, 0x8509},
958*4882a593Smuzhiyun 	{0x0011, 0x850a},
959*4882a593Smuzhiyun 	{0x0032, 0x850b},
960*4882a593Smuzhiyun 	{0x0010, 0x850c},
961*4882a593Smuzhiyun 	{0x0021, 0x850d},
962*4882a593Smuzhiyun 	{0x0001, 0x8500},
963*4882a593Smuzhiyun 	{0x0000, 0x8508},
964*4882a593Smuzhiyun 
965*4882a593Smuzhiyun 	{0x0012, 0x8608},
966*4882a593Smuzhiyun 	{0x002c, 0x8609},
967*4882a593Smuzhiyun 	{0x0002, 0x860a},
968*4882a593Smuzhiyun 	{0x0039, 0x860b},
969*4882a593Smuzhiyun 	{0x00d0, 0x860c},
970*4882a593Smuzhiyun 	{0x00f7, 0x860d},
971*4882a593Smuzhiyun 	{0x00ed, 0x860e},
972*4882a593Smuzhiyun 	{0x00db, 0x860f},
973*4882a593Smuzhiyun 	{0x0039, 0x8610},
974*4882a593Smuzhiyun 	{0x0012, 0x8657},
975*4882a593Smuzhiyun 	{0x0064, 0x8619},
976*4882a593Smuzhiyun 
977*4882a593Smuzhiyun /* This line starts it all, it is not needed here */
978*4882a593Smuzhiyun /* since it has been build into the driver */
979*4882a593Smuzhiyun /* jfm: don't start now */
980*4882a593Smuzhiyun /*	{0x0030, 0x8112}, */
981*4882a593Smuzhiyun 	{}
982*4882a593Smuzhiyun };
983*4882a593Smuzhiyun 
984*4882a593Smuzhiyun /*
985*4882a593Smuzhiyun  * Initialization data for Creative Webcam Vista
986*4882a593Smuzhiyun  */
987*4882a593Smuzhiyun static const u16 spca508_vista_init_data[][2] = {
988*4882a593Smuzhiyun 	{0x0008, 0x8200},	/* Clear register */
989*4882a593Smuzhiyun 	{0x0000, 0x870b},	/* Reset CTL3 */
990*4882a593Smuzhiyun 	{0x0020, 0x8112},	/* Video Drop packet enable */
991*4882a593Smuzhiyun 	{0x0003, 0x8111},	/* Soft Reset compression, memory, TG & CDSP */
992*4882a593Smuzhiyun 	{0x0000, 0x8110},	/* Disable everything */
993*4882a593Smuzhiyun 	{0x0000, 0x8114},	/* Software GPIO output data */
994*4882a593Smuzhiyun 	{0x0000, 0x8114},
995*4882a593Smuzhiyun 
996*4882a593Smuzhiyun 	{0x0003, 0x8111},
997*4882a593Smuzhiyun 	{0x0000, 0x8111},
998*4882a593Smuzhiyun 	{0x0090, 0x8110},    /* Enable: SSI output, External 2X clock output */
999*4882a593Smuzhiyun 	{0x0020, 0x8112},
1000*4882a593Smuzhiyun 	{0x0000, 0x8114},
1001*4882a593Smuzhiyun 	{0x0001, 0x8114},
1002*4882a593Smuzhiyun 	{0x0001, 0x8114},
1003*4882a593Smuzhiyun 	{0x0001, 0x8114},
1004*4882a593Smuzhiyun 	{0x0003, 0x8114},
1005*4882a593Smuzhiyun 
1006*4882a593Smuzhiyun 	{0x000f, 0x8402},	/* Memory bank Address */
1007*4882a593Smuzhiyun 	{0x0000, 0x8403},	/* Memory bank Address */
1008*4882a593Smuzhiyun 	{0x00ba, 0x8804},	/* SSI Slave address */
1009*4882a593Smuzhiyun 	{0x0010, 0x8802},	/* 93.75kHz SSI Clock Two DataByte */
1010*4882a593Smuzhiyun 
1011*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1012*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
1013*4882a593Smuzhiyun 	{0x0010, 0x8802},	/* Will write 2 bytes (DATA1+DATA2) */
1014*4882a593Smuzhiyun 	{0x0020, 0x8801},	/* Register address for SSI read/write */
1015*4882a593Smuzhiyun 	{0x0044, 0x8805},	/* DATA2 */
1016*4882a593Smuzhiyun 	{0x0004, 0x8800},	/* DATA1 -> write triggered */
1017*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1018*4882a593Smuzhiyun 
1019*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1020*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
1021*4882a593Smuzhiyun 	{0x0010, 0x8802},
1022*4882a593Smuzhiyun 	{0x0009, 0x8801},
1023*4882a593Smuzhiyun 	{0x0042, 0x8805},
1024*4882a593Smuzhiyun 	{0x0001, 0x8800},
1025*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1026*4882a593Smuzhiyun 
1027*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1028*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
1029*4882a593Smuzhiyun 	{0x0010, 0x8802},
1030*4882a593Smuzhiyun 	{0x003c, 0x8801},
1031*4882a593Smuzhiyun 	{0x0001, 0x8805},
1032*4882a593Smuzhiyun 	{0x0000, 0x8800},
1033*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1034*4882a593Smuzhiyun 
1035*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1036*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
1037*4882a593Smuzhiyun 	{0x0010, 0x8802},
1038*4882a593Smuzhiyun 	{0x0001, 0x8801},
1039*4882a593Smuzhiyun 	{0x000a, 0x8805},
1040*4882a593Smuzhiyun 	{0x0000, 0x8800},
1041*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1042*4882a593Smuzhiyun 
1043*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1044*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
1045*4882a593Smuzhiyun 	{0x0010, 0x8802},
1046*4882a593Smuzhiyun 	{0x0002, 0x8801},
1047*4882a593Smuzhiyun 	{0x0000, 0x8805},
1048*4882a593Smuzhiyun 	{0x0000, 0x8800},
1049*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1050*4882a593Smuzhiyun 
1051*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1052*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
1053*4882a593Smuzhiyun 	{0x0010, 0x8802},
1054*4882a593Smuzhiyun 	{0x0003, 0x8801},
1055*4882a593Smuzhiyun 	{0x0027, 0x8805},
1056*4882a593Smuzhiyun 	{0x0001, 0x8800},
1057*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1058*4882a593Smuzhiyun 
1059*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1060*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
1061*4882a593Smuzhiyun 	{0x0010, 0x8802},
1062*4882a593Smuzhiyun 	{0x0004, 0x8801},
1063*4882a593Smuzhiyun 	{0x0065, 0x8805},
1064*4882a593Smuzhiyun 	{0x0001, 0x8800},
1065*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1066*4882a593Smuzhiyun 
1067*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1068*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
1069*4882a593Smuzhiyun 	{0x0010, 0x8802},
1070*4882a593Smuzhiyun 	{0x0005, 0x8801},
1071*4882a593Smuzhiyun 	{0x0003, 0x8805},
1072*4882a593Smuzhiyun 	{0x0000, 0x8800},
1073*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1074*4882a593Smuzhiyun 
1075*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1076*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
1077*4882a593Smuzhiyun 	{0x0010, 0x8802},
1078*4882a593Smuzhiyun 	{0x0006, 0x8801},
1079*4882a593Smuzhiyun 	{0x001c, 0x8805},
1080*4882a593Smuzhiyun 	{0x0000, 0x8800},
1081*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1082*4882a593Smuzhiyun 
1083*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1084*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
1085*4882a593Smuzhiyun 	{0x0010, 0x8802},
1086*4882a593Smuzhiyun 	{0x0007, 0x8801},
1087*4882a593Smuzhiyun 	{0x002a, 0x8805},
1088*4882a593Smuzhiyun 	{0x0000, 0x8800},
1089*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1090*4882a593Smuzhiyun 
1091*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1092*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
1093*4882a593Smuzhiyun 	{0x0010, 0x8802},
1094*4882a593Smuzhiyun 	{0x000e, 0x8801},
1095*4882a593Smuzhiyun 	{0x0000, 0x8805},
1096*4882a593Smuzhiyun 	{0x0000, 0x8800},
1097*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1098*4882a593Smuzhiyun 
1099*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1100*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
1101*4882a593Smuzhiyun 	{0x0010, 0x8802},
1102*4882a593Smuzhiyun 	{0x0028, 0x8801},
1103*4882a593Smuzhiyun 	{0x002e, 0x8805},
1104*4882a593Smuzhiyun 	{0x0000, 0x8800},
1105*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1106*4882a593Smuzhiyun 
1107*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1108*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
1109*4882a593Smuzhiyun 	{0x0010, 0x8802},
1110*4882a593Smuzhiyun 	{0x0039, 0x8801},
1111*4882a593Smuzhiyun 	{0x0013, 0x8805},
1112*4882a593Smuzhiyun 	{0x0000, 0x8800},
1113*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1114*4882a593Smuzhiyun 
1115*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1116*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
1117*4882a593Smuzhiyun 	{0x0010, 0x8802},
1118*4882a593Smuzhiyun 	{0x003b, 0x8801},
1119*4882a593Smuzhiyun 	{0x000c, 0x8805},
1120*4882a593Smuzhiyun 	{0x0000, 0x8800},
1121*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1122*4882a593Smuzhiyun 
1123*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1124*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
1125*4882a593Smuzhiyun 	{0x0010, 0x8802},
1126*4882a593Smuzhiyun 	{0x0035, 0x8801},
1127*4882a593Smuzhiyun 	{0x0028, 0x8805},
1128*4882a593Smuzhiyun 	{0x0000, 0x8800},
1129*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1130*4882a593Smuzhiyun 
1131*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1132*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8802 } -> 0000: 10  */
1133*4882a593Smuzhiyun 	{0x0010, 0x8802},
1134*4882a593Smuzhiyun 	{0x0009, 0x8801},
1135*4882a593Smuzhiyun 	{0x0042, 0x8805},
1136*4882a593Smuzhiyun 	{0x0001, 0x8800},
1137*4882a593Smuzhiyun 	/* READ { 0x0001, 0x8803 } -> 0000: 00  */
1138*4882a593Smuzhiyun 
1139*4882a593Smuzhiyun 	{0x0050, 0x8703},
1140*4882a593Smuzhiyun 	{0x0002, 0x8704},	/* External input CKIx1 */
1141*4882a593Smuzhiyun 	{0x0001, 0x870c},	/* Select CKOx2 output */
1142*4882a593Smuzhiyun 	{0x009a, 0x8600},	/* Line memory Read Counter (L) */
1143*4882a593Smuzhiyun 	{0x0001, 0x8606},    /* 1 Line memory Read Counter (H) Result: (d)410 */
1144*4882a593Smuzhiyun 	{0x0023, 0x8601},
1145*4882a593Smuzhiyun 	{0x0010, 0x8602},
1146*4882a593Smuzhiyun 	{0x000a, 0x8603},
1147*4882a593Smuzhiyun 	{0x009a, 0x8600},
1148*4882a593Smuzhiyun 	{0x0001, 0x865b},	/* 1 Horizontal Offset for Valid Pixel(L) */
1149*4882a593Smuzhiyun 	{0x0003, 0x865c},	/* Vertical offset for valid lines (L) */
1150*4882a593Smuzhiyun 	{0x0058, 0x865d},	/* Horizontal valid pixels window (L) */
1151*4882a593Smuzhiyun 	{0x0048, 0x865e},	/* Vertical valid lines window (L) */
1152*4882a593Smuzhiyun 	{0x0000, 0x865f},
1153*4882a593Smuzhiyun 
1154*4882a593Smuzhiyun 	{0x0006, 0x8660},
1155*4882a593Smuzhiyun 		    /* Enable nibble data input, select nibble input order */
1156*4882a593Smuzhiyun 
1157*4882a593Smuzhiyun 	{0x0013, 0x8608},	/* A11 Coeficients for color correction */
1158*4882a593Smuzhiyun 	{0x0028, 0x8609},
1159*4882a593Smuzhiyun 		    /* Note: these values are confirmed at the end of array */
1160*4882a593Smuzhiyun 	{0x0005, 0x860a},	/* ... */
1161*4882a593Smuzhiyun 	{0x0025, 0x860b},
1162*4882a593Smuzhiyun 	{0x00e1, 0x860c},
1163*4882a593Smuzhiyun 	{0x00fa, 0x860d},
1164*4882a593Smuzhiyun 	{0x00f4, 0x860e},
1165*4882a593Smuzhiyun 	{0x00e8, 0x860f},
1166*4882a593Smuzhiyun 	{0x0025, 0x8610},	/* A33 Coef. */
1167*4882a593Smuzhiyun 	{0x00fc, 0x8611},	/* White balance offset: R */
1168*4882a593Smuzhiyun 	{0x0001, 0x8612},	/* White balance offset: Gr */
1169*4882a593Smuzhiyun 	{0x00fe, 0x8613},	/* White balance offset: B */
1170*4882a593Smuzhiyun 	{0x0000, 0x8614},	/* White balance offset: Gb */
1171*4882a593Smuzhiyun 
1172*4882a593Smuzhiyun 	{0x0064, 0x8651},	/* R gain for white balance (L) */
1173*4882a593Smuzhiyun 	{0x0040, 0x8652},	/* Gr gain for white balance (L) */
1174*4882a593Smuzhiyun 	{0x0066, 0x8653},	/* B gain for white balance (L) */
1175*4882a593Smuzhiyun 	{0x0040, 0x8654},	/* Gb gain for white balance (L) */
1176*4882a593Smuzhiyun 	{0x0001, 0x863f},	/* Enable fixed gamma correction */
1177*4882a593Smuzhiyun 
1178*4882a593Smuzhiyun 	{0x00a1, 0x8656},	/* Size - Window1: 256x256, Window2: 128x128,
1179*4882a593Smuzhiyun 				 * UV division: UV no change,
1180*4882a593Smuzhiyun 				 * Enable New edge enhancement */
1181*4882a593Smuzhiyun 	{0x0018, 0x8657},	/* Edge gain high threshold */
1182*4882a593Smuzhiyun 	{0x0020, 0x8658},	/* Edge gain low threshold */
1183*4882a593Smuzhiyun 	{0x000a, 0x8659},	/* Edge bandwidth high threshold */
1184*4882a593Smuzhiyun 	{0x0005, 0x865a},	/* Edge bandwidth low threshold */
1185*4882a593Smuzhiyun 	{0x0064, 0x8607},	/* UV filter enable */
1186*4882a593Smuzhiyun 
1187*4882a593Smuzhiyun 	{0x0016, 0x8660},
1188*4882a593Smuzhiyun 	{0x0000, 0x86b0},	/* Bad pixels compensation address */
1189*4882a593Smuzhiyun 	{0x00dc, 0x86b1},	/* X coord for bad pixels compensation (L) */
1190*4882a593Smuzhiyun 	{0x0000, 0x86b2},
1191*4882a593Smuzhiyun 	{0x0009, 0x86b3},	/* Y coord for bad pixels compensation (L) */
1192*4882a593Smuzhiyun 	{0x0000, 0x86b4},
1193*4882a593Smuzhiyun 
1194*4882a593Smuzhiyun 	{0x0001, 0x86b0},
1195*4882a593Smuzhiyun 	{0x00f5, 0x86b1},
1196*4882a593Smuzhiyun 	{0x0000, 0x86b2},
1197*4882a593Smuzhiyun 	{0x00c6, 0x86b3},
1198*4882a593Smuzhiyun 	{0x0000, 0x86b4},
1199*4882a593Smuzhiyun 
1200*4882a593Smuzhiyun 	{0x0002, 0x86b0},
1201*4882a593Smuzhiyun 	{0x001c, 0x86b1},
1202*4882a593Smuzhiyun 	{0x0001, 0x86b2},
1203*4882a593Smuzhiyun 	{0x00d7, 0x86b3},
1204*4882a593Smuzhiyun 	{0x0000, 0x86b4},
1205*4882a593Smuzhiyun 
1206*4882a593Smuzhiyun 	{0x0003, 0x86b0},
1207*4882a593Smuzhiyun 	{0x001c, 0x86b1},
1208*4882a593Smuzhiyun 	{0x0001, 0x86b2},
1209*4882a593Smuzhiyun 	{0x00d8, 0x86b3},
1210*4882a593Smuzhiyun 	{0x0000, 0x86b4},
1211*4882a593Smuzhiyun 
1212*4882a593Smuzhiyun 	{0x0004, 0x86b0},
1213*4882a593Smuzhiyun 	{0x001d, 0x86b1},
1214*4882a593Smuzhiyun 	{0x0001, 0x86b2},
1215*4882a593Smuzhiyun 	{0x00d8, 0x86b3},
1216*4882a593Smuzhiyun 	{0x0000, 0x86b4},
1217*4882a593Smuzhiyun 	{0x001e, 0x8660},
1218*4882a593Smuzhiyun 
1219*4882a593Smuzhiyun 	/* READ { 0x0000, 0x8608 } -> 0000: 13  */
1220*4882a593Smuzhiyun 	/* READ { 0x0000, 0x8609 } -> 0000: 28  */
1221*4882a593Smuzhiyun 	/* READ { 0x0000, 0x8610 } -> 0000: 05  */
1222*4882a593Smuzhiyun 	/* READ { 0x0000, 0x8611 } -> 0000: 25  */
1223*4882a593Smuzhiyun 	/* READ { 0x0000, 0x8612 } -> 0000: e1  */
1224*4882a593Smuzhiyun 	/* READ { 0x0000, 0x8613 } -> 0000: fa  */
1225*4882a593Smuzhiyun 	/* READ { 0x0000, 0x8614 } -> 0000: f4  */
1226*4882a593Smuzhiyun 	/* READ { 0x0000, 0x8615 } -> 0000: e8  */
1227*4882a593Smuzhiyun 	/* READ { 0x0000, 0x8616 } -> 0000: 25  */
1228*4882a593Smuzhiyun 	{}
1229*4882a593Smuzhiyun };
1230*4882a593Smuzhiyun 
reg_write(struct gspca_dev * gspca_dev,u16 index,u16 value)1231*4882a593Smuzhiyun static int reg_write(struct gspca_dev *gspca_dev, u16 index, u16 value)
1232*4882a593Smuzhiyun {
1233*4882a593Smuzhiyun 	int ret;
1234*4882a593Smuzhiyun 	struct usb_device *dev = gspca_dev->dev;
1235*4882a593Smuzhiyun 
1236*4882a593Smuzhiyun 	ret = usb_control_msg(dev,
1237*4882a593Smuzhiyun 			usb_sndctrlpipe(dev, 0),
1238*4882a593Smuzhiyun 			0,		/* request */
1239*4882a593Smuzhiyun 			USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1240*4882a593Smuzhiyun 			value, index, NULL, 0, 500);
1241*4882a593Smuzhiyun 	gspca_dbg(gspca_dev, D_USBO, "reg write i:0x%04x = 0x%02x\n",
1242*4882a593Smuzhiyun 		  index, value);
1243*4882a593Smuzhiyun 	if (ret < 0)
1244*4882a593Smuzhiyun 		pr_err("reg write: error %d\n", ret);
1245*4882a593Smuzhiyun 	return ret;
1246*4882a593Smuzhiyun }
1247*4882a593Smuzhiyun 
1248*4882a593Smuzhiyun /* read 1 byte */
1249*4882a593Smuzhiyun /* returns: negative is error, pos or zero is data */
reg_read(struct gspca_dev * gspca_dev,u16 index)1250*4882a593Smuzhiyun static int reg_read(struct gspca_dev *gspca_dev,
1251*4882a593Smuzhiyun 			u16 index)	/* wIndex */
1252*4882a593Smuzhiyun {
1253*4882a593Smuzhiyun 	int ret;
1254*4882a593Smuzhiyun 
1255*4882a593Smuzhiyun 	ret = usb_control_msg(gspca_dev->dev,
1256*4882a593Smuzhiyun 			usb_rcvctrlpipe(gspca_dev->dev, 0),
1257*4882a593Smuzhiyun 			0,			/* register */
1258*4882a593Smuzhiyun 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1259*4882a593Smuzhiyun 			0,		/* value */
1260*4882a593Smuzhiyun 			index,
1261*4882a593Smuzhiyun 			gspca_dev->usb_buf, 1,
1262*4882a593Smuzhiyun 			500);			/* timeout */
1263*4882a593Smuzhiyun 	gspca_dbg(gspca_dev, D_USBI, "reg read i:%04x --> %02x\n",
1264*4882a593Smuzhiyun 		  index, gspca_dev->usb_buf[0]);
1265*4882a593Smuzhiyun 	if (ret < 0) {
1266*4882a593Smuzhiyun 		pr_err("reg_read err %d\n", ret);
1267*4882a593Smuzhiyun 		return ret;
1268*4882a593Smuzhiyun 	}
1269*4882a593Smuzhiyun 	return gspca_dev->usb_buf[0];
1270*4882a593Smuzhiyun }
1271*4882a593Smuzhiyun 
1272*4882a593Smuzhiyun /* send 1 or 2 bytes to the sensor via the Synchronous Serial Interface */
ssi_w(struct gspca_dev * gspca_dev,u16 reg,u16 val)1273*4882a593Smuzhiyun static int ssi_w(struct gspca_dev *gspca_dev,
1274*4882a593Smuzhiyun 		u16 reg, u16 val)
1275*4882a593Smuzhiyun {
1276*4882a593Smuzhiyun 	int ret, retry;
1277*4882a593Smuzhiyun 
1278*4882a593Smuzhiyun 	ret = reg_write(gspca_dev, 0x8802, reg >> 8);
1279*4882a593Smuzhiyun 	if (ret < 0)
1280*4882a593Smuzhiyun 		goto out;
1281*4882a593Smuzhiyun 	ret = reg_write(gspca_dev, 0x8801, reg & 0x00ff);
1282*4882a593Smuzhiyun 	if (ret < 0)
1283*4882a593Smuzhiyun 		goto out;
1284*4882a593Smuzhiyun 	if ((reg & 0xff00) == 0x1000) {		/* if 2 bytes */
1285*4882a593Smuzhiyun 		ret = reg_write(gspca_dev, 0x8805, val & 0x00ff);
1286*4882a593Smuzhiyun 		if (ret < 0)
1287*4882a593Smuzhiyun 			goto out;
1288*4882a593Smuzhiyun 		val >>= 8;
1289*4882a593Smuzhiyun 	}
1290*4882a593Smuzhiyun 	ret = reg_write(gspca_dev, 0x8800, val);
1291*4882a593Smuzhiyun 	if (ret < 0)
1292*4882a593Smuzhiyun 		goto out;
1293*4882a593Smuzhiyun 
1294*4882a593Smuzhiyun 	/* poll until not busy */
1295*4882a593Smuzhiyun 	retry = 10;
1296*4882a593Smuzhiyun 	for (;;) {
1297*4882a593Smuzhiyun 		ret = reg_read(gspca_dev, 0x8803);
1298*4882a593Smuzhiyun 		if (ret < 0)
1299*4882a593Smuzhiyun 			break;
1300*4882a593Smuzhiyun 		if (gspca_dev->usb_buf[0] == 0)
1301*4882a593Smuzhiyun 			break;
1302*4882a593Smuzhiyun 		if (--retry <= 0) {
1303*4882a593Smuzhiyun 			gspca_err(gspca_dev, "ssi_w busy %02x\n",
1304*4882a593Smuzhiyun 				  gspca_dev->usb_buf[0]);
1305*4882a593Smuzhiyun 			ret = -1;
1306*4882a593Smuzhiyun 			break;
1307*4882a593Smuzhiyun 		}
1308*4882a593Smuzhiyun 		msleep(8);
1309*4882a593Smuzhiyun 	}
1310*4882a593Smuzhiyun 
1311*4882a593Smuzhiyun out:
1312*4882a593Smuzhiyun 	return ret;
1313*4882a593Smuzhiyun }
1314*4882a593Smuzhiyun 
write_vector(struct gspca_dev * gspca_dev,const u16 (* data)[2])1315*4882a593Smuzhiyun static int write_vector(struct gspca_dev *gspca_dev,
1316*4882a593Smuzhiyun 			const u16 (*data)[2])
1317*4882a593Smuzhiyun {
1318*4882a593Smuzhiyun 	int ret = 0;
1319*4882a593Smuzhiyun 
1320*4882a593Smuzhiyun 	while ((*data)[1] != 0) {
1321*4882a593Smuzhiyun 		if ((*data)[1] & 0x8000) {
1322*4882a593Smuzhiyun 			if ((*data)[1] == 0xdd00)	/* delay */
1323*4882a593Smuzhiyun 				msleep((*data)[0]);
1324*4882a593Smuzhiyun 			else
1325*4882a593Smuzhiyun 				ret = reg_write(gspca_dev, (*data)[1],
1326*4882a593Smuzhiyun 								(*data)[0]);
1327*4882a593Smuzhiyun 		} else {
1328*4882a593Smuzhiyun 			ret = ssi_w(gspca_dev, (*data)[1], (*data)[0]);
1329*4882a593Smuzhiyun 		}
1330*4882a593Smuzhiyun 		if (ret < 0)
1331*4882a593Smuzhiyun 			break;
1332*4882a593Smuzhiyun 		data++;
1333*4882a593Smuzhiyun 	}
1334*4882a593Smuzhiyun 	return ret;
1335*4882a593Smuzhiyun }
1336*4882a593Smuzhiyun 
1337*4882a593Smuzhiyun /* this function is called at probe time */
sd_config(struct gspca_dev * gspca_dev,const struct usb_device_id * id)1338*4882a593Smuzhiyun static int sd_config(struct gspca_dev *gspca_dev,
1339*4882a593Smuzhiyun 			const struct usb_device_id *id)
1340*4882a593Smuzhiyun {
1341*4882a593Smuzhiyun 	struct sd *sd = (struct sd *) gspca_dev;
1342*4882a593Smuzhiyun 	struct cam *cam;
1343*4882a593Smuzhiyun 	const u16 (*init_data)[2];
1344*4882a593Smuzhiyun 	static const u16 (*(init_data_tb[]))[2] = {
1345*4882a593Smuzhiyun 		spca508_vista_init_data,	/* CreativeVista 0 */
1346*4882a593Smuzhiyun 		spca508_sightcam_init_data,	/* HamaUSBSightcam 1 */
1347*4882a593Smuzhiyun 		spca508_sightcam2_init_data,	/* HamaUSBSightcam2 2 */
1348*4882a593Smuzhiyun 		spca508cs110_init_data,		/* IntelEasyPCCamera 3 */
1349*4882a593Smuzhiyun 		spca508cs110_init_data,		/* MicroInnovationIC200 4 */
1350*4882a593Smuzhiyun 		spca508_init_data,		/* ViewQuestVQ110 5 */
1351*4882a593Smuzhiyun 	};
1352*4882a593Smuzhiyun 	int data1, data2;
1353*4882a593Smuzhiyun 
1354*4882a593Smuzhiyun 	/* Read from global register the USB product and vendor IDs, just to
1355*4882a593Smuzhiyun 	 * prove that we can communicate with the device.  This works, which
1356*4882a593Smuzhiyun 	 * confirms at we are communicating properly and that the device
1357*4882a593Smuzhiyun 	 * is a 508. */
1358*4882a593Smuzhiyun 	data1 = reg_read(gspca_dev, 0x8104);
1359*4882a593Smuzhiyun 	data2 = reg_read(gspca_dev, 0x8105);
1360*4882a593Smuzhiyun 	gspca_dbg(gspca_dev, D_PROBE, "Webcam Vendor ID: 0x%02x%02x\n",
1361*4882a593Smuzhiyun 		  data2, data1);
1362*4882a593Smuzhiyun 
1363*4882a593Smuzhiyun 	data1 = reg_read(gspca_dev, 0x8106);
1364*4882a593Smuzhiyun 	data2 = reg_read(gspca_dev, 0x8107);
1365*4882a593Smuzhiyun 	gspca_dbg(gspca_dev, D_PROBE, "Webcam Product ID: 0x%02x%02x\n",
1366*4882a593Smuzhiyun 		  data2, data1);
1367*4882a593Smuzhiyun 
1368*4882a593Smuzhiyun 	data1 = reg_read(gspca_dev, 0x8621);
1369*4882a593Smuzhiyun 	gspca_dbg(gspca_dev, D_PROBE, "Window 1 average luminance: %d\n",
1370*4882a593Smuzhiyun 		  data1);
1371*4882a593Smuzhiyun 
1372*4882a593Smuzhiyun 	cam = &gspca_dev->cam;
1373*4882a593Smuzhiyun 	cam->cam_mode = sif_mode;
1374*4882a593Smuzhiyun 	cam->nmodes = ARRAY_SIZE(sif_mode);
1375*4882a593Smuzhiyun 
1376*4882a593Smuzhiyun 	sd->subtype = id->driver_info;
1377*4882a593Smuzhiyun 
1378*4882a593Smuzhiyun 	init_data = init_data_tb[sd->subtype];
1379*4882a593Smuzhiyun 	return write_vector(gspca_dev, init_data);
1380*4882a593Smuzhiyun }
1381*4882a593Smuzhiyun 
1382*4882a593Smuzhiyun /* this function is called at probe and resume time */
sd_init(struct gspca_dev * gspca_dev)1383*4882a593Smuzhiyun static int sd_init(struct gspca_dev *gspca_dev)
1384*4882a593Smuzhiyun {
1385*4882a593Smuzhiyun 	return 0;
1386*4882a593Smuzhiyun }
1387*4882a593Smuzhiyun 
sd_start(struct gspca_dev * gspca_dev)1388*4882a593Smuzhiyun static int sd_start(struct gspca_dev *gspca_dev)
1389*4882a593Smuzhiyun {
1390*4882a593Smuzhiyun 	int mode;
1391*4882a593Smuzhiyun 
1392*4882a593Smuzhiyun 	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1393*4882a593Smuzhiyun 	reg_write(gspca_dev, 0x8500, mode);
1394*4882a593Smuzhiyun 	switch (mode) {
1395*4882a593Smuzhiyun 	case 0:
1396*4882a593Smuzhiyun 	case 1:
1397*4882a593Smuzhiyun 		reg_write(gspca_dev, 0x8700, 0x28); /* clock */
1398*4882a593Smuzhiyun 		break;
1399*4882a593Smuzhiyun 	default:
1400*4882a593Smuzhiyun /*	case 2: */
1401*4882a593Smuzhiyun /*	case 3: */
1402*4882a593Smuzhiyun 		reg_write(gspca_dev, 0x8700, 0x23); /* clock */
1403*4882a593Smuzhiyun 		break;
1404*4882a593Smuzhiyun 	}
1405*4882a593Smuzhiyun 	reg_write(gspca_dev, 0x8112, 0x10 | 0x20);
1406*4882a593Smuzhiyun 	return 0;
1407*4882a593Smuzhiyun }
1408*4882a593Smuzhiyun 
sd_stopN(struct gspca_dev * gspca_dev)1409*4882a593Smuzhiyun static void sd_stopN(struct gspca_dev *gspca_dev)
1410*4882a593Smuzhiyun {
1411*4882a593Smuzhiyun 	/* Video ISO disable, Video Drop Packet enable: */
1412*4882a593Smuzhiyun 	reg_write(gspca_dev, 0x8112, 0x20);
1413*4882a593Smuzhiyun }
1414*4882a593Smuzhiyun 
sd_pkt_scan(struct gspca_dev * gspca_dev,u8 * data,int len)1415*4882a593Smuzhiyun static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1416*4882a593Smuzhiyun 			u8 *data,			/* isoc packet */
1417*4882a593Smuzhiyun 			int len)			/* iso packet length */
1418*4882a593Smuzhiyun {
1419*4882a593Smuzhiyun 	switch (data[0]) {
1420*4882a593Smuzhiyun 	case 0:				/* start of frame */
1421*4882a593Smuzhiyun 		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
1422*4882a593Smuzhiyun 		data += SPCA508_OFFSET_DATA;
1423*4882a593Smuzhiyun 		len -= SPCA508_OFFSET_DATA;
1424*4882a593Smuzhiyun 		gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
1425*4882a593Smuzhiyun 		break;
1426*4882a593Smuzhiyun 	case 0xff:			/* drop */
1427*4882a593Smuzhiyun 		break;
1428*4882a593Smuzhiyun 	default:
1429*4882a593Smuzhiyun 		data += 1;
1430*4882a593Smuzhiyun 		len -= 1;
1431*4882a593Smuzhiyun 		gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1432*4882a593Smuzhiyun 		break;
1433*4882a593Smuzhiyun 	}
1434*4882a593Smuzhiyun }
1435*4882a593Smuzhiyun 
setbrightness(struct gspca_dev * gspca_dev,s32 brightness)1436*4882a593Smuzhiyun static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness)
1437*4882a593Smuzhiyun {
1438*4882a593Smuzhiyun 	/* MX seem contrast */
1439*4882a593Smuzhiyun 	reg_write(gspca_dev, 0x8651, brightness);
1440*4882a593Smuzhiyun 	reg_write(gspca_dev, 0x8652, brightness);
1441*4882a593Smuzhiyun 	reg_write(gspca_dev, 0x8653, brightness);
1442*4882a593Smuzhiyun 	reg_write(gspca_dev, 0x8654, brightness);
1443*4882a593Smuzhiyun }
1444*4882a593Smuzhiyun 
sd_s_ctrl(struct v4l2_ctrl * ctrl)1445*4882a593Smuzhiyun static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
1446*4882a593Smuzhiyun {
1447*4882a593Smuzhiyun 	struct gspca_dev *gspca_dev =
1448*4882a593Smuzhiyun 		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
1449*4882a593Smuzhiyun 
1450*4882a593Smuzhiyun 	gspca_dev->usb_err = 0;
1451*4882a593Smuzhiyun 
1452*4882a593Smuzhiyun 	if (!gspca_dev->streaming)
1453*4882a593Smuzhiyun 		return 0;
1454*4882a593Smuzhiyun 
1455*4882a593Smuzhiyun 	switch (ctrl->id) {
1456*4882a593Smuzhiyun 	case V4L2_CID_BRIGHTNESS:
1457*4882a593Smuzhiyun 		setbrightness(gspca_dev, ctrl->val);
1458*4882a593Smuzhiyun 		break;
1459*4882a593Smuzhiyun 	}
1460*4882a593Smuzhiyun 	return gspca_dev->usb_err;
1461*4882a593Smuzhiyun }
1462*4882a593Smuzhiyun 
1463*4882a593Smuzhiyun static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1464*4882a593Smuzhiyun 	.s_ctrl = sd_s_ctrl,
1465*4882a593Smuzhiyun };
1466*4882a593Smuzhiyun 
sd_init_controls(struct gspca_dev * gspca_dev)1467*4882a593Smuzhiyun static int sd_init_controls(struct gspca_dev *gspca_dev)
1468*4882a593Smuzhiyun {
1469*4882a593Smuzhiyun 	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1470*4882a593Smuzhiyun 
1471*4882a593Smuzhiyun 	gspca_dev->vdev.ctrl_handler = hdl;
1472*4882a593Smuzhiyun 	v4l2_ctrl_handler_init(hdl, 5);
1473*4882a593Smuzhiyun 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1474*4882a593Smuzhiyun 			V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1475*4882a593Smuzhiyun 
1476*4882a593Smuzhiyun 	if (hdl->error) {
1477*4882a593Smuzhiyun 		pr_err("Could not initialize controls\n");
1478*4882a593Smuzhiyun 		return hdl->error;
1479*4882a593Smuzhiyun 	}
1480*4882a593Smuzhiyun 	return 0;
1481*4882a593Smuzhiyun }
1482*4882a593Smuzhiyun 
1483*4882a593Smuzhiyun /* sub-driver description */
1484*4882a593Smuzhiyun static const struct sd_desc sd_desc = {
1485*4882a593Smuzhiyun 	.name = MODULE_NAME,
1486*4882a593Smuzhiyun 	.config = sd_config,
1487*4882a593Smuzhiyun 	.init = sd_init,
1488*4882a593Smuzhiyun 	.init_controls = sd_init_controls,
1489*4882a593Smuzhiyun 	.start = sd_start,
1490*4882a593Smuzhiyun 	.stopN = sd_stopN,
1491*4882a593Smuzhiyun 	.pkt_scan = sd_pkt_scan,
1492*4882a593Smuzhiyun };
1493*4882a593Smuzhiyun 
1494*4882a593Smuzhiyun /* -- module initialisation -- */
1495*4882a593Smuzhiyun static const struct usb_device_id device_table[] = {
1496*4882a593Smuzhiyun 	{USB_DEVICE(0x0130, 0x0130), .driver_info = HamaUSBSightcam},
1497*4882a593Smuzhiyun 	{USB_DEVICE(0x041e, 0x4018), .driver_info = CreativeVista},
1498*4882a593Smuzhiyun 	{USB_DEVICE(0x0733, 0x0110), .driver_info = ViewQuestVQ110},
1499*4882a593Smuzhiyun 	{USB_DEVICE(0x0af9, 0x0010), .driver_info = HamaUSBSightcam},
1500*4882a593Smuzhiyun 	{USB_DEVICE(0x0af9, 0x0011), .driver_info = HamaUSBSightcam2},
1501*4882a593Smuzhiyun 	{USB_DEVICE(0x8086, 0x0110), .driver_info = IntelEasyPCCamera},
1502*4882a593Smuzhiyun 	{}
1503*4882a593Smuzhiyun };
1504*4882a593Smuzhiyun MODULE_DEVICE_TABLE(usb, device_table);
1505*4882a593Smuzhiyun 
1506*4882a593Smuzhiyun /* -- device connect -- */
sd_probe(struct usb_interface * intf,const struct usb_device_id * id)1507*4882a593Smuzhiyun static int sd_probe(struct usb_interface *intf,
1508*4882a593Smuzhiyun 			const struct usb_device_id *id)
1509*4882a593Smuzhiyun {
1510*4882a593Smuzhiyun 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1511*4882a593Smuzhiyun 				THIS_MODULE);
1512*4882a593Smuzhiyun }
1513*4882a593Smuzhiyun 
1514*4882a593Smuzhiyun static struct usb_driver sd_driver = {
1515*4882a593Smuzhiyun 	.name = MODULE_NAME,
1516*4882a593Smuzhiyun 	.id_table = device_table,
1517*4882a593Smuzhiyun 	.probe = sd_probe,
1518*4882a593Smuzhiyun 	.disconnect = gspca_disconnect,
1519*4882a593Smuzhiyun #ifdef CONFIG_PM
1520*4882a593Smuzhiyun 	.suspend = gspca_suspend,
1521*4882a593Smuzhiyun 	.resume = gspca_resume,
1522*4882a593Smuzhiyun 	.reset_resume = gspca_resume,
1523*4882a593Smuzhiyun #endif
1524*4882a593Smuzhiyun };
1525*4882a593Smuzhiyun 
1526*4882a593Smuzhiyun module_usb_driver(sd_driver);
1527