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