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