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