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