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