V4L/DVB (9863): gspca - sonixj: Cleanup / simplify code.
[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 /* read <len> bytes to gspca_dev->usb_buf */
453 static void reg_r(struct gspca_dev *gspca_dev,
454                   __u16 req,
455                   __u16 index,
456                   __u16 len)
457 {
458 #ifdef GSPCA_DEBUG
459         if (len > USB_BUF_SZ) {
460                 err("reg_r: buffer overflow");
461                 return;
462         }
463 #endif
464         usb_control_msg(gspca_dev->dev,
465                         usb_rcvctrlpipe(gspca_dev->dev, 0),
466                         req,
467                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
468                         0,              /* value */
469                         index,
470                         len ? gspca_dev->usb_buf : NULL, len,
471                         500);
472 }
473
474 /* write <len> bytes from gspca_dev->usb_buf */
475 static void reg_w(struct gspca_dev *gspca_dev,
476                    __u16 req,
477                    __u16 value,
478                    __u16 index,
479                    __u16 len)
480 {
481 #ifdef GSPCA_DEBUG
482         if (len > USB_BUF_SZ) {
483                 err("reg_w: buffer overflow");
484                 return;
485         }
486 #endif
487         usb_control_msg(gspca_dev->dev,
488                         usb_sndctrlpipe(gspca_dev->dev, 0),
489                         req,
490                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
491                         value, index,
492                         len ? gspca_dev->usb_buf : NULL, len,
493                         500);
494 }
495
496 /* write req / index / value */
497 static int reg_w_riv(struct usb_device *dev,
498                      __u16 req, __u16 index, __u16 value)
499 {
500         int ret;
501
502         ret = usb_control_msg(dev,
503                         usb_sndctrlpipe(dev, 0),
504                         req,
505                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
506                         value, index, NULL, 0, 500);
507         PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d",
508                 req, index, value, ret);
509         if (ret < 0)
510                 PDEBUG(D_ERR, "reg write: error %d", ret);
511         return ret;
512 }
513
514 /* read 1 byte */
515 static int reg_r_1(struct gspca_dev *gspca_dev,
516                         __u16 value)    /* wValue */
517 {
518         int ret;
519
520         ret = usb_control_msg(gspca_dev->dev,
521                         usb_rcvctrlpipe(gspca_dev->dev, 0),
522                         0x20,                   /* request */
523                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
524                         value,
525                         0,                      /* index */
526                         gspca_dev->usb_buf, 1,
527                         500);                   /* timeout */
528         if (ret < 0) {
529                 PDEBUG(D_ERR, "reg_r_1 err %d", ret);
530                 return 0;
531         }
532         return gspca_dev->usb_buf[0];
533 }
534
535 /* read 1 or 2 bytes - returns < 0 if error */
536 static int reg_r_12(struct gspca_dev *gspca_dev,
537                         __u16 req,      /* bRequest */
538                         __u16 index,    /* wIndex */
539                         __u16 length)   /* wLength (1 or 2 only) */
540 {
541         int ret;
542
543         gspca_dev->usb_buf[1] = 0;
544         ret = usb_control_msg(gspca_dev->dev,
545                         usb_rcvctrlpipe(gspca_dev->dev, 0),
546                         req,
547                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
548                         0,              /* value */
549                         index,
550                         gspca_dev->usb_buf, length,
551                         500);
552         if (ret < 0) {
553                 PDEBUG(D_ERR, "reg_read err %d", ret);
554                 return -1;
555         }
556         return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
557 }
558
559 static int write_vector(struct gspca_dev *gspca_dev,
560                         const __u16 data[][3])
561 {
562         struct usb_device *dev = gspca_dev->dev;
563         int ret, i = 0;
564
565         while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
566                 ret = reg_w_riv(dev, data[i][0], data[i][2], data[i][1]);
567                 if (ret < 0) {
568                         PDEBUG(D_ERR,
569                                 "Register write failed for 0x%x,0x%x,0x%x",
570                                 data[i][0], data[i][1], data[i][2]);
571                         return ret;
572                 }
573                 i++;
574         }
575         return 0;
576 }
577
578 static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
579                                 unsigned int request,
580                                 unsigned int ybase,
581                                 unsigned int cbase,
582                                 const __u8 qtable[2][64])
583 {
584         struct usb_device *dev = gspca_dev->dev;
585         int i, err;
586
587         /* loop over y components */
588         for (i = 0; i < 64; i++) {
589                 err = reg_w_riv(dev, request, ybase + i, qtable[0][i]);
590                 if (err < 0)
591                         return err;
592         }
593
594         /* loop over c components */
595         for (i = 0; i < 64; i++) {
596                 err = reg_w_riv(dev, request, cbase + i, qtable[1][i]);
597                 if (err < 0)
598                         return err;
599         }
600         return 0;
601 }
602
603 static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
604                              __u16 req, __u16 idx, __u16 val)
605 {
606         struct usb_device *dev = gspca_dev->dev;
607         __u8 notdone;
608
609         reg_w_riv(dev, req, idx, val);
610         notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
611         reg_w_riv(dev, req, idx, val);
612
613         PDEBUG(D_FRAM, "before wait 0x%x", notdone);
614
615         msleep(200);
616         notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
617         PDEBUG(D_FRAM, "after wait 0x%x", notdone);
618 }
619
620 static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
621                         __u16 req,
622                         __u16 idx, __u16 val, __u8 stat, __u8 count)
623 {
624         struct usb_device *dev = gspca_dev->dev;
625         __u8 status;
626         __u8 endcode;
627
628         reg_w_riv(dev, req, idx, val);
629         status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
630         endcode = stat;
631         PDEBUG(D_FRAM, "Status 0x%x Need 0x%x", status, stat);
632         if (!count)
633                 return;
634         count = 200;
635         while (--count > 0) {
636                 msleep(10);
637                 /* gsmart mini2 write a each wait setting 1 ms is enought */
638 /*              reg_w_riv(dev, req, idx, val); */
639                 status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
640                 if (status == endcode) {
641                         PDEBUG(D_FRAM, "status 0x%x after wait 0x%x",
642                                 status, 200 - count);
643                                 break;
644                 }
645         }
646 }
647
648 static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
649 {
650         int count = 10;
651
652         while (--count > 0) {
653                 reg_r(gspca_dev, 0x21, 0, 1);
654                 if ((gspca_dev->usb_buf[0] & 0x01) == 0)
655                         break;
656                 msleep(10);
657         }
658         return gspca_dev->usb_buf[0];
659 }
660
661 static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
662 {
663         int count = 50;
664
665         while (--count > 0) {
666                 reg_r(gspca_dev, 0x21, 1, 1);
667                 if (gspca_dev->usb_buf[0] != 0) {
668                         gspca_dev->usb_buf[0] = 0;
669                         reg_w(gspca_dev, 0x21, 0, 1, 1);
670                         reg_r(gspca_dev, 0x21, 1, 1);
671                         spca504B_PollingDataReady(gspca_dev);
672                         break;
673                 }
674                 msleep(10);
675         }
676 }
677
678 static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
679 {
680         __u8 *data;
681
682         data = gspca_dev->usb_buf;
683         reg_r(gspca_dev, 0x20, 0, 5);
684         PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ",
685                 data[0], data[1], data[2], data[3], data[4]);
686         reg_r(gspca_dev, 0x23, 0, 64);
687         reg_r(gspca_dev, 0x23, 1, 64);
688 }
689
690 static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
691 {
692         struct sd *sd = (struct sd *) gspca_dev;
693         struct usb_device *dev = gspca_dev->dev;
694         __u8 Size;
695         __u8 Type;
696         int rc;
697
698         Size = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
699         Type = 0;
700         switch (sd->bridge) {
701         case BRIDGE_SPCA533:
702                 reg_w(gspca_dev, 0x31, 0, 0, 0);
703                 spca504B_WaitCmdStatus(gspca_dev);
704                 rc = spca504B_PollingDataReady(gspca_dev);
705                 spca50x_GetFirmware(gspca_dev);
706                 gspca_dev->usb_buf[0] = 2;                      /* type */
707                 reg_w(gspca_dev, 0x24, 0, 8, 1);
708                 reg_r(gspca_dev, 0x24, 8, 1);
709
710                 gspca_dev->usb_buf[0] = Size;
711                 reg_w(gspca_dev, 0x25, 0, 4, 1);
712                 reg_r(gspca_dev, 0x25, 4, 1);                   /* size */
713                 rc = spca504B_PollingDataReady(gspca_dev);
714
715                 /* Init the cam width height with some values get on init ? */
716                 reg_w(gspca_dev, 0x31, 0, 4, 0);
717                 spca504B_WaitCmdStatus(gspca_dev);
718                 rc = spca504B_PollingDataReady(gspca_dev);
719                 break;
720         default:
721 /* case BRIDGE_SPCA504B: */
722 /* case BRIDGE_SPCA536: */
723                 gspca_dev->usb_buf[0] = Size;
724                 reg_w(gspca_dev, 0x25, 0, 4, 1);
725                 reg_r(gspca_dev, 0x25, 4, 1);                   /* size */
726                 Type = 6;
727                 gspca_dev->usb_buf[0] = Type;
728                 reg_w(gspca_dev, 0x27, 0, 0, 1);
729                 reg_r(gspca_dev, 0x27, 0, 1);                   /* type */
730                 rc = spca504B_PollingDataReady(gspca_dev);
731                 break;
732         case BRIDGE_SPCA504:
733                 Size += 3;
734                 if (sd->subtype == AiptekMiniPenCam13) {
735                         /* spca504a aiptek */
736                         spca504A_acknowledged_command(gspca_dev,
737                                                 0x08, Size, 0,
738                                                 0x80 | (Size & 0x0f), 1);
739                         spca504A_acknowledged_command(gspca_dev,
740                                                         1, 3, 0, 0x9f, 0);
741                 } else {
742                         spca504_acknowledged_command(gspca_dev, 0x08, Size, 0);
743                 }
744                 break;
745         case BRIDGE_SPCA504C:
746                 /* capture mode */
747                 reg_w_riv(dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00);
748                 reg_w_riv(dev, 0x20, 0x01, 0x0500 | (Size & 0x0f));
749                 break;
750         }
751 }
752
753 static void spca504_wait_status(struct gspca_dev *gspca_dev)
754 {
755         int cnt;
756
757         cnt = 256;
758         while (--cnt > 0) {
759                 /* With this we get the status, when return 0 it's all ok */
760                 if (reg_r_12(gspca_dev, 0x06, 0x00, 1) == 0)
761                         return;
762                 msleep(10);
763         }
764 }
765
766 static void spca504B_setQtable(struct gspca_dev *gspca_dev)
767 {
768         gspca_dev->usb_buf[0] = 3;
769         reg_w(gspca_dev, 0x26, 0, 0, 1);
770         reg_r(gspca_dev, 0x26, 0, 1);
771         spca504B_PollingDataReady(gspca_dev);
772 }
773
774 static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev)
775 {
776         struct sd *sd = (struct sd *) gspca_dev;
777         int pollreg = 1;
778
779         switch (sd->bridge) {
780         case BRIDGE_SPCA504:
781         case BRIDGE_SPCA504C:
782                 pollreg = 0;
783                 /* fall thru */
784         default:
785 /*      case BRIDGE_SPCA533: */
786 /*      case BRIDGE_SPCA504B: */
787                 reg_w(gspca_dev, 0, 0, 0x21a7, 0);      /* brightness */
788                 reg_w(gspca_dev, 0, 0x20, 0x21a8, 0);   /* contrast */
789                 reg_w(gspca_dev, 0, 0, 0x21ad, 0);      /* hue */
790                 reg_w(gspca_dev, 0, 1, 0x21ac, 0);      /* sat/hue */
791                 reg_w(gspca_dev, 0, 0x20, 0x21ae, 0);   /* saturation */
792                 reg_w(gspca_dev, 0, 0, 0x21a3, 0);      /* gamma */
793                 break;
794         case BRIDGE_SPCA536:
795                 reg_w(gspca_dev, 0, 0, 0x20f0, 0);
796                 reg_w(gspca_dev, 0, 0x21, 0x20f1, 0);
797                 reg_w(gspca_dev, 0, 0x40, 0x20f5, 0);
798                 reg_w(gspca_dev, 0, 1, 0x20f4, 0);
799                 reg_w(gspca_dev, 0, 0x40, 0x20f6, 0);
800                 reg_w(gspca_dev, 0, 0, 0x2089, 0);
801                 break;
802         }
803         if (pollreg)
804                 spca504B_PollingDataReady(gspca_dev);
805 }
806
807 /* this function is called at probe time */
808 static int sd_config(struct gspca_dev *gspca_dev,
809                         const struct usb_device_id *id)
810 {
811         struct sd *sd = (struct sd *) gspca_dev;
812         struct cam *cam;
813
814         cam = &gspca_dev->cam;
815         cam->epaddr = 0x01;
816
817         sd->bridge = id->driver_info >> 8;
818         sd->subtype = id->driver_info;
819
820         if (sd->subtype == AiptekMiniPenCam13) {
821 /* try to get the firmware as some cam answer 2.0.1.2.2
822  * and should be a spca504b then overwrite that setting */
823                 reg_r(gspca_dev, 0x20, 0, 1);
824                 switch (gspca_dev->usb_buf[0]) {
825                 case 1:
826                         break;          /* (right bridge/subtype) */
827                 case 2:
828                         sd->bridge = BRIDGE_SPCA504B;
829                         sd->subtype = 0;
830                         break;
831                 default:
832                         return -ENODEV;
833                 }
834         }
835
836         switch (sd->bridge) {
837         default:
838 /*      case BRIDGE_SPCA504B: */
839 /*      case BRIDGE_SPCA504: */
840 /*      case BRIDGE_SPCA536: */
841                 cam->cam_mode = vga_mode;
842                 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
843                 break;
844         case BRIDGE_SPCA533:
845                 cam->cam_mode = custom_mode;
846                 cam->nmodes = sizeof custom_mode / sizeof custom_mode[0];
847                 break;
848         case BRIDGE_SPCA504C:
849                 cam->cam_mode = vga_mode2;
850                 cam->nmodes = sizeof vga_mode2 / sizeof vga_mode2[0];
851                 break;
852         }
853         sd->qindex = 5;                 /* set the quantization table */
854         sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
855         sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
856         sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
857         return 0;
858 }
859
860 /* this function is called at probe and resume time */
861 static int sd_init(struct gspca_dev *gspca_dev)
862 {
863         struct sd *sd = (struct sd *) gspca_dev;
864         struct usb_device *dev = gspca_dev->dev;
865         int rc;
866         __u8 i;
867         __u8 info[6];
868         int err_code;
869
870         switch (sd->bridge) {
871         case BRIDGE_SPCA504B:
872                 reg_w(gspca_dev, 0x1d, 0, 0, 0);
873                 reg_w(gspca_dev, 0, 1, 0x2306, 0);
874                 reg_w(gspca_dev, 0, 0, 0x0d04, 0);
875                 reg_w(gspca_dev, 0, 0, 0x2000, 0);
876                 reg_w(gspca_dev, 0, 0x13, 0x2301, 0);
877                 reg_w(gspca_dev, 0, 0, 0x2306, 0);
878                 /* fall thru */
879         case BRIDGE_SPCA533:
880                 rc = spca504B_PollingDataReady(gspca_dev);
881                 spca50x_GetFirmware(gspca_dev);
882                 break;
883         case BRIDGE_SPCA536:
884                 spca50x_GetFirmware(gspca_dev);
885                 reg_r(gspca_dev, 0x00, 0x5002, 1);
886                 gspca_dev->usb_buf[0] = 0;
887                 reg_w(gspca_dev, 0x24, 0, 0, 1);
888                 reg_r(gspca_dev, 0x24, 0, 1);
889                 rc = spca504B_PollingDataReady(gspca_dev);
890                 reg_w(gspca_dev, 0x34, 0, 0, 0);
891                 spca504B_WaitCmdStatus(gspca_dev);
892                 break;
893         case BRIDGE_SPCA504C:   /* pccam600 */
894                 PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)");
895                 reg_w_riv(dev, 0xe0, 0x0000, 0x0000);
896                 reg_w_riv(dev, 0xe0, 0x0000, 0x0001);   /* reset */
897                 spca504_wait_status(gspca_dev);
898                 if (sd->subtype == LogitechClickSmart420)
899                         write_vector(gspca_dev,
900                                         spca504A_clicksmart420_open_data);
901                 else
902                         write_vector(gspca_dev, spca504_pccam600_open_data);
903                 err_code = spca50x_setup_qtable(gspca_dev,
904                                                 0x00, 0x2800,
905                                                 0x2840, qtable_creative_pccam);
906                 if (err_code < 0) {
907                         PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed");
908                         return err_code;
909                 }
910                 break;
911         default:
912 /*      case BRIDGE_SPCA504: */
913                 PDEBUG(D_STREAM, "Opening SPCA504");
914                 if (sd->subtype == AiptekMiniPenCam13) {
915                         /*****************************/
916                         for (i = 0; i < 6; i++)
917                                 info[i] = reg_r_1(gspca_dev, i);
918                         PDEBUG(D_STREAM,
919                                 "Read info: %d %d %d %d %d %d."
920                                 " Should be 1,0,2,2,0,0",
921                                 info[0], info[1], info[2],
922                                 info[3], info[4], info[5]);
923                         /* spca504a aiptek */
924                         /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
925                         spca504A_acknowledged_command(gspca_dev, 0x24,
926                                                         8, 3, 0x9e, 1);
927                         /* Twice sequencial need status 0xff->0x9e->0x9d */
928                         spca504A_acknowledged_command(gspca_dev, 0x24,
929                                                         8, 3, 0x9e, 0);
930
931                         spca504A_acknowledged_command(gspca_dev, 0x24,
932                                                         0, 0, 0x9d, 1);
933                         /******************************/
934                         /* spca504a aiptek */
935                         spca504A_acknowledged_command(gspca_dev, 0x08,
936                                                         6, 0, 0x86, 1);
937 /*                      reg_write (dev, 0, 0x2000, 0); */
938 /*                      reg_write (dev, 0, 0x2883, 1); */
939 /*                      spca504A_acknowledged_command (gspca_dev, 0x08,
940                                                         6, 0, 0x86, 1); */
941 /*                      spca504A_acknowledged_command (gspca_dev, 0x24,
942                                                         0, 0, 0x9D, 1); */
943                         reg_w_riv(dev, 0x0, 0x270c, 0x05); /* L92 sno1t.txt */
944                         reg_w_riv(dev, 0x0, 0x2310, 0x05);
945                         spca504A_acknowledged_command(gspca_dev, 0x01,
946                                                         0x0f, 0, 0xff, 0);
947                 }
948                 /* setup qtable */
949                 reg_w_riv(dev, 0, 0x2000, 0);
950                 reg_w_riv(dev, 0, 0x2883, 1);
951                 err_code = spca50x_setup_qtable(gspca_dev,
952                                                 0x00, 0x2800,
953                                                 0x2840,
954                                                 qtable_spca504_default);
955                 if (err_code < 0) {
956                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
957                         return err_code;
958                 }
959                 break;
960         }
961         return 0;
962 }
963
964 static int sd_start(struct gspca_dev *gspca_dev)
965 {
966         struct sd *sd = (struct sd *) gspca_dev;
967         struct usb_device *dev = gspca_dev->dev;
968         int rc;
969         int enable;
970         __u8 i;
971         __u8 info[6];
972
973         if (sd->bridge == BRIDGE_SPCA504B)
974                 spca504B_setQtable(gspca_dev);
975         spca504B_SetSizeType(gspca_dev);
976         switch (sd->bridge) {
977         default:
978 /*      case BRIDGE_SPCA504B: */
979 /*      case BRIDGE_SPCA533: */
980 /*      case BRIDGE_SPCA536: */
981                 if (sd->subtype == MegapixV4 ||
982                     sd->subtype == LogitechClickSmart820) {
983                         reg_w(gspca_dev, 0xf0, 0, 0, 0);
984                         spca504B_WaitCmdStatus(gspca_dev);
985                         reg_r(gspca_dev, 0xf0, 4, 0);
986                         spca504B_WaitCmdStatus(gspca_dev);
987                 } else {
988                         reg_w(gspca_dev, 0x31, 0, 4, 0);
989                         spca504B_WaitCmdStatus(gspca_dev);
990                         rc = spca504B_PollingDataReady(gspca_dev);
991                 }
992                 break;
993         case BRIDGE_SPCA504:
994                 if (sd->subtype == AiptekMiniPenCam13) {
995                         for (i = 0; i < 6; i++)
996                                 info[i] = reg_r_1(gspca_dev, i);
997                         PDEBUG(D_STREAM,
998                                 "Read info: %d %d %d %d %d %d."
999                                 " Should be 1,0,2,2,0,0",
1000                                 info[0], info[1], info[2],
1001                                 info[3], info[4], info[5]);
1002                         /* spca504a aiptek */
1003                         /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
1004                         spca504A_acknowledged_command(gspca_dev, 0x24,
1005                                                         8, 3, 0x9e, 1);
1006                         /* Twice sequencial need status 0xff->0x9e->0x9d */
1007                         spca504A_acknowledged_command(gspca_dev, 0x24,
1008                                                         8, 3, 0x9e, 0);
1009                         spca504A_acknowledged_command(gspca_dev, 0x24,
1010                                                         0, 0, 0x9d, 1);
1011                 } else {
1012                         spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
1013                         for (i = 0; i < 6; i++)
1014                                 info[i] = reg_r_1(gspca_dev, i);
1015                         PDEBUG(D_STREAM,
1016                                 "Read info: %d %d %d %d %d %d."
1017                                 " Should be 1,0,2,2,0,0",
1018                                 info[0], info[1], info[2],
1019                                 info[3], info[4], info[5]);
1020                         spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
1021                         spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
1022                 }
1023                 spca504B_SetSizeType(gspca_dev);
1024                 reg_w_riv(dev, 0x0, 0x270c, 0x05);      /* L92 sno1t.txt */
1025                 reg_w_riv(dev, 0x0, 0x2310, 0x05);
1026                 break;
1027         case BRIDGE_SPCA504C:
1028                 if (sd->subtype == LogitechClickSmart420) {
1029                         write_vector(gspca_dev,
1030                                         spca504A_clicksmart420_init_data);
1031                 } else {
1032                         write_vector(gspca_dev, spca504_pccam600_init_data);
1033                 }
1034                 enable = (sd->autogain ? 0x04 : 0x01);
1035                 reg_w_riv(dev, 0x0c, 0x0000, enable);   /* auto exposure */
1036                 reg_w_riv(dev, 0xb0, 0x0000, enable);   /* auto whiteness */
1037
1038                 /* set default exposure compensation and whiteness balance */
1039                 reg_w_riv(dev, 0x30, 0x0001, 800);      /* ~ 20 fps */
1040                 reg_w_riv(dev, 0x30, 0x0002, 1600);
1041                 spca504B_SetSizeType(gspca_dev);
1042                 break;
1043         }
1044         sp5xx_initContBrigHueRegisters(gspca_dev);
1045         return 0;
1046 }
1047
1048 static void sd_stopN(struct gspca_dev *gspca_dev)
1049 {
1050         struct sd *sd = (struct sd *) gspca_dev;
1051         struct usb_device *dev = gspca_dev->dev;
1052
1053         switch (sd->bridge) {
1054         default:
1055 /*      case BRIDGE_SPCA533: */
1056 /*      case BRIDGE_SPCA536: */
1057 /*      case BRIDGE_SPCA504B: */
1058                 reg_w(gspca_dev, 0x31, 0, 0, 0);
1059                 spca504B_WaitCmdStatus(gspca_dev);
1060                 spca504B_PollingDataReady(gspca_dev);
1061                 break;
1062         case BRIDGE_SPCA504:
1063         case BRIDGE_SPCA504C:
1064                 reg_w_riv(dev, 0x00, 0x2000, 0x0000);
1065
1066                 if (sd->subtype == AiptekMiniPenCam13) {
1067                         /* spca504a aiptek */
1068 /*                      spca504A_acknowledged_command(gspca_dev, 0x08,
1069                                                          6, 0, 0x86, 1); */
1070                         spca504A_acknowledged_command(gspca_dev, 0x24,
1071                                                         0x00, 0x00, 0x9d, 1);
1072                         spca504A_acknowledged_command(gspca_dev, 0x01,
1073                                                         0x0f, 0x00, 0xff, 1);
1074                 } else {
1075                         spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
1076                         reg_w_riv(dev, 0x01, 0x000f, 0x00);
1077                 }
1078                 break;
1079         }
1080 }
1081
1082 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1083                         struct gspca_frame *frame,      /* target */
1084                         __u8 *data,                     /* isoc packet */
1085                         int len)                        /* iso packet length */
1086 {
1087         struct sd *sd = (struct sd *) gspca_dev;
1088         int i, sof = 0;
1089         unsigned char *s, *d;
1090         static unsigned char ffd9[] = {0xff, 0xd9};
1091
1092 /* frames are jpeg 4.1.1 without 0xff escape */
1093         switch (sd->bridge) {
1094         case BRIDGE_SPCA533:
1095                 if (data[0] == 0xff) {
1096                         if (data[1] != 0x01) {  /* drop packet */
1097 /*                              gspca_dev->last_packet_type = DISCARD_PACKET; */
1098                                 return;
1099                         }
1100                         sof = 1;
1101                         data += SPCA533_OFFSET_DATA;
1102                         len -= SPCA533_OFFSET_DATA;
1103                 } else {
1104                         data += 1;
1105                         len -= 1;
1106                 }
1107                 break;
1108         case BRIDGE_SPCA536:
1109                 if (data[0] == 0xff) {
1110                         sof = 1;
1111                         data += SPCA536_OFFSET_DATA;
1112                         len -= SPCA536_OFFSET_DATA;
1113                 } else {
1114                         data += 2;
1115                         len -= 2;
1116                 }
1117                 break;
1118         default:
1119 /*      case BRIDGE_SPCA504: */
1120 /*      case BRIDGE_SPCA504B: */
1121                 switch (data[0]) {
1122                 case 0xfe:                      /* start of frame */
1123                         sof = 1;
1124                         data += SPCA50X_OFFSET_DATA;
1125                         len -= SPCA50X_OFFSET_DATA;
1126                         break;
1127                 case 0xff:                      /* drop packet */
1128 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
1129                         return;
1130                 default:
1131                         data += 1;
1132                         len -= 1;
1133                         break;
1134                 }
1135                 break;
1136         case BRIDGE_SPCA504C:
1137                 switch (data[0]) {
1138                 case 0xfe:                      /* start of frame */
1139                         sof = 1;
1140                         data += SPCA504_PCCAM600_OFFSET_DATA;
1141                         len -= SPCA504_PCCAM600_OFFSET_DATA;
1142                         break;
1143                 case 0xff:                      /* drop packet */
1144 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
1145                         return;
1146                 default:
1147                         data += 1;
1148                         len -= 1;
1149                         break;
1150                 }
1151                 break;
1152         }
1153         if (sof) {              /* start of frame */
1154                 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
1155                                         ffd9, 2);
1156
1157                 /* put the JPEG header in the new frame */
1158                 jpeg_put_header(gspca_dev, frame,
1159                                 ((struct sd *) gspca_dev)->qindex,
1160                                 0x22);
1161         }
1162
1163         /* add 0x00 after 0xff */
1164         for (i = len; --i >= 0; )
1165                 if (data[i] == 0xff)
1166                         break;
1167         if (i < 0) {                    /* no 0xff */
1168                 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1169                 return;
1170         }
1171         s = data;
1172         d = sd->packet;
1173         for (i = 0; i < len; i++) {
1174                 *d++ = *s++;
1175                 if (s[-1] == 0xff)
1176                         *d++ = 0x00;
1177         }
1178         gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1179                         sd->packet, d - sd->packet);
1180 }
1181
1182 static void setbrightness(struct gspca_dev *gspca_dev)
1183 {
1184         struct sd *sd = (struct sd *) gspca_dev;
1185         struct usb_device *dev = gspca_dev->dev;
1186
1187         switch (sd->bridge) {
1188         default:
1189 /*      case BRIDGE_SPCA533: */
1190 /*      case BRIDGE_SPCA504B: */
1191 /*      case BRIDGE_SPCA504: */
1192 /*      case BRIDGE_SPCA504C: */
1193                 reg_w_riv(dev, 0x0, 0x21a7, sd->brightness);
1194                 break;
1195         case BRIDGE_SPCA536:
1196                 reg_w_riv(dev, 0x0, 0x20f0, sd->brightness);
1197                 break;
1198         }
1199 }
1200
1201 static void getbrightness(struct gspca_dev *gspca_dev)
1202 {
1203         struct sd *sd = (struct sd *) gspca_dev;
1204         __u16 brightness = 0;
1205
1206         switch (sd->bridge) {
1207         default:
1208 /*      case BRIDGE_SPCA533: */
1209 /*      case BRIDGE_SPCA504B: */
1210 /*      case BRIDGE_SPCA504: */
1211 /*      case BRIDGE_SPCA504C: */
1212                 brightness = reg_r_12(gspca_dev, 0x00, 0x21a7, 2);
1213                 break;
1214         case BRIDGE_SPCA536:
1215                 brightness = reg_r_12(gspca_dev, 0x00, 0x20f0, 2);
1216                 break;
1217         }
1218         sd->brightness = ((brightness & 0xff) - 128) % 255;
1219 }
1220
1221 static void setcontrast(struct gspca_dev *gspca_dev)
1222 {
1223         struct sd *sd = (struct sd *) gspca_dev;
1224         struct usb_device *dev = gspca_dev->dev;
1225
1226         switch (sd->bridge) {
1227         default:
1228 /*      case BRIDGE_SPCA533: */
1229 /*      case BRIDGE_SPCA504B: */
1230 /*      case BRIDGE_SPCA504: */
1231 /*      case BRIDGE_SPCA504C: */
1232                 reg_w_riv(dev, 0x0, 0x21a8, sd->contrast);
1233                 break;
1234         case BRIDGE_SPCA536:
1235                 reg_w_riv(dev, 0x0, 0x20f1, sd->contrast);
1236                 break;
1237         }
1238 }
1239
1240 static void getcontrast(struct gspca_dev *gspca_dev)
1241 {
1242         struct sd *sd = (struct sd *) gspca_dev;
1243
1244         switch (sd->bridge) {
1245         default:
1246 /*      case BRIDGE_SPCA533: */
1247 /*      case BRIDGE_SPCA504B: */
1248 /*      case BRIDGE_SPCA504: */
1249 /*      case BRIDGE_SPCA504C: */
1250                 sd->contrast = reg_r_12(gspca_dev, 0x00, 0x21a8, 2);
1251                 break;
1252         case BRIDGE_SPCA536:
1253                 sd->contrast = reg_r_12(gspca_dev, 0x00, 0x20f1, 2);
1254                 break;
1255         }
1256 }
1257
1258 static void setcolors(struct gspca_dev *gspca_dev)
1259 {
1260         struct sd *sd = (struct sd *) gspca_dev;
1261         struct usb_device *dev = gspca_dev->dev;
1262
1263         switch (sd->bridge) {
1264         default:
1265 /*      case BRIDGE_SPCA533: */
1266 /*      case BRIDGE_SPCA504B: */
1267 /*      case BRIDGE_SPCA504: */
1268 /*      case BRIDGE_SPCA504C: */
1269                 reg_w_riv(dev, 0x0, 0x21ae, sd->colors);
1270                 break;
1271         case BRIDGE_SPCA536:
1272                 reg_w_riv(dev, 0x0, 0x20f6, sd->colors);
1273                 break;
1274         }
1275 }
1276
1277 static void getcolors(struct gspca_dev *gspca_dev)
1278 {
1279         struct sd *sd = (struct sd *) gspca_dev;
1280
1281         switch (sd->bridge) {
1282         default:
1283 /*      case BRIDGE_SPCA533: */
1284 /*      case BRIDGE_SPCA504B: */
1285 /*      case BRIDGE_SPCA504: */
1286 /*      case BRIDGE_SPCA504C: */
1287                 sd->colors = reg_r_12(gspca_dev, 0x00, 0x21ae, 2) >> 1;
1288                 break;
1289         case BRIDGE_SPCA536:
1290                 sd->colors = reg_r_12(gspca_dev, 0x00, 0x20f6, 2) >> 1;
1291                 break;
1292         }
1293 }
1294
1295 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1296 {
1297         struct sd *sd = (struct sd *) gspca_dev;
1298
1299         sd->brightness = val;
1300         if (gspca_dev->streaming)
1301                 setbrightness(gspca_dev);
1302         return 0;
1303 }
1304
1305 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1306 {
1307         struct sd *sd = (struct sd *) gspca_dev;
1308
1309         getbrightness(gspca_dev);
1310         *val = sd->brightness;
1311         return 0;
1312 }
1313
1314 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1315 {
1316         struct sd *sd = (struct sd *) gspca_dev;
1317
1318         sd->contrast = val;
1319         if (gspca_dev->streaming)
1320                 setcontrast(gspca_dev);
1321         return 0;
1322 }
1323
1324 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1325 {
1326         struct sd *sd = (struct sd *) gspca_dev;
1327
1328         getcontrast(gspca_dev);
1329         *val = sd->contrast;
1330         return 0;
1331 }
1332
1333 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1334 {
1335         struct sd *sd = (struct sd *) gspca_dev;
1336
1337         sd->colors = val;
1338         if (gspca_dev->streaming)
1339                 setcolors(gspca_dev);
1340         return 0;
1341 }
1342
1343 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1344 {
1345         struct sd *sd = (struct sd *) gspca_dev;
1346
1347         getcolors(gspca_dev);
1348         *val = sd->colors;
1349         return 0;
1350 }
1351
1352 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1353 {
1354         struct sd *sd = (struct sd *) gspca_dev;
1355
1356         sd->autogain = val;
1357         return 0;
1358 }
1359
1360 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1361 {
1362         struct sd *sd = (struct sd *) gspca_dev;
1363
1364         *val = sd->autogain;
1365         return 0;
1366 }
1367
1368 /* sub-driver description */
1369 static const struct sd_desc sd_desc = {
1370         .name = MODULE_NAME,
1371         .ctrls = sd_ctrls,
1372         .nctrls = ARRAY_SIZE(sd_ctrls),
1373         .config = sd_config,
1374         .init = sd_init,
1375         .start = sd_start,
1376         .stopN = sd_stopN,
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 #ifdef CONFIG_PM
1460         .suspend = gspca_suspend,
1461         .resume = gspca_resume,
1462 #endif
1463 };
1464
1465 /* -- module insert / remove -- */
1466 static int __init sd_mod_init(void)
1467 {
1468         if (usb_register(&sd_driver) < 0)
1469                 return -1;
1470         PDEBUG(D_PROBE, "registered");
1471         return 0;
1472 }
1473 static void __exit sd_mod_exit(void)
1474 {
1475         usb_deregister(&sd_driver);
1476         PDEBUG(D_PROBE, "deregistered");
1477 }
1478
1479 module_init(sd_mod_init);
1480 module_exit(sd_mod_exit);