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