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