aa8f995ce04ec1f263df04e1b123923fc2689ca8
[linux-2.6.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 #ifdef GSPCA_DEBUG
464         if (len > USB_BUF_SZ) {
465                 err("reg_r: buffer overflow");
466                 return;
467         }
468 #endif
469         usb_control_msg(gspca_dev->dev,
470                         usb_rcvctrlpipe(gspca_dev->dev, 0),
471                         req,
472                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
473                         0,              /* value */
474                         index,
475                         len ? gspca_dev->usb_buf : NULL, len,
476                         500);
477 }
478
479 /* write one byte */
480 static void reg_w_1(struct gspca_dev *gspca_dev,
481                    u8 req,
482                    u16 value,
483                    u16 index,
484                    u16 byte)
485 {
486         gspca_dev->usb_buf[0] = byte;
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                         gspca_dev->usb_buf, 1,
493                         500);
494 }
495
496 /* write req / index / value */
497 static int reg_w_riv(struct usb_device *dev,
498                      u8 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                         u8 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 struct cmd *data, int ncmds)
561 {
562         struct usb_device *dev = gspca_dev->dev;
563         int ret;
564
565         while (--ncmds >= 0) {
566                 ret = reg_w_riv(dev, data->req, data->idx, data->val);
567                 if (ret < 0) {
568                         PDEBUG(D_ERR,
569                            "Register write failed for 0x%02x, 0x%04x, 0x%04x",
570                                 data->req, data->val, data->idx);
571                         return ret;
572                 }
573                 data++;
574         }
575         return 0;
576 }
577
578 static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
579                                 const u8 qtable[2][64])
580 {
581         struct usb_device *dev = gspca_dev->dev;
582         int i, err;
583
584         /* loop over y components */
585         for (i = 0; i < 64; i++) {
586                 err = reg_w_riv(dev, 0x00, 0x2800 + i, qtable[0][i]);
587                 if (err < 0)
588                         return err;
589         }
590
591         /* loop over c components */
592         for (i = 0; i < 64; i++) {
593                 err = reg_w_riv(dev, 0x00, 0x2840 + i, qtable[1][i]);
594                 if (err < 0)
595                         return err;
596         }
597         return 0;
598 }
599
600 static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
601                              u8 req, u16 idx, u16 val)
602 {
603         struct usb_device *dev = gspca_dev->dev;
604         int notdone;
605
606         reg_w_riv(dev, req, idx, val);
607         notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
608         reg_w_riv(dev, req, idx, val);
609
610         PDEBUG(D_FRAM, "before wait 0x%04x", notdone);
611
612         msleep(200);
613         notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
614         PDEBUG(D_FRAM, "after wait 0x%04x", notdone);
615 }
616
617 static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
618                         u8 req,
619                         u16 idx, u16 val, u8 stat, u8 count)
620 {
621         struct usb_device *dev = gspca_dev->dev;
622         int status;
623         u8 endcode;
624
625         reg_w_riv(dev, req, idx, val);
626         status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
627         endcode = stat;
628         PDEBUG(D_FRAM, "Status 0x%x Need 0x%04x", status, stat);
629         if (!count)
630                 return;
631         count = 200;
632         while (--count > 0) {
633                 msleep(10);
634                 /* gsmart mini2 write a each wait setting 1 ms is enought */
635 /*              reg_w_riv(dev, req, idx, val); */
636                 status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
637                 if (status == endcode) {
638                         PDEBUG(D_FRAM, "status 0x%04x after wait %d",
639                                 status, 200 - count);
640                                 break;
641                 }
642         }
643 }
644
645 static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
646 {
647         int count = 10;
648
649         while (--count > 0) {
650                 reg_r(gspca_dev, 0x21, 0, 1);
651                 if ((gspca_dev->usb_buf[0] & 0x01) == 0)
652                         break;
653                 msleep(10);
654         }
655         return gspca_dev->usb_buf[0];
656 }
657
658 static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
659 {
660         int count = 50;
661
662         while (--count > 0) {
663                 reg_r(gspca_dev, 0x21, 1, 1);
664                 if (gspca_dev->usb_buf[0] != 0) {
665                         reg_w_1(gspca_dev, 0x21, 0, 1, 0);
666                         reg_r(gspca_dev, 0x21, 1, 1);
667                         spca504B_PollingDataReady(gspca_dev);
668                         break;
669                 }
670                 msleep(10);
671         }
672 }
673
674 static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
675 {
676         u8 *data;
677
678         data = gspca_dev->usb_buf;
679         reg_r(gspca_dev, 0x20, 0, 5);
680         PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ",
681                 data[0], data[1], data[2], data[3], data[4]);
682         reg_r(gspca_dev, 0x23, 0, 64);
683         reg_r(gspca_dev, 0x23, 1, 64);
684 }
685
686 static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
687 {
688         struct sd *sd = (struct sd *) gspca_dev;
689         struct usb_device *dev = gspca_dev->dev;
690         u8 Size;
691         int rc;
692
693         Size = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
694         switch (sd->bridge) {
695         case BRIDGE_SPCA533:
696                 reg_w_riv(dev, 0x31, 0, 0);
697                 spca504B_WaitCmdStatus(gspca_dev);
698                 rc = spca504B_PollingDataReady(gspca_dev);
699                 spca50x_GetFirmware(gspca_dev);
700                 reg_w_1(gspca_dev, 0x24, 0, 8, 2);              /* type */
701                 reg_r(gspca_dev, 0x24, 8, 1);
702
703                 reg_w_1(gspca_dev, 0x25, 0, 4, Size);
704                 reg_r(gspca_dev, 0x25, 4, 1);                   /* size */
705                 rc = spca504B_PollingDataReady(gspca_dev);
706
707                 /* Init the cam width height with some values get on init ? */
708                 reg_w_riv(dev, 0x31, 0, 0x04);
709                 spca504B_WaitCmdStatus(gspca_dev);
710                 rc = spca504B_PollingDataReady(gspca_dev);
711                 break;
712         default:
713 /* case BRIDGE_SPCA504B: */
714 /* case BRIDGE_SPCA536: */
715                 reg_w_1(gspca_dev, 0x25, 0, 4, Size);
716                 reg_r(gspca_dev, 0x25, 4, 1);                   /* size */
717                 reg_w_1(gspca_dev, 0x27, 0, 0, 6);
718                 reg_r(gspca_dev, 0x27, 0, 1);                   /* type */
719                 rc = spca504B_PollingDataReady(gspca_dev);
720                 break;
721         case BRIDGE_SPCA504:
722                 Size += 3;
723                 if (sd->subtype == AiptekMiniPenCam13) {
724                         /* spca504a aiptek */
725                         spca504A_acknowledged_command(gspca_dev,
726                                                 0x08, Size, 0,
727                                                 0x80 | (Size & 0x0f), 1);
728                         spca504A_acknowledged_command(gspca_dev,
729                                                         1, 3, 0, 0x9f, 0);
730                 } else {
731                         spca504_acknowledged_command(gspca_dev, 0x08, Size, 0);
732                 }
733                 break;
734         case BRIDGE_SPCA504C:
735                 /* capture mode */
736                 reg_w_riv(dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00);
737                 reg_w_riv(dev, 0x20, 0x01, 0x0500 | (Size & 0x0f));
738                 break;
739         }
740 }
741
742 static void spca504_wait_status(struct gspca_dev *gspca_dev)
743 {
744         int cnt;
745
746         cnt = 256;
747         while (--cnt > 0) {
748                 /* With this we get the status, when return 0 it's all ok */
749                 if (reg_r_12(gspca_dev, 0x06, 0x00, 1) == 0)
750                         return;
751                 msleep(10);
752         }
753 }
754
755 static void spca504B_setQtable(struct gspca_dev *gspca_dev)
756 {
757         reg_w_1(gspca_dev, 0x26, 0, 0, 3);
758         reg_r(gspca_dev, 0x26, 0, 1);
759         spca504B_PollingDataReady(gspca_dev);
760 }
761
762 static void setbrightness(struct gspca_dev *gspca_dev)
763 {
764         struct sd *sd = (struct sd *) gspca_dev;
765         struct usb_device *dev = gspca_dev->dev;
766         u16 reg;
767
768         reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7;
769         reg_w_riv(dev, 0x00, reg, sd->brightness);
770 }
771
772 static void setcontrast(struct gspca_dev *gspca_dev)
773 {
774         struct sd *sd = (struct sd *) gspca_dev;
775         struct usb_device *dev = gspca_dev->dev;
776         u16 reg;
777
778         reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8;
779         reg_w_riv(dev, 0x00, reg, sd->contrast);
780 }
781
782 static void setcolors(struct gspca_dev *gspca_dev)
783 {
784         struct sd *sd = (struct sd *) gspca_dev;
785         struct usb_device *dev = gspca_dev->dev;
786         u16 reg;
787
788         reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae;
789         reg_w_riv(dev, 0x00, reg, sd->colors);
790 }
791
792 static void init_ctl_reg(struct gspca_dev *gspca_dev)
793 {
794         struct sd *sd = (struct sd *) gspca_dev;
795         struct usb_device *dev = gspca_dev->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(dev, 0, 0x00, 0x21ad);        /* hue */
811                 reg_w_riv(dev, 0, 0x01, 0x21ac);        /* sat/hue */
812                 reg_w_riv(dev, 0, 0x00, 0x21a3);        /* gamma */
813                 break;
814         case BRIDGE_SPCA536:
815                 reg_w_riv(dev, 0, 0x40, 0x20f5);
816                 reg_w_riv(dev, 0, 0x01, 0x20f4);
817                 reg_w_riv(dev, 0, 0x00, 0x2089);
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         struct usb_device *dev = gspca_dev->dev;
885         int i, err_code;
886         u8 info[6];
887
888         switch (sd->bridge) {
889         case BRIDGE_SPCA504B:
890                 reg_w_riv(dev, 0x1d, 0x00, 0);
891                 reg_w_riv(dev, 0, 0x01, 0x2306);
892                 reg_w_riv(dev, 0, 0x00, 0x0d04);
893                 reg_w_riv(dev, 0, 0x00, 0x2000);
894                 reg_w_riv(dev, 0, 0x13, 0x2301);
895                 reg_w_riv(dev, 0, 0x00, 0x2306);
896                 /* fall thru */
897         case BRIDGE_SPCA533:
898                 spca504B_PollingDataReady(gspca_dev);
899                 spca50x_GetFirmware(gspca_dev);
900                 break;
901         case BRIDGE_SPCA536:
902                 spca50x_GetFirmware(gspca_dev);
903                 reg_r(gspca_dev, 0x00, 0x5002, 1);
904                 reg_w_1(gspca_dev, 0x24, 0, 0, 0);
905                 reg_r(gspca_dev, 0x24, 0, 1);
906                 spca504B_PollingDataReady(gspca_dev);
907                 reg_w_riv(dev, 0x34, 0, 0);
908                 spca504B_WaitCmdStatus(gspca_dev);
909                 break;
910         case BRIDGE_SPCA504C:   /* pccam600 */
911                 PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)");
912                 reg_w_riv(dev, 0xe0, 0x0000, 0x0000);
913                 reg_w_riv(dev, 0xe0, 0x0000, 0x0001);   /* reset */
914                 spca504_wait_status(gspca_dev);
915                 if (sd->subtype == LogitechClickSmart420)
916                         write_vector(gspca_dev,
917                                 spca504A_clicksmart420_open_data,
918                                 ARRAY_SIZE(spca504A_clicksmart420_open_data));
919                 else
920                         write_vector(gspca_dev, spca504_pccam600_open_data,
921                                 ARRAY_SIZE(spca504_pccam600_open_data));
922                 err_code = spca50x_setup_qtable(gspca_dev,
923                                                 qtable_creative_pccam);
924                 if (err_code < 0) {
925                         PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed");
926                         return err_code;
927                 }
928                 break;
929         default:
930 /*      case BRIDGE_SPCA504: */
931                 PDEBUG(D_STREAM, "Opening SPCA504");
932                 if (sd->subtype == AiptekMiniPenCam13) {
933                         /*****************************/
934                         for (i = 0; i < 6; i++)
935                                 info[i] = reg_r_1(gspca_dev, i);
936                         PDEBUG(D_STREAM,
937                                 "Read info: %d %d %d %d %d %d."
938                                 " Should be 1,0,2,2,0,0",
939                                 info[0], info[1], info[2],
940                                 info[3], info[4], info[5]);
941                         /* spca504a aiptek */
942                         /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
943                         spca504A_acknowledged_command(gspca_dev, 0x24,
944                                                         8, 3, 0x9e, 1);
945                         /* Twice sequencial need status 0xff->0x9e->0x9d */
946                         spca504A_acknowledged_command(gspca_dev, 0x24,
947                                                         8, 3, 0x9e, 0);
948
949                         spca504A_acknowledged_command(gspca_dev, 0x24,
950                                                         0, 0, 0x9d, 1);
951                         /******************************/
952                         /* spca504a aiptek */
953                         spca504A_acknowledged_command(gspca_dev, 0x08,
954                                                         6, 0, 0x86, 1);
955 /*                      reg_write (dev, 0, 0x2000, 0); */
956 /*                      reg_write (dev, 0, 0x2883, 1); */
957 /*                      spca504A_acknowledged_command (gspca_dev, 0x08,
958                                                         6, 0, 0x86, 1); */
959 /*                      spca504A_acknowledged_command (gspca_dev, 0x24,
960                                                         0, 0, 0x9D, 1); */
961                         reg_w_riv(dev, 0x00, 0x270c, 0x05); /* L92 sno1t.txt */
962                         reg_w_riv(dev, 0x00, 0x2310, 0x05);
963                         spca504A_acknowledged_command(gspca_dev, 0x01,
964                                                         0x0f, 0, 0xff, 0);
965                 }
966                 /* setup qtable */
967                 reg_w_riv(dev, 0, 0x2000, 0);
968                 reg_w_riv(dev, 0, 0x2883, 1);
969                 err_code = spca50x_setup_qtable(gspca_dev,
970                                                 qtable_spca504_default);
971                 if (err_code < 0) {
972                         PDEBUG(D_ERR, "spca50x_setup_qtable failed");
973                         return err_code;
974                 }
975                 break;
976         }
977         return 0;
978 }
979
980 static int sd_start(struct gspca_dev *gspca_dev)
981 {
982         struct sd *sd = (struct sd *) gspca_dev;
983         struct usb_device *dev = gspca_dev->dev;
984         int enable;
985         int i;
986         u8 info[6];
987
988         /* create the JPEG header */
989         sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
990         if (!sd->jpeg_hdr)
991                 return -ENOMEM;
992         jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
993                         0x22);          /* JPEG 411 */
994         jpeg_set_qual(sd->jpeg_hdr, sd->quality);
995
996         if (sd->bridge == BRIDGE_SPCA504B)
997                 spca504B_setQtable(gspca_dev);
998         spca504B_SetSizeType(gspca_dev);
999         switch (sd->bridge) {
1000         default:
1001 /*      case BRIDGE_SPCA504B: */
1002 /*      case BRIDGE_SPCA533: */
1003 /*      case BRIDGE_SPCA536: */
1004                 switch (sd->subtype) {
1005                 case MegapixV4:
1006                 case LogitechClickSmart820:
1007                 case MegaImageVI:
1008                         reg_w_riv(dev, 0xf0, 0, 0);
1009                         spca504B_WaitCmdStatus(gspca_dev);
1010                         reg_r(gspca_dev, 0xf0, 4, 0);
1011                         spca504B_WaitCmdStatus(gspca_dev);
1012                         break;
1013                 default:
1014                         reg_w_riv(dev, 0x31, 0, 0x04);
1015                         spca504B_WaitCmdStatus(gspca_dev);
1016                         spca504B_PollingDataReady(gspca_dev);
1017                         break;
1018                 }
1019                 break;
1020         case BRIDGE_SPCA504:
1021                 if (sd->subtype == AiptekMiniPenCam13) {
1022                         for (i = 0; i < 6; i++)
1023                                 info[i] = reg_r_1(gspca_dev, i);
1024                         PDEBUG(D_STREAM,
1025                                 "Read info: %d %d %d %d %d %d."
1026                                 " Should be 1,0,2,2,0,0",
1027                                 info[0], info[1], info[2],
1028                                 info[3], info[4], info[5]);
1029                         /* spca504a aiptek */
1030                         /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
1031                         spca504A_acknowledged_command(gspca_dev, 0x24,
1032                                                         8, 3, 0x9e, 1);
1033                         /* Twice sequencial need status 0xff->0x9e->0x9d */
1034                         spca504A_acknowledged_command(gspca_dev, 0x24,
1035                                                         8, 3, 0x9e, 0);
1036                         spca504A_acknowledged_command(gspca_dev, 0x24,
1037                                                         0, 0, 0x9d, 1);
1038                 } else {
1039                         spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
1040                         for (i = 0; i < 6; i++)
1041                                 info[i] = reg_r_1(gspca_dev, i);
1042                         PDEBUG(D_STREAM,
1043                                 "Read info: %d %d %d %d %d %d."
1044                                 " Should be 1,0,2,2,0,0",
1045                                 info[0], info[1], info[2],
1046                                 info[3], info[4], info[5]);
1047                         spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
1048                         spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
1049                 }
1050                 spca504B_SetSizeType(gspca_dev);
1051                 reg_w_riv(dev, 0x00, 0x270c, 0x05);     /* L92 sno1t.txt */
1052                 reg_w_riv(dev, 0x00, 0x2310, 0x05);
1053                 break;
1054         case BRIDGE_SPCA504C:
1055                 if (sd->subtype == LogitechClickSmart420) {
1056                         write_vector(gspca_dev,
1057                                 spca504A_clicksmart420_init_data,
1058                                 ARRAY_SIZE(spca504A_clicksmart420_init_data));
1059                 } else {
1060                         write_vector(gspca_dev, spca504_pccam600_init_data,
1061                                 ARRAY_SIZE(spca504_pccam600_init_data));
1062                 }
1063                 enable = (sd->autogain ? 0x04 : 0x01);
1064                 reg_w_riv(dev, 0x0c, 0x0000, enable);   /* auto exposure */
1065                 reg_w_riv(dev, 0xb0, 0x0000, enable);   /* auto whiteness */
1066
1067                 /* set default exposure compensation and whiteness balance */
1068                 reg_w_riv(dev, 0x30, 0x0001, 800);      /* ~ 20 fps */
1069                 reg_w_riv(dev, 0x30, 0x0002, 1600);
1070                 spca504B_SetSizeType(gspca_dev);
1071                 break;
1072         }
1073         init_ctl_reg(gspca_dev);
1074         return 0;
1075 }
1076
1077 static void sd_stopN(struct gspca_dev *gspca_dev)
1078 {
1079         struct sd *sd = (struct sd *) gspca_dev;
1080         struct usb_device *dev = gspca_dev->dev;
1081
1082         switch (sd->bridge) {
1083         default:
1084 /*      case BRIDGE_SPCA533: */
1085 /*      case BRIDGE_SPCA536: */
1086 /*      case BRIDGE_SPCA504B: */
1087                 reg_w_riv(dev, 0x31, 0, 0);
1088                 spca504B_WaitCmdStatus(gspca_dev);
1089                 spca504B_PollingDataReady(gspca_dev);
1090                 break;
1091         case BRIDGE_SPCA504:
1092         case BRIDGE_SPCA504C:
1093                 reg_w_riv(dev, 0x00, 0x2000, 0x0000);
1094
1095                 if (sd->subtype == AiptekMiniPenCam13) {
1096                         /* spca504a aiptek */
1097 /*                      spca504A_acknowledged_command(gspca_dev, 0x08,
1098                                                          6, 0, 0x86, 1); */
1099                         spca504A_acknowledged_command(gspca_dev, 0x24,
1100                                                         0x00, 0x00, 0x9d, 1);
1101                         spca504A_acknowledged_command(gspca_dev, 0x01,
1102                                                         0x0f, 0x00, 0xff, 1);
1103                 } else {
1104                         spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
1105                         reg_w_riv(dev, 0x01, 0x000f, 0x0000);
1106                 }
1107                 break;
1108         }
1109 }
1110
1111 static void sd_stop0(struct gspca_dev *gspca_dev)
1112 {
1113         struct sd *sd = (struct sd *) gspca_dev;
1114
1115         kfree(sd->jpeg_hdr);
1116 }
1117
1118 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1119                         struct gspca_frame *frame,      /* target */
1120                         u8 *data,                       /* isoc packet */
1121                         int len)                        /* iso packet length */
1122 {
1123         struct sd *sd = (struct sd *) gspca_dev;
1124         int i, sof = 0;
1125         static u8 ffd9[] = {0xff, 0xd9};
1126
1127 /* frames are jpeg 4.1.1 without 0xff escape */
1128         switch (sd->bridge) {
1129         case BRIDGE_SPCA533:
1130                 if (data[0] == 0xff) {
1131                         if (data[1] != 0x01) {  /* drop packet */
1132 /*                              gspca_dev->last_packet_type = DISCARD_PACKET; */
1133                                 return;
1134                         }
1135                         sof = 1;
1136                         data += SPCA533_OFFSET_DATA;
1137                         len -= SPCA533_OFFSET_DATA;
1138                 } else {
1139                         data += 1;
1140                         len -= 1;
1141                 }
1142                 break;
1143         case BRIDGE_SPCA536:
1144                 if (data[0] == 0xff) {
1145                         sof = 1;
1146                         data += SPCA536_OFFSET_DATA;
1147                         len -= SPCA536_OFFSET_DATA;
1148                 } else {
1149                         data += 2;
1150                         len -= 2;
1151                 }
1152                 break;
1153         default:
1154 /*      case BRIDGE_SPCA504: */
1155 /*      case BRIDGE_SPCA504B: */
1156                 switch (data[0]) {
1157                 case 0xfe:                      /* start of frame */
1158                         sof = 1;
1159                         data += SPCA50X_OFFSET_DATA;
1160                         len -= SPCA50X_OFFSET_DATA;
1161                         break;
1162                 case 0xff:                      /* drop packet */
1163 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
1164                         return;
1165                 default:
1166                         data += 1;
1167                         len -= 1;
1168                         break;
1169                 }
1170                 break;
1171         case BRIDGE_SPCA504C:
1172                 switch (data[0]) {
1173                 case 0xfe:                      /* start of frame */
1174                         sof = 1;
1175                         data += SPCA504_PCCAM600_OFFSET_DATA;
1176                         len -= SPCA504_PCCAM600_OFFSET_DATA;
1177                         break;
1178                 case 0xff:                      /* drop packet */
1179 /*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
1180                         return;
1181                 default:
1182                         data += 1;
1183                         len -= 1;
1184                         break;
1185                 }
1186                 break;
1187         }
1188         if (sof) {              /* start of frame */
1189                 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
1190                                         ffd9, 2);
1191
1192                 /* put the JPEG header in the new frame */
1193                 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
1194                         sd->jpeg_hdr, JPEG_HDR_SZ);
1195         }
1196
1197         /* add 0x00 after 0xff */
1198         i = 0;
1199         do {
1200                 if (data[i] == 0xff) {
1201                         gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1202                                         data, i + 1);
1203                         len -= i;
1204                         data += i;
1205                         *data = 0x00;
1206                         i = 0;
1207                 }
1208                 i++;
1209         } while (i < len);
1210         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1211 }
1212
1213 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1214 {
1215         struct sd *sd = (struct sd *) gspca_dev;
1216
1217         sd->brightness = val;
1218         if (gspca_dev->streaming)
1219                 setbrightness(gspca_dev);
1220         return 0;
1221 }
1222
1223 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1224 {
1225         struct sd *sd = (struct sd *) gspca_dev;
1226
1227         *val = sd->brightness;
1228         return 0;
1229 }
1230
1231 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1232 {
1233         struct sd *sd = (struct sd *) gspca_dev;
1234
1235         sd->contrast = val;
1236         if (gspca_dev->streaming)
1237                 setcontrast(gspca_dev);
1238         return 0;
1239 }
1240
1241 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1242 {
1243         struct sd *sd = (struct sd *) gspca_dev;
1244
1245         *val = sd->contrast;
1246         return 0;
1247 }
1248
1249 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1250 {
1251         struct sd *sd = (struct sd *) gspca_dev;
1252
1253         sd->colors = val;
1254         if (gspca_dev->streaming)
1255                 setcolors(gspca_dev);
1256         return 0;
1257 }
1258
1259 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1260 {
1261         struct sd *sd = (struct sd *) gspca_dev;
1262
1263         *val = sd->colors;
1264         return 0;
1265 }
1266
1267 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1268 {
1269         struct sd *sd = (struct sd *) gspca_dev;
1270
1271         sd->autogain = val;
1272         return 0;
1273 }
1274
1275 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1276 {
1277         struct sd *sd = (struct sd *) gspca_dev;
1278
1279         *val = sd->autogain;
1280         return 0;
1281 }
1282
1283 static int sd_set_jcomp(struct gspca_dev *gspca_dev,
1284                         struct v4l2_jpegcompression *jcomp)
1285 {
1286         struct sd *sd = (struct sd *) gspca_dev;
1287
1288         if (jcomp->quality < QUALITY_MIN)
1289                 sd->quality = QUALITY_MIN;
1290         else if (jcomp->quality > QUALITY_MAX)
1291                 sd->quality = QUALITY_MAX;
1292         else
1293                 sd->quality = jcomp->quality;
1294         if (gspca_dev->streaming)
1295                 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1296         return 0;
1297 }
1298
1299 static int sd_get_jcomp(struct gspca_dev *gspca_dev,
1300                         struct v4l2_jpegcompression *jcomp)
1301 {
1302         struct sd *sd = (struct sd *) gspca_dev;
1303
1304         memset(jcomp, 0, sizeof *jcomp);
1305         jcomp->quality = sd->quality;
1306         jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
1307                         | V4L2_JPEG_MARKER_DQT;
1308         return 0;
1309 }
1310
1311 /* sub-driver description */
1312 static const struct sd_desc sd_desc = {
1313         .name = MODULE_NAME,
1314         .ctrls = sd_ctrls,
1315         .nctrls = ARRAY_SIZE(sd_ctrls),
1316         .config = sd_config,
1317         .init = sd_init,
1318         .start = sd_start,
1319         .stopN = sd_stopN,
1320         .stop0 = sd_stop0,
1321         .pkt_scan = sd_pkt_scan,
1322         .get_jcomp = sd_get_jcomp,
1323         .set_jcomp = sd_set_jcomp,
1324 };
1325
1326 /* -- module initialisation -- */
1327 #define BS(bridge, subtype) \
1328         .driver_info = (BRIDGE_ ## bridge << 8) \
1329                         | (subtype)
1330 static const __devinitdata struct usb_device_id device_table[] = {
1331         {USB_DEVICE(0x041e, 0x400b), BS(SPCA504C, 0)},
1332         {USB_DEVICE(0x041e, 0x4012), BS(SPCA504C, 0)},
1333         {USB_DEVICE(0x041e, 0x4013), BS(SPCA504C, 0)},
1334         {USB_DEVICE(0x0458, 0x7006), BS(SPCA504B, 0)},
1335         {USB_DEVICE(0x0461, 0x0821), BS(SPCA533, 0)},
1336         {USB_DEVICE(0x046d, 0x0905), BS(SPCA533, LogitechClickSmart820)},
1337         {USB_DEVICE(0x046d, 0x0960), BS(SPCA504C, LogitechClickSmart420)},
1338         {USB_DEVICE(0x0471, 0x0322), BS(SPCA504B, 0)},
1339         {USB_DEVICE(0x04a5, 0x3003), BS(SPCA504B, 0)},
1340         {USB_DEVICE(0x04a5, 0x3008), BS(SPCA533, 0)},
1341         {USB_DEVICE(0x04a5, 0x300a), BS(SPCA533, 0)},
1342         {USB_DEVICE(0x04f1, 0x1001), BS(SPCA504B, 0)},
1343         {USB_DEVICE(0x04fc, 0x500c), BS(SPCA504B, 0)},
1344         {USB_DEVICE(0x04fc, 0x504a), BS(SPCA504, AiptekMiniPenCam13)},
1345         {USB_DEVICE(0x04fc, 0x504b), BS(SPCA504B, 0)},
1346         {USB_DEVICE(0x04fc, 0x5330), BS(SPCA533, 0)},
1347         {USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)},
1348         {USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)},
1349         {USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)},
1350         {USB_DEVICE(0x052b, 0x1803), BS(SPCA533, MegaImageVI)},
1351         {USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)},
1352         {USB_DEVICE(0x0546, 0x3191), BS(SPCA504B, 0)},
1353         {USB_DEVICE(0x0546, 0x3273), BS(SPCA504B, 0)},
1354         {USB_DEVICE(0x055f, 0xc211), BS(SPCA536, 0)},
1355         {USB_DEVICE(0x055f, 0xc230), BS(SPCA533, 0)},
1356         {USB_DEVICE(0x055f, 0xc232), BS(SPCA533, 0)},
1357         {USB_DEVICE(0x055f, 0xc360), BS(SPCA536, 0)},
1358         {USB_DEVICE(0x055f, 0xc420), BS(SPCA504, 0)},
1359         {USB_DEVICE(0x055f, 0xc430), BS(SPCA533, 0)},
1360         {USB_DEVICE(0x055f, 0xc440), BS(SPCA533, 0)},
1361         {USB_DEVICE(0x055f, 0xc520), BS(SPCA504, 0)},
1362         {USB_DEVICE(0x055f, 0xc530), BS(SPCA533, 0)},
1363         {USB_DEVICE(0x055f, 0xc540), BS(SPCA533, 0)},
1364         {USB_DEVICE(0x055f, 0xc630), BS(SPCA533, 0)},
1365         {USB_DEVICE(0x055f, 0xc650), BS(SPCA533, 0)},
1366         {USB_DEVICE(0x05da, 0x1018), BS(SPCA504B, 0)},
1367         {USB_DEVICE(0x06d6, 0x0031), BS(SPCA533, 0)},
1368         {USB_DEVICE(0x0733, 0x1311), BS(SPCA533, 0)},
1369         {USB_DEVICE(0x0733, 0x1314), BS(SPCA533, 0)},
1370         {USB_DEVICE(0x0733, 0x2211), BS(SPCA533, 0)},
1371         {USB_DEVICE(0x0733, 0x2221), BS(SPCA533, 0)},
1372         {USB_DEVICE(0x0733, 0x3261), BS(SPCA536, 0)},
1373         {USB_DEVICE(0x0733, 0x3281), BS(SPCA536, 0)},
1374         {USB_DEVICE(0x08ca, 0x0104), BS(SPCA533, 0)},
1375         {USB_DEVICE(0x08ca, 0x0106), BS(SPCA533, 0)},
1376         {USB_DEVICE(0x08ca, 0x2008), BS(SPCA504B, 0)},
1377         {USB_DEVICE(0x08ca, 0x2010), BS(SPCA533, 0)},
1378         {USB_DEVICE(0x08ca, 0x2016), BS(SPCA504B, 0)},
1379         {USB_DEVICE(0x08ca, 0x2018), BS(SPCA504B, 0)},
1380         {USB_DEVICE(0x08ca, 0x2020), BS(SPCA533, 0)},
1381         {USB_DEVICE(0x08ca, 0x2022), BS(SPCA533, 0)},
1382         {USB_DEVICE(0x08ca, 0x2024), BS(SPCA536, 0)},
1383         {USB_DEVICE(0x08ca, 0x2028), BS(SPCA533, 0)},
1384         {USB_DEVICE(0x08ca, 0x2040), BS(SPCA536, 0)},
1385         {USB_DEVICE(0x08ca, 0x2042), BS(SPCA536, 0)},
1386         {USB_DEVICE(0x08ca, 0x2050), BS(SPCA536, 0)},
1387         {USB_DEVICE(0x08ca, 0x2060), BS(SPCA536, 0)},
1388         {USB_DEVICE(0x0d64, 0x0303), BS(SPCA536, 0)},
1389         {}
1390 };
1391 MODULE_DEVICE_TABLE(usb, device_table);
1392
1393 /* -- device connect -- */
1394 static int sd_probe(struct usb_interface *intf,
1395                         const struct usb_device_id *id)
1396 {
1397         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1398                                 THIS_MODULE);
1399 }
1400
1401 static struct usb_driver sd_driver = {
1402         .name = MODULE_NAME,
1403         .id_table = device_table,
1404         .probe = sd_probe,
1405         .disconnect = gspca_disconnect,
1406 #ifdef CONFIG_PM
1407         .suspend = gspca_suspend,
1408         .resume = gspca_resume,
1409 #endif
1410 };
1411
1412 /* -- module insert / remove -- */
1413 static int __init sd_mod_init(void)
1414 {
1415         int ret;
1416         ret = usb_register(&sd_driver);
1417         if (ret < 0)
1418                 return ret;
1419         PDEBUG(D_PROBE, "registered");
1420         return 0;
1421 }
1422 static void __exit sd_mod_exit(void)
1423 {
1424         usb_deregister(&sd_driver);
1425         PDEBUG(D_PROBE, "deregistered");
1426 }
1427
1428 module_init(sd_mod_init);
1429 module_exit(sd_mod_exit);