OMAP3 SRF: Generic shared resource f/w
[linux-ginger.git] / drivers / media / video / gspca / t613.c
blob1d321c30d22f57c630fafa87d2bf52eb7025c6c1
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
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_setlowlight(struct gspca_dev *gspca_dev, __s32 val);
65 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val);
66 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
67 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
68 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
69 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
70 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
71 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
72 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val);
73 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val);
74 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val);
75 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val);
76 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val);
77 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val);
78 static int sd_querymenu(struct gspca_dev *gspca_dev,
79 struct v4l2_querymenu *menu);
81 static struct ctrl sd_ctrls[] = {
84 .id = V4L2_CID_BRIGHTNESS,
85 .type = V4L2_CTRL_TYPE_INTEGER,
86 .name = "Brightness",
87 .minimum = 0,
88 .maximum = 14,
89 .step = 1,
90 #define BRIGHTNESS_DEF 8
91 .default_value = BRIGHTNESS_DEF,
93 .set = sd_setbrightness,
94 .get = sd_getbrightness,
98 .id = V4L2_CID_CONTRAST,
99 .type = V4L2_CTRL_TYPE_INTEGER,
100 .name = "Contrast",
101 .minimum = 0,
102 .maximum = 0x0d,
103 .step = 1,
104 #define CONTRAST_DEF 0x07
105 .default_value = CONTRAST_DEF,
107 .set = sd_setcontrast,
108 .get = sd_getcontrast,
112 .id = V4L2_CID_SATURATION,
113 .type = V4L2_CTRL_TYPE_INTEGER,
114 .name = "Color",
115 .minimum = 0,
116 .maximum = 0x0f,
117 .step = 1,
118 #define COLORS_DEF 0x05
119 .default_value = COLORS_DEF,
121 .set = sd_setcolors,
122 .get = sd_getcolors,
124 #define GAMMA_MAX 16
125 #define GAMMA_DEF 10
128 .id = V4L2_CID_GAMMA, /* (gamma on win) */
129 .type = V4L2_CTRL_TYPE_INTEGER,
130 .name = "Gamma",
131 .minimum = 0,
132 .maximum = GAMMA_MAX - 1,
133 .step = 1,
134 .default_value = GAMMA_DEF,
136 .set = sd_setgamma,
137 .get = sd_getgamma,
141 .id = V4L2_CID_GAIN, /* here, i activate only the lowlight,
142 * some apps dont bring up the
143 * backligth_compensation control) */
144 .type = V4L2_CTRL_TYPE_INTEGER,
145 .name = "Low Light",
146 .minimum = 0,
147 .maximum = 1,
148 .step = 1,
149 #define AUTOGAIN_DEF 0x01
150 .default_value = AUTOGAIN_DEF,
152 .set = sd_setlowlight,
153 .get = sd_getlowlight,
157 .id = V4L2_CID_HFLIP,
158 .type = V4L2_CTRL_TYPE_BOOLEAN,
159 .name = "Mirror Image",
160 .minimum = 0,
161 .maximum = 1,
162 .step = 1,
163 #define MIRROR_DEF 0
164 .default_value = MIRROR_DEF,
166 .set = sd_setflip,
167 .get = sd_getflip
171 .id = V4L2_CID_POWER_LINE_FREQUENCY,
172 .type = V4L2_CTRL_TYPE_MENU,
173 .name = "Light Frequency Filter",
174 .minimum = 1, /* 1 -> 0x50, 2->0x60 */
175 .maximum = 2,
176 .step = 1,
177 #define FREQ_DEF 1
178 .default_value = FREQ_DEF,
180 .set = sd_setfreq,
181 .get = sd_getfreq},
185 .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
186 .type = V4L2_CTRL_TYPE_INTEGER,
187 .name = "White Balance",
188 .minimum = 0,
189 .maximum = 1,
190 .step = 1,
191 #define WHITE_BALANCE_DEF 0
192 .default_value = WHITE_BALANCE_DEF,
194 .set = sd_setwhitebalance,
195 .get = sd_getwhitebalance
199 .id = V4L2_CID_SHARPNESS,
200 .type = V4L2_CTRL_TYPE_INTEGER,
201 .name = "Sharpness",
202 .minimum = 0,
203 .maximum = 15,
204 .step = 1,
205 #define SHARPNESS_DEF 0x06
206 .default_value = SHARPNESS_DEF,
208 .set = sd_setsharpness,
209 .get = sd_getsharpness,
213 .id = V4L2_CID_EFFECTS,
214 .type = V4L2_CTRL_TYPE_MENU,
215 .name = "Webcam Effects",
216 .minimum = 0,
217 .maximum = 4,
218 .step = 1,
219 #define EFFECTS_DEF 0
220 .default_value = EFFECTS_DEF,
222 .set = sd_seteffect,
223 .get = sd_geteffect
227 static char *effects_control[] = {
228 "Normal",
229 "Emboss", /* disabled */
230 "Monochrome",
231 "Sepia",
232 "Sketch",
233 "Sun Effect", /* disabled */
234 "Negative",
237 static const struct v4l2_pix_format vga_mode_t16[] = {
238 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
239 .bytesperline = 160,
240 .sizeimage = 160 * 120 * 4 / 8 + 590,
241 .colorspace = V4L2_COLORSPACE_JPEG,
242 .priv = 4},
243 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
244 .bytesperline = 176,
245 .sizeimage = 176 * 144 * 3 / 8 + 590,
246 .colorspace = V4L2_COLORSPACE_JPEG,
247 .priv = 3},
248 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
249 .bytesperline = 320,
250 .sizeimage = 320 * 240 * 3 / 8 + 590,
251 .colorspace = V4L2_COLORSPACE_JPEG,
252 .priv = 2},
253 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
254 .bytesperline = 352,
255 .sizeimage = 352 * 288 * 3 / 8 + 590,
256 .colorspace = V4L2_COLORSPACE_JPEG,
257 .priv = 1},
258 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
259 .bytesperline = 640,
260 .sizeimage = 640 * 480 * 3 / 8 + 590,
261 .colorspace = V4L2_COLORSPACE_JPEG,
262 .priv = 0},
265 /* sensor specific data */
266 struct additional_sensor_data {
267 const u8 n3[6];
268 const u8 *n4, n4sz;
269 const u8 reg80, reg8e;
270 const u8 nset8[6];
271 const u8 data1[10];
272 const u8 data2[9];
273 const u8 data3[9];
274 const u8 data4[4];
275 const u8 data5[6];
276 const u8 stream[4];
279 static const u8 n4_om6802[] = {
280 0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
281 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
282 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
283 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
284 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
285 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
286 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
287 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
288 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46
290 static const u8 n4_other[] = {
291 0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69,
292 0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68,
293 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8,
294 0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8,
295 0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56,
296 0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5,
297 0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0,
298 0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00
300 static const u8 n4_tas5130a[] = {
301 0x80, 0x3c, 0x81, 0x68, 0x83, 0xa0, 0x84, 0x20,
302 0x8a, 0x68, 0x8b, 0x58, 0x8c, 0x88, 0x8e, 0xb4,
303 0x8f, 0x24, 0xa1, 0xb1, 0xa2, 0x30, 0xa5, 0x10,
304 0xa6, 0x4a, 0xae, 0x03, 0xb1, 0x44, 0xb2, 0x08,
305 0xb7, 0x06, 0xb9, 0xe7, 0xbb, 0xc4, 0xbc, 0x4a,
306 0xbe, 0x36, 0xbf, 0xff, 0xc2, 0x88, 0xc5, 0xc8,
307 0xc6, 0xda
310 static const struct additional_sensor_data sensor_data[] = {
311 { /* 0: OM6802 */
312 .n3 =
313 {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04},
314 .n4 = n4_om6802,
315 .n4sz = sizeof n4_om6802,
316 .reg80 = 0x3c,
317 .reg8e = 0x33,
318 .nset8 = {0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00},
319 .data1 =
320 {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06,
321 0xb3, 0xfc},
322 .data2 =
323 {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
324 0xff},
325 .data3 =
326 {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
327 0xff},
328 .data4 = /*Freq (50/60Hz). Splitted for test purpose */
329 {0x66, 0xca, 0xa8, 0xf0},
330 .data5 = /* this could be removed later */
331 {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
332 .stream =
333 {0x0b, 0x04, 0x0a, 0x78},
335 { /* 1: OTHER */
336 .n3 =
337 {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00},
338 .n4 = n4_other,
339 .n4sz = sizeof n4_other,
340 .reg80 = 0xac,
341 .reg8e = 0xb8,
342 .nset8 = {0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00},
343 .data1 =
344 {0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a,
345 0xe8, 0xfc},
346 .data2 =
347 {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
348 0xd9},
349 .data3 =
350 {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
351 0xd9},
352 .data4 =
353 {0x66, 0x00, 0xa8, 0xa8},
354 .data5 =
355 {0x0c, 0x03, 0xab, 0x29, 0x81, 0x69},
356 .stream =
357 {0x0b, 0x04, 0x0a, 0x00},
359 { /* 2: TAS5130A */
360 .n3 =
361 {0x61, 0xc2, 0x65, 0x0d, 0x60, 0x08},
362 .n4 = n4_tas5130a,
363 .n4sz = sizeof n4_tas5130a,
364 .reg80 = 0x3c,
365 .reg8e = 0xb4,
366 .nset8 = {0xa8, 0xf0, 0xc6, 0xda, 0xc0, 0x00},
367 .data1 =
368 {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
369 0xc8, 0xfc},
370 .data2 =
371 {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
372 0xe0},
373 .data3 =
374 {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
375 0xe0},
376 .data4 = /* Freq (50/60Hz). Splitted for test purpose */
377 {0x66, 0x00, 0xa8, 0xe8},
378 .data5 =
379 {0x0c, 0x03, 0xab, 0x10, 0x81, 0x20},
380 .stream =
381 {0x0b, 0x04, 0x0a, 0x40},
385 #define MAX_EFFECTS 7
386 /* easily done by soft, this table could be removed,
387 * i keep it here just in case */
388 static const u8 effects_table[MAX_EFFECTS][6] = {
389 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */
390 {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */
391 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */
392 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80}, /* Sepia */
393 {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02}, /* Croquis */
394 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10}, /* Sun Effect */
395 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */
398 static const u8 gamma_table[GAMMA_MAX][17] = {
399 {0x00, 0x3e, 0x69, 0x85, 0x95, 0xa1, 0xae, 0xb9, /* 0 */
400 0xc2, 0xcb, 0xd4, 0xdb, 0xe3, 0xea, 0xf1, 0xf8,
401 0xff},
402 {0x00, 0x33, 0x5a, 0x75, 0x85, 0x93, 0xa1, 0xad, /* 1 */
403 0xb7, 0xc2, 0xcb, 0xd4, 0xde, 0xe7, 0xf0, 0xf7,
404 0xff},
405 {0x00, 0x2f, 0x51, 0x6b, 0x7c, 0x8a, 0x99, 0xa6, /* 2 */
406 0xb1, 0xbc, 0xc6, 0xd0, 0xdb, 0xe4, 0xed, 0xf6,
407 0xff},
408 {0x00, 0x29, 0x48, 0x60, 0x72, 0x81, 0x90, 0x9e, /* 3 */
409 0xaa, 0xb5, 0xbf, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
410 0xff},
411 {0x00, 0x23, 0x3f, 0x55, 0x68, 0x77, 0x86, 0x95, /* 4 */
412 0xa2, 0xad, 0xb9, 0xc6, 0xd2, 0xde, 0xe9, 0xf4,
413 0xff},
414 {0x00, 0x1b, 0x33, 0x48, 0x59, 0x69, 0x79, 0x87, /* 5 */
415 0x96, 0xa3, 0xb1, 0xbe, 0xcc, 0xda, 0xe7, 0xf3,
416 0xff},
417 {0x00, 0x02, 0x10, 0x20, 0x32, 0x40, 0x57, 0x67, /* 6 */
418 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
419 0xff},
420 {0x00, 0x02, 0x14, 0x26, 0x38, 0x4a, 0x60, 0x70, /* 7 */
421 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
422 0xff},
423 {0x00, 0x10, 0x22, 0x35, 0x47, 0x5a, 0x69, 0x79, /* 8 */
424 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe0, 0xf0,
425 0xff},
426 {0x00, 0x10, 0x26, 0x40, 0x54, 0x65, 0x75, 0x84, /* 9 */
427 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd6, 0xe0, 0xf0,
428 0xff},
429 {0x00, 0x18, 0x2b, 0x44, 0x60, 0x70, 0x80, 0x8e, /* 10 */
430 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xd8, 0xe2, 0xf0,
431 0xff},
432 {0x00, 0x1a, 0x34, 0x52, 0x66, 0x7e, 0x8d, 0x9b, /* 11 */
433 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
434 0xff},
435 {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8, /* 12 */
436 0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6,
437 0xff},
438 {0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7, /* 13 */
439 0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9,
440 0xff},
441 {0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6, /* 14 */
442 0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa,
443 0xff},
444 {0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8, /* 15 */
445 0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc,
446 0xff}
449 static const u8 tas5130a_sensor_init[][8] = {
450 {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
451 {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
452 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
455 static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
457 /* read 1 byte */
458 static u8 reg_r(struct gspca_dev *gspca_dev,
459 u16 index)
461 usb_control_msg(gspca_dev->dev,
462 usb_rcvctrlpipe(gspca_dev->dev, 0),
463 0, /* request */
464 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
465 0, /* value */
466 index,
467 gspca_dev->usb_buf, 1, 500);
468 return gspca_dev->usb_buf[0];
471 static void reg_w(struct gspca_dev *gspca_dev,
472 u16 index)
474 usb_control_msg(gspca_dev->dev,
475 usb_sndctrlpipe(gspca_dev->dev, 0),
477 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
478 0, index,
479 NULL, 0, 500);
482 static void reg_w_buf(struct gspca_dev *gspca_dev,
483 const u8 *buffer, u16 len)
485 if (len <= USB_BUF_SZ) {
486 memcpy(gspca_dev->usb_buf, buffer, len);
487 usb_control_msg(gspca_dev->dev,
488 usb_sndctrlpipe(gspca_dev->dev, 0),
490 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
491 0x01, 0,
492 gspca_dev->usb_buf, len, 500);
493 } else {
494 u8 *tmpbuf;
496 tmpbuf = kmalloc(len, GFP_KERNEL);
497 memcpy(tmpbuf, buffer, len);
498 usb_control_msg(gspca_dev->dev,
499 usb_sndctrlpipe(gspca_dev->dev, 0),
501 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
502 0x01, 0,
503 tmpbuf, len, 500);
504 kfree(tmpbuf);
508 /* write values to consecutive registers */
509 static void reg_w_ixbuf(struct gspca_dev *gspca_dev,
510 u8 reg,
511 const u8 *buffer, u16 len)
513 int i;
514 u8 *p, *tmpbuf;
516 if (len * 2 <= USB_BUF_SZ)
517 p = tmpbuf = gspca_dev->usb_buf;
518 else
519 p = tmpbuf = kmalloc(len * 2, GFP_KERNEL);
520 i = len;
521 while (--i >= 0) {
522 *p++ = reg++;
523 *p++ = *buffer++;
525 usb_control_msg(gspca_dev->dev,
526 usb_sndctrlpipe(gspca_dev->dev, 0),
528 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
529 0x01, 0,
530 tmpbuf, len * 2, 500);
531 if (len * 2 > USB_BUF_SZ)
532 kfree(tmpbuf);
535 /* Reported as OM6802*/
536 static void om6802_sensor_init(struct gspca_dev *gspca_dev)
538 int i;
539 const u8 *p;
540 u8 byte;
541 u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
542 static const u8 sensor_init[] = {
543 0xdf, 0x6d,
544 0xdd, 0x18,
545 0x5a, 0xe0,
546 0x5c, 0x07,
547 0x5d, 0xb0,
548 0x5e, 0x1e,
549 0x60, 0x71,
550 0xef, 0x00,
551 0xe9, 0x00,
552 0xea, 0x00,
553 0x90, 0x24,
554 0x91, 0xb2,
555 0x82, 0x32,
556 0xfd, 0x41,
557 0x00 /* table end */
560 reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
561 msleep(100);
562 i = 4;
563 while (--i > 0) {
564 byte = reg_r(gspca_dev, 0x0060);
565 if (!(byte & 0x01))
566 break;
567 msleep(100);
569 byte = reg_r(gspca_dev, 0x0063);
570 if (byte != 0x17) {
571 err("Bad sensor reset %02x", byte);
572 /* continue? */
575 p = sensor_init;
576 while (*p != 0) {
577 val[1] = *p++;
578 val[3] = *p++;
579 if (*p == 0)
580 reg_w(gspca_dev, 0x3c80);
581 reg_w_buf(gspca_dev, val, sizeof val);
582 i = 4;
583 while (--i >= 0) {
584 msleep(15);
585 byte = reg_r(gspca_dev, 0x60);
586 if (!(byte & 0x01))
587 break;
590 msleep(15);
591 reg_w(gspca_dev, 0x3c80);
594 /* this function is called at probe time */
595 static int sd_config(struct gspca_dev *gspca_dev,
596 const struct usb_device_id *id)
598 struct sd *sd = (struct sd *) gspca_dev;
599 struct cam *cam;
601 cam = &gspca_dev->cam;
603 cam->cam_mode = vga_mode_t16;
604 cam->nmodes = ARRAY_SIZE(vga_mode_t16);
606 sd->brightness = BRIGHTNESS_DEF;
607 sd->contrast = CONTRAST_DEF;
608 sd->colors = COLORS_DEF;
609 sd->gamma = GAMMA_DEF;
610 sd->autogain = AUTOGAIN_DEF;
611 sd->mirror = MIRROR_DEF;
612 sd->freq = FREQ_DEF;
613 sd->whitebalance = WHITE_BALANCE_DEF;
614 sd->sharpness = SHARPNESS_DEF;
615 sd->effect = EFFECTS_DEF;
616 return 0;
619 static void setbrightness(struct gspca_dev *gspca_dev)
621 struct sd *sd = (struct sd *) gspca_dev;
622 unsigned int brightness;
623 u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
625 brightness = sd->brightness;
626 if (brightness < 7) {
627 set6[1] = 0x26;
628 set6[3] = 0x70 - brightness * 0x10;
629 } else {
630 set6[3] = 0x00 + ((brightness - 7) * 0x10);
633 reg_w_buf(gspca_dev, set6, sizeof set6);
636 static void setcontrast(struct gspca_dev *gspca_dev)
638 struct sd *sd = (struct sd *) gspca_dev;
639 unsigned int contrast = sd->contrast;
640 u16 reg_to_write;
642 if (contrast < 7)
643 reg_to_write = 0x8ea9 - contrast * 0x200;
644 else
645 reg_to_write = 0x00a9 + (contrast - 7) * 0x200;
647 reg_w(gspca_dev, reg_to_write);
650 static void setcolors(struct gspca_dev *gspca_dev)
652 struct sd *sd = (struct sd *) gspca_dev;
653 u16 reg_to_write;
655 reg_to_write = 0x80bb + sd->colors * 0x100; /* was 0xc0 */
656 reg_w(gspca_dev, reg_to_write);
659 static void setgamma(struct gspca_dev *gspca_dev)
661 struct sd *sd = (struct sd *) gspca_dev;
663 PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
664 reg_w_ixbuf(gspca_dev, 0x90,
665 gamma_table[sd->gamma], sizeof gamma_table[0]);
668 static void setwhitebalance(struct gspca_dev *gspca_dev)
670 struct sd *sd = (struct sd *) gspca_dev;
672 u8 white_balance[8] =
673 {0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38};
675 if (sd->whitebalance)
676 white_balance[7] = 0x3c;
678 reg_w_buf(gspca_dev, white_balance, sizeof white_balance);
681 static void setsharpness(struct gspca_dev *gspca_dev)
683 struct sd *sd = (struct sd *) gspca_dev;
684 u16 reg_to_write;
686 reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
688 reg_w(gspca_dev, reg_to_write);
691 /* this function is called at probe and resume time */
692 static int sd_init(struct gspca_dev *gspca_dev)
694 /* some of this registers are not really neded, because
695 * they are overriden by setbrigthness, setcontrast, etc,
696 * but wont hurt anyway, and can help someone with similar webcam
697 * to see the initial parameters.*/
698 struct sd *sd = (struct sd *) gspca_dev;
699 const struct additional_sensor_data *sensor;
700 int i;
701 u16 sensor_id;
702 u8 test_byte = 0;
704 static const u8 read_indexs[] =
705 { 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
706 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00 };
707 static const u8 n1[] =
708 {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
709 static const u8 n2[] =
710 {0x08, 0x00};
712 sensor_id = (reg_r(gspca_dev, 0x06) << 8)
713 | reg_r(gspca_dev, 0x07);
714 switch (sensor_id & 0xff0f) {
715 case 0x0801:
716 PDEBUG(D_PROBE, "sensor tas5130a");
717 sd->sensor = SENSOR_TAS5130A;
718 break;
719 case 0x0803:
720 PDEBUG(D_PROBE, "sensor 'other'");
721 sd->sensor = SENSOR_OTHER;
722 break;
723 case 0x0807:
724 PDEBUG(D_PROBE, "sensor om6802");
725 sd->sensor = SENSOR_OM6802;
726 break;
727 default:
728 PDEBUG(D_ERR|D_PROBE, "unknown sensor %04x", sensor_id);
729 return -EINVAL;
732 if (sd->sensor == SENSOR_OM6802) {
733 reg_w_buf(gspca_dev, n1, sizeof n1);
734 i = 5;
735 while (--i >= 0) {
736 reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
737 test_byte = reg_r(gspca_dev, 0x0063);
738 msleep(100);
739 if (test_byte == 0x17)
740 break; /* OK */
742 if (i < 0) {
743 err("Bad sensor reset %02x", test_byte);
744 return -EIO;
746 reg_w_buf(gspca_dev, n2, sizeof n2);
749 i = 0;
750 while (read_indexs[i] != 0x00) {
751 test_byte = reg_r(gspca_dev, read_indexs[i]);
752 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i],
753 test_byte);
754 i++;
757 sensor = &sensor_data[sd->sensor];
758 reg_w_buf(gspca_dev, sensor->n3, sizeof sensor->n3);
759 reg_w_buf(gspca_dev, sensor->n4, sensor->n4sz);
761 reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
762 reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
763 reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
765 reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
766 reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
767 reg_w(gspca_dev, (sensor->reg8e << 8) + 0x8e);
769 setbrightness(gspca_dev);
770 setcontrast(gspca_dev);
771 setgamma(gspca_dev);
772 setcolors(gspca_dev);
773 setsharpness(gspca_dev);
774 setwhitebalance(gspca_dev);
776 reg_w(gspca_dev, 0x2087); /* tied to white balance? */
777 reg_w(gspca_dev, 0x2088);
778 reg_w(gspca_dev, 0x2089);
780 reg_w_buf(gspca_dev, sensor->data4, sizeof sensor->data4);
781 reg_w_buf(gspca_dev, sensor->data5, sizeof sensor->data5);
782 reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8);
783 reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
785 reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
786 reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
787 reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
789 return 0;
792 static void setflip(struct gspca_dev *gspca_dev)
794 struct sd *sd = (struct sd *) gspca_dev;
795 u8 flipcmd[8] =
796 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
798 if (sd->mirror)
799 flipcmd[3] = 0x01;
801 reg_w_buf(gspca_dev, flipcmd, sizeof flipcmd);
804 static void seteffect(struct gspca_dev *gspca_dev)
806 struct sd *sd = (struct sd *) gspca_dev;
808 reg_w_buf(gspca_dev, effects_table[sd->effect],
809 sizeof effects_table[0]);
810 if (sd->effect == 1 || sd->effect == 5) {
811 PDEBUG(D_CONF,
812 "This effect have been disabled for webcam \"safety\"");
813 return;
816 if (sd->effect == 1 || sd->effect == 4)
817 reg_w(gspca_dev, 0x4aa6);
818 else
819 reg_w(gspca_dev, 0xfaa6);
822 static void setlightfreq(struct gspca_dev *gspca_dev)
824 struct sd *sd = (struct sd *) gspca_dev;
825 u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
827 if (sd->freq == 2) /* 60hz */
828 freq[1] = 0x00;
830 reg_w_buf(gspca_dev, freq, sizeof freq);
833 /* Is this really needed?
834 * i added some module parameters for test with some users */
835 static void poll_sensor(struct gspca_dev *gspca_dev)
837 static const u8 poll1[] =
838 {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
839 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
840 0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
841 0x60, 0x14};
842 static const u8 poll2[] =
843 {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
844 0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
845 static const u8 poll3[] =
846 {0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d};
847 static const u8 poll4[] =
848 {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
849 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
850 0xc2, 0x80, 0xc3, 0x10};
852 PDEBUG(D_STREAM, "[Sensor requires polling]");
853 reg_w_buf(gspca_dev, poll1, sizeof poll1);
854 reg_w_buf(gspca_dev, poll2, sizeof poll2);
855 reg_w_buf(gspca_dev, poll3, sizeof poll3);
856 reg_w_buf(gspca_dev, poll4, sizeof poll4);
859 static int sd_start(struct gspca_dev *gspca_dev)
861 struct sd *sd = (struct sd *) gspca_dev;
862 const struct additional_sensor_data *sensor;
863 int i, mode;
864 u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
865 static const u8 t3[] =
866 { 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 };
868 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
869 switch (mode) {
870 case 0: /* 640x480 (0x00) */
871 break;
872 case 1: /* 352x288 */
873 t2[1] = 0x40;
874 break;
875 case 2: /* 320x240 */
876 t2[1] = 0x10;
877 break;
878 case 3: /* 176x144 */
879 t2[1] = 0x50;
880 break;
881 default:
882 /* case 4: * 160x120 */
883 t2[1] = 0x20;
884 break;
887 switch (sd->sensor) {
888 case SENSOR_OM6802:
889 om6802_sensor_init(gspca_dev);
890 break;
891 case SENSOR_OTHER:
892 break;
893 default:
894 /* case SENSOR_TAS5130A: */
895 i = 0;
896 for (;;) {
897 reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
898 sizeof tas5130a_sensor_init[0]);
899 if (i >= ARRAY_SIZE(tas5130a_sensor_init) - 1)
900 break;
901 i++;
903 reg_w(gspca_dev, 0x3c80);
904 /* just in case and to keep sync with logs (for mine) */
905 reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
906 sizeof tas5130a_sensor_init[0]);
907 reg_w(gspca_dev, 0x3c80);
908 break;
910 sensor = &sensor_data[sd->sensor];
911 reg_w_buf(gspca_dev, sensor->data4, sizeof sensor->data4);
912 reg_r(gspca_dev, 0x0012);
913 reg_w_buf(gspca_dev, t2, sizeof t2);
914 reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3);
915 reg_w(gspca_dev, 0x0013);
916 msleep(15);
917 reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
918 reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
920 if (sd->sensor == SENSOR_OM6802)
921 poll_sensor(gspca_dev);
923 return 0;
926 static void sd_stopN(struct gspca_dev *gspca_dev)
928 struct sd *sd = (struct sd *) gspca_dev;
930 reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
931 sizeof sensor_data[sd->sensor].stream);
932 reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
933 sizeof sensor_data[sd->sensor].stream);
934 if (sd->sensor == SENSOR_OM6802) {
935 msleep(20);
936 reg_w(gspca_dev, 0x0309);
940 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
941 struct gspca_frame *frame, /* target */
942 u8 *data, /* isoc packet */
943 int len) /* iso packet length */
945 static u8 ffd9[] = { 0xff, 0xd9 };
947 if (data[0] == 0x5a) {
948 /* Control Packet, after this came the header again,
949 * but extra bytes came in the packet before this,
950 * sometimes an EOF arrives, sometimes not... */
951 return;
953 data += 2;
954 len -= 2;
955 if (data[0] == 0xff && data[1] == 0xd8) {
956 /* extra bytes....., could be processed too but would be
957 * a waste of time, right now leave the application and
958 * libjpeg do it for ourserlves.. */
959 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
960 ffd9, 2);
961 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
962 return;
965 if (data[len - 2] == 0xff && data[len - 1] == 0xd9) {
966 /* Just in case, i have seen packets with the marker,
967 * other's do not include it... */
968 len -= 2;
970 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
973 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
975 struct sd *sd = (struct sd *) gspca_dev;
977 sd->brightness = val;
978 if (gspca_dev->streaming)
979 setbrightness(gspca_dev);
980 return 0;
983 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
985 struct sd *sd = (struct sd *) gspca_dev;
987 *val = sd->brightness;
988 return *val;
991 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
993 struct sd *sd = (struct sd *) gspca_dev;
995 sd->whitebalance = val;
996 if (gspca_dev->streaming)
997 setwhitebalance(gspca_dev);
998 return 0;
1001 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
1003 struct sd *sd = (struct sd *) gspca_dev;
1005 *val = sd->whitebalance;
1006 return *val;
1009 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val)
1011 struct sd *sd = (struct sd *) gspca_dev;
1013 sd->mirror = val;
1014 if (gspca_dev->streaming)
1015 setflip(gspca_dev);
1016 return 0;
1019 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val)
1021 struct sd *sd = (struct sd *) gspca_dev;
1023 *val = sd->mirror;
1024 return *val;
1027 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val)
1029 struct sd *sd = (struct sd *) gspca_dev;
1031 sd->effect = val;
1032 if (gspca_dev->streaming)
1033 seteffect(gspca_dev);
1034 return 0;
1037 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val)
1039 struct sd *sd = (struct sd *) gspca_dev;
1041 *val = sd->effect;
1042 return *val;
1045 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1047 struct sd *sd = (struct sd *) gspca_dev;
1049 sd->contrast = val;
1050 if (gspca_dev->streaming)
1051 setcontrast(gspca_dev);
1052 return 0;
1055 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1057 struct sd *sd = (struct sd *) gspca_dev;
1059 *val = sd->contrast;
1060 return *val;
1063 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1065 struct sd *sd = (struct sd *) gspca_dev;
1067 sd->colors = val;
1068 if (gspca_dev->streaming)
1069 setcolors(gspca_dev);
1070 return 0;
1073 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1075 struct sd *sd = (struct sd *) gspca_dev;
1077 *val = sd->colors;
1078 return 0;
1081 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
1083 struct sd *sd = (struct sd *) gspca_dev;
1085 sd->gamma = val;
1086 if (gspca_dev->streaming)
1087 setgamma(gspca_dev);
1088 return 0;
1091 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
1093 struct sd *sd = (struct sd *) gspca_dev;
1095 *val = sd->gamma;
1096 return 0;
1099 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1101 struct sd *sd = (struct sd *) gspca_dev;
1103 sd->freq = val;
1104 if (gspca_dev->streaming)
1105 setlightfreq(gspca_dev);
1106 return 0;
1109 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1111 struct sd *sd = (struct sd *) gspca_dev;
1113 *val = sd->freq;
1114 return 0;
1117 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
1119 struct sd *sd = (struct sd *) gspca_dev;
1121 sd->sharpness = val;
1122 if (gspca_dev->streaming)
1123 setsharpness(gspca_dev);
1124 return 0;
1127 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
1129 struct sd *sd = (struct sd *) gspca_dev;
1131 *val = sd->sharpness;
1132 return 0;
1135 /* Low Light set here......*/
1136 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
1138 struct sd *sd = (struct sd *) gspca_dev;
1140 sd->autogain = val;
1141 if (val != 0)
1142 reg_w(gspca_dev, 0xf48e);
1143 else
1144 reg_w(gspca_dev, 0xb48e);
1145 return 0;
1148 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
1150 struct sd *sd = (struct sd *) gspca_dev;
1152 *val = sd->autogain;
1153 return 0;
1156 static int sd_querymenu(struct gspca_dev *gspca_dev,
1157 struct v4l2_querymenu *menu)
1159 switch (menu->id) {
1160 case V4L2_CID_POWER_LINE_FREQUENCY:
1161 switch (menu->index) {
1162 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1163 strcpy((char *) menu->name, "50 Hz");
1164 return 0;
1165 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1166 strcpy((char *) menu->name, "60 Hz");
1167 return 0;
1169 break;
1170 case V4L2_CID_EFFECTS:
1171 if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
1172 strncpy((char *) menu->name,
1173 effects_control[menu->index], 32);
1174 return 0;
1176 break;
1178 return -EINVAL;
1181 /* sub-driver description */
1182 static const struct sd_desc sd_desc = {
1183 .name = MODULE_NAME,
1184 .ctrls = sd_ctrls,
1185 .nctrls = ARRAY_SIZE(sd_ctrls),
1186 .config = sd_config,
1187 .init = sd_init,
1188 .start = sd_start,
1189 .stopN = sd_stopN,
1190 .pkt_scan = sd_pkt_scan,
1191 .querymenu = sd_querymenu,
1194 /* -- module initialisation -- */
1195 static const __devinitdata struct usb_device_id device_table[] = {
1196 {USB_DEVICE(0x17a1, 0x0128)},
1199 MODULE_DEVICE_TABLE(usb, device_table);
1201 /* -- device connect -- */
1202 static int sd_probe(struct usb_interface *intf,
1203 const struct usb_device_id *id)
1205 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1206 THIS_MODULE);
1209 static struct usb_driver sd_driver = {
1210 .name = MODULE_NAME,
1211 .id_table = device_table,
1212 .probe = sd_probe,
1213 .disconnect = gspca_disconnect,
1214 #ifdef CONFIG_PM
1215 .suspend = gspca_suspend,
1216 .resume = gspca_resume,
1217 #endif
1220 /* -- module insert / remove -- */
1221 static int __init sd_mod_init(void)
1223 int ret;
1224 ret = usb_register(&sd_driver);
1225 if (ret < 0)
1226 return ret;
1227 PDEBUG(D_PROBE, "registered");
1228 return 0;
1230 static void __exit sd_mod_exit(void)
1232 usb_deregister(&sd_driver);
1233 PDEBUG(D_PROBE, "deregistered");
1236 module_init(sd_mod_init);
1237 module_exit(sd_mod_exit);