GNU Linux-libre 4.14.290-gnu1
[releases.git] / drivers / media / usb / gspca / spca505.c
1 /*
2  * SPCA505 chip based cameras initialization data
3  *
4  * V4L2 by Jean-Francis 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  */
17
18 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19
20 #define MODULE_NAME "spca505"
21
22 #include "gspca.h"
23
24 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
25 MODULE_DESCRIPTION("GSPCA/SPCA505 USB Camera Driver");
26 MODULE_LICENSE("GPL");
27
28 /* specific webcam descriptor */
29 struct sd {
30         struct gspca_dev gspca_dev;             /* !! must be the first item */
31
32         u8 subtype;
33 #define IntelPCCameraPro 0
34 #define Nxultra 1
35 };
36
37 static const struct v4l2_pix_format vga_mode[] = {
38         {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
39                 .bytesperline = 160,
40                 .sizeimage = 160 * 120 * 3 / 2,
41                 .colorspace = V4L2_COLORSPACE_SRGB,
42                 .priv = 4},
43         {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
44                 .bytesperline = 176,
45                 .sizeimage = 176 * 144 * 3 / 2,
46                 .colorspace = V4L2_COLORSPACE_SRGB,
47                 .priv = 3},
48         {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
49                 .bytesperline = 320,
50                 .sizeimage = 320 * 240 * 3 / 2,
51                 .colorspace = V4L2_COLORSPACE_SRGB,
52                 .priv = 2},
53         {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
54                 .bytesperline = 352,
55                 .sizeimage = 352 * 288 * 3 / 2,
56                 .colorspace = V4L2_COLORSPACE_SRGB,
57                 .priv = 1},
58         {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
59                 .bytesperline = 640,
60                 .sizeimage = 640 * 480 * 3 / 2,
61                 .colorspace = V4L2_COLORSPACE_SRGB,
62                 .priv = 0},
63 };
64
65 #define SPCA50X_OFFSET_DATA 10
66
67 #define SPCA50X_REG_USB 0x02    /* spca505 501 */
68
69 #define SPCA50X_USB_CTRL 0x00   /* spca505 */
70 #define SPCA50X_CUSB_ENABLE 0x01 /* spca505 */
71
72 #define SPCA50X_REG_GLOBAL 0x03 /* spca505 */
73 #define SPCA50X_GMISC0_IDSEL 0x01 /* Global control device ID select spca505 */
74 #define SPCA50X_GLOBAL_MISC0 0x00 /* Global control miscellaneous 0 spca505 */
75
76 #define SPCA50X_GLOBAL_MISC1 0x01 /* 505 */
77 #define SPCA50X_GLOBAL_MISC3 0x03 /* 505 */
78 #define SPCA50X_GMISC3_SAA7113RST 0x20  /* Not sure about this one spca505 */
79
80 /* Image format and compression control */
81 #define SPCA50X_REG_COMPRESS 0x04
82
83 /*
84  * Data to initialize a SPCA505. Common to the CCD and external modes
85  */
86 static const u8 spca505_init_data[][3] = {
87         /* bmRequest,value,index */
88         {SPCA50X_REG_GLOBAL, SPCA50X_GMISC3_SAA7113RST, SPCA50X_GLOBAL_MISC3},
89         /* Sensor reset */
90         {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3},
91         {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1},
92         /* Block USB reset */
93         {SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL, SPCA50X_GLOBAL_MISC0},
94
95         {0x05, 0x01, 0x10},
96                                         /* Maybe power down some stuff */
97         {0x05, 0x0f, 0x11},
98
99         /* Setup internal CCD  ? */
100         {0x06, 0x10, 0x08},
101         {0x06, 0x00, 0x09},
102         {0x06, 0x00, 0x0a},
103         {0x06, 0x00, 0x0b},
104         {0x06, 0x10, 0x0c},
105         {0x06, 0x00, 0x0d},
106         {0x06, 0x00, 0x0e},
107         {0x06, 0x00, 0x0f},
108         {0x06, 0x10, 0x10},
109         {0x06, 0x02, 0x11},
110         {0x06, 0x00, 0x12},
111         {0x06, 0x04, 0x13},
112         {0x06, 0x02, 0x14},
113         {0x06, 0x8a, 0x51},
114         {0x06, 0x40, 0x52},
115         {0x06, 0xb6, 0x53},
116         {0x06, 0x3d, 0x54},
117         {}
118 };
119
120 /*
121  * Data to initialize the camera using the internal CCD
122  */
123 static const u8 spca505_open_data_ccd[][3] = {
124         /* bmRequest,value,index */
125         /* Internal CCD data set */
126         {0x03, 0x04, 0x01},
127         /* This could be a reset */
128         {0x03, 0x00, 0x01},
129
130         /* Setup compression and image registers. 0x6 and 0x7 seem to be
131            related to H&V hold, and are resolution mode specific */
132                 {0x04, 0x10, 0x01},
133                 /* DIFF(0x50), was (0x10) */
134         {0x04, 0x00, 0x04},
135         {0x04, 0x00, 0x05},
136         {0x04, 0x20, 0x06},
137         {0x04, 0x20, 0x07},
138
139         {0x08, 0x0a, 0x00},
140         /* DIFF (0x4a), was (0xa) */
141
142         {0x05, 0x00, 0x10},
143         {0x05, 0x00, 0x11},
144         {0x05, 0x00, 0x00},
145         /* DIFF not written */
146         {0x05, 0x00, 0x01},
147         /* DIFF not written */
148         {0x05, 0x00, 0x02},
149         /* DIFF not written */
150         {0x05, 0x00, 0x03},
151         /* DIFF not written */
152         {0x05, 0x00, 0x04},
153         /* DIFF not written */
154                 {0x05, 0x80, 0x05},
155                 /* DIFF not written */
156                 {0x05, 0xe0, 0x06},
157                 /* DIFF not written */
158                 {0x05, 0x20, 0x07},
159                 /* DIFF not written */
160                 {0x05, 0xa0, 0x08},
161                 /* DIFF not written */
162                 {0x05, 0x0, 0x12},
163                 /* DIFF not written */
164         {0x05, 0x02, 0x0f},
165         /* DIFF not written */
166                 {0x05, 0x10, 0x46},
167                 /* DIFF not written */
168                 {0x05, 0x8, 0x4a},
169                 /* DIFF not written */
170
171         {0x03, 0x08, 0x03},
172         /* DIFF (0x3,0x28,0x3) */
173         {0x03, 0x08, 0x01},
174         {0x03, 0x0c, 0x03},
175         /* DIFF not written */
176                 {0x03, 0x21, 0x00},
177                 /* DIFF (0x39) */
178
179 /* Extra block copied from init to hopefully ensure CCD is in a sane state */
180         {0x06, 0x10, 0x08},
181         {0x06, 0x00, 0x09},
182         {0x06, 0x00, 0x0a},
183         {0x06, 0x00, 0x0b},
184         {0x06, 0x10, 0x0c},
185         {0x06, 0x00, 0x0d},
186         {0x06, 0x00, 0x0e},
187         {0x06, 0x00, 0x0f},
188         {0x06, 0x10, 0x10},
189         {0x06, 0x02, 0x11},
190         {0x06, 0x00, 0x12},
191         {0x06, 0x04, 0x13},
192         {0x06, 0x02, 0x14},
193         {0x06, 0x8a, 0x51},
194         {0x06, 0x40, 0x52},
195         {0x06, 0xb6, 0x53},
196         {0x06, 0x3d, 0x54},
197         /* End of extra block */
198
199                 {0x06, 0x3f, 0x1},
200                 /* Block skipped */
201         {0x06, 0x10, 0x02},
202         {0x06, 0x64, 0x07},
203         {0x06, 0x10, 0x08},
204         {0x06, 0x00, 0x09},
205         {0x06, 0x00, 0x0a},
206         {0x06, 0x00, 0x0b},
207         {0x06, 0x10, 0x0c},
208         {0x06, 0x00, 0x0d},
209         {0x06, 0x00, 0x0e},
210         {0x06, 0x00, 0x0f},
211         {0x06, 0x10, 0x10},
212         {0x06, 0x02, 0x11},
213         {0x06, 0x00, 0x12},
214         {0x06, 0x04, 0x13},
215         {0x06, 0x02, 0x14},
216         {0x06, 0x8a, 0x51},
217         {0x06, 0x40, 0x52},
218         {0x06, 0xb6, 0x53},
219         {0x06, 0x3d, 0x54},
220         {0x06, 0x60, 0x57},
221         {0x06, 0x20, 0x58},
222         {0x06, 0x15, 0x59},
223         {0x06, 0x05, 0x5a},
224
225         {0x05, 0x01, 0xc0},
226         {0x05, 0x10, 0xcb},
227                 {0x05, 0x80, 0xc1},
228                 /* */
229                 {0x05, 0x0, 0xc2},
230                 /* 4 was 0 */
231         {0x05, 0x00, 0xca},
232                 {0x05, 0x80, 0xc1},
233                 /*  */
234         {0x05, 0x04, 0xc2},
235         {0x05, 0x00, 0xca},
236                 {0x05, 0x0, 0xc1},
237                 /*  */
238         {0x05, 0x00, 0xc2},
239         {0x05, 0x00, 0xca},
240                 {0x05, 0x40, 0xc1},
241                 /* */
242         {0x05, 0x17, 0xc2},
243         {0x05, 0x00, 0xca},
244                 {0x05, 0x80, 0xc1},
245                 /* */
246         {0x05, 0x06, 0xc2},
247         {0x05, 0x00, 0xca},
248                 {0x05, 0x80, 0xc1},
249                 /* */
250         {0x05, 0x04, 0xc2},
251         {0x05, 0x00, 0xca},
252
253         {0x03, 0x4c, 0x3},
254         {0x03, 0x18, 0x1},
255
256         {0x06, 0x70, 0x51},
257         {0x06, 0xbe, 0x53},
258         {0x06, 0x71, 0x57},
259         {0x06, 0x20, 0x58},
260         {0x06, 0x05, 0x59},
261         {0x06, 0x15, 0x5a},
262
263         {0x04, 0x00, 0x08},
264         /* Compress = OFF (0x1 to turn on) */
265         {0x04, 0x12, 0x09},
266         {0x04, 0x21, 0x0a},
267         {0x04, 0x10, 0x0b},
268         {0x04, 0x21, 0x0c},
269         {0x04, 0x05, 0x00},
270         /* was 5 (Image Type ? ) */
271         {0x04, 0x00, 0x01},
272
273         {0x06, 0x3f, 0x01},
274
275         {0x04, 0x00, 0x04},
276         {0x04, 0x00, 0x05},
277         {0x04, 0x40, 0x06},
278         {0x04, 0x40, 0x07},
279
280         {0x06, 0x1c, 0x17},
281         {0x06, 0xe2, 0x19},
282         {0x06, 0x1c, 0x1b},
283         {0x06, 0xe2, 0x1d},
284         {0x06, 0xaa, 0x1f},
285         {0x06, 0x70, 0x20},
286
287         {0x05, 0x01, 0x10},
288         {0x05, 0x00, 0x11},
289         {0x05, 0x01, 0x00},
290         {0x05, 0x05, 0x01},
291                 {0x05, 0x00, 0xc1},
292                 /* */
293         {0x05, 0x00, 0xc2},
294         {0x05, 0x00, 0xca},
295
296         {0x06, 0x70, 0x51},
297         {0x06, 0xbe, 0x53},
298         {}
299 };
300
301 /*
302  * Made by Tomasz Zablocki (skalamandra@poczta.onet.pl)
303  * SPCA505b chip based cameras initialization data
304  */
305 /* jfm */
306 #define initial_brightness 0x7f /* 0x0(white)-0xff(black) */
307 /* #define initial_brightness 0x0       //0x0(white)-0xff(black) */
308 /*
309  * Data to initialize a SPCA505. Common to the CCD and external modes
310  */
311 static const u8 spca505b_init_data[][3] = {
312 /* start */
313         {0x02, 0x00, 0x00},             /* init */
314         {0x02, 0x00, 0x01},
315         {0x02, 0x00, 0x02},
316         {0x02, 0x00, 0x03},
317         {0x02, 0x00, 0x04},
318         {0x02, 0x00, 0x05},
319         {0x02, 0x00, 0x06},
320         {0x02, 0x00, 0x07},
321         {0x02, 0x00, 0x08},
322         {0x02, 0x00, 0x09},
323         {0x03, 0x00, 0x00},
324         {0x03, 0x00, 0x01},
325         {0x03, 0x00, 0x02},
326         {0x03, 0x00, 0x03},
327         {0x03, 0x00, 0x04},
328         {0x03, 0x00, 0x05},
329         {0x03, 0x00, 0x06},
330         {0x04, 0x00, 0x00},
331         {0x04, 0x00, 0x02},
332         {0x04, 0x00, 0x04},
333         {0x04, 0x00, 0x05},
334         {0x04, 0x00, 0x06},
335         {0x04, 0x00, 0x07},
336         {0x04, 0x00, 0x08},
337         {0x04, 0x00, 0x09},
338         {0x04, 0x00, 0x0a},
339         {0x04, 0x00, 0x0b},
340         {0x04, 0x00, 0x0c},
341         {0x07, 0x00, 0x00},
342         {0x07, 0x00, 0x03},
343         {0x08, 0x00, 0x00},
344         {0x08, 0x00, 0x01},
345         {0x08, 0x00, 0x02},
346         {0x06, 0x18, 0x08},
347         {0x06, 0xfc, 0x09},
348         {0x06, 0xfc, 0x0a},
349         {0x06, 0xfc, 0x0b},
350         {0x06, 0x18, 0x0c},
351         {0x06, 0xfc, 0x0d},
352         {0x06, 0xfc, 0x0e},
353         {0x06, 0xfc, 0x0f},
354         {0x06, 0x18, 0x10},
355         {0x06, 0xfe, 0x12},
356         {0x06, 0x00, 0x11},
357         {0x06, 0x00, 0x14},
358         {0x06, 0x00, 0x13},
359         {0x06, 0x28, 0x51},
360         {0x06, 0xff, 0x53},
361         {0x02, 0x00, 0x08},
362
363         {0x03, 0x00, 0x03},
364         {0x03, 0x10, 0x03},
365         {}
366 };
367
368 /*
369  * Data to initialize the camera using the internal CCD
370  */
371 static const u8 spca505b_open_data_ccd[][3] = {
372
373 /* {0x02,0x00,0x00}, */
374         {0x03, 0x04, 0x01},             /* rst */
375         {0x03, 0x00, 0x01},
376         {0x03, 0x00, 0x00},
377         {0x03, 0x21, 0x00},
378         {0x03, 0x00, 0x04},
379         {0x03, 0x00, 0x03},
380         {0x03, 0x18, 0x03},
381         {0x03, 0x08, 0x01},
382         {0x03, 0x1c, 0x03},
383         {0x03, 0x5c, 0x03},
384         {0x03, 0x5c, 0x03},
385         {0x03, 0x18, 0x01},
386
387 /* same as 505 */
388         {0x04, 0x10, 0x01},
389         {0x04, 0x00, 0x04},
390         {0x04, 0x00, 0x05},
391         {0x04, 0x20, 0x06},
392         {0x04, 0x20, 0x07},
393
394         {0x08, 0x0a, 0x00},
395
396         {0x05, 0x00, 0x10},
397         {0x05, 0x00, 0x11},
398         {0x05, 0x00, 0x12},
399         {0x05, 0x6f, 0x00},
400         {0x05, initial_brightness >> 6, 0x00},
401         {0x05, (initial_brightness << 2) & 0xff, 0x01},
402         {0x05, 0x00, 0x02},
403         {0x05, 0x01, 0x03},
404         {0x05, 0x00, 0x04},
405         {0x05, 0x03, 0x05},
406         {0x05, 0xe0, 0x06},
407         {0x05, 0x20, 0x07},
408         {0x05, 0xa0, 0x08},
409         {0x05, 0x00, 0x12},
410         {0x05, 0x02, 0x0f},
411         {0x05, 0x80, 0x14},             /* max exposure off (0=on) */
412         {0x05, 0x01, 0xb0},
413         {0x05, 0x01, 0xbf},
414         {0x03, 0x02, 0x06},
415         {0x05, 0x10, 0x46},
416         {0x05, 0x08, 0x4a},
417
418         {0x06, 0x00, 0x01},
419         {0x06, 0x10, 0x02},
420         {0x06, 0x64, 0x07},
421         {0x06, 0x18, 0x08},
422         {0x06, 0xfc, 0x09},
423         {0x06, 0xfc, 0x0a},
424         {0x06, 0xfc, 0x0b},
425         {0x04, 0x00, 0x01},
426         {0x06, 0x18, 0x0c},
427         {0x06, 0xfc, 0x0d},
428         {0x06, 0xfc, 0x0e},
429         {0x06, 0xfc, 0x0f},
430         {0x06, 0x11, 0x10},             /* contrast */
431         {0x06, 0x00, 0x11},
432         {0x06, 0xfe, 0x12},
433         {0x06, 0x00, 0x13},
434         {0x06, 0x00, 0x14},
435         {0x06, 0x9d, 0x51},
436         {0x06, 0x40, 0x52},
437         {0x06, 0x7c, 0x53},
438         {0x06, 0x40, 0x54},
439         {0x06, 0x02, 0x57},
440         {0x06, 0x03, 0x58},
441         {0x06, 0x15, 0x59},
442         {0x06, 0x05, 0x5a},
443         {0x06, 0x03, 0x56},
444         {0x06, 0x02, 0x3f},
445         {0x06, 0x00, 0x40},
446         {0x06, 0x39, 0x41},
447         {0x06, 0x69, 0x42},
448         {0x06, 0x87, 0x43},
449         {0x06, 0x9e, 0x44},
450         {0x06, 0xb1, 0x45},
451         {0x06, 0xbf, 0x46},
452         {0x06, 0xcc, 0x47},
453         {0x06, 0xd5, 0x48},
454         {0x06, 0xdd, 0x49},
455         {0x06, 0xe3, 0x4a},
456         {0x06, 0xe8, 0x4b},
457         {0x06, 0xed, 0x4c},
458         {0x06, 0xf2, 0x4d},
459         {0x06, 0xf7, 0x4e},
460         {0x06, 0xfc, 0x4f},
461         {0x06, 0xff, 0x50},
462
463         {0x05, 0x01, 0xc0},
464         {0x05, 0x10, 0xcb},
465         {0x05, 0x40, 0xc1},
466         {0x05, 0x04, 0xc2},
467         {0x05, 0x00, 0xca},
468         {0x05, 0x40, 0xc1},
469         {0x05, 0x09, 0xc2},
470         {0x05, 0x00, 0xca},
471         {0x05, 0xc0, 0xc1},
472         {0x05, 0x09, 0xc2},
473         {0x05, 0x00, 0xca},
474         {0x05, 0x40, 0xc1},
475         {0x05, 0x59, 0xc2},
476         {0x05, 0x00, 0xca},
477         {0x04, 0x00, 0x01},
478         {0x05, 0x80, 0xc1},
479         {0x05, 0xec, 0xc2},
480         {0x05, 0x0, 0xca},
481
482         {0x06, 0x02, 0x57},
483         {0x06, 0x01, 0x58},
484         {0x06, 0x15, 0x59},
485         {0x06, 0x0a, 0x5a},
486         {0x06, 0x01, 0x57},
487         {0x06, 0x8a, 0x03},
488         {0x06, 0x0a, 0x6c},
489         {0x06, 0x30, 0x01},
490         {0x06, 0x20, 0x02},
491         {0x06, 0x00, 0x03},
492
493         {0x05, 0x8c, 0x25},
494
495         {0x06, 0x4d, 0x51},             /* maybe saturation (4d) */
496         {0x06, 0x84, 0x53},             /* making green (84) */
497         {0x06, 0x00, 0x57},             /* sharpness (1) */
498         {0x06, 0x18, 0x08},
499         {0x06, 0xfc, 0x09},
500         {0x06, 0xfc, 0x0a},
501         {0x06, 0xfc, 0x0b},
502         {0x06, 0x18, 0x0c},             /* maybe hue (18) */
503         {0x06, 0xfc, 0x0d},
504         {0x06, 0xfc, 0x0e},
505         {0x06, 0xfc, 0x0f},
506         {0x06, 0x18, 0x10},             /* maybe contrast (18) */
507
508         {0x05, 0x01, 0x02},
509
510         {0x04, 0x00, 0x08},             /* compression */
511         {0x04, 0x12, 0x09},
512         {0x04, 0x21, 0x0a},
513         {0x04, 0x10, 0x0b},
514         {0x04, 0x21, 0x0c},
515         {0x04, 0x1d, 0x00},             /* imagetype (1d) */
516         {0x04, 0x41, 0x01},             /* hardware snapcontrol */
517
518         {0x04, 0x00, 0x04},
519         {0x04, 0x00, 0x05},
520         {0x04, 0x10, 0x06},
521         {0x04, 0x10, 0x07},
522         {0x04, 0x40, 0x06},
523         {0x04, 0x40, 0x07},
524         {0x04, 0x00, 0x04},
525         {0x04, 0x00, 0x05},
526
527         {0x06, 0x1c, 0x17},
528         {0x06, 0xe2, 0x19},
529         {0x06, 0x1c, 0x1b},
530         {0x06, 0xe2, 0x1d},
531         {0x06, 0x5f, 0x1f},
532         {0x06, 0x32, 0x20},
533
534         {0x05, initial_brightness >> 6, 0x00},
535         {0x05, (initial_brightness << 2) & 0xff, 0x01},
536         {0x05, 0x06, 0xc1},
537         {0x05, 0x58, 0xc2},
538         {0x05, 0x00, 0xca},
539         {0x05, 0x00, 0x11},
540         {}
541 };
542
543 static int reg_write(struct gspca_dev *gspca_dev,
544                      u16 req, u16 index, u16 value)
545 {
546         int ret;
547         struct usb_device *dev = gspca_dev->dev;
548
549         ret = usb_control_msg(dev,
550                         usb_sndctrlpipe(dev, 0),
551                         req,
552                         USB_TYPE_VENDOR | USB_RECIP_DEVICE,
553                         value, index, NULL, 0, 500);
554         PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d",
555                 req, index, value, ret);
556         if (ret < 0)
557                 pr_err("reg write: error %d\n", ret);
558         return ret;
559 }
560
561 /* returns: negative is error, pos or zero is data */
562 static int reg_read(struct gspca_dev *gspca_dev,
563                         u16 req,        /* bRequest */
564                         u16 index)      /* wIndex */
565 {
566         int ret;
567
568         ret = usb_control_msg(gspca_dev->dev,
569                         usb_rcvctrlpipe(gspca_dev->dev, 0),
570                         req,
571                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
572                         0,                      /* value */
573                         index,
574                         gspca_dev->usb_buf, 2,
575                         500);                   /* timeout */
576         if (ret < 0)
577                 return ret;
578         return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
579 }
580
581 static int write_vector(struct gspca_dev *gspca_dev,
582                         const u8 data[][3])
583 {
584         int ret, i = 0;
585
586         while (data[i][0] != 0) {
587                 ret = reg_write(gspca_dev, data[i][0], data[i][2],
588                                                                 data[i][1]);
589                 if (ret < 0)
590                         return ret;
591                 i++;
592         }
593         return 0;
594 }
595
596 /* this function is called at probe time */
597 static int sd_config(struct gspca_dev *gspca_dev,
598                         const struct usb_device_id *id)
599 {
600         struct sd *sd = (struct sd *) gspca_dev;
601         struct cam *cam;
602
603         cam = &gspca_dev->cam;
604         cam->cam_mode = vga_mode;
605         sd->subtype = id->driver_info;
606         if (sd->subtype != IntelPCCameraPro)
607                 cam->nmodes = ARRAY_SIZE(vga_mode);
608         else                    /* no 640x480 for IntelPCCameraPro */
609                 cam->nmodes = ARRAY_SIZE(vga_mode) - 1;
610
611         return 0;
612 }
613
614 /* this function is called at probe and resume time */
615 static int sd_init(struct gspca_dev *gspca_dev)
616 {
617         struct sd *sd = (struct sd *) gspca_dev;
618
619         if (write_vector(gspca_dev,
620                          sd->subtype == Nxultra
621                                 ? spca505b_init_data
622                                 : spca505_init_data))
623                 return -EIO;
624         return 0;
625 }
626
627 static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness)
628 {
629         reg_write(gspca_dev, 0x05, 0x00, (255 - brightness) >> 6);
630         reg_write(gspca_dev, 0x05, 0x01, (255 - brightness) << 2);
631 }
632
633 static int sd_start(struct gspca_dev *gspca_dev)
634 {
635         struct sd *sd = (struct sd *) gspca_dev;
636         int ret, mode;
637         static u8 mode_tb[][3] = {
638         /*        r00   r06   r07       */
639                 {0x00, 0x10, 0x10},     /* 640x480 */
640                 {0x01, 0x1a, 0x1a},     /* 352x288 */
641                 {0x02, 0x1c, 0x1d},     /* 320x240 */
642                 {0x04, 0x34, 0x34},     /* 176x144 */
643                 {0x05, 0x40, 0x40}      /* 160x120 */
644         };
645
646         if (sd->subtype == Nxultra)
647                 write_vector(gspca_dev, spca505b_open_data_ccd);
648         else
649                 write_vector(gspca_dev, spca505_open_data_ccd);
650         ret = reg_read(gspca_dev, 0x06, 0x16);
651
652         if (ret < 0) {
653                 PERR("register read failed err: %d", ret);
654                 return ret;
655         }
656         if (ret != 0x0101) {
657                 pr_err("After vector read returns 0x%04x should be 0x0101\n",
658                        ret);
659         }
660
661         ret = reg_write(gspca_dev, 0x06, 0x16, 0x0a);
662         if (ret < 0)
663                 return ret;
664         reg_write(gspca_dev, 0x05, 0xc2, 0x12);
665
666         /* necessary because without it we can see stream
667          * only once after loading module */
668         /* stopping usb registers Tomasz change */
669         reg_write(gspca_dev, 0x02, 0x00, 0x00);
670
671         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
672         reg_write(gspca_dev, SPCA50X_REG_COMPRESS, 0x00, mode_tb[mode][0]);
673         reg_write(gspca_dev, SPCA50X_REG_COMPRESS, 0x06, mode_tb[mode][1]);
674         reg_write(gspca_dev, SPCA50X_REG_COMPRESS, 0x07, mode_tb[mode][2]);
675
676         return reg_write(gspca_dev, SPCA50X_REG_USB,
677                          SPCA50X_USB_CTRL,
678                          SPCA50X_CUSB_ENABLE);
679 }
680
681 static void sd_stopN(struct gspca_dev *gspca_dev)
682 {
683         /* Disable ISO packet machine */
684         reg_write(gspca_dev, 0x02, 0x00, 0x00);
685 }
686
687 /* called on streamoff with alt 0 and on disconnect */
688 static void sd_stop0(struct gspca_dev *gspca_dev)
689 {
690         if (!gspca_dev->present)
691                 return;
692
693         /* This maybe reset or power control */
694         reg_write(gspca_dev, 0x03, 0x03, 0x20);
695         reg_write(gspca_dev, 0x03, 0x01, 0x00);
696         reg_write(gspca_dev, 0x03, 0x00, 0x01);
697         reg_write(gspca_dev, 0x05, 0x10, 0x01);
698         reg_write(gspca_dev, 0x05, 0x11, 0x0f);
699 }
700
701 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
702                         u8 *data,                       /* isoc packet */
703                         int len)                        /* iso packet length */
704 {
705         switch (data[0]) {
706         case 0:                         /* start of frame */
707                 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
708                 data += SPCA50X_OFFSET_DATA;
709                 len -= SPCA50X_OFFSET_DATA;
710                 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
711                 break;
712         case 0xff:                      /* drop */
713                 break;
714         default:
715                 data += 1;
716                 len -= 1;
717                 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
718                 break;
719         }
720 }
721
722 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
723 {
724         struct gspca_dev *gspca_dev =
725                 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
726
727         gspca_dev->usb_err = 0;
728
729         if (!gspca_dev->streaming)
730                 return 0;
731
732         switch (ctrl->id) {
733         case V4L2_CID_BRIGHTNESS:
734                 setbrightness(gspca_dev, ctrl->val);
735                 break;
736         }
737         return gspca_dev->usb_err;
738 }
739
740 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
741         .s_ctrl = sd_s_ctrl,
742 };
743
744 static int sd_init_controls(struct gspca_dev *gspca_dev)
745 {
746         struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
747
748         gspca_dev->vdev.ctrl_handler = hdl;
749         v4l2_ctrl_handler_init(hdl, 5);
750         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
751                         V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
752
753         if (hdl->error) {
754                 pr_err("Could not initialize controls\n");
755                 return hdl->error;
756         }
757         return 0;
758 }
759
760 /* sub-driver description */
761 static const struct sd_desc sd_desc = {
762         .name = MODULE_NAME,
763         .config = sd_config,
764         .init_controls = sd_init_controls,
765         .init = sd_init,
766         .start = sd_start,
767         .stopN = sd_stopN,
768         .stop0 = sd_stop0,
769         .pkt_scan = sd_pkt_scan,
770 };
771
772 /* -- module initialisation -- */
773 static const struct usb_device_id device_table[] = {
774         {USB_DEVICE(0x041e, 0x401d), .driver_info = Nxultra},
775         {USB_DEVICE(0x0733, 0x0430), .driver_info = IntelPCCameraPro},
776 /*fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */
777         {}
778 };
779 MODULE_DEVICE_TABLE(usb, device_table);
780
781 /* -- device connect -- */
782 static int sd_probe(struct usb_interface *intf,
783                         const struct usb_device_id *id)
784 {
785         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
786                                 THIS_MODULE);
787 }
788
789 static struct usb_driver sd_driver = {
790         .name = MODULE_NAME,
791         .id_table = device_table,
792         .probe = sd_probe,
793         .disconnect = gspca_disconnect,
794 #ifdef CONFIG_PM
795         .suspend = gspca_suspend,
796         .resume = gspca_resume,
797         .reset_resume = gspca_resume,
798 #endif
799 };
800
801 module_usb_driver(sd_driver);