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