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
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.
27 #define MODULE_NAME "t613"
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");
38 struct gspca_dev gspca_dev
; /* !! must be the first item */
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
,
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
,
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
,
119 #define COLORS_DEF 0x05
120 .default_value
= COLORS_DEF
,
129 .id
= V4L2_CID_GAMMA
, /* (gamma on win) */
130 .type
= V4L2_CTRL_TYPE_INTEGER
,
133 .maximum
= GAMMA_MAX
- 1,
135 .default_value
= GAMMA_DEF
,
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
,
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",
165 .default_value
= MIRROR_DEF
,
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 */
179 .default_value
= FREQ_DEF
,
186 .id
= V4L2_CID_WHITE_BALANCE_TEMPERATURE
,
187 .type
= V4L2_CTRL_TYPE_INTEGER
,
188 .name
= "White Balance",
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
,
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",
220 #define EFFECTS_DEF 0
221 .default_value
= EFFECTS_DEF
,
228 static char *effects_control
[] = {
230 "Emboss", /* disabled */
234 "Sun Effect", /* disabled */
238 static const struct v4l2_pix_format vga_mode_t16
[] = {
239 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
241 .sizeimage
= 160 * 120 * 4 / 8 + 590,
242 .colorspace
= V4L2_COLORSPACE_JPEG
,
244 {176, 144, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
246 .sizeimage
= 176 * 144 * 3 / 8 + 590,
247 .colorspace
= V4L2_COLORSPACE_JPEG
,
249 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
251 .sizeimage
= 320 * 240 * 3 / 8 + 590,
252 .colorspace
= V4L2_COLORSPACE_JPEG
,
254 {352, 288, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
256 .sizeimage
= 352 * 288 * 3 / 8 + 590,
257 .colorspace
= V4L2_COLORSPACE_JPEG
,
259 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
261 .sizeimage
= 640 * 480 * 3 / 8 + 590,
262 .colorspace
= V4L2_COLORSPACE_JPEG
,
266 /* sensor specific data */
267 struct additional_sensor_data
{
270 const u8 reg80
, reg8e
;
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,
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
[] = {
325 {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04},
327 .n4sz
= sizeof n4_om6802
,
330 .nset8
= {0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00},
332 {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06,
335 {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
338 {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 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},
345 {0x0b, 0x04, 0x0a, 0x78},
349 {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00},
351 .n4sz
= sizeof n4_other
,
354 .nset8
= {0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00},
356 {0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a,
359 {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
362 {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
365 {0x66, 0x00, 0xa8, 0xa8},
367 {0x0c, 0x03, 0xab, 0x29, 0x81, 0x69},
369 {0x0b, 0x04, 0x0a, 0x00},
373 {0x61, 0xc2, 0x65, 0x0d, 0x60, 0x08},
375 .n4sz
= sizeof n4_tas5130a
,
378 .nset8
= {0xa8, 0xf0, 0xc6, 0xda, 0xc0, 0x00},
380 {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
383 {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
386 {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
388 .data4
= /* Freq (50/60Hz). Splitted for test purpose */
389 {0x66, 0x00, 0xa8, 0xe8},
391 {0x0c, 0x03, 0xab, 0x10, 0x81, 0x20},
393 {0x0b, 0x04, 0x0a, 0x40},
396 .n3
= {0x61, 0xc2, 0x65, 0x68, 0x60, 0x00},
398 .n4sz
= sizeof n4_lt168g
,
401 .nset8
= {0xa8, 0xf0, 0xc6, 0xba, 0xc0, 0x00},
402 .data1
= {0xc0, 0x38, 0x08, 0x10, 0xc0, 0x30, 0x10, 0x40,
404 .data2
= {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
406 .data3
= {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
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,
431 {0x00, 0x33, 0x5a, 0x75, 0x85, 0x93, 0xa1, 0xad, /* 1 */
432 0xb7, 0xc2, 0xcb, 0xd4, 0xde, 0xe7, 0xf0, 0xf7,
434 {0x00, 0x2f, 0x51, 0x6b, 0x7c, 0x8a, 0x99, 0xa6, /* 2 */
435 0xb1, 0xbc, 0xc6, 0xd0, 0xdb, 0xe4, 0xed, 0xf6,
437 {0x00, 0x29, 0x48, 0x60, 0x72, 0x81, 0x90, 0x9e, /* 3 */
438 0xaa, 0xb5, 0xbf, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
440 {0x00, 0x23, 0x3f, 0x55, 0x68, 0x77, 0x86, 0x95, /* 4 */
441 0xa2, 0xad, 0xb9, 0xc6, 0xd2, 0xde, 0xe9, 0xf4,
443 {0x00, 0x1b, 0x33, 0x48, 0x59, 0x69, 0x79, 0x87, /* 5 */
444 0x96, 0xa3, 0xb1, 0xbe, 0xcc, 0xda, 0xe7, 0xf3,
446 {0x00, 0x02, 0x10, 0x20, 0x32, 0x40, 0x57, 0x67, /* 6 */
447 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
449 {0x00, 0x02, 0x14, 0x26, 0x38, 0x4a, 0x60, 0x70, /* 7 */
450 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
452 {0x00, 0x10, 0x22, 0x35, 0x47, 0x5a, 0x69, 0x79, /* 8 */
453 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe0, 0xf0,
455 {0x00, 0x10, 0x26, 0x40, 0x54, 0x65, 0x75, 0x84, /* 9 */
456 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd6, 0xe0, 0xf0,
458 {0x00, 0x18, 0x2b, 0x44, 0x60, 0x70, 0x80, 0x8e, /* 10 */
459 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xd8, 0xe2, 0xf0,
461 {0x00, 0x1a, 0x34, 0x52, 0x66, 0x7e, 0x8d, 0x9b, /* 11 */
462 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
464 {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8, /* 12 */
465 0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6,
467 {0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7, /* 13 */
468 0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9,
470 {0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6, /* 14 */
471 0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa,
473 {0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8, /* 15 */
474 0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc,
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};
487 static u8
reg_r(struct gspca_dev
*gspca_dev
,
490 usb_control_msg(gspca_dev
->dev
,
491 usb_rcvctrlpipe(gspca_dev
->dev
, 0),
493 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
496 gspca_dev
->usb_buf
, 1, 500);
497 return gspca_dev
->usb_buf
[0];
500 static void reg_w(struct gspca_dev
*gspca_dev
,
503 usb_control_msg(gspca_dev
->dev
,
504 usb_sndctrlpipe(gspca_dev
->dev
, 0),
506 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
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
,
521 gspca_dev
->usb_buf
, len
, 500);
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
,
537 /* write values to consecutive registers */
538 static void reg_w_ixbuf(struct gspca_dev
*gspca_dev
,
540 const u8
*buffer
, u16 len
)
545 if (len
* 2 <= USB_BUF_SZ
)
546 p
= tmpbuf
= gspca_dev
->usb_buf
;
548 p
= tmpbuf
= kmalloc(len
* 2, GFP_KERNEL
);
554 usb_control_msg(gspca_dev
->dev
,
555 usb_sndctrlpipe(gspca_dev
->dev
, 0),
557 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
559 tmpbuf
, len
* 2, 500);
560 if (len
* 2 > USB_BUF_SZ
)
564 /* Reported as OM6802*/
565 static void om6802_sensor_init(struct gspca_dev
*gspca_dev
)
570 u8 val
[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
571 static const u8 sensor_init
[] = {
589 reg_w_buf(gspca_dev
, sensor_reset
, sizeof sensor_reset
);
593 byte
= reg_r(gspca_dev
, 0x0060);
598 byte
= reg_r(gspca_dev
, 0x0063);
600 err("Bad sensor reset %02x", byte
);
609 reg_w(gspca_dev
, 0x3c80);
610 reg_w_buf(gspca_dev
, val
, sizeof val
);
614 byte
= reg_r(gspca_dev
, 0x60);
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
;
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
;
642 sd
->whitebalance
= WHITE_BALANCE_DEF
;
643 sd
->sharpness
= SHARPNESS_DEF
;
644 sd
->effect
= EFFECTS_DEF
;
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) {
657 set6
[3] = 0x70 - brightness
* 0x10;
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
;
672 reg_to_write
= 0x8ea9 - contrast
* 0x200;
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
;
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
;
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
;
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
[] =
741 sensor_id
= (reg_r(gspca_dev
, 0x06) << 8)
742 | reg_r(gspca_dev
, 0x07);
743 switch (sensor_id
& 0xff0f) {
745 PDEBUG(D_PROBE
, "sensor tas5130a");
746 sd
->sensor
= SENSOR_TAS5130A
;
749 PDEBUG(D_PROBE
, "sensor lt168g");
750 sd
->sensor
= SENSOR_LT168G
;
753 PDEBUG(D_PROBE
, "sensor 'other'");
754 sd
->sensor
= SENSOR_OTHER
;
757 PDEBUG(D_PROBE
, "sensor om6802");
758 sd
->sensor
= SENSOR_OM6802
;
761 PDEBUG(D_ERR
|D_PROBE
, "unknown sensor %04x", sensor_id
);
765 if (sd
->sensor
== SENSOR_OM6802
) {
766 reg_w_buf(gspca_dev
, n1
, sizeof n1
);
769 reg_w_buf(gspca_dev
, sensor_reset
, sizeof sensor_reset
);
770 test_byte
= reg_r(gspca_dev
, 0x0063);
772 if (test_byte
== 0x17)
776 err("Bad sensor reset %02x", test_byte
);
779 reg_w_buf(gspca_dev
, n2
, sizeof n2
);
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
],
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,
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
);
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,
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
);
839 static void setflip(struct gspca_dev
*gspca_dev
)
841 struct sd
*sd
= (struct sd
*) gspca_dev
;
843 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
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) {
859 "This effect have been disabled for webcam \"safety\"");
863 if (sd
->effect
== 1 || sd
->effect
== 4)
864 reg_w(gspca_dev
, 0x4aa6);
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 */
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,
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
;
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
;
917 case 0: /* 640x480 (0x00) */
919 case 1: /* 352x288 */
922 case 2: /* 320x240 */
925 case 3: /* 176x144 */
929 /* case 4: * 160x120 */
934 switch (sd
->sensor
) {
936 om6802_sensor_init(gspca_dev
);
943 /* case SENSOR_TAS5130A: */
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)
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);
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);
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
);
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
) {
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... */
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
,
1009 gspca_frame_add(gspca_dev
, FIRST_PACKET
, data
, len
);
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... */
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
);
1031 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
)
1033 struct sd
*sd
= (struct sd
*) gspca_dev
;
1035 *val
= sd
->brightness
;
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
);
1049 static int sd_getwhitebalance(struct gspca_dev
*gspca_dev
, __s32
*val
)
1051 struct sd
*sd
= (struct sd
*) gspca_dev
;
1053 *val
= sd
->whitebalance
;
1057 static int sd_setflip(struct gspca_dev
*gspca_dev
, __s32 val
)
1059 struct sd
*sd
= (struct sd
*) gspca_dev
;
1062 if (gspca_dev
->streaming
)
1067 static int sd_getflip(struct gspca_dev
*gspca_dev
, __s32
*val
)
1069 struct sd
*sd
= (struct sd
*) gspca_dev
;
1075 static int sd_seteffect(struct gspca_dev
*gspca_dev
, __s32 val
)
1077 struct sd
*sd
= (struct sd
*) gspca_dev
;
1080 if (gspca_dev
->streaming
)
1081 seteffect(gspca_dev
);
1085 static int sd_geteffect(struct gspca_dev
*gspca_dev
, __s32
*val
)
1087 struct sd
*sd
= (struct sd
*) gspca_dev
;
1093 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
)
1095 struct sd
*sd
= (struct sd
*) gspca_dev
;
1098 if (gspca_dev
->streaming
)
1099 setcontrast(gspca_dev
);
1103 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
)
1105 struct sd
*sd
= (struct sd
*) gspca_dev
;
1107 *val
= sd
->contrast
;
1111 static int sd_setcolors(struct gspca_dev
*gspca_dev
, __s32 val
)
1113 struct sd
*sd
= (struct sd
*) gspca_dev
;
1116 if (gspca_dev
->streaming
)
1117 setcolors(gspca_dev
);
1121 static int sd_getcolors(struct gspca_dev
*gspca_dev
, __s32
*val
)
1123 struct sd
*sd
= (struct sd
*) gspca_dev
;
1129 static int sd_setgamma(struct gspca_dev
*gspca_dev
, __s32 val
)
1131 struct sd
*sd
= (struct sd
*) gspca_dev
;
1134 if (gspca_dev
->streaming
)
1135 setgamma(gspca_dev
);
1139 static int sd_getgamma(struct gspca_dev
*gspca_dev
, __s32
*val
)
1141 struct sd
*sd
= (struct sd
*) gspca_dev
;
1147 static int sd_setfreq(struct gspca_dev
*gspca_dev
, __s32 val
)
1149 struct sd
*sd
= (struct sd
*) gspca_dev
;
1152 if (gspca_dev
->streaming
)
1153 setlightfreq(gspca_dev
);
1157 static int sd_getfreq(struct gspca_dev
*gspca_dev
, __s32
*val
)
1159 struct sd
*sd
= (struct sd
*) gspca_dev
;
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
);
1175 static int sd_getsharpness(struct gspca_dev
*gspca_dev
, __s32
*val
)
1177 struct sd
*sd
= (struct sd
*) gspca_dev
;
1179 *val
= sd
->sharpness
;
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
;
1190 reg_w(gspca_dev
, 0xf48e);
1192 reg_w(gspca_dev
, 0xb48e);
1196 static int sd_getlowlight(struct gspca_dev
*gspca_dev
, __s32
*val
)
1198 struct sd
*sd
= (struct sd
*) gspca_dev
;
1200 *val
= sd
->autogain
;
1204 static int sd_querymenu(struct gspca_dev
*gspca_dev
,
1205 struct v4l2_querymenu
*menu
)
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");
1213 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1214 strcpy((char *) menu
->name
, "60 Hz");
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);
1229 /* sub-driver description */
1230 static const struct sd_desc sd_desc
= {
1231 .name
= MODULE_NAME
,
1233 .nctrls
= ARRAY_SIZE(sd_ctrls
),
1234 .config
= sd_config
,
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
),
1257 static struct usb_driver sd_driver
= {
1258 .name
= MODULE_NAME
,
1259 .id_table
= device_table
,
1261 .disconnect
= gspca_disconnect
,
1263 .suspend
= gspca_suspend
,
1264 .resume
= gspca_resume
,
1268 /* -- module insert / remove -- */
1269 static int __init
sd_mod_init(void)
1272 ret
= usb_register(&sd_driver
);
1275 PDEBUG(D_PROBE
, "registered");
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
);