xen: make CPU hotplug functions static
[safe/jmp/linux-2.6] / drivers / media / video / gspca / sunplus.c
1 /*
2  *              Sunplus spca504(abc) spca533 spca536 library
3  *              Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
4  *
5  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21
22 #define MODULE_NAME "sunplus"
23
24 #include "gspca.h"
25 #include "jpeg.h"
26
27 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
28 MODULE_DESCRIPTION("GSPCA/SPCA5xx 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 packet[ISO_MAX_SIZE + 128];
36                                 /* !! no more than 128 ff in an ISO packet */
37
38         unsigned char brightness;
39         unsigned char contrast;
40         unsigned char colors;
41         unsigned char autogain;
42
43         char qindex;
44         char bridge;
45 #define BRIDGE_SPCA504 0
46 #define BRIDGE_SPCA504B 1
47 #define BRIDGE_SPCA504C 2
48 #define BRIDGE_SPCA533 3
49 #define BRIDGE_SPCA536 4
50         char subtype;
51 #define AiptekMiniPenCam13 1
52 #define LogitechClickSmart420 2
53 #define LogitechClickSmart820 3
54 #define MegapixV4 4
55 };
56
57 /* V4L2 controls supported by the driver */
58 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
59 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
60 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
61 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
62 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
63 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
64 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
65 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
66
67 static struct ctrl sd_ctrls[] = {
68 #define SD_BRIGHTNESS 0
69         {
70             {
71                 .id      = V4L2_CID_BRIGHTNESS,
72                 .type    = V4L2_CTRL_TYPE_INTEGER,
73                 .name    = "Brightness",
74                 .minimum = 0,
75                 .maximum = 0xff,
76                 .step    = 1,
77                 .default_value = 0,
78             },
79             .set = sd_setbrightness,
80             .get = sd_getbrightness,
81         },
82 #define SD_CONTRAST 1
83         {
84             {
85                 .id      = V4L2_CID_CONTRAST,
86                 .type    = V4L2_CTRL_TYPE_INTEGER,
87                 .name    = "Contrast",
88                 .minimum = 0,
89                 .maximum = 0xff,
90                 .step    = 1,
91                 .default_value = 0x20,
92             },
93             .set = sd_setcontrast,
94             .get = sd_getcontrast,
95         },
96 #define SD_COLOR 2
97         {
98             {
99                 .id      = V4L2_CID_SATURATION,
100                 .type    = V4L2_CTRL_TYPE_INTEGER,
101                 .name    = "Color",
102                 .minimum = 0,
103                 .maximum = 0xff,
104                 .step    = 1,
105                 .default_value = 0x1a,
106             },
107             .set = sd_setcolors,
108             .get = sd_getcolors,
109         },
110 #define SD_AUTOGAIN 3
111         {
112             {
113                 .id      = V4L2_CID_AUTOGAIN,
114                 .type    = V4L2_CTRL_TYPE_BOOLEAN,
115                 .name    = "Auto Gain",
116                 .minimum = 0,
117                 .maximum = 1,
118                 .step    = 1,
119                 .default_value = 1,
120             },
121             .set = sd_setautogain,
122             .get = sd_getautogain,
123         },
124 };
125
126 static struct v4l2_pix_format vga_mode[] = {
127         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
128                 .bytesperline = 320,
129                 .sizeimage = 320 * 240 * 3 / 8 + 590,
130                 .colorspace = V4L2_COLORSPACE_JPEG,
131                 .priv = 2},
132         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
133                 .bytesperline = 640,
134                 .sizeimage = 640 * 480 * 3 / 8 + 590,
135                 .colorspace = V4L2_COLORSPACE_JPEG,
136                 .priv = 1},
137 };
138
139 static struct v4l2_pix_format custom_mode[] = {
140         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
141                 .bytesperline = 320,
142                 .sizeimage = 320 * 240 * 3 / 8 + 590,
143                 .colorspace = V4L2_COLORSPACE_JPEG,
144                 .priv = 2},
145         {464, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
146                 .bytesperline = 464,
147                 .sizeimage = 464 * 480 * 3 / 8 + 590,
148                 .colorspace = V4L2_COLORSPACE_JPEG,
149                 .priv = 1},
150 };
151
152 static struct v4l2_pix_format vga_mode2[] = {
153         {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
154                 .bytesperline = 176,
155                 .sizeimage = 176 * 144 * 3 / 8 + 590,
156                 .colorspace = V4L2_COLORSPACE_JPEG,
157                 .priv = 4},
158         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
159                 .bytesperline = 320,
160                 .sizeimage = 320 * 240 * 3 / 8 + 590,
161                 .colorspace = V4L2_COLORSPACE_JPEG,
162                 .priv = 3},
163         {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
164                 .bytesperline = 352,
165                 .sizeimage = 352 * 288 * 3 / 8 + 590,
166                 .colorspace = V4L2_COLORSPACE_JPEG,
167                 .priv = 2},
168         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
169                 .bytesperline = 640,
170                 .sizeimage = 640 * 480 * 3 / 8 + 590,
171                 .colorspace = V4L2_COLORSPACE_JPEG,
172                 .priv = 1},
173 };
174
175 #define SPCA50X_OFFSET_DATA 10
176 #define SPCA504_PCCAM600_OFFSET_SNAPSHOT 3
177 #define SPCA504_PCCAM600_OFFSET_COMPRESS 4
178 #define SPCA504_PCCAM600_OFFSET_MODE     5
179 #define SPCA504_PCCAM600_OFFSET_DATA     14
180  /* Frame packet header offsets for the spca533 */
181 #define SPCA533_OFFSET_DATA      16
182 #define SPCA533_OFFSET_FRAMSEQ  15
183 /* Frame packet header offsets for the spca536 */
184 #define SPCA536_OFFSET_DATA      4
185 #define SPCA536_OFFSET_FRAMSEQ   1
186
187 /* Initialisation data for the Creative PC-CAM 600 */
188 static const __u16 spca504_pccam600_init_data[][3] = {
189 /*      {0xa0, 0x0000, 0x0503},  * capture mode */
190         {0x00, 0x0000, 0x2000},
191         {0x00, 0x0013, 0x2301},
192         {0x00, 0x0003, 0x2000},
193         {0x00, 0x0001, 0x21ac},
194         {0x00, 0x0001, 0x21a6},
195         {0x00, 0x0000, 0x21a7}, /* brightness */
196         {0x00, 0x0020, 0x21a8}, /* contrast */
197         {0x00, 0x0001, 0x21ac}, /* sat/hue */
198         {0x00, 0x0000, 0x21ad}, /* hue */
199         {0x00, 0x001a, 0x21ae}, /* saturation */
200         {0x00, 0x0002, 0x21a3}, /* gamma */
201         {0x30, 0x0154, 0x0008},
202         {0x30, 0x0004, 0x0006},
203         {0x30, 0x0258, 0x0009},
204         {0x30, 0x0004, 0x0000},
205         {0x30, 0x0093, 0x0004},
206         {0x30, 0x0066, 0x0005},
207         {0x00, 0x0000, 0x2000},
208         {0x00, 0x0013, 0x2301},
209         {0x00, 0x0003, 0x2000},
210         {0x00, 0x0013, 0x2301},
211         {0x00, 0x0003, 0x2000},
212         {}
213 };
214
215 /* Creative PC-CAM 600 specific open data, sent before using the
216  * generic initialisation data from spca504_open_data.
217  */
218 static const __u16 spca504_pccam600_open_data[][3] = {
219         {0x00, 0x0001, 0x2501},
220         {0x20, 0x0500, 0x0001}, /* snapshot mode */
221         {0x00, 0x0003, 0x2880},
222         {0x00, 0x0001, 0x2881},
223         {}
224 };
225
226 /* Initialisation data for the logitech clicksmart 420 */
227 static const __u16 spca504A_clicksmart420_init_data[][3] = {
228 /*      {0xa0, 0x0000, 0x0503},  * capture mode */
229         {0x00, 0x0000, 0x2000},
230         {0x00, 0x0013, 0x2301},
231         {0x00, 0x0003, 0x2000},
232         {0x00, 0x0001, 0x21ac},
233         {0x00, 0x0001, 0x21a6},
234         {0x00, 0x0000, 0x21a7}, /* brightness */
235         {0x00, 0x0020, 0x21a8}, /* contrast */
236         {0x00, 0x0001, 0x21ac}, /* sat/hue */
237         {0x00, 0x0000, 0x21ad}, /* hue */
238         {0x00, 0x001a, 0x21ae}, /* saturation */
239         {0x00, 0x0002, 0x21a3}, /* gamma */
240         {0x30, 0x0004, 0x000a},
241         {0xb0, 0x0001, 0x0000},
242
243
244         {0x0a1, 0x0080, 0x0001},
245         {0x30, 0x0049, 0x0000},
246         {0x30, 0x0060, 0x0005},
247         {0x0c, 0x0004, 0x0000},
248         {0x00, 0x0000, 0x0000},
249         {0x00, 0x0000, 0x2000},
250         {0x00, 0x0013, 0x2301},
251         {0x00, 0x0003, 0x2000},
252         {0x00, 0x0000, 0x2000},
253
254         {}
255 };
256
257 /* clicksmart 420 open data ? */
258 static const __u16 spca504A_clicksmart420_open_data[][3] = {
259         {0x00, 0x0001, 0x2501},
260         {0x20, 0x0502, 0x0000},
261         {0x06, 0x0000, 0x0000},
262         {0x00, 0x0004, 0x2880},
263         {0x00, 0x0001, 0x2881},
264 /* look like setting a qTable */
265         {0x00, 0x0006, 0x2800},
266         {0x00, 0x0004, 0x2801},
267         {0x00, 0x0004, 0x2802},
268         {0x00, 0x0006, 0x2803},
269         {0x00, 0x000a, 0x2804},
270         {0x00, 0x0010, 0x2805},
271         {0x00, 0x0014, 0x2806},
272         {0x00, 0x0018, 0x2807},
273         {0x00, 0x0005, 0x2808},
274         {0x00, 0x0005, 0x2809},
275         {0x00, 0x0006, 0x280a},
276         {0x00, 0x0008, 0x280b},
277         {0x00, 0x000a, 0x280c},
278         {0x00, 0x0017, 0x280d},
279         {0x00, 0x0018, 0x280e},
280         {0x00, 0x0016, 0x280f},
281
282         {0x00, 0x0006, 0x2810},
283         {0x00, 0x0005, 0x2811},
284         {0x00, 0x0006, 0x2812},
285         {0x00, 0x000a, 0x2813},
286         {0x00, 0x0010, 0x2814},
287         {0x00, 0x0017, 0x2815},
288         {0x00, 0x001c, 0x2816},
289         {0x00, 0x0016, 0x2817},
290         {0x00, 0x0006, 0x2818},
291         {0x00, 0x0007, 0x2819},
292         {0x00, 0x0009, 0x281a},
293         {0x00, 0x000c, 0x281b},
294         {0x00, 0x0014, 0x281c},
295         {0x00, 0x0023, 0x281d},
296         {0x00, 0x0020, 0x281e},
297         {0x00, 0x0019, 0x281f},
298
299         {0x00, 0x0007, 0x2820},
300         {0x00, 0x0009, 0x2821},
301         {0x00, 0x000f, 0x2822},
302         {0x00, 0x0016, 0x2823},
303         {0x00, 0x001b, 0x2824},
304         {0x00, 0x002c, 0x2825},
305         {0x00, 0x0029, 0x2826},
306         {0x00, 0x001f, 0x2827},
307         {0x00, 0x000a, 0x2828},
308         {0x00, 0x000e, 0x2829},
309         {0x00, 0x0016, 0x282a},
310         {0x00, 0x001a, 0x282b},
311         {0x00, 0x0020, 0x282c},
312         {0x00, 0x002a, 0x282d},
313         {0x00, 0x002d, 0x282e},
314         {0x00, 0x0025, 0x282f},
315
316         {0x00, 0x0014, 0x2830},
317         {0x00, 0x001a, 0x2831},
318         {0x00, 0x001f, 0x2832},
319         {0x00, 0x0023, 0x2833},
320         {0x00, 0x0029, 0x2834},
321         {0x00, 0x0030, 0x2835},
322         {0x00, 0x0030, 0x2836},
323         {0x00, 0x0028, 0x2837},
324         {0x00, 0x001d, 0x2838},
325         {0x00, 0x0025, 0x2839},
326         {0x00, 0x0026, 0x283a},
327         {0x00, 0x0027, 0x283b},
328         {0x00, 0x002d, 0x283c},
329         {0x00, 0x0028, 0x283d},
330         {0x00, 0x0029, 0x283e},
331         {0x00, 0x0028, 0x283f},
332
333         {0x00, 0x0007, 0x2840},
334         {0x00, 0x0007, 0x2841},
335         {0x00, 0x000a, 0x2842},
336         {0x00, 0x0013, 0x2843},
337         {0x00, 0x0028, 0x2844},
338         {0x00, 0x0028, 0x2845},
339         {0x00, 0x0028, 0x2846},
340         {0x00, 0x0028, 0x2847},
341         {0x00, 0x0007, 0x2848},
342         {0x00, 0x0008, 0x2849},
343         {0x00, 0x000a, 0x284a},
344         {0x00, 0x001a, 0x284b},
345         {0x00, 0x0028, 0x284c},
346         {0x00, 0x0028, 0x284d},
347         {0x00, 0x0028, 0x284e},
348         {0x00, 0x0028, 0x284f},
349
350         {0x00, 0x000a, 0x2850},
351         {0x00, 0x000a, 0x2851},
352         {0x00, 0x0016, 0x2852},
353         {0x00, 0x0028, 0x2853},
354         {0x00, 0x0028, 0x2854},
355         {0x00, 0x0028, 0x2855},
356         {0x00, 0x0028, 0x2856},
357         {0x00, 0x0028, 0x2857},
358         {0x00, 0x0013, 0x2858},
359         {0x00, 0x001a, 0x2859},
360         {0x00, 0x0028, 0x285a},
361         {0x00, 0x0028, 0x285b},
362         {0x00, 0x0028, 0x285c},
363         {0x00, 0x0028, 0x285d},
364         {0x00, 0x0028, 0x285e},
365         {0x00, 0x0028, 0x285f},
366
367         {0x00, 0x0028, 0x2860},
368         {0x00, 0x0028, 0x2861},
369         {0x00, 0x0028, 0x2862},
370         {0x00, 0x0028, 0x2863},
371         {0x00, 0x0028, 0x2864},
372         {0x00, 0x0028, 0x2865},
373         {0x00, 0x0028, 0x2866},
374         {0x00, 0x0028, 0x2867},
375         {0x00, 0x0028, 0x2868},
376         {0x00, 0x0028, 0x2869},
377         {0x00, 0x0028, 0x286a},
378         {0x00, 0x0028, 0x286b},
379         {0x00, 0x0028, 0x286c},
380         {0x00, 0x0028, 0x286d},
381         {0x00, 0x0028, 0x286e},
382         {0x00, 0x0028, 0x286f},
383
384         {0x00, 0x0028, 0x2870},
385         {0x00, 0x0028, 0x2871},
386         {0x00, 0x0028, 0x2872},
387         {0x00, 0x0028, 0x2873},
388         {0x00, 0x0028, 0x2874},
389         {0x00, 0x0028, 0x2875},
390         {0x00, 0x0028, 0x2876},
391         {0x00, 0x0028, 0x2877},
392         {0x00, 0x0028, 0x2878},
393         {0x00, 0x0028, 0x2879},
394         {0x00, 0x0028, 0x287a},
395         {0x00, 0x0028, 0x287b},
396         {0x00, 0x0028, 0x287c},
397         {0x00, 0x0028, 0x287d},
398         {0x00, 0x0028, 0x287e},
399         {0x00, 0x0028, 0x287f},
400
401         {0xa0, 0x0000, 0x0503},
402         {}
403 };
404
405 static const __u8 qtable_creative_pccam[2][64] = {
406         {                               /* Q-table Y-components */
407          0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
408          0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
409          0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
410          0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
411          0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
412          0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
413          0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
414          0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
415         {                               /* Q-table C-components */
416          0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
417          0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
418          0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
419          0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
420          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
421          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
422          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
423          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
424 };
425
426 /* FIXME: This Q-table is identical to the Creative PC-CAM one,
427  *              except for one byte. Possibly a typo?
428  *              NWG: 18/05/2003.
429  */
430 static const __u8 qtable_spca504_default[2][64] = {
431         {                               /* Q-table Y-components */
432          0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
433          0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
434          0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
435          0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
436          0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
437          0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
438          0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
439          0x16, 0x1c, 0x1d, 0x1d, 0x1d /* 0x22 */ , 0x1e, 0x1f, 0x1e,
440          },
441         {                               /* Q-table C-components */
442          0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
443          0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
444          0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
445          0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
446          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
447          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
448          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
449          0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
450 };
451
452 static void reg_r(struct usb_device *dev,
453                            __u16 req,
454                            __u16 index,
455                            __u8 *buffer, __u16 length)
456 {
457         usb_control_msg(dev,
458                         usb_rcvctrlpipe(dev, 0),
459                         req,
460                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
461                         0,              /* value */
462                         index, buffer, length,
463                         500);
464 }
465
466 static void reg_w(struct usb_device *dev,
467                             __u16 req,
468                             __u16 value,
469                             __u16 index,
470                             __u8 *buffer, __u16 length)
471 {
472         usb_control_msg(dev,
473                         usb_sndctrlpipe(dev, 0),
474                         req,
475                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
476                         value, index, buffer, length,
477                         500);
478 }
479
480 /* write req / index / value */
481 static int reg_w_riv(struct usb_device *dev,
482                      __u16 req, __u16 index, __u16 value)
483 {
484         int ret;
485
486         ret = usb_control_msg(dev,
487                         usb_sndctrlpipe(dev, 0),
488                         req,
489                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
490                         value, index, NULL, 0, 500);
491         PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d",
492                 req, index, value, ret);
493         if (ret < 0)
494                 PDEBUG(D_ERR, "reg write: error %d", ret);
495         return ret;
496 }
497
498 /* read 1 byte */
499 static int reg_r_1(struct gspca_dev *gspca_dev,
500                         __u16 value)    /* wValue */
501 {
502         int ret;
503
504         ret = usb_control_msg(gspca_dev->dev,
505                         usb_rcvctrlpipe(gspca_dev->dev, 0),
506                         0x20,                   /* request */
507                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
508                         value,
509                         0,                      /* index */
510                         gspca_dev->usb_buf, 1,
511                         500);                   /* timeout */
512         if (ret < 0) {
513                 PDEBUG(D_ERR, "reg_r_1 err %d", ret);
514                 return 0;
515         }
516         return gspca_dev->usb_buf[0];
517 }
518
519 /* read 1 or 2 bytes - returns < 0 if error */
520 static int reg_r_12(struct gspca_dev *gspca_dev,
521                         __u16 req,      /* bRequest */
522                         __u16 index,    /* wIndex */
523                         __u16 length)   /* wLength (1 or 2 only) */
524 {
525         int ret;
526
527         gspca_dev->usb_buf[1] = 0;
528         ret = usb_control_msg(gspca_dev->dev,
529                         usb_rcvctrlpipe(gspca_dev->dev, 0),
530                         req,
531                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
532                         0,              /* value */
533                         index,
534                         gspca_dev->usb_buf, length,
535                         500);
536         if (ret < 0) {
537                 PDEBUG(D_ERR, "reg_read err %d", ret);
538                 return -1;
539         }
540         return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
541 }
542
543 static int write_vector(struct gspca_dev *gspca_dev,
544                         const __u16 data[][3])
545 {
546         struct usb_device *dev = gspca_dev->dev;
547         int ret, i = 0;
548
549         while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
550                 ret = reg_w_riv(dev, data[i][0], data[i][2], data[i][1]);
551                 if (ret < 0) {
552                         PDEBUG(D_ERR,
553                                 "Register write failed for 0x%x,0x%x,0x%x",
554                                 data[i][0], data[i][1], data[i][2]);
555                         return ret;
556                 }
557                 i++;
558         }
559         return 0;
560 }
561
562 static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
563                                 unsigned int request,
564                                 unsigned int ybase,
565                                 unsigned int cbase,
566                                 const __u8 qtable[2][64])
567 {
568         struct usb_device *dev = gspca_dev->dev;
569         int i, err;
570
571         /* loop over y components */
572         for (i = 0; i < 64; i++) {
573                 err = reg_w_riv(dev, request, ybase + i, qtable[0][i]);
574                 if (err < 0)
575                         return err;
576         }
577
578         /* loop over c components */
579         for (i = 0; i < 64; i++) {
580                 err = reg_w_riv(dev, request, cbase + i, qtable[1][i]);
581                 if (err < 0)
582                         return err;
583         }
584         return 0;
585 }
586
587 static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
588                              __u16 req, __u16 idx, __u16 val)
589 {
590         struct usb_device *dev = gspca_dev->dev;
591         __u8 notdone;
592
593         reg_w_riv(dev, req, idx, val);
594         notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
595         reg_w_riv(dev, req, idx, val);
596
597         PDEBUG(D_FRAM, "before wait 0x%x", notdone);
598
599         msleep(200);
600         notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
601         PDEBUG(D_FRAM, "after wait 0x%x", notdone);
602 }
603
604 static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
605                         __u16 req,
606                         __u16 idx, __u16 val, __u8 stat, __u8 count)
607 {
608         struct usb_device *dev = gspca_dev->dev;
609         __u8 status;
610         __u8 endcode;
611
612         reg_w_riv(dev, req, idx, val);
613         status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
614         endcode = stat;
615         PDEBUG(D_FRAM, "Status 0x%x Need 0x%x", status, stat);
616         if (!count)
617                 return;
618         count = 200;
619         while (--count > 0) {
620                 msleep(10);
621                 /* gsmart mini2 write a each wait setting 1 ms is enought */
622 /*              reg_w_riv(dev, req, idx, val); */
623                 status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
624                 if (status == endcode) {
625                         PDEBUG(D_FRAM, "status 0x%x after wait 0x%x",
626                                 status, 200 - count);
627                                 break;
628                 }
629         }
630 }
631
632 static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
633 {
634         int count = 10;
635
636         while (--count > 0) {
637                 reg_r(gspca_dev->dev, 0x21, 0, gspca_dev->usb_buf, 1);
638                 if ((gspca_dev->usb_buf[0] & 0x01) == 0)
639                         break;
640                 msleep(10);
641         }
642         return gspca_dev->usb_buf[0];
643 }
644
645 static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
646 {
647         struct usb_device *dev = gspca_dev->dev;
648         int count = 50;
649
650         while (--count > 0) {
651                 reg_r(dev, 0x21, 1, gspca_dev->usb_buf, 1);
652                 if (gspca_dev->usb_buf[0] != 0) {
653                         gspca_dev->usb_buf[0] = 0;
654                         reg_w(dev, 0x21, 0, 1, gspca_dev->usb_buf, 1);
655                         reg_r(dev, 0x21, 1, gspca_dev->usb_buf, 1);
656                         spca504B_PollingDataReady(gspca_dev);
657                         break;
658                 }
659                 msleep(10);
660         }
661 }
662
663 static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
664 {
665         struct usb_device *dev = gspca_dev->dev;
666         __u8 *data;
667
668         data = kmalloc(64, GFP_KERNEL);
669         reg_r(dev, 0x20, 0, data, 5);
670         PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ",
671                 data[0], data[1], data[2], data[3], data[4]);
672         reg_r(dev, 0x23, 0, data, 64);
673         reg_r(dev, 0x23, 1, data, 64);
674         kfree(data);
675 }
676
677 static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
678 {
679         struct sd *sd = (struct sd *) gspca_dev;
680         struct usb_device *dev = gspca_dev->dev;
681         __u8 Size;
682         __u8 Type;
683         int rc;
684
685         Size = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
686         Type = 0;
687         switch (sd->bridge) {
688         case BRIDGE_SPCA533:
689                 reg_w(dev, 0x31, 0, 0, NULL, 0);
690                 spca504B_WaitCmdStatus(gspca_dev);
691                 rc = spca504B_PollingDataReady(gspca_dev);
692                 spca50x_GetFirmware(gspca_dev);
693                 gspca_dev->usb_buf[0] = 2;                      /* type */
694                 reg_w(dev, 0x24, 0, 8, gspca_dev->usb_buf, 1);
695                 reg_r(dev, 0x24, 8, gspca_dev->usb_buf, 1);
696
697                 gspca_dev->usb_buf[0] = Size;
698                 reg_w(dev, 0x25, 0, 4, gspca_dev->usb_buf, 1);
699                 reg_r(dev, 0x25, 4, gspca_dev->usb_buf, 1);     /* size */
700                 rc = spca504B_PollingDataReady(gspca_dev);
701
702                 /* Init the cam width height with some values get on init ? */
703                 reg_w(dev, 0x31, 0, 4, NULL, 0);
704                 spca504B_WaitCmdStatus(gspca_dev);
705                 rc = spca504B_PollingDataReady(gspca_dev);
706                 break;
707         default:
708 /* case BRIDGE_SPCA504B: */
709 /* case BRIDGE_SPCA536: */
710                 gspca_dev->usb_buf[0] = Size;
711                 reg_w(dev, 0x25, 0, 4, gspca_dev->usb_buf, 1);
712                 reg_r(dev, 0x25, 4, gspca_dev->usb_buf, 1);     /* size */
713                 Type = 6;
714                 gspca_dev->usb_buf[0] = Type;
715                 reg_w(dev, 0x27, 0, 0, gspca_dev->usb_buf, 1);
716                 reg_r(dev, 0x27, 0, gspca_dev->usb_buf, 1);     /* type */
717                 rc = spca504B_PollingDataReady(gspca_dev);
718                 break;
719         case BRIDGE_SPCA504:
720                 Size += 3;
721                 if (sd->subtype == AiptekMiniPenCam13) {
722                         /* spca504a aiptek */
723                         spca504A_acknowledged_command(gspca_dev,
724                                                 0x08, Size, 0,
725                                                 0x80 | (Size & 0x0f), 1);
726                         spca504A_acknowledged_command(gspca_dev,
727                                                         1, 3, 0, 0x9f, 0);
728                 } else {
729                         spca504_acknowledged_command(gspca_dev, 0x08, Size, 0);
730                 }
731                 break;
732         case BRIDGE_SPCA504C:
733                 /* capture mode */
734                 reg_w_riv(dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00);
735                 reg_w_riv(dev, 0x20, 0x01, 0x0500 | (Size & 0x0f));
736                 break;
737         }
738 }
739
740 static void spca504_wait_status(struct gspca_dev *gspca_dev)
741 {
742         int cnt;
743
744         cnt = 256;
745         while (--cnt > 0) {
746                 /* With this we get the status, when return 0 it's all ok */
747                 if (reg_r_12(gspca_dev, 0x06, 0x00, 1) == 0)
748                         return;
749                 msleep(10);
750         }
751 }
752
753 static void spca504B_setQtable(struct gspca_dev *gspca_dev)
754 {
755         struct usb_device *dev = gspca_dev->dev;
756
757         gspca_dev->usb_buf[0] = 3;
758         reg_w(dev, 0x26, 0, 0, gspca_dev->usb_buf, 1);
759         reg_r(dev, 0x26, 0, gspca_dev->usb_buf, 1);
760         spca504B_PollingDataReady(gspca_dev);
761 }
762
763 static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev)
764 {
765         struct sd *sd = (struct sd *) gspca_dev;
766         struct usb_device *dev = gspca_dev->dev;
767         int pollreg = 1;
768
769         switch (sd->bridge) {
770         case BRIDGE_SPCA504:
771         case BRIDGE_SPCA504C:
772                 pollreg = 0;
773                 /* fall thru */
774         default:
775 /*      case BRIDGE_SPCA533: */
776 /*      case BRIDGE_SPCA504B: */
777                 reg_w(dev, 0, 0, 0x21a7, NULL, 0);      /* brightness */
778                 reg_w(dev, 0, 0x20, 0x21a8, NULL, 0);   /* contrast */
779                 reg_w(dev, 0, 0, 0x21ad, NULL, 0);      /* hue */
780                 reg_w(dev, 0, 1, 0x21ac, NULL, 0);      /* sat/hue */
781                 reg_w(dev, 0, 0x20, 0x21ae, NULL, 0);   /* saturation */
782                 reg_w(dev, 0, 0, 0x21a3, NULL, 0);      /* gamma */
783                 break;
784         case BRIDGE_SPCA536:
785                 reg_w(dev, 0, 0, 0x20f0, NULL, 0);
786                 reg_w(dev, 0, 0x21, 0x20f1, NULL, 0);
787                 reg_w(dev, 0, 0x40, 0x20f5, NULL, 0);
788                 reg_w(dev, 0, 1, 0x20f4, NULL, 0);
789                 reg_w(dev, 0, 0x40, 0x20f6, NULL, 0);
790                 reg_w(dev, 0, 0, 0x2089, NULL, 0);
791                 break;
792         }
793         if (pollreg)
794                 spca504B_PollingDataReady(gspca_dev);
795 }
796
797 /* this function is called at probe time */
798 static int sd_config(struct gspca_dev *gspca_dev,
799                         const struct usb_device_id *id)
800 {
801         struct sd *sd = (struct sd *) gspca_dev;
802         struct usb_device *dev = gspca_dev->dev;
803         struct cam *cam;
804
805         cam = &gspca_dev->cam;
806         cam->epaddr = 0x01;
807
808         sd->bridge = id->driver_info >> 8;
809         sd->subtype = id->driver_info;
810
811         if (sd->subtype == AiptekMiniPenCam13) {
812 /* try to get the firmware as some cam answer 2.0.1.2.2
813  * and should be a spca504b then overwrite that setting */
814                 reg_r(dev, 0x20, 0, gspca_dev->usb_buf, 1);
815                 switch (gspca_dev->usb_buf[0]) {
816                 case 1:
817                         break;          /* (right bridge/subtype) */
818                 case 2:
819                         sd->bridge = BRIDGE_SPCA504B;
820                         sd->subtype = 0;
821                         break;
822                 default:
823                         return -ENODEV;
824                 }
825         }
826
827         switch (sd->bridge) {
828         default:
829 /*      case BRIDGE_SPCA504B: */
830 /*      case BRIDGE_SPCA504: */
831 /*      case BRIDGE_SPCA536: */
832                 cam->cam_mode = vga_mode;
833                 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
834                 break;
835         case BRIDGE_SPCA533:
836                 cam->cam_mode = custom_mode;
837                 cam->nmodes = sizeof custom_mode / sizeof custom_mode[0];
838                 break;
839         case BRIDGE_SPCA504C:
840                 cam->cam_mode = vga_mode2;
841                 cam->nmodes = sizeof vga_mode2 / sizeof vga_mode2[0];
842                 break;
843         }
844         sd->qindex = 5;                 /* set the quantization table */
845         sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
846         sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
847         sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
848         return 0;
849 }
850
851 /* this function is called at open time */
852 static int sd_open(struct gspca_dev *gspca_dev)
853 {
854         struct sd *sd = (struct sd *) gspca_dev;
855         struct usb_device *dev = gspca_dev->dev;
856         int rc;
857         __u8 i;
858         __u8 info[6];
859         int err_code;
860
861         switch (sd->bridge) {
862         case BRIDGE_SPCA504B:
863                 reg_w(dev, 0x1d, 0, 0, NULL, 0);
864                 reg_w(dev, 0, 1, 0x2306, NULL, 0);
865                 reg_w(dev, 0, 0, 0x0d04, NULL, 0);
866                 reg_w(dev, 0, 0, 0x2000, NULL, 0);
867                 reg_w(dev, 0, 0x13, 0x2301, NULL, 0);
868                 reg_w(dev, 0, 0, 0x2306, NULL, 0);
869                 /* fall thru */
870         case BRIDGE_SPCA533:
871                 rc = spca504B_PollingDataReady(gspca_dev);
872                 spca50x_GetFirmware(gspca_dev);
873                 break;
874         case BRIDGE_SPCA536:
875                 spca50x_GetFirmware(gspca_dev);
876                 reg_r(dev, 0x00, 0x5002, gspca_dev->usb_buf, 1);
877                 gspca_dev->usb_buf[0] = 0;
878                 reg_w(dev, 0x24, 0, 0, gspca_dev->usb_buf, 1);
879                 reg_r(dev, 0x24, 0, gspca_dev->usb_buf, 1);
880                 rc = spca504B_PollingDataReady(gspca_dev);
881                 reg_w(dev, 0x34, 0, 0, NULL, 0);
882                 spca504B_WaitCmdStatus(gspca_dev);
883                 break;
884         case BRIDGE_SPCA504C:   /* pccam600 */
885                 PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)");
886                 reg_w_riv(dev, 0xe0, 0x0000, 0x0000);
887                 reg_w_riv(dev, 0xe0, 0x0000, 0x0001);   /* reset */
888                 spca504_wait_status(gspca_dev);
889                 if (sd->subtype == LogitechClickSmart420)
890                         write_vector(gspca_dev,
891                                         spca504A_clicksmart420_open_data);
892                 else
893                         write_vector(gspca_dev, spca504_pccam600_open_data);
894                 err_code = spca50x_setup_qtable(gspca_dev,
895                                                 0x00, 0x2800,
896                                                 0x2840, qtable_creative_pccam);
897                 if (err_code < 0) {
898                         PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed");
899                         return err_code;
900                 }
901                 break;
902         default:
903 /*      case BRIDGE_SPCA504: */
904                 PDEBUG(D_STREAM, "Opening SPCA504");
905                 if (sd->subtype == AiptekMiniPenCam13) {
906                         /*****************************/
907                         for (i = 0; i < 6; i++)
908                                 info[i] = reg_r_1(gspca_dev, i);
909                         PDEBUG(D_STREAM,
910                                 "Read info: %d %d %d %d %d %d."
911                                 " Should be 1,0,2,2,0,0",
912                                 info[0], info[1], info[2],
913                                 info[3], info[4], info[5]);
914                         /* spca504a aiptek */
915                         /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
916                         spca504A_acknowledged_command(gspca_dev, 0x24,
917                                                         8, 3, 0x9e, 1);
918                         /* Twice sequencial need status 0xff->0x9e->0x9d */
919                         spca504A_acknowledged_command(gspca_dev, 0x24,
920                                                         8, 3, 0x9e, 0);
921
922                         spca504A_acknowledged_command(gspca_dev, 0x24,
923                                                         0, 0, 0x9d, 1);
924                         /******************************/
925                         /* spca504a aiptek */
926                         spca504A_acknowledged_command(gspca_dev, 0x08,
927                                                         6, 0, 0x86, 1);
928 /*                      reg_write (dev, 0, 0x2000, 0); */
929 /*                      reg_write (dev, 0, 0x2883, 1); */
930 /*                      spca504A_acknowledged_command (gspca_dev, 0x08,
931                                                         6, 0, 0x86, 1); */
932 /*                      spca504A_acknowledged_command (gspca_dev, 0x24,
933                                                         0, 0, 0x9D, 1); */
934                         reg_w_riv(dev, 0x0, 0x270c, 0x05); /* L92 sno1t.txt */
935                         reg_w_riv(dev, 0x0, 0x2310, 0x05);
936                         spca504A_acknowledged_command(gspca_dev, 0x01,
937                                                         0x0f, 0, 0xff, 0);
938                 }
939                 /* setup qtable */
940                 reg_w_riv(dev, 0, 0x2000, 0);
941                 reg_w_riv(dev, 0, 0x2883, 1);
942                 err_code = spca50x_setup_qtable(gspca_dev,
943                                                 0x00, 0x2800,
944                                                 0x2840,
945                                                 qtable_spca504_default);
946                 if (err_code < 0) {
947                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
948                         return err_code;
949                 }
950                 break;
951         }
952         return 0;
953 }
954
955 static void sd_start(struct gspca_dev *gspca_dev)
956 {
957         struct sd *sd = (struct sd *) gspca_dev;
958         struct usb_device *dev = gspca_dev->dev;
959         int rc;
960         int enable;
961         __u8 i;
962         __u8 info[6];
963
964         if (sd->bridge == BRIDGE_SPCA504B)
965                 spca504B_setQtable(gspca_dev);
966         spca504B_SetSizeType(gspca_dev);
967         switch (sd->bridge) {
968         default:
969 /*      case BRIDGE_SPCA504B: */
970 /*      case BRIDGE_SPCA533: */
971 /*      case BRIDGE_SPCA536: */
972                 if (sd->subtype == MegapixV4 ||
973                     sd->subtype == LogitechClickSmart820) {
974                         reg_w(dev, 0xf0, 0, 0, NULL, 0);
975                         spca504B_WaitCmdStatus(gspca_dev);
976                         reg_r(dev, 0xf0, 4, NULL, 0);
977                         spca504B_WaitCmdStatus(gspca_dev);
978                 } else {
979                         reg_w(dev, 0x31, 0, 4, NULL, 0);
980                         spca504B_WaitCmdStatus(gspca_dev);
981                         rc = spca504B_PollingDataReady(gspca_dev);
982                 }
983                 break;
984         case BRIDGE_SPCA504:
985                 if (sd->subtype == AiptekMiniPenCam13) {
986                         for (i = 0; i < 6; i++)
987                                 info[i] = reg_r_1(gspca_dev, i);
988                         PDEBUG(D_STREAM,
989                                 "Read info: %d %d %d %d %d %d."
990                                 " Should be 1,0,2,2,0,0",
991                                 info[0], info[1], info[2],
992                                 info[3], info[4], info[5]);
993                         /* spca504a aiptek */
994                         /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
995                         spca504A_acknowledged_command(gspca_dev, 0x24,
996                                                         8, 3, 0x9e, 1);
997                         /* Twice sequencial need status 0xff->0x9e->0x9d */
998                         spca504A_acknowledged_command(gspca_dev, 0x24,
999                                                         8, 3, 0x9e, 0);
1000                         spca504A_acknowledged_command(gspca_dev, 0x24,
1001                                                         0, 0, 0x9d, 1);
1002                 } else {
1003                         spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
1004                         for (i = 0; i < 6; i++)
1005                                 info[i] = reg_r_1(gspca_dev, i);
1006                         PDEBUG(D_STREAM,
1007                                 "Read info: %d %d %d %d %d %d."
1008                                 " Should be 1,0,2,2,0,0",
1009                                 info[0], info[1], info[2],
1010                                 info[3], info[4], info[5]);
1011                         spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
1012                         spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
1013                 }
1014                 spca504B_SetSizeType(gspca_dev);
1015                 reg_w_riv(dev, 0x0, 0x270c, 0x05);      /* L92 sno1t.txt */
1016                 reg_w_riv(dev, 0x0, 0x2310, 0x05);
1017                 break;
1018         case BRIDGE_SPCA504C:
1019                 if (sd->subtype == LogitechClickSmart420) {
1020                         write_vector(gspca_dev,
1021                                         spca504A_clicksmart420_init_data);
1022                 } else {
1023                         write_vector(gspca_dev, spca504_pccam600_init_data);
1024                 }
1025                 enable = (sd->autogain ? 0x04 : 0x01);
1026                 reg_w_riv(dev, 0x0c, 0x0000, enable);   /* auto exposure */
1027                 reg_w_riv(dev, 0xb0, 0x0000, enable);   /* auto whiteness */
1028
1029                 /* set default exposure compensation and whiteness balance */
1030                 reg_w_riv(dev, 0x30, 0x0001, 800);      /* ~ 20 fps */
1031                 reg_w_riv(dev, 0x30, 0x0002, 1600);
1032                 spca504B_SetSizeType(gspca_dev);
1033                 break;
1034         }
1035         sp5xx_initContBrigHueRegisters(gspca_dev);
1036 }
1037
1038 static void sd_stopN(struct gspca_dev *gspca_dev)
1039 {
1040         struct sd *sd = (struct sd *) gspca_dev;
1041         struct usb_device *dev = gspca_dev->dev;
1042
1043         switch (sd->bridge) {
1044         default:
1045 /*      case BRIDGE_SPCA533: */
1046 /*      case BRIDGE_SPCA536: */
1047 /*      case BRIDGE_SPCA504B: */
1048                 reg_w(dev, 0x31, 0, 0, NULL, 0);
1049                 spca504B_WaitCmdStatus(gspca_dev);
1050                 spca504B_PollingDataReady(gspca_dev);
1051                 break;
1052         case BRIDGE_SPCA504:
1053         case BRIDGE_SPCA504C:
1054                 reg_w_riv(dev, 0x00, 0x2000, 0x0000);
1055
1056                 if (sd->subtype == AiptekMiniPenCam13) {
1057                         /* spca504a aiptek */
1058 /*                      spca504A_acknowledged_command(gspca_dev, 0x08,
1059                                                          6, 0, 0x86, 1); */
1060                         spca504A_acknowledged_command(gspca_dev, 0x24,
1061                                                         0x00, 0x00, 0x9d, 1);
1062                         spca504A_acknowledged_command(gspca_dev, 0x01,
1063                                                         0x0f, 0x00, 0xff, 1);
1064                 } else {
1065                         spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
1066                         reg_w_riv(dev, 0x01, 0x000f, 0x00);
1067                 }
1068                 break;
1069         }
1070 }
1071
1072 static void sd_stop0(struct gspca_dev *gspca_dev)
1073 {
1074 }
1075
1076 static void sd_close(struct gspca_dev *gspca_dev)
1077 {
1078 }
1079
1080 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1081                         struct gspca_frame *frame,      /* target */
1082                         __u8 *data,                     /* isoc packet */
1083                         int len)                        /* iso packet length */
1084 {
1085         struct sd *sd = (struct sd *) gspca_dev;
1086         int i, sof = 0;
1087         unsigned char *s, *d;
1088         static unsigned char ffd9[] = {0xff, 0xd9};
1089
1090 /* frames are jpeg 4.1.1 without 0xff escape */
1091         switch (sd->bridge) {
1092         case BRIDGE_SPCA533:
1093                 if (data[0] == 0xff) {
1094                         if (data[1] != 0x01) {  /* drop packet */
1095 /*                              gspca_dev->last_packet_type = DISCARD_PACKET; */
1096                                 return;
1097                         }
1098                         sof = 1;
1099                         data += SPCA533_OFFSET_DATA;
1100                         len -= SPCA533_OFFSET_DATA;
1101                 } else {
1102                         data += 1;
1103                         len -= 1;
1104                 }
1105                 break;
1106         case BRIDGE_SPCA536:
1107                 if (data[0] == 0xff) {
1108                         sof = 1;
1109                         data += SPCA536_OFFSET_DATA;
1110                         len -= SPCA536_OFFSET_DATA;
1111                 } else {
1112                         data += 2;
1113                         len -= 2;
1114                 }
1115                 break;
1116         default:
1117 /*      case BRIDGE_SPCA504: */
1118 /*      case BRIDGE_SPCA504B: */
1119                 switch (data[0]) {
1120                 case 0xfe:                      /* start of frame */
1121                         sof = 1;
1122                         data += SPCA50X_OFFSET_DATA;
1123                         len -= SPCA50X_OFFSET_DATA;
1124                         break;
1125                 case 0xff:                      /* drop packet */
1126 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
1127                         return;
1128                 default:
1129                         data += 1;
1130                         len -= 1;
1131                         break;
1132                 }
1133                 break;
1134         case BRIDGE_SPCA504C:
1135                 switch (data[0]) {
1136                 case 0xfe:                      /* start of frame */
1137                         sof = 1;
1138                         data += SPCA504_PCCAM600_OFFSET_DATA;
1139                         len -= SPCA504_PCCAM600_OFFSET_DATA;
1140                         break;
1141                 case 0xff:                      /* drop packet */
1142 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
1143                         return;
1144                 default:
1145                         data += 1;
1146                         len -= 1;
1147                         break;
1148                 }
1149                 break;
1150         }
1151         if (sof) {              /* start of frame */
1152                 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
1153                                         ffd9, 2);
1154
1155                 /* put the JPEG header in the new frame */
1156                 jpeg_put_header(gspca_dev, frame,
1157                                 ((struct sd *) gspca_dev)->qindex,
1158                                 0x22);
1159         }
1160
1161         /* add 0x00 after 0xff */
1162         for (i = len; --i >= 0; )
1163                 if (data[i] == 0xff)
1164                         break;
1165         if (i < 0) {                    /* no 0xff */
1166                 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1167                 return;
1168         }
1169         s = data;
1170         d = sd->packet;
1171         for (i = 0; i < len; i++) {
1172                 *d++ = *s++;
1173                 if (s[-1] == 0xff)
1174                         *d++ = 0x00;
1175         }
1176         gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1177                         sd->packet, d - sd->packet);
1178 }
1179
1180 static void setbrightness(struct gspca_dev *gspca_dev)
1181 {
1182         struct sd *sd = (struct sd *) gspca_dev;
1183         struct usb_device *dev = gspca_dev->dev;
1184
1185         switch (sd->bridge) {
1186         default:
1187 /*      case BRIDGE_SPCA533: */
1188 /*      case BRIDGE_SPCA504B: */
1189 /*      case BRIDGE_SPCA504: */
1190 /*      case BRIDGE_SPCA504C: */
1191                 reg_w_riv(dev, 0x0, 0x21a7, sd->brightness);
1192                 break;
1193         case BRIDGE_SPCA536:
1194                 reg_w_riv(dev, 0x0, 0x20f0, sd->brightness);
1195                 break;
1196         }
1197 }
1198
1199 static void getbrightness(struct gspca_dev *gspca_dev)
1200 {
1201         struct sd *sd = (struct sd *) gspca_dev;
1202         __u16 brightness = 0;
1203
1204         switch (sd->bridge) {
1205         default:
1206 /*      case BRIDGE_SPCA533: */
1207 /*      case BRIDGE_SPCA504B: */
1208 /*      case BRIDGE_SPCA504: */
1209 /*      case BRIDGE_SPCA504C: */
1210                 brightness = reg_r_12(gspca_dev, 0x00, 0x21a7, 2);
1211                 break;
1212         case BRIDGE_SPCA536:
1213                 brightness = reg_r_12(gspca_dev, 0x00, 0x20f0, 2);
1214                 break;
1215         }
1216         sd->brightness = ((brightness & 0xff) - 128) % 255;
1217 }
1218
1219 static void setcontrast(struct gspca_dev *gspca_dev)
1220 {
1221         struct sd *sd = (struct sd *) gspca_dev;
1222         struct usb_device *dev = gspca_dev->dev;
1223
1224         switch (sd->bridge) {
1225         default:
1226 /*      case BRIDGE_SPCA533: */
1227 /*      case BRIDGE_SPCA504B: */
1228 /*      case BRIDGE_SPCA504: */
1229 /*      case BRIDGE_SPCA504C: */
1230                 reg_w_riv(dev, 0x0, 0x21a8, sd->contrast);
1231                 break;
1232         case BRIDGE_SPCA536:
1233                 reg_w_riv(dev, 0x0, 0x20f1, sd->contrast);
1234                 break;
1235         }
1236 }
1237
1238 static void getcontrast(struct gspca_dev *gspca_dev)
1239 {
1240         struct sd *sd = (struct sd *) gspca_dev;
1241
1242         switch (sd->bridge) {
1243         default:
1244 /*      case BRIDGE_SPCA533: */
1245 /*      case BRIDGE_SPCA504B: */
1246 /*      case BRIDGE_SPCA504: */
1247 /*      case BRIDGE_SPCA504C: */
1248                 sd->contrast = reg_r_12(gspca_dev, 0x00, 0x21a8, 2);
1249                 break;
1250         case BRIDGE_SPCA536:
1251                 sd->contrast = reg_r_12(gspca_dev, 0x00, 0x20f1, 2);
1252                 break;
1253         }
1254 }
1255
1256 static void setcolors(struct gspca_dev *gspca_dev)
1257 {
1258         struct sd *sd = (struct sd *) gspca_dev;
1259         struct usb_device *dev = gspca_dev->dev;
1260
1261         switch (sd->bridge) {
1262         default:
1263 /*      case BRIDGE_SPCA533: */
1264 /*      case BRIDGE_SPCA504B: */
1265 /*      case BRIDGE_SPCA504: */
1266 /*      case BRIDGE_SPCA504C: */
1267                 reg_w_riv(dev, 0x0, 0x21ae, sd->colors);
1268                 break;
1269         case BRIDGE_SPCA536:
1270                 reg_w_riv(dev, 0x0, 0x20f6, sd->colors);
1271                 break;
1272         }
1273 }
1274
1275 static void getcolors(struct gspca_dev *gspca_dev)
1276 {
1277         struct sd *sd = (struct sd *) gspca_dev;
1278
1279         switch (sd->bridge) {
1280         default:
1281 /*      case BRIDGE_SPCA533: */
1282 /*      case BRIDGE_SPCA504B: */
1283 /*      case BRIDGE_SPCA504: */
1284 /*      case BRIDGE_SPCA504C: */
1285                 sd->colors = reg_r_12(gspca_dev, 0x00, 0x21ae, 2) >> 1;
1286                 break;
1287         case BRIDGE_SPCA536:
1288                 sd->colors = reg_r_12(gspca_dev, 0x00, 0x20f6, 2) >> 1;
1289                 break;
1290         }
1291 }
1292
1293 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1294 {
1295         struct sd *sd = (struct sd *) gspca_dev;
1296
1297         sd->brightness = val;
1298         if (gspca_dev->streaming)
1299                 setbrightness(gspca_dev);
1300         return 0;
1301 }
1302
1303 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1304 {
1305         struct sd *sd = (struct sd *) gspca_dev;
1306
1307         getbrightness(gspca_dev);
1308         *val = sd->brightness;
1309         return 0;
1310 }
1311
1312 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1313 {
1314         struct sd *sd = (struct sd *) gspca_dev;
1315
1316         sd->contrast = val;
1317         if (gspca_dev->streaming)
1318                 setcontrast(gspca_dev);
1319         return 0;
1320 }
1321
1322 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1323 {
1324         struct sd *sd = (struct sd *) gspca_dev;
1325
1326         getcontrast(gspca_dev);
1327         *val = sd->contrast;
1328         return 0;
1329 }
1330
1331 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1332 {
1333         struct sd *sd = (struct sd *) gspca_dev;
1334
1335         sd->colors = val;
1336         if (gspca_dev->streaming)
1337                 setcolors(gspca_dev);
1338         return 0;
1339 }
1340
1341 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1342 {
1343         struct sd *sd = (struct sd *) gspca_dev;
1344
1345         getcolors(gspca_dev);
1346         *val = sd->colors;
1347         return 0;
1348 }
1349
1350 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1351 {
1352         struct sd *sd = (struct sd *) gspca_dev;
1353
1354         sd->autogain = val;
1355         return 0;
1356 }
1357
1358 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1359 {
1360         struct sd *sd = (struct sd *) gspca_dev;
1361
1362         *val = sd->autogain;
1363         return 0;
1364 }
1365
1366 /* sub-driver description */
1367 static const struct sd_desc sd_desc = {
1368         .name = MODULE_NAME,
1369         .ctrls = sd_ctrls,
1370         .nctrls = ARRAY_SIZE(sd_ctrls),
1371         .config = sd_config,
1372         .open = sd_open,
1373         .start = sd_start,
1374         .stopN = sd_stopN,
1375         .stop0 = sd_stop0,
1376         .close = sd_close,
1377         .pkt_scan = sd_pkt_scan,
1378 };
1379
1380 /* -- module initialisation -- */
1381 #define BS(bridge, subtype) \
1382         .driver_info = (BRIDGE_ ## bridge << 8) \
1383                         | (subtype)
1384 static const __devinitdata struct usb_device_id device_table[] = {
1385         {USB_DEVICE(0x041e, 0x400b), BS(SPCA504C, 0)},
1386         {USB_DEVICE(0x041e, 0x4012), BS(SPCA504C, 0)},
1387         {USB_DEVICE(0x041e, 0x4013), BS(SPCA504C, 0)},
1388         {USB_DEVICE(0x0458, 0x7006), BS(SPCA504B, 0)},
1389         {USB_DEVICE(0x0461, 0x0821), BS(SPCA533, 0)},
1390         {USB_DEVICE(0x046d, 0x0905), BS(SPCA533, LogitechClickSmart820)},
1391         {USB_DEVICE(0x046d, 0x0960), BS(SPCA504C, LogitechClickSmart420)},
1392         {USB_DEVICE(0x0471, 0x0322), BS(SPCA504B, 0)},
1393         {USB_DEVICE(0x04a5, 0x3003), BS(SPCA504B, 0)},
1394         {USB_DEVICE(0x04a5, 0x3008), BS(SPCA533, 0)},
1395         {USB_DEVICE(0x04a5, 0x300a), BS(SPCA533, 0)},
1396         {USB_DEVICE(0x04f1, 0x1001), BS(SPCA504B, 0)},
1397         {USB_DEVICE(0x04fc, 0x500c), BS(SPCA504B, 0)},
1398         {USB_DEVICE(0x04fc, 0x504a), BS(SPCA504, AiptekMiniPenCam13)},
1399         {USB_DEVICE(0x04fc, 0x504b), BS(SPCA504B, 0)},
1400         {USB_DEVICE(0x04fc, 0x5330), BS(SPCA533, 0)},
1401         {USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)},
1402         {USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)},
1403         {USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)},
1404         {USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)},
1405         {USB_DEVICE(0x0546, 0x3191), BS(SPCA504B, 0)},
1406         {USB_DEVICE(0x0546, 0x3273), BS(SPCA504B, 0)},
1407         {USB_DEVICE(0x055f, 0xc211), BS(SPCA536, 0)},
1408         {USB_DEVICE(0x055f, 0xc230), BS(SPCA533, 0)},
1409         {USB_DEVICE(0x055f, 0xc232), BS(SPCA533, 0)},
1410         {USB_DEVICE(0x055f, 0xc360), BS(SPCA536, 0)},
1411         {USB_DEVICE(0x055f, 0xc420), BS(SPCA504, 0)},
1412         {USB_DEVICE(0x055f, 0xc430), BS(SPCA533, 0)},
1413         {USB_DEVICE(0x055f, 0xc440), BS(SPCA533, 0)},
1414         {USB_DEVICE(0x055f, 0xc520), BS(SPCA504, 0)},
1415         {USB_DEVICE(0x055f, 0xc530), BS(SPCA533, 0)},
1416         {USB_DEVICE(0x055f, 0xc540), BS(SPCA533, 0)},
1417         {USB_DEVICE(0x055f, 0xc630), BS(SPCA533, 0)},
1418         {USB_DEVICE(0x055f, 0xc650), BS(SPCA533, 0)},
1419         {USB_DEVICE(0x05da, 0x1018), BS(SPCA504B, 0)},
1420         {USB_DEVICE(0x06d6, 0x0031), BS(SPCA533, 0)},
1421         {USB_DEVICE(0x0733, 0x1311), BS(SPCA533, 0)},
1422         {USB_DEVICE(0x0733, 0x1314), BS(SPCA533, 0)},
1423         {USB_DEVICE(0x0733, 0x2211), BS(SPCA533, 0)},
1424         {USB_DEVICE(0x0733, 0x2221), BS(SPCA533, 0)},
1425         {USB_DEVICE(0x0733, 0x3261), BS(SPCA536, 0)},
1426         {USB_DEVICE(0x0733, 0x3281), BS(SPCA536, 0)},
1427         {USB_DEVICE(0x08ca, 0x0104), BS(SPCA533, 0)},
1428         {USB_DEVICE(0x08ca, 0x0106), BS(SPCA533, 0)},
1429         {USB_DEVICE(0x08ca, 0x2008), BS(SPCA504B, 0)},
1430         {USB_DEVICE(0x08ca, 0x2010), BS(SPCA533, 0)},
1431         {USB_DEVICE(0x08ca, 0x2016), BS(SPCA504B, 0)},
1432         {USB_DEVICE(0x08ca, 0x2018), BS(SPCA504B, 0)},
1433         {USB_DEVICE(0x08ca, 0x2020), BS(SPCA533, 0)},
1434         {USB_DEVICE(0x08ca, 0x2022), BS(SPCA533, 0)},
1435         {USB_DEVICE(0x08ca, 0x2024), BS(SPCA536, 0)},
1436         {USB_DEVICE(0x08ca, 0x2028), BS(SPCA533, 0)},
1437         {USB_DEVICE(0x08ca, 0x2040), BS(SPCA536, 0)},
1438         {USB_DEVICE(0x08ca, 0x2042), BS(SPCA536, 0)},
1439         {USB_DEVICE(0x08ca, 0x2050), BS(SPCA536, 0)},
1440         {USB_DEVICE(0x08ca, 0x2060), BS(SPCA536, 0)},
1441         {USB_DEVICE(0x0d64, 0x0303), BS(SPCA536, 0)},
1442         {}
1443 };
1444 MODULE_DEVICE_TABLE(usb, device_table);
1445
1446 /* -- device connect -- */
1447 static int sd_probe(struct usb_interface *intf,
1448                         const struct usb_device_id *id)
1449 {
1450         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1451                                 THIS_MODULE);
1452 }
1453
1454 static struct usb_driver sd_driver = {
1455         .name = MODULE_NAME,
1456         .id_table = device_table,
1457         .probe = sd_probe,
1458         .disconnect = gspca_disconnect,
1459 };
1460
1461 /* -- module insert / remove -- */
1462 static int __init sd_mod_init(void)
1463 {
1464         if (usb_register(&sd_driver) < 0)
1465                 return -1;
1466         PDEBUG(D_PROBE, "registered");
1467         return 0;
1468 }
1469 static void __exit sd_mod_exit(void)
1470 {
1471         usb_deregister(&sd_driver);
1472         PDEBUG(D_PROBE, "deregistered");
1473 }
1474
1475 module_init(sd_mod_init);
1476 module_exit(sd_mod_exit);