Linux 2.6.34-rc3
[pohmelfs.git] / drivers / media / video / gspca / t613.c
blob668a7536af90707686b3c12f761af86657b41507
1 /*
2 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *Notes: * t613 + tas5130A
19 * * Focus to light do not balance well as in win.
20 * Quality in win is not good, but its kinda better.
21 * * Fix some "extraneous bytes", most of apps will show the image anyway
22 * * Gamma table, is there, but its really doing something?
23 * * 7~8 Fps, its ok, max on win its 10.
24 * Costantino Leandro
27 #define MODULE_NAME "t613"
29 #include "gspca.h"
31 #define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 0)
33 MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
34 MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver");
35 MODULE_LICENSE("GPL");
37 struct sd {
38 struct gspca_dev gspca_dev; /* !! must be the first item */
40 u8 brightness;
41 u8 contrast;
42 u8 colors;
43 u8 autogain;
44 u8 gamma;
45 u8 sharpness;
46 u8 freq;
47 u8 whitebalance;
48 u8 mirror;
49 u8 effect;
51 u8 sensor;
52 #define SENSOR_OM6802 0
53 #define SENSOR_OTHER 1
54 #define SENSOR_TAS5130A 2
55 #define SENSOR_LT168G 3 /* must verify if this is the actual model */
58 /* V4L2 controls supported by the driver */
59 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
60 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
61 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
62 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
63 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
64 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
65 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val);
66 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val);
67 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
68 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
69 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
70 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
71 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
72 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
73 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val);
74 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val);
75 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val);
76 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val);
77 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val);
78 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val);
79 static int sd_querymenu(struct gspca_dev *gspca_dev,
80 struct v4l2_querymenu *menu);
82 static const struct ctrl sd_ctrls[] = {
85 .id = V4L2_CID_BRIGHTNESS,
86 .type = V4L2_CTRL_TYPE_INTEGER,
87 .name = "Brightness",
88 .minimum = 0,
89 .maximum = 14,
90 .step = 1,
91 #define BRIGHTNESS_DEF 8
92 .default_value = BRIGHTNESS_DEF,
94 .set = sd_setbrightness,
95 .get = sd_getbrightness,
99 .id = V4L2_CID_CONTRAST,
100 .type = V4L2_CTRL_TYPE_INTEGER,
101 .name = "Contrast",
102 .minimum = 0,
103 .maximum = 0x0d,
104 .step = 1,
105 #define CONTRAST_DEF 0x07
106 .default_value = CONTRAST_DEF,
108 .set = sd_setcontrast,
109 .get = sd_getcontrast,
113 .id = V4L2_CID_SATURATION,
114 .type = V4L2_CTRL_TYPE_INTEGER,
115 .name = "Color",
116 .minimum = 0,
117 .maximum = 0x0f,
118 .step = 1,
119 #define COLORS_DEF 0x05
120 .default_value = COLORS_DEF,
122 .set = sd_setcolors,
123 .get = sd_getcolors,
125 #define GAMMA_MAX 16
126 #define GAMMA_DEF 10
129 .id = V4L2_CID_GAMMA, /* (gamma on win) */
130 .type = V4L2_CTRL_TYPE_INTEGER,
131 .name = "Gamma",
132 .minimum = 0,
133 .maximum = GAMMA_MAX - 1,
134 .step = 1,
135 .default_value = GAMMA_DEF,
137 .set = sd_setgamma,
138 .get = sd_getgamma,
142 .id = V4L2_CID_GAIN, /* here, i activate only the lowlight,
143 * some apps dont bring up the
144 * backligth_compensation control) */
145 .type = V4L2_CTRL_TYPE_INTEGER,
146 .name = "Low Light",
147 .minimum = 0,
148 .maximum = 1,
149 .step = 1,
150 #define AUTOGAIN_DEF 0x01
151 .default_value = AUTOGAIN_DEF,
153 .set = sd_setlowlight,
154 .get = sd_getlowlight,
158 .id = V4L2_CID_HFLIP,
159 .type = V4L2_CTRL_TYPE_BOOLEAN,
160 .name = "Mirror Image",
161 .minimum = 0,
162 .maximum = 1,
163 .step = 1,
164 #define MIRROR_DEF 0
165 .default_value = MIRROR_DEF,
167 .set = sd_setflip,
168 .get = sd_getflip
172 .id = V4L2_CID_POWER_LINE_FREQUENCY,
173 .type = V4L2_CTRL_TYPE_MENU,
174 .name = "Light Frequency Filter",
175 .minimum = 1, /* 1 -> 0x50, 2->0x60 */
176 .maximum = 2,
177 .step = 1,
178 #define FREQ_DEF 1
179 .default_value = FREQ_DEF,
181 .set = sd_setfreq,
182 .get = sd_getfreq},
186 .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
187 .type = V4L2_CTRL_TYPE_INTEGER,
188 .name = "White Balance",
189 .minimum = 0,
190 .maximum = 1,
191 .step = 1,
192 #define WHITE_BALANCE_DEF 0
193 .default_value = WHITE_BALANCE_DEF,
195 .set = sd_setwhitebalance,
196 .get = sd_getwhitebalance
200 .id = V4L2_CID_SHARPNESS,
201 .type = V4L2_CTRL_TYPE_INTEGER,
202 .name = "Sharpness",
203 .minimum = 0,
204 .maximum = 15,
205 .step = 1,
206 #define SHARPNESS_DEF 0x06
207 .default_value = SHARPNESS_DEF,
209 .set = sd_setsharpness,
210 .get = sd_getsharpness,
214 .id = V4L2_CID_EFFECTS,
215 .type = V4L2_CTRL_TYPE_MENU,
216 .name = "Webcam Effects",
217 .minimum = 0,
218 .maximum = 4,
219 .step = 1,
220 #define EFFECTS_DEF 0
221 .default_value = EFFECTS_DEF,
223 .set = sd_seteffect,
224 .get = sd_geteffect
228 static char *effects_control[] = {
229 "Normal",
230 "Emboss", /* disabled */
231 "Monochrome",
232 "Sepia",
233 "Sketch",
234 "Sun Effect", /* disabled */
235 "Negative",
238 static const struct v4l2_pix_format vga_mode_t16[] = {
239 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
240 .bytesperline = 160,
241 .sizeimage = 160 * 120 * 4 / 8 + 590,
242 .colorspace = V4L2_COLORSPACE_JPEG,
243 .priv = 4},
244 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
245 .bytesperline = 176,
246 .sizeimage = 176 * 144 * 3 / 8 + 590,
247 .colorspace = V4L2_COLORSPACE_JPEG,
248 .priv = 3},
249 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
250 .bytesperline = 320,
251 .sizeimage = 320 * 240 * 3 / 8 + 590,
252 .colorspace = V4L2_COLORSPACE_JPEG,
253 .priv = 2},
254 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
255 .bytesperline = 352,
256 .sizeimage = 352 * 288 * 3 / 8 + 590,
257 .colorspace = V4L2_COLORSPACE_JPEG,
258 .priv = 1},
259 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
260 .bytesperline = 640,
261 .sizeimage = 640 * 480 * 3 / 8 + 590,
262 .colorspace = V4L2_COLORSPACE_JPEG,
263 .priv = 0},
266 /* sensor specific data */
267 struct additional_sensor_data {
268 const u8 n3[6];
269 const u8 *n4, n4sz;
270 const u8 reg80, reg8e;
271 const u8 nset8[6];
272 const u8 data1[10];
273 const u8 data2[9];
274 const u8 data3[9];
275 const u8 data4[4];
276 const u8 data5[6];
277 const u8 stream[4];
280 static const u8 n4_om6802[] = {
281 0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
282 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
283 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
284 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
285 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
286 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
287 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
288 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
289 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46
291 static const u8 n4_other[] = {
292 0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69,
293 0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68,
294 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8,
295 0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8,
296 0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56,
297 0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5,
298 0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0,
299 0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00
301 static const u8 n4_tas5130a[] = {
302 0x80, 0x3c, 0x81, 0x68, 0x83, 0xa0, 0x84, 0x20,
303 0x8a, 0x68, 0x8b, 0x58, 0x8c, 0x88, 0x8e, 0xb4,
304 0x8f, 0x24, 0xa1, 0xb1, 0xa2, 0x30, 0xa5, 0x10,
305 0xa6, 0x4a, 0xae, 0x03, 0xb1, 0x44, 0xb2, 0x08,
306 0xb7, 0x06, 0xb9, 0xe7, 0xbb, 0xc4, 0xbc, 0x4a,
307 0xbe, 0x36, 0xbf, 0xff, 0xc2, 0x88, 0xc5, 0xc8,
308 0xc6, 0xda
310 static const u8 n4_lt168g[] = {
311 0x66, 0x01, 0x7f, 0x00, 0x80, 0x7c, 0x81, 0x28,
312 0x83, 0x44, 0x84, 0x20, 0x86, 0x20, 0x8a, 0x70,
313 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xa0, 0x8e, 0xb3,
314 0x8f, 0x24, 0xa1, 0xb0, 0xa2, 0x38, 0xa5, 0x20,
315 0xa6, 0x4a, 0xa8, 0xe8, 0xaf, 0x38, 0xb0, 0x68,
316 0xb1, 0x44, 0xb2, 0x88, 0xbb, 0x86, 0xbd, 0x40,
317 0xbe, 0x26, 0xc1, 0x05, 0xc2, 0x88, 0xc5, 0xc0,
318 0xda, 0x8e, 0xdb, 0xca, 0xdc, 0xa8, 0xdd, 0x8c,
319 0xde, 0x44, 0xdf, 0x0c, 0xe9, 0x80
322 static const struct additional_sensor_data sensor_data[] = {
323 { /* 0: OM6802 */
324 .n3 =
325 {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04},
326 .n4 = n4_om6802,
327 .n4sz = sizeof n4_om6802,
328 .reg80 = 0x3c,
329 .reg8e = 0x33,
330 .nset8 = {0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00},
331 .data1 =
332 {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06,
333 0xb3, 0xfc},
334 .data2 =
335 {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
336 0xff},
337 .data3 =
338 {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
339 0xff},
340 .data4 = /*Freq (50/60Hz). Splitted for test purpose */
341 {0x66, 0xca, 0xa8, 0xf0},
342 .data5 = /* this could be removed later */
343 {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
344 .stream =
345 {0x0b, 0x04, 0x0a, 0x78},
347 { /* 1: OTHER */
348 .n3 =
349 {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00},
350 .n4 = n4_other,
351 .n4sz = sizeof n4_other,
352 .reg80 = 0xac,
353 .reg8e = 0xb8,
354 .nset8 = {0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00},
355 .data1 =
356 {0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a,
357 0xe8, 0xfc},
358 .data2 =
359 {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
360 0xd9},
361 .data3 =
362 {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
363 0xd9},
364 .data4 =
365 {0x66, 0x00, 0xa8, 0xa8},
366 .data5 =
367 {0x0c, 0x03, 0xab, 0x29, 0x81, 0x69},
368 .stream =
369 {0x0b, 0x04, 0x0a, 0x00},
371 { /* 2: TAS5130A */
372 .n3 =
373 {0x61, 0xc2, 0x65, 0x0d, 0x60, 0x08},
374 .n4 = n4_tas5130a,
375 .n4sz = sizeof n4_tas5130a,
376 .reg80 = 0x3c,
377 .reg8e = 0xb4,
378 .nset8 = {0xa8, 0xf0, 0xc6, 0xda, 0xc0, 0x00},
379 .data1 =
380 {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
381 0xc8, 0xfc},
382 .data2 =
383 {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
384 0xe0},
385 .data3 =
386 {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
387 0xe0},
388 .data4 = /* Freq (50/60Hz). Splitted for test purpose */
389 {0x66, 0x00, 0xa8, 0xe8},
390 .data5 =
391 {0x0c, 0x03, 0xab, 0x10, 0x81, 0x20},
392 .stream =
393 {0x0b, 0x04, 0x0a, 0x40},
395 { /* 3: LT168G */
396 .n3 = {0x61, 0xc2, 0x65, 0x68, 0x60, 0x00},
397 .n4 = n4_lt168g,
398 .n4sz = sizeof n4_lt168g,
399 .reg80 = 0x7c,
400 .reg8e = 0xb3,
401 .nset8 = {0xa8, 0xf0, 0xc6, 0xba, 0xc0, 0x00},
402 .data1 = {0xc0, 0x38, 0x08, 0x10, 0xc0, 0x30, 0x10, 0x40,
403 0xb0, 0xf4},
404 .data2 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
405 0xff},
406 .data3 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
407 0xff},
408 .data4 = {0x66, 0x41, 0xa8, 0xf0},
409 .data5 = {0x0c, 0x03, 0xab, 0x4b, 0x81, 0x2b},
410 .stream = {0x0b, 0x04, 0x0a, 0x28},
414 #define MAX_EFFECTS 7
415 /* easily done by soft, this table could be removed,
416 * i keep it here just in case */
417 static const u8 effects_table[MAX_EFFECTS][6] = {
418 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */
419 {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */
420 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */
421 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80}, /* Sepia */
422 {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02}, /* Croquis */
423 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10}, /* Sun Effect */
424 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */
427 static const u8 gamma_table[GAMMA_MAX][17] = {
428 {0x00, 0x3e, 0x69, 0x85, 0x95, 0xa1, 0xae, 0xb9, /* 0 */
429 0xc2, 0xcb, 0xd4, 0xdb, 0xe3, 0xea, 0xf1, 0xf8,
430 0xff},
431 {0x00, 0x33, 0x5a, 0x75, 0x85, 0x93, 0xa1, 0xad, /* 1 */
432 0xb7, 0xc2, 0xcb, 0xd4, 0xde, 0xe7, 0xf0, 0xf7,
433 0xff},
434 {0x00, 0x2f, 0x51, 0x6b, 0x7c, 0x8a, 0x99, 0xa6, /* 2 */
435 0xb1, 0xbc, 0xc6, 0xd0, 0xdb, 0xe4, 0xed, 0xf6,
436 0xff},
437 {0x00, 0x29, 0x48, 0x60, 0x72, 0x81, 0x90, 0x9e, /* 3 */
438 0xaa, 0xb5, 0xbf, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
439 0xff},
440 {0x00, 0x23, 0x3f, 0x55, 0x68, 0x77, 0x86, 0x95, /* 4 */
441 0xa2, 0xad, 0xb9, 0xc6, 0xd2, 0xde, 0xe9, 0xf4,
442 0xff},
443 {0x00, 0x1b, 0x33, 0x48, 0x59, 0x69, 0x79, 0x87, /* 5 */
444 0x96, 0xa3, 0xb1, 0xbe, 0xcc, 0xda, 0xe7, 0xf3,
445 0xff},
446 {0x00, 0x02, 0x10, 0x20, 0x32, 0x40, 0x57, 0x67, /* 6 */
447 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
448 0xff},
449 {0x00, 0x02, 0x14, 0x26, 0x38, 0x4a, 0x60, 0x70, /* 7 */
450 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
451 0xff},
452 {0x00, 0x10, 0x22, 0x35, 0x47, 0x5a, 0x69, 0x79, /* 8 */
453 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe0, 0xf0,
454 0xff},
455 {0x00, 0x10, 0x26, 0x40, 0x54, 0x65, 0x75, 0x84, /* 9 */
456 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd6, 0xe0, 0xf0,
457 0xff},
458 {0x00, 0x18, 0x2b, 0x44, 0x60, 0x70, 0x80, 0x8e, /* 10 */
459 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xd8, 0xe2, 0xf0,
460 0xff},
461 {0x00, 0x1a, 0x34, 0x52, 0x66, 0x7e, 0x8d, 0x9b, /* 11 */
462 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
463 0xff},
464 {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8, /* 12 */
465 0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6,
466 0xff},
467 {0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7, /* 13 */
468 0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9,
469 0xff},
470 {0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6, /* 14 */
471 0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa,
472 0xff},
473 {0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8, /* 15 */
474 0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc,
475 0xff}
478 static const u8 tas5130a_sensor_init[][8] = {
479 {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
480 {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
481 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
484 static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
486 /* read 1 byte */
487 static u8 reg_r(struct gspca_dev *gspca_dev,
488 u16 index)
490 usb_control_msg(gspca_dev->dev,
491 usb_rcvctrlpipe(gspca_dev->dev, 0),
492 0, /* request */
493 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
494 0, /* value */
495 index,
496 gspca_dev->usb_buf, 1, 500);
497 return gspca_dev->usb_buf[0];
500 static void reg_w(struct gspca_dev *gspca_dev,
501 u16 index)
503 usb_control_msg(gspca_dev->dev,
504 usb_sndctrlpipe(gspca_dev->dev, 0),
506 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
507 0, index,
508 NULL, 0, 500);
511 static void reg_w_buf(struct gspca_dev *gspca_dev,
512 const u8 *buffer, u16 len)
514 if (len <= USB_BUF_SZ) {
515 memcpy(gspca_dev->usb_buf, buffer, len);
516 usb_control_msg(gspca_dev->dev,
517 usb_sndctrlpipe(gspca_dev->dev, 0),
519 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
520 0x01, 0,
521 gspca_dev->usb_buf, len, 500);
522 } else {
523 u8 *tmpbuf;
525 tmpbuf = kmalloc(len, GFP_KERNEL);
526 memcpy(tmpbuf, buffer, len);
527 usb_control_msg(gspca_dev->dev,
528 usb_sndctrlpipe(gspca_dev->dev, 0),
530 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
531 0x01, 0,
532 tmpbuf, len, 500);
533 kfree(tmpbuf);
537 /* write values to consecutive registers */
538 static void reg_w_ixbuf(struct gspca_dev *gspca_dev,
539 u8 reg,
540 const u8 *buffer, u16 len)
542 int i;
543 u8 *p, *tmpbuf;
545 if (len * 2 <= USB_BUF_SZ)
546 p = tmpbuf = gspca_dev->usb_buf;
547 else
548 p = tmpbuf = kmalloc(len * 2, GFP_KERNEL);
549 i = len;
550 while (--i >= 0) {
551 *p++ = reg++;
552 *p++ = *buffer++;
554 usb_control_msg(gspca_dev->dev,
555 usb_sndctrlpipe(gspca_dev->dev, 0),
557 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
558 0x01, 0,
559 tmpbuf, len * 2, 500);
560 if (len * 2 > USB_BUF_SZ)
561 kfree(tmpbuf);
564 /* Reported as OM6802*/
565 static void om6802_sensor_init(struct gspca_dev *gspca_dev)
567 int i;
568 const u8 *p;
569 u8 byte;
570 u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
571 static const u8 sensor_init[] = {
572 0xdf, 0x6d,
573 0xdd, 0x18,
574 0x5a, 0xe0,
575 0x5c, 0x07,
576 0x5d, 0xb0,
577 0x5e, 0x1e,
578 0x60, 0x71,
579 0xef, 0x00,
580 0xe9, 0x00,
581 0xea, 0x00,
582 0x90, 0x24,
583 0x91, 0xb2,
584 0x82, 0x32,
585 0xfd, 0x41,
586 0x00 /* table end */
589 reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
590 msleep(100);
591 i = 4;
592 while (--i > 0) {
593 byte = reg_r(gspca_dev, 0x0060);
594 if (!(byte & 0x01))
595 break;
596 msleep(100);
598 byte = reg_r(gspca_dev, 0x0063);
599 if (byte != 0x17) {
600 err("Bad sensor reset %02x", byte);
601 /* continue? */
604 p = sensor_init;
605 while (*p != 0) {
606 val[1] = *p++;
607 val[3] = *p++;
608 if (*p == 0)
609 reg_w(gspca_dev, 0x3c80);
610 reg_w_buf(gspca_dev, val, sizeof val);
611 i = 4;
612 while (--i >= 0) {
613 msleep(15);
614 byte = reg_r(gspca_dev, 0x60);
615 if (!(byte & 0x01))
616 break;
619 msleep(15);
620 reg_w(gspca_dev, 0x3c80);
623 /* this function is called at probe time */
624 static int sd_config(struct gspca_dev *gspca_dev,
625 const struct usb_device_id *id)
627 struct sd *sd = (struct sd *) gspca_dev;
628 struct cam *cam;
630 cam = &gspca_dev->cam;
632 cam->cam_mode = vga_mode_t16;
633 cam->nmodes = ARRAY_SIZE(vga_mode_t16);
635 sd->brightness = BRIGHTNESS_DEF;
636 sd->contrast = CONTRAST_DEF;
637 sd->colors = COLORS_DEF;
638 sd->gamma = GAMMA_DEF;
639 sd->autogain = AUTOGAIN_DEF;
640 sd->mirror = MIRROR_DEF;
641 sd->freq = FREQ_DEF;
642 sd->whitebalance = WHITE_BALANCE_DEF;
643 sd->sharpness = SHARPNESS_DEF;
644 sd->effect = EFFECTS_DEF;
645 return 0;
648 static void setbrightness(struct gspca_dev *gspca_dev)
650 struct sd *sd = (struct sd *) gspca_dev;
651 unsigned int brightness;
652 u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
654 brightness = sd->brightness;
655 if (brightness < 7) {
656 set6[1] = 0x26;
657 set6[3] = 0x70 - brightness * 0x10;
658 } else {
659 set6[3] = 0x00 + ((brightness - 7) * 0x10);
662 reg_w_buf(gspca_dev, set6, sizeof set6);
665 static void setcontrast(struct gspca_dev *gspca_dev)
667 struct sd *sd = (struct sd *) gspca_dev;
668 unsigned int contrast = sd->contrast;
669 u16 reg_to_write;
671 if (contrast < 7)
672 reg_to_write = 0x8ea9 - contrast * 0x200;
673 else
674 reg_to_write = 0x00a9 + (contrast - 7) * 0x200;
676 reg_w(gspca_dev, reg_to_write);
679 static void setcolors(struct gspca_dev *gspca_dev)
681 struct sd *sd = (struct sd *) gspca_dev;
682 u16 reg_to_write;
684 reg_to_write = 0x80bb + sd->colors * 0x100; /* was 0xc0 */
685 reg_w(gspca_dev, reg_to_write);
688 static void setgamma(struct gspca_dev *gspca_dev)
690 struct sd *sd = (struct sd *) gspca_dev;
692 PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
693 reg_w_ixbuf(gspca_dev, 0x90,
694 gamma_table[sd->gamma], sizeof gamma_table[0]);
697 static void setwhitebalance(struct gspca_dev *gspca_dev)
699 struct sd *sd = (struct sd *) gspca_dev;
701 u8 white_balance[8] =
702 {0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38};
704 if (sd->whitebalance)
705 white_balance[7] = 0x3c;
707 reg_w_buf(gspca_dev, white_balance, sizeof white_balance);
710 static void setsharpness(struct gspca_dev *gspca_dev)
712 struct sd *sd = (struct sd *) gspca_dev;
713 u16 reg_to_write;
715 reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
717 reg_w(gspca_dev, reg_to_write);
720 /* this function is called at probe and resume time */
721 static int sd_init(struct gspca_dev *gspca_dev)
723 /* some of this registers are not really neded, because
724 * they are overriden by setbrigthness, setcontrast, etc,
725 * but wont hurt anyway, and can help someone with similar webcam
726 * to see the initial parameters.*/
727 struct sd *sd = (struct sd *) gspca_dev;
728 const struct additional_sensor_data *sensor;
729 int i;
730 u16 sensor_id;
731 u8 test_byte = 0;
733 static const u8 read_indexs[] =
734 { 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
735 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00 };
736 static const u8 n1[] =
737 {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
738 static const u8 n2[] =
739 {0x08, 0x00};
741 sensor_id = (reg_r(gspca_dev, 0x06) << 8)
742 | reg_r(gspca_dev, 0x07);
743 switch (sensor_id & 0xff0f) {
744 case 0x0801:
745 PDEBUG(D_PROBE, "sensor tas5130a");
746 sd->sensor = SENSOR_TAS5130A;
747 break;
748 case 0x0802:
749 PDEBUG(D_PROBE, "sensor lt168g");
750 sd->sensor = SENSOR_LT168G;
751 break;
752 case 0x0803:
753 PDEBUG(D_PROBE, "sensor 'other'");
754 sd->sensor = SENSOR_OTHER;
755 break;
756 case 0x0807:
757 PDEBUG(D_PROBE, "sensor om6802");
758 sd->sensor = SENSOR_OM6802;
759 break;
760 default:
761 PDEBUG(D_ERR|D_PROBE, "unknown sensor %04x", sensor_id);
762 return -EINVAL;
765 if (sd->sensor == SENSOR_OM6802) {
766 reg_w_buf(gspca_dev, n1, sizeof n1);
767 i = 5;
768 while (--i >= 0) {
769 reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
770 test_byte = reg_r(gspca_dev, 0x0063);
771 msleep(100);
772 if (test_byte == 0x17)
773 break; /* OK */
775 if (i < 0) {
776 err("Bad sensor reset %02x", test_byte);
777 return -EIO;
779 reg_w_buf(gspca_dev, n2, sizeof n2);
782 i = 0;
783 while (read_indexs[i] != 0x00) {
784 test_byte = reg_r(gspca_dev, read_indexs[i]);
785 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i],
786 test_byte);
787 i++;
790 sensor = &sensor_data[sd->sensor];
791 reg_w_buf(gspca_dev, sensor->n3, sizeof sensor->n3);
792 reg_w_buf(gspca_dev, sensor->n4, sensor->n4sz);
794 if (sd->sensor == SENSOR_LT168G) {
795 test_byte = reg_r(gspca_dev, 0x80);
796 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80,
797 test_byte);
798 reg_w(gspca_dev, 0x6c80);
801 reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
802 reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
803 reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
805 reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
806 reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
807 reg_w(gspca_dev, (sensor->reg8e << 8) + 0x8e);
809 setbrightness(gspca_dev);
810 setcontrast(gspca_dev);
811 setgamma(gspca_dev);
812 setcolors(gspca_dev);
813 setsharpness(gspca_dev);
814 setwhitebalance(gspca_dev);
816 reg_w(gspca_dev, 0x2087); /* tied to white balance? */
817 reg_w(gspca_dev, 0x2088);
818 reg_w(gspca_dev, 0x2089);
820 reg_w_buf(gspca_dev, sensor->data4, sizeof sensor->data4);
821 reg_w_buf(gspca_dev, sensor->data5, sizeof sensor->data5);
822 reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8);
823 reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
825 if (sd->sensor == SENSOR_LT168G) {
826 test_byte = reg_r(gspca_dev, 0x80);
827 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80,
828 test_byte);
829 reg_w(gspca_dev, 0x6c80);
832 reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
833 reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
834 reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
836 return 0;
839 static void setflip(struct gspca_dev *gspca_dev)
841 struct sd *sd = (struct sd *) gspca_dev;
842 u8 flipcmd[8] =
843 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
845 if (sd->mirror)
846 flipcmd[3] = 0x01;
848 reg_w_buf(gspca_dev, flipcmd, sizeof flipcmd);
851 static void seteffect(struct gspca_dev *gspca_dev)
853 struct sd *sd = (struct sd *) gspca_dev;
855 reg_w_buf(gspca_dev, effects_table[sd->effect],
856 sizeof effects_table[0]);
857 if (sd->effect == 1 || sd->effect == 5) {
858 PDEBUG(D_CONF,
859 "This effect have been disabled for webcam \"safety\"");
860 return;
863 if (sd->effect == 1 || sd->effect == 4)
864 reg_w(gspca_dev, 0x4aa6);
865 else
866 reg_w(gspca_dev, 0xfaa6);
869 static void setlightfreq(struct gspca_dev *gspca_dev)
871 struct sd *sd = (struct sd *) gspca_dev;
872 u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
874 if (sd->freq == 2) /* 60hz */
875 freq[1] = 0x00;
877 reg_w_buf(gspca_dev, freq, sizeof freq);
880 /* Is this really needed?
881 * i added some module parameters for test with some users */
882 static void poll_sensor(struct gspca_dev *gspca_dev)
884 static const u8 poll1[] =
885 {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
886 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
887 0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
888 0x60, 0x14};
889 static const u8 poll2[] =
890 {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
891 0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
892 static const u8 poll3[] =
893 {0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d};
894 static const u8 poll4[] =
895 {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
896 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
897 0xc2, 0x80, 0xc3, 0x10};
899 PDEBUG(D_STREAM, "[Sensor requires polling]");
900 reg_w_buf(gspca_dev, poll1, sizeof poll1);
901 reg_w_buf(gspca_dev, poll2, sizeof poll2);
902 reg_w_buf(gspca_dev, poll3, sizeof poll3);
903 reg_w_buf(gspca_dev, poll4, sizeof poll4);
906 static int sd_start(struct gspca_dev *gspca_dev)
908 struct sd *sd = (struct sd *) gspca_dev;
909 const struct additional_sensor_data *sensor;
910 int i, mode;
911 u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
912 static const u8 t3[] =
913 { 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 };
915 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
916 switch (mode) {
917 case 0: /* 640x480 (0x00) */
918 break;
919 case 1: /* 352x288 */
920 t2[1] = 0x40;
921 break;
922 case 2: /* 320x240 */
923 t2[1] = 0x10;
924 break;
925 case 3: /* 176x144 */
926 t2[1] = 0x50;
927 break;
928 default:
929 /* case 4: * 160x120 */
930 t2[1] = 0x20;
931 break;
934 switch (sd->sensor) {
935 case SENSOR_OM6802:
936 om6802_sensor_init(gspca_dev);
937 break;
938 case SENSOR_LT168G:
939 break;
940 case SENSOR_OTHER:
941 break;
942 default:
943 /* case SENSOR_TAS5130A: */
944 i = 0;
945 for (;;) {
946 reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
947 sizeof tas5130a_sensor_init[0]);
948 if (i >= ARRAY_SIZE(tas5130a_sensor_init) - 1)
949 break;
950 i++;
952 reg_w(gspca_dev, 0x3c80);
953 /* just in case and to keep sync with logs (for mine) */
954 reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
955 sizeof tas5130a_sensor_init[0]);
956 reg_w(gspca_dev, 0x3c80);
957 break;
959 sensor = &sensor_data[sd->sensor];
960 reg_w_buf(gspca_dev, sensor->data4, sizeof sensor->data4);
961 reg_r(gspca_dev, 0x0012);
962 reg_w_buf(gspca_dev, t2, sizeof t2);
963 reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3);
964 reg_w(gspca_dev, 0x0013);
965 msleep(15);
966 reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
967 reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
969 if (sd->sensor == SENSOR_OM6802)
970 poll_sensor(gspca_dev);
972 return 0;
975 static void sd_stopN(struct gspca_dev *gspca_dev)
977 struct sd *sd = (struct sd *) gspca_dev;
979 reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
980 sizeof sensor_data[sd->sensor].stream);
981 reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
982 sizeof sensor_data[sd->sensor].stream);
983 if (sd->sensor == SENSOR_OM6802) {
984 msleep(20);
985 reg_w(gspca_dev, 0x0309);
989 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
990 u8 *data, /* isoc packet */
991 int len) /* iso packet length */
993 static u8 ffd9[] = { 0xff, 0xd9 };
995 if (data[0] == 0x5a) {
996 /* Control Packet, after this came the header again,
997 * but extra bytes came in the packet before this,
998 * sometimes an EOF arrives, sometimes not... */
999 return;
1001 data += 2;
1002 len -= 2;
1003 if (data[0] == 0xff && data[1] == 0xd8) {
1004 /* extra bytes....., could be processed too but would be
1005 * a waste of time, right now leave the application and
1006 * libjpeg do it for ourserlves.. */
1007 gspca_frame_add(gspca_dev, LAST_PACKET,
1008 ffd9, 2);
1009 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
1010 return;
1013 if (data[len - 2] == 0xff && data[len - 1] == 0xd9) {
1014 /* Just in case, i have seen packets with the marker,
1015 * other's do not include it... */
1016 len -= 2;
1018 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1021 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1023 struct sd *sd = (struct sd *) gspca_dev;
1025 sd->brightness = val;
1026 if (gspca_dev->streaming)
1027 setbrightness(gspca_dev);
1028 return 0;
1031 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1033 struct sd *sd = (struct sd *) gspca_dev;
1035 *val = sd->brightness;
1036 return *val;
1039 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
1041 struct sd *sd = (struct sd *) gspca_dev;
1043 sd->whitebalance = val;
1044 if (gspca_dev->streaming)
1045 setwhitebalance(gspca_dev);
1046 return 0;
1049 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
1051 struct sd *sd = (struct sd *) gspca_dev;
1053 *val = sd->whitebalance;
1054 return *val;
1057 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val)
1059 struct sd *sd = (struct sd *) gspca_dev;
1061 sd->mirror = val;
1062 if (gspca_dev->streaming)
1063 setflip(gspca_dev);
1064 return 0;
1067 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val)
1069 struct sd *sd = (struct sd *) gspca_dev;
1071 *val = sd->mirror;
1072 return *val;
1075 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val)
1077 struct sd *sd = (struct sd *) gspca_dev;
1079 sd->effect = val;
1080 if (gspca_dev->streaming)
1081 seteffect(gspca_dev);
1082 return 0;
1085 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val)
1087 struct sd *sd = (struct sd *) gspca_dev;
1089 *val = sd->effect;
1090 return *val;
1093 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1095 struct sd *sd = (struct sd *) gspca_dev;
1097 sd->contrast = val;
1098 if (gspca_dev->streaming)
1099 setcontrast(gspca_dev);
1100 return 0;
1103 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1105 struct sd *sd = (struct sd *) gspca_dev;
1107 *val = sd->contrast;
1108 return *val;
1111 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1113 struct sd *sd = (struct sd *) gspca_dev;
1115 sd->colors = val;
1116 if (gspca_dev->streaming)
1117 setcolors(gspca_dev);
1118 return 0;
1121 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1123 struct sd *sd = (struct sd *) gspca_dev;
1125 *val = sd->colors;
1126 return 0;
1129 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
1131 struct sd *sd = (struct sd *) gspca_dev;
1133 sd->gamma = val;
1134 if (gspca_dev->streaming)
1135 setgamma(gspca_dev);
1136 return 0;
1139 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
1141 struct sd *sd = (struct sd *) gspca_dev;
1143 *val = sd->gamma;
1144 return 0;
1147 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1149 struct sd *sd = (struct sd *) gspca_dev;
1151 sd->freq = val;
1152 if (gspca_dev->streaming)
1153 setlightfreq(gspca_dev);
1154 return 0;
1157 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1159 struct sd *sd = (struct sd *) gspca_dev;
1161 *val = sd->freq;
1162 return 0;
1165 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
1167 struct sd *sd = (struct sd *) gspca_dev;
1169 sd->sharpness = val;
1170 if (gspca_dev->streaming)
1171 setsharpness(gspca_dev);
1172 return 0;
1175 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
1177 struct sd *sd = (struct sd *) gspca_dev;
1179 *val = sd->sharpness;
1180 return 0;
1183 /* Low Light set here......*/
1184 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
1186 struct sd *sd = (struct sd *) gspca_dev;
1188 sd->autogain = val;
1189 if (val != 0)
1190 reg_w(gspca_dev, 0xf48e);
1191 else
1192 reg_w(gspca_dev, 0xb48e);
1193 return 0;
1196 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
1198 struct sd *sd = (struct sd *) gspca_dev;
1200 *val = sd->autogain;
1201 return 0;
1204 static int sd_querymenu(struct gspca_dev *gspca_dev,
1205 struct v4l2_querymenu *menu)
1207 switch (menu->id) {
1208 case V4L2_CID_POWER_LINE_FREQUENCY:
1209 switch (menu->index) {
1210 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1211 strcpy((char *) menu->name, "50 Hz");
1212 return 0;
1213 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1214 strcpy((char *) menu->name, "60 Hz");
1215 return 0;
1217 break;
1218 case V4L2_CID_EFFECTS:
1219 if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
1220 strncpy((char *) menu->name,
1221 effects_control[menu->index], 32);
1222 return 0;
1224 break;
1226 return -EINVAL;
1229 /* sub-driver description */
1230 static const struct sd_desc sd_desc = {
1231 .name = MODULE_NAME,
1232 .ctrls = sd_ctrls,
1233 .nctrls = ARRAY_SIZE(sd_ctrls),
1234 .config = sd_config,
1235 .init = sd_init,
1236 .start = sd_start,
1237 .stopN = sd_stopN,
1238 .pkt_scan = sd_pkt_scan,
1239 .querymenu = sd_querymenu,
1242 /* -- module initialisation -- */
1243 static const __devinitdata struct usb_device_id device_table[] = {
1244 {USB_DEVICE(0x17a1, 0x0128)},
1247 MODULE_DEVICE_TABLE(usb, device_table);
1249 /* -- device connect -- */
1250 static int sd_probe(struct usb_interface *intf,
1251 const struct usb_device_id *id)
1253 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1254 THIS_MODULE);
1257 static struct usb_driver sd_driver = {
1258 .name = MODULE_NAME,
1259 .id_table = device_table,
1260 .probe = sd_probe,
1261 .disconnect = gspca_disconnect,
1262 #ifdef CONFIG_PM
1263 .suspend = gspca_suspend,
1264 .resume = gspca_resume,
1265 #endif
1268 /* -- module insert / remove -- */
1269 static int __init sd_mod_init(void)
1271 int ret;
1272 ret = usb_register(&sd_driver);
1273 if (ret < 0)
1274 return ret;
1275 PDEBUG(D_PROBE, "registered");
1276 return 0;
1278 static void __exit sd_mod_exit(void)
1280 usb_deregister(&sd_driver);
1281 PDEBUG(D_PROBE, "deregistered");
1284 module_init(sd_mod_init);
1285 module_exit(sd_mod_exit);