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