Version:  2.6.34 2.6.35 2.6.36 2.6.37 2.6.38 2.6.39 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14

Linux/drivers/media/usb/gspca/spca508.c

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us