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 */
40 unsigned char brightness
;
41 unsigned char contrast
;
43 unsigned char autogain
;
45 unsigned char sharpness
;
47 unsigned char whitebalance
;
52 #define SENSOR_TAS5130A 0
53 #define SENSOR_OM6802 1
56 /* V4L2 controls supported by the driver */
57 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
);
58 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
);
59 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
);
60 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
);
61 static int sd_setcolors(struct gspca_dev
*gspca_dev
, __s32 val
);
62 static int sd_getcolors(struct gspca_dev
*gspca_dev
, __s32
*val
);
63 static int sd_setlowlight(struct gspca_dev
*gspca_dev
, __s32 val
);
64 static int sd_getlowlight(struct gspca_dev
*gspca_dev
, __s32
*val
);
65 static int sd_setgamma(struct gspca_dev
*gspca_dev
, __s32 val
);
66 static int sd_getgamma(struct gspca_dev
*gspca_dev
, __s32
*val
);
67 static int sd_setsharpness(struct gspca_dev
*gspca_dev
, __s32 val
);
68 static int sd_getsharpness(struct gspca_dev
*gspca_dev
, __s32
*val
);
69 static int sd_setfreq(struct gspca_dev
*gspca_dev
, __s32 val
);
70 static int sd_getfreq(struct gspca_dev
*gspca_dev
, __s32
*val
);
71 static int sd_setwhitebalance(struct gspca_dev
*gspca_dev
, __s32 val
);
72 static int sd_getwhitebalance(struct gspca_dev
*gspca_dev
, __s32
*val
);
73 static int sd_setflip(struct gspca_dev
*gspca_dev
, __s32 val
);
74 static int sd_getflip(struct gspca_dev
*gspca_dev
, __s32
*val
);
75 static int sd_seteffect(struct gspca_dev
*gspca_dev
, __s32 val
);
76 static int sd_geteffect(struct gspca_dev
*gspca_dev
, __s32
*val
);
77 static int sd_querymenu(struct gspca_dev
*gspca_dev
,
78 struct v4l2_querymenu
*menu
);
80 static struct ctrl sd_ctrls
[] = {
81 #define SD_BRIGHTNESS 0
84 .id
= V4L2_CID_BRIGHTNESS
,
85 .type
= V4L2_CTRL_TYPE_INTEGER
,
92 .set
= sd_setbrightness
,
93 .get
= sd_getbrightness
,
98 .id
= V4L2_CID_CONTRAST
,
99 .type
= V4L2_CTRL_TYPE_INTEGER
,
104 .default_value
= 0x07,
106 .set
= sd_setcontrast
,
107 .get
= sd_getcontrast
,
112 .id
= V4L2_CID_SATURATION
,
113 .type
= V4L2_CTRL_TYPE_INTEGER
,
118 .default_value
= 0x05,
127 .id
= V4L2_CID_GAMMA
, /* (gamma on win) */
128 .type
= V4L2_CTRL_TYPE_INTEGER
,
131 .maximum
= GAMMA_MAX
- 1,
133 .default_value
= GAMMA_DEF
,
138 #define SD_AUTOGAIN 4
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
,
149 .default_value
= 0x01,
151 .set
= sd_setlowlight
,
152 .get
= sd_getlowlight
,
157 .id
= V4L2_CID_HFLIP
,
158 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
159 .name
= "Mirror Image",
168 #define SD_LIGHTFREQ 6
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 */
182 #define SD_WHITE_BALANCE 7
185 .id
= V4L2_CID_WHITE_BALANCE_TEMPERATURE
,
186 .type
= V4L2_CTRL_TYPE_INTEGER
,
187 .name
= "White Balance",
193 .set
= sd_setwhitebalance
,
194 .get
= sd_getwhitebalance
196 #define SD_SHARPNESS 8 /* (aka definition on win) */
199 .id
= V4L2_CID_SHARPNESS
,
200 .type
= V4L2_CTRL_TYPE_INTEGER
,
205 .default_value
= 0x06,
207 .set
= sd_setsharpness
,
208 .get
= sd_getsharpness
,
213 .id
= V4L2_CID_EFFECTS
,
214 .type
= V4L2_CTRL_TYPE_MENU
,
215 .name
= "Webcam Effects",
226 static char *effects_control
[] = {
228 "Emboss", /* disabled */
232 "Sun Effect", /* disabled */
236 static const struct v4l2_pix_format vga_mode_t16
[] = {
237 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
239 .sizeimage
= 160 * 120 * 4 / 8 + 590,
240 .colorspace
= V4L2_COLORSPACE_JPEG
,
242 {176, 144, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
244 .sizeimage
= 176 * 144 * 3 / 8 + 590,
245 .colorspace
= V4L2_COLORSPACE_JPEG
,
247 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
249 .sizeimage
= 320 * 240 * 3 / 8 + 590,
250 .colorspace
= V4L2_COLORSPACE_JPEG
,
252 {352, 288, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
254 .sizeimage
= 352 * 288 * 3 / 8 + 590,
255 .colorspace
= V4L2_COLORSPACE_JPEG
,
257 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
259 .sizeimage
= 640 * 480 * 3 / 8 + 590,
260 .colorspace
= V4L2_COLORSPACE_JPEG
,
264 /* sensor specific data */
265 struct additional_sensor_data
{
266 const __u8 data1
[20];
267 const __u8 data2
[18];
268 const __u8 data3
[18];
271 const __u8 stream
[4];
274 const static struct additional_sensor_data sensor_data
[] = {
277 {0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10,
278 0xd4, 0xbb, 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
279 0xd8, 0xc8, 0xd9, 0xfc},
281 {0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60,
282 0xe4, 0xa8, 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
285 {0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60,
286 0xcb, 0xa8, 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
288 .data4
= /* Freq (50/60Hz). Splitted for test purpose */
289 {0x66, 0x00, 0xa8, 0xe8},
291 {0x0c, 0x03, 0xab, 0x10, 0x81, 0x20},
293 {0x0b, 0x04, 0x0a, 0x40},
297 {0xd0, 0xc2, 0xd1, 0x28, 0xd2, 0x0f, 0xd3, 0x22,
298 0xd4, 0xcd, 0xd5, 0x27, 0xd6, 0x2c, 0xd7, 0x06,
299 0xd8, 0xb3, 0xd9, 0xfc},
301 {0xe0, 0x80, 0xe1, 0xff, 0xe2, 0xff, 0xe3, 0x80,
302 0xe4, 0xff, 0xe5, 0xff, 0xe6, 0x80, 0xe7, 0xff,
305 {0xc7, 0x80, 0xc8, 0xff, 0xc9, 0xff, 0xca, 0x80,
306 0xcb, 0xff, 0xcc, 0xff, 0xcd, 0x80, 0xce, 0xff,
308 .data4
= /*Freq (50/60Hz). Splitted for test purpose */
309 {0x66, 0xca, 0xa8, 0xf0 },
310 .data5
= /* this could be removed later */
311 {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
313 {0x0b, 0x04, 0x0a, 0x78},
317 #define MAX_EFFECTS 7
318 /* easily done by soft, this table could be removed,
319 * i keep it here just in case */
320 static const __u8 effects_table
[MAX_EFFECTS
][6] = {
321 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */
322 {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */
323 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */
324 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80}, /* Sepia */
325 {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02}, /* Croquis */
326 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10}, /* Sun Effect */
327 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */
330 static const __u8 gamma_table
[GAMMA_MAX
][34] = {
331 {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85, /* 0 */
332 0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9,
333 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb,
334 0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8,
336 {0x90, 0x00, 0x91, 0x33, 0x92, 0x5a, 0x93, 0x75, /* 1 */
337 0x94, 0x85, 0x95, 0x93, 0x96, 0xa1, 0x97, 0xad,
338 0x98, 0xb7, 0x99, 0xc2, 0x9a, 0xcb, 0x9b, 0xd4,
339 0x9c, 0xde, 0x9D, 0xe7, 0x9e, 0xf0, 0x9f, 0xf7,
341 {0x90, 0x00, 0x91, 0x2f, 0x92, 0x51, 0x93, 0x6b, /* 2 */
342 0x94, 0x7c, 0x95, 0x8a, 0x96, 0x99, 0x97, 0xa6,
343 0x98, 0xb1, 0x99, 0xbc, 0x9a, 0xc6, 0x9b, 0xd0,
344 0x9c, 0xdb, 0x9d, 0xe4, 0x9e, 0xed, 0x9f, 0xf6,
346 {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60, /* 3 */
347 0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9e,
348 0x98, 0xaa, 0x99, 0xb5, 0x9a, 0xbf, 0x9b, 0xcb,
349 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5,
351 {0x90, 0x00, 0x91, 0x23, 0x92, 0x3f, 0x93, 0x55, /* 4 */
352 0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95,
353 0x98, 0xa2, 0x99, 0xad, 0x9a, 0xb9, 0x9b, 0xc6,
354 0x9c, 0xd2, 0x9d, 0xde, 0x9e, 0xe9, 0x9f, 0xf4,
356 {0x90, 0x00, 0x91, 0x1b, 0x92, 0x33, 0x93, 0x48, /* 5 */
357 0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87,
358 0x98, 0x96, 0x99, 0xa3, 0x9a, 0xb1, 0x9b, 0xbe,
359 0x9c, 0xcc, 0x9d, 0xda, 0x9e, 0xe7, 0x9f, 0xf3,
361 {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20, /* 6 */
362 0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67,
363 0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa,
364 0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee,
366 {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26, /* 7 */
367 0x94, 0x38, 0x95, 0x4a, 0x96, 0x60, 0x97, 0x70,
368 0x98, 0x80, 0x99, 0x90, 0x9a, 0xa0, 0x9b, 0xb0,
369 0x9c, 0xc0, 0x9D, 0xd0, 0x9e, 0xe0, 0x9f, 0xf0,
371 {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35, /* 8 */
372 0x94, 0x47, 0x95, 0x5a, 0x96, 0x69, 0x97, 0x79,
373 0x98, 0x88, 0x99, 0x97, 0x9a, 0xa7, 0x9b, 0xb6,
374 0x9c, 0xc4, 0x9d, 0xd3, 0x9e, 0xe0, 0x9f, 0xf0,
376 {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40, /* 9 */
377 0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
378 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd,
379 0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0,
381 {0x90, 0x00, 0x91, 0x18, 0x92, 0x2b, 0x93, 0x44, /* 10 */
382 0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8e,
383 0x98, 0x9c, 0x99, 0xaa, 0x9a, 0xb7, 0x9b, 0xc4,
384 0x9c, 0xd0, 0x9d, 0xd8, 0x9e, 0xe2, 0x9f, 0xf0,
386 {0x90, 0x00, 0x91, 0x1a, 0x92, 0x34, 0x93, 0x52, /* 11 */
387 0x94, 0x66, 0x95, 0x7e, 0x96, 0x8D, 0x97, 0x9B,
388 0x98, 0xa8, 0x99, 0xb4, 0x9a, 0xc0, 0x9b, 0xcb,
389 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5,
391 {0x90, 0x00, 0x91, 0x3f, 0x92, 0x5a, 0x93, 0x6e, /* 12 */
392 0x94, 0x7f, 0x95, 0x8e, 0x96, 0x9c, 0x97, 0xa8,
393 0x98, 0xb4, 0x99, 0xbf, 0x9a, 0xc9, 0x9b, 0xd3,
394 0x9c, 0xdc, 0x9d, 0xe5, 0x9e, 0xee, 0x9f, 0xf6,
396 {0x90, 0x00, 0x91, 0x54, 0x92, 0x6f, 0x93, 0x83, /* 13 */
397 0x94, 0x93, 0x95, 0xa0, 0x96, 0xad, 0x97, 0xb7,
398 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdc,
399 0x9c, 0xe4, 0x9d, 0xeb, 0x9e, 0xf2, 0x9f, 0xf9,
401 {0x90, 0x00, 0x91, 0x6e, 0x92, 0x88, 0x93, 0x9a, /* 14 */
402 0x94, 0xa8, 0x95, 0xb3, 0x96, 0xbd, 0x97, 0xc6,
403 0x98, 0xcf, 0x99, 0xd6, 0x9a, 0xdd, 0x9b, 0xe3,
404 0x9c, 0xe9, 0x9d, 0xef, 0x9e, 0xf4, 0x9f, 0xfa,
406 {0x90, 0x00, 0x91, 0x93, 0x92, 0xa8, 0x93, 0xb7, /* 15 */
407 0x94, 0xc1, 0x95, 0xca, 0x96, 0xd2, 0x97, 0xd8,
408 0x98, 0xde, 0x99, 0xe3, 0x9a, 0xe8, 0x9b, 0xed,
409 0x9c, 0xf1, 0x9d, 0xf5, 0x9e, 0xf8, 0x9f, 0xfc,
413 static const __u8 tas5130a_sensor_init
[][8] = {
414 {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
415 {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
416 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
417 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
421 static __u8 sensor_reset
[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
424 static int reg_r(struct gspca_dev
*gspca_dev
,
427 usb_control_msg(gspca_dev
->dev
,
428 usb_rcvctrlpipe(gspca_dev
->dev
, 0),
430 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
433 gspca_dev
->usb_buf
, 1, 500);
434 return gspca_dev
->usb_buf
[0];
437 static void reg_w(struct gspca_dev
*gspca_dev
,
440 usb_control_msg(gspca_dev
->dev
,
441 usb_sndctrlpipe(gspca_dev
->dev
, 0),
443 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
448 static void reg_w_buf(struct gspca_dev
*gspca_dev
,
449 const __u8
*buffer
, __u16 len
)
451 if (len
<= USB_BUF_SZ
) {
452 memcpy(gspca_dev
->usb_buf
, buffer
, len
);
453 usb_control_msg(gspca_dev
->dev
,
454 usb_sndctrlpipe(gspca_dev
->dev
, 0),
456 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
458 gspca_dev
->usb_buf
, len
, 500);
462 tmpbuf
= kmalloc(len
, GFP_KERNEL
);
463 memcpy(tmpbuf
, buffer
, len
);
464 usb_control_msg(gspca_dev
->dev
,
465 usb_sndctrlpipe(gspca_dev
->dev
, 0),
467 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
474 /* Reported as OM6802*/
475 static void om6802_sensor_init(struct gspca_dev
*gspca_dev
)
480 __u8 val
[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
481 static const __u8 sensor_init
[] = {
499 reg_w_buf(gspca_dev
, sensor_reset
, sizeof sensor_reset
);
503 byte
= reg_r(gspca_dev
, 0x0060);
508 byte
= reg_r(gspca_dev
, 0x0063);
510 err("Bad sensor reset %02x", byte
);
519 reg_w(gspca_dev
, 0x3c80);
520 reg_w_buf(gspca_dev
, val
, sizeof val
);
524 byte
= reg_r(gspca_dev
, 0x60);
530 reg_w(gspca_dev
, 0x3c80);
533 /* this function is called at probe time */
534 static int sd_config(struct gspca_dev
*gspca_dev
,
535 const struct usb_device_id
*id
)
537 struct sd
*sd
= (struct sd
*) gspca_dev
;
540 cam
= &gspca_dev
->cam
;
542 cam
->cam_mode
= vga_mode_t16
;
543 cam
->nmodes
= ARRAY_SIZE(vga_mode_t16
);
545 sd
->brightness
= sd_ctrls
[SD_BRIGHTNESS
].qctrl
.default_value
;
546 sd
->contrast
= sd_ctrls
[SD_CONTRAST
].qctrl
.default_value
;
547 sd
->colors
= sd_ctrls
[SD_COLOR
].qctrl
.default_value
;
548 sd
->gamma
= GAMMA_DEF
;
549 sd
->mirror
= sd_ctrls
[SD_MIRROR
].qctrl
.default_value
;
550 sd
->freq
= sd_ctrls
[SD_LIGHTFREQ
].qctrl
.default_value
;
551 sd
->whitebalance
= sd_ctrls
[SD_WHITE_BALANCE
].qctrl
.default_value
;
552 sd
->sharpness
= sd_ctrls
[SD_SHARPNESS
].qctrl
.default_value
;
553 sd
->effect
= sd_ctrls
[SD_EFFECTS
].qctrl
.default_value
;
557 static void setbrightness(struct gspca_dev
*gspca_dev
)
559 struct sd
*sd
= (struct sd
*) gspca_dev
;
560 unsigned int brightness
;
561 __u8 set6
[4] = { 0x8f, 0x24, 0xc3, 0x00 };
563 brightness
= sd
->brightness
;
564 if (brightness
< 7) {
566 set6
[3] = 0x70 - brightness
* 0x10;
568 set6
[3] = 0x00 + ((brightness
- 7) * 0x10);
571 reg_w_buf(gspca_dev
, set6
, sizeof set6
);
574 static void setcontrast(struct gspca_dev
*gspca_dev
)
576 struct sd
*sd
= (struct sd
*) gspca_dev
;
577 unsigned int contrast
= sd
->contrast
;
581 reg_to_write
= 0x8ea9 - contrast
* 0x200;
583 reg_to_write
= 0x00a9 + (contrast
- 7) * 0x200;
585 reg_w(gspca_dev
, reg_to_write
);
588 static void setcolors(struct gspca_dev
*gspca_dev
)
590 struct sd
*sd
= (struct sd
*) gspca_dev
;
593 reg_to_write
= 0x80bb + sd
->colors
* 0x100; /* was 0xc0 */
594 reg_w(gspca_dev
, reg_to_write
);
597 static void setgamma(struct gspca_dev
*gspca_dev
)
599 struct sd
*sd
= (struct sd
*) gspca_dev
;
601 PDEBUG(D_CONF
, "Gamma: %d", sd
->gamma
);
602 reg_w_buf(gspca_dev
, gamma_table
[sd
->gamma
], sizeof gamma_table
[0]);
605 static void setwhitebalance(struct gspca_dev
*gspca_dev
)
607 struct sd
*sd
= (struct sd
*) gspca_dev
;
609 __u8 white_balance
[8] =
610 {0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38};
612 if (sd
->whitebalance
)
613 white_balance
[7] = 0x3c;
615 reg_w_buf(gspca_dev
, white_balance
, sizeof white_balance
);
618 static void setsharpness(struct gspca_dev
*gspca_dev
)
620 struct sd
*sd
= (struct sd
*) gspca_dev
;
623 reg_to_write
= 0x0aa6 + 0x1000 * sd
->sharpness
;
625 reg_w(gspca_dev
, reg_to_write
);
628 /* this function is called at probe and resume time */
629 static int sd_init(struct gspca_dev
*gspca_dev
)
631 /* some of this registers are not really neded, because
632 * they are overriden by setbrigthness, setcontrast, etc,
633 * but wont hurt anyway, and can help someone with similar webcam
634 * to see the initial parameters.*/
635 struct sd
*sd
= (struct sd
*) gspca_dev
;
637 __u8 byte
, test_byte
;
639 static const __u8 read_indexs
[] =
640 { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
641 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 };
642 static const __u8 n1
[] =
643 {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
644 static const __u8 n2
[] =
646 static const __u8 n3
[] =
647 {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
648 static const __u8 n4
[] =
649 {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
650 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
651 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
652 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
653 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
654 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
655 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
656 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
657 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
658 static const __u8 nset9
[4] =
659 { 0x0b, 0x04, 0x0a, 0x78 };
660 static const __u8 nset8
[6] =
661 { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
663 byte
= reg_r(gspca_dev
, 0x06);
664 test_byte
= reg_r(gspca_dev
, 0x07);
665 if (byte
== 0x08 && test_byte
== 0x07) {
666 PDEBUG(D_CONF
, "sensor om6802");
667 sd
->sensor
= SENSOR_OM6802
;
668 } else if (byte
== 0x08 && test_byte
== 0x01) {
669 PDEBUG(D_CONF
, "sensor tas5130a");
670 sd
->sensor
= SENSOR_TAS5130A
;
672 PDEBUG(D_CONF
, "unknown sensor %02x %02x", byte
, test_byte
);
673 sd
->sensor
= SENSOR_TAS5130A
;
676 reg_w_buf(gspca_dev
, n1
, sizeof n1
);
680 reg_w_buf(gspca_dev
, sensor_reset
, sizeof sensor_reset
);
681 test_byte
= reg_r(gspca_dev
, 0x0063);
683 if (test_byte
== 0x17)
687 err("Bad sensor reset %02x", test_byte
);
689 /*fixme: test - continue */
691 reg_w_buf(gspca_dev
, n2
, sizeof n2
);
694 while (read_indexs
[i
] != 0x00) {
695 test_byte
= reg_r(gspca_dev
, read_indexs
[i
]);
696 PDEBUG(D_STREAM
, "Reg 0x%02x = 0x%02x", read_indexs
[i
],
701 reg_w_buf(gspca_dev
, n3
, sizeof n3
);
702 reg_w_buf(gspca_dev
, n4
, sizeof n4
);
703 reg_r(gspca_dev
, 0x0080);
704 reg_w(gspca_dev
, 0x2c80);
706 reg_w_buf(gspca_dev
, sensor_data
[sd
->sensor
].data1
,
707 sizeof sensor_data
[sd
->sensor
].data1
);
708 reg_w_buf(gspca_dev
, sensor_data
[sd
->sensor
].data3
,
709 sizeof sensor_data
[sd
->sensor
].data3
);
710 reg_w_buf(gspca_dev
, sensor_data
[sd
->sensor
].data2
,
711 sizeof sensor_data
[sd
->sensor
].data2
);
713 reg_w(gspca_dev
, 0x3880);
714 reg_w(gspca_dev
, 0x3880);
715 reg_w(gspca_dev
, 0x338e);
717 setbrightness(gspca_dev
);
718 setcontrast(gspca_dev
);
720 setcolors(gspca_dev
);
721 setsharpness(gspca_dev
);
722 setwhitebalance(gspca_dev
);
724 reg_w(gspca_dev
, 0x2087); /* tied to white balance? */
725 reg_w(gspca_dev
, 0x2088);
726 reg_w(gspca_dev
, 0x2089);
728 reg_w_buf(gspca_dev
, sensor_data
[sd
->sensor
].data4
,
729 sizeof sensor_data
[sd
->sensor
].data4
);
730 reg_w_buf(gspca_dev
, sensor_data
[sd
->sensor
].data5
,
731 sizeof sensor_data
[sd
->sensor
].data5
);
732 reg_w_buf(gspca_dev
, nset8
, sizeof nset8
);
733 reg_w_buf(gspca_dev
, nset9
, sizeof nset9
);
735 reg_w(gspca_dev
, 0x2880);
737 reg_w_buf(gspca_dev
, sensor_data
[sd
->sensor
].data1
,
738 sizeof sensor_data
[sd
->sensor
].data1
);
739 reg_w_buf(gspca_dev
, sensor_data
[sd
->sensor
].data3
,
740 sizeof sensor_data
[sd
->sensor
].data3
);
741 reg_w_buf(gspca_dev
, sensor_data
[sd
->sensor
].data2
,
742 sizeof sensor_data
[sd
->sensor
].data2
);
747 static void setflip(struct gspca_dev
*gspca_dev
)
749 struct sd
*sd
= (struct sd
*) gspca_dev
;
751 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
756 reg_w_buf(gspca_dev
, flipcmd
, sizeof flipcmd
);
759 static void seteffect(struct gspca_dev
*gspca_dev
)
761 struct sd
*sd
= (struct sd
*) gspca_dev
;
763 reg_w_buf(gspca_dev
, effects_table
[sd
->effect
],
764 sizeof effects_table
[0]);
765 if (sd
->effect
== 1 || sd
->effect
== 5) {
767 "This effect have been disabled for webcam \"safety\"");
771 if (sd
->effect
== 1 || sd
->effect
== 4)
772 reg_w(gspca_dev
, 0x4aa6);
774 reg_w(gspca_dev
, 0xfaa6);
777 static void setlightfreq(struct gspca_dev
*gspca_dev
)
779 struct sd
*sd
= (struct sd
*) gspca_dev
;
780 __u8 freq
[4] = { 0x66, 0x40, 0xa8, 0xe8 };
782 if (sd
->freq
== 2) /* 60hz */
785 reg_w_buf(gspca_dev
, freq
, sizeof freq
);
788 /* Is this really needed?
789 * i added some module parameters for test with some users */
790 static void poll_sensor(struct gspca_dev
*gspca_dev
)
792 struct sd
*sd
= (struct sd
*) gspca_dev
;
793 static const __u8 poll1
[] =
794 {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
795 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
796 0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
798 static const __u8 poll2
[] =
799 {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
800 0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
801 static const __u8 poll3
[] =
802 {0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d};
803 static const __u8 poll4
[] =
804 {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
805 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
806 0xc2, 0x80, 0xc3, 0x10};
808 if (sd
->sensor
!= SENSOR_TAS5130A
) {
809 PDEBUG(D_STREAM
, "[Sensor requires polling]");
810 reg_w_buf(gspca_dev
, poll1
, sizeof poll1
);
811 reg_w_buf(gspca_dev
, poll2
, sizeof poll2
);
812 reg_w_buf(gspca_dev
, poll3
, sizeof poll3
);
813 reg_w_buf(gspca_dev
, poll4
, sizeof poll4
);
817 static int sd_start(struct gspca_dev
*gspca_dev
)
819 struct sd
*sd
= (struct sd
*) gspca_dev
;
821 __u8 t2
[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
822 static const __u8 t3
[] =
823 { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
824 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
826 mode
= gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
]. priv
;
828 case 1: /* 352x288 */
831 case 2: /* 320x240 */
834 case 3: /* 176x144 */
837 case 4: /* 160x120 */
840 default: /* 640x480 (0x00) */
844 if (sd
->sensor
== SENSOR_TAS5130A
) {
846 while (tas5130a_sensor_init
[i
][0] != 0) {
847 reg_w_buf(gspca_dev
, tas5130a_sensor_init
[i
],
848 sizeof tas5130a_sensor_init
[0]);
851 reg_w(gspca_dev
, 0x3c80);
852 /* just in case and to keep sync with logs (for mine) */
853 reg_w_buf(gspca_dev
, tas5130a_sensor_init
[3],
854 sizeof tas5130a_sensor_init
[0]);
855 reg_w(gspca_dev
, 0x3c80);
857 om6802_sensor_init(gspca_dev
);
859 reg_w_buf(gspca_dev
, sensor_data
[sd
->sensor
].data4
,
860 sizeof sensor_data
[sd
->sensor
].data4
);
861 reg_r(gspca_dev
, 0x0012);
862 reg_w_buf(gspca_dev
, t2
, sizeof t2
);
863 reg_w_buf(gspca_dev
, t3
, sizeof t3
);
864 reg_w(gspca_dev
, 0x0013);
866 reg_w_buf(gspca_dev
, sensor_data
[sd
->sensor
].stream
,
867 sizeof sensor_data
[sd
->sensor
].stream
);
868 poll_sensor(gspca_dev
);
870 /* restart on each start, just in case, sometimes regs goes wrong
871 * when using controls from app */
872 setbrightness(gspca_dev
);
873 setcontrast(gspca_dev
);
874 setcolors(gspca_dev
);
878 static void sd_stopN(struct gspca_dev
*gspca_dev
)
880 struct sd
*sd
= (struct sd
*) gspca_dev
;
882 reg_w_buf(gspca_dev
, sensor_data
[sd
->sensor
].stream
,
883 sizeof sensor_data
[sd
->sensor
].stream
);
885 reg_w_buf(gspca_dev
, sensor_data
[sd
->sensor
].stream
,
886 sizeof sensor_data
[sd
->sensor
].stream
);
888 reg_w(gspca_dev
, 0x0309);
891 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
892 struct gspca_frame
*frame
, /* target */
893 __u8
*data
, /* isoc packet */
894 int len
) /* iso packet length */
896 static __u8 ffd9
[] = { 0xff, 0xd9 };
898 if (data
[0] == 0x5a) {
899 /* Control Packet, after this came the header again,
900 * but extra bytes came in the packet before this,
901 * sometimes an EOF arrives, sometimes not... */
906 if (data
[0] == 0xff && data
[1] == 0xd8) {
907 /* extra bytes....., could be processed too but would be
908 * a waste of time, right now leave the application and
909 * libjpeg do it for ourserlves.. */
910 frame
= gspca_frame_add(gspca_dev
, LAST_PACKET
, frame
,
912 gspca_frame_add(gspca_dev
, FIRST_PACKET
, frame
, data
, len
);
916 if (data
[len
- 2] == 0xff && data
[len
- 1] == 0xd9) {
917 /* Just in case, i have seen packets with the marker,
918 * other's do not include it... */
921 gspca_frame_add(gspca_dev
, INTER_PACKET
, frame
, data
, len
);
924 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
)
926 struct sd
*sd
= (struct sd
*) gspca_dev
;
928 sd
->brightness
= val
;
929 if (gspca_dev
->streaming
)
930 setbrightness(gspca_dev
);
934 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
)
936 struct sd
*sd
= (struct sd
*) gspca_dev
;
938 *val
= sd
->brightness
;
942 static int sd_setwhitebalance(struct gspca_dev
*gspca_dev
, __s32 val
)
944 struct sd
*sd
= (struct sd
*) gspca_dev
;
946 sd
->whitebalance
= val
;
947 if (gspca_dev
->streaming
)
948 setwhitebalance(gspca_dev
);
952 static int sd_getwhitebalance(struct gspca_dev
*gspca_dev
, __s32
*val
)
954 struct sd
*sd
= (struct sd
*) gspca_dev
;
956 *val
= sd
->whitebalance
;
960 static int sd_setflip(struct gspca_dev
*gspca_dev
, __s32 val
)
962 struct sd
*sd
= (struct sd
*) gspca_dev
;
965 if (gspca_dev
->streaming
)
970 static int sd_getflip(struct gspca_dev
*gspca_dev
, __s32
*val
)
972 struct sd
*sd
= (struct sd
*) gspca_dev
;
978 static int sd_seteffect(struct gspca_dev
*gspca_dev
, __s32 val
)
980 struct sd
*sd
= (struct sd
*) gspca_dev
;
983 if (gspca_dev
->streaming
)
984 seteffect(gspca_dev
);
988 static int sd_geteffect(struct gspca_dev
*gspca_dev
, __s32
*val
)
990 struct sd
*sd
= (struct sd
*) gspca_dev
;
996 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
)
998 struct sd
*sd
= (struct sd
*) gspca_dev
;
1001 if (gspca_dev
->streaming
)
1002 setcontrast(gspca_dev
);
1006 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
)
1008 struct sd
*sd
= (struct sd
*) gspca_dev
;
1010 *val
= sd
->contrast
;
1014 static int sd_setcolors(struct gspca_dev
*gspca_dev
, __s32 val
)
1016 struct sd
*sd
= (struct sd
*) gspca_dev
;
1019 if (gspca_dev
->streaming
)
1020 setcolors(gspca_dev
);
1024 static int sd_getcolors(struct gspca_dev
*gspca_dev
, __s32
*val
)
1026 struct sd
*sd
= (struct sd
*) gspca_dev
;
1032 static int sd_setgamma(struct gspca_dev
*gspca_dev
, __s32 val
)
1034 struct sd
*sd
= (struct sd
*) gspca_dev
;
1037 if (gspca_dev
->streaming
)
1038 setgamma(gspca_dev
);
1042 static int sd_getgamma(struct gspca_dev
*gspca_dev
, __s32
*val
)
1044 struct sd
*sd
= (struct sd
*) gspca_dev
;
1050 static int sd_setfreq(struct gspca_dev
*gspca_dev
, __s32 val
)
1052 struct sd
*sd
= (struct sd
*) gspca_dev
;
1055 if (gspca_dev
->streaming
)
1056 setlightfreq(gspca_dev
);
1060 static int sd_getfreq(struct gspca_dev
*gspca_dev
, __s32
*val
)
1062 struct sd
*sd
= (struct sd
*) gspca_dev
;
1068 static int sd_setsharpness(struct gspca_dev
*gspca_dev
, __s32 val
)
1070 struct sd
*sd
= (struct sd
*) gspca_dev
;
1072 sd
->sharpness
= val
;
1073 if (gspca_dev
->streaming
)
1074 setsharpness(gspca_dev
);
1078 static int sd_getsharpness(struct gspca_dev
*gspca_dev
, __s32
*val
)
1080 struct sd
*sd
= (struct sd
*) gspca_dev
;
1082 *val
= sd
->sharpness
;
1086 /* Low Light set here......*/
1087 static int sd_setlowlight(struct gspca_dev
*gspca_dev
, __s32 val
)
1089 struct sd
*sd
= (struct sd
*) gspca_dev
;
1093 reg_w(gspca_dev
, 0xf48e);
1095 reg_w(gspca_dev
, 0xb48e);
1099 static int sd_getlowlight(struct gspca_dev
*gspca_dev
, __s32
*val
)
1101 struct sd
*sd
= (struct sd
*) gspca_dev
;
1103 *val
= sd
->autogain
;
1107 static int sd_querymenu(struct gspca_dev
*gspca_dev
,
1108 struct v4l2_querymenu
*menu
)
1111 case V4L2_CID_POWER_LINE_FREQUENCY
:
1112 switch (menu
->index
) {
1113 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1114 strcpy((char *) menu
->name
, "50 Hz");
1116 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1117 strcpy((char *) menu
->name
, "60 Hz");
1121 case V4L2_CID_EFFECTS
:
1122 if ((unsigned) menu
->index
< ARRAY_SIZE(effects_control
)) {
1123 strncpy((char *) menu
->name
,
1124 effects_control
[menu
->index
], 32);
1132 /* sub-driver description */
1133 static const struct sd_desc sd_desc
= {
1134 .name
= MODULE_NAME
,
1136 .nctrls
= ARRAY_SIZE(sd_ctrls
),
1137 .config
= sd_config
,
1141 .pkt_scan
= sd_pkt_scan
,
1142 .querymenu
= sd_querymenu
,
1145 /* -- module initialisation -- */
1146 static const __devinitdata
struct usb_device_id device_table
[] = {
1147 {USB_DEVICE(0x17a1, 0x0128)},
1150 MODULE_DEVICE_TABLE(usb
, device_table
);
1152 /* -- device connect -- */
1153 static int sd_probe(struct usb_interface
*intf
,
1154 const struct usb_device_id
*id
)
1156 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
1160 static struct usb_driver sd_driver
= {
1161 .name
= MODULE_NAME
,
1162 .id_table
= device_table
,
1164 .disconnect
= gspca_disconnect
,
1166 .suspend
= gspca_suspend
,
1167 .resume
= gspca_resume
,
1171 /* -- module insert / remove -- */
1172 static int __init
sd_mod_init(void)
1174 if (usb_register(&sd_driver
) < 0)
1176 PDEBUG(D_PROBE
, "registered");
1179 static void __exit
sd_mod_exit(void)
1181 usb_deregister(&sd_driver
);
1182 PDEBUG(D_PROBE
, "deregistered");
1185 module_init(sd_mod_init
);
1186 module_exit(sd_mod_exit
);