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