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
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
,
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
,
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
,
118 #define COLORS_DEF 0x05
119 .default_value
= COLORS_DEF
,
128 .id
= V4L2_CID_GAMMA
, /* (gamma on win) */
129 .type
= V4L2_CTRL_TYPE_INTEGER
,
132 .maximum
= GAMMA_MAX
- 1,
134 .default_value
= GAMMA_DEF
,
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 #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",
164 .default_value
= MIRROR_DEF
,
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 */
178 .default_value
= FREQ_DEF
,
185 .id
= V4L2_CID_WHITE_BALANCE_TEMPERATURE
,
186 .type
= V4L2_CTRL_TYPE_INTEGER
,
187 .name
= "White Balance",
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
,
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",
219 #define EFFECTS_DEF 0
220 .default_value
= EFFECTS_DEF
,
227 static char *effects_control
[] = {
229 "Emboss", /* disabled */
233 "Sun Effect", /* disabled */
237 static const struct v4l2_pix_format vga_mode_t16
[] = {
238 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
240 .sizeimage
= 160 * 120 * 4 / 8 + 590,
241 .colorspace
= V4L2_COLORSPACE_JPEG
,
243 {176, 144, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
245 .sizeimage
= 176 * 144 * 3 / 8 + 590,
246 .colorspace
= V4L2_COLORSPACE_JPEG
,
248 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
250 .sizeimage
= 320 * 240 * 3 / 8 + 590,
251 .colorspace
= V4L2_COLORSPACE_JPEG
,
253 {352, 288, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
255 .sizeimage
= 352 * 288 * 3 / 8 + 590,
256 .colorspace
= V4L2_COLORSPACE_JPEG
,
258 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
260 .sizeimage
= 640 * 480 * 3 / 8 + 590,
261 .colorspace
= V4L2_COLORSPACE_JPEG
,
265 /* sensor specific data */
266 struct additional_sensor_data
{
275 static const struct additional_sensor_data sensor_data
[] = {
278 {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06,
281 {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
283 .data4
= /*Freq (50/60Hz). Splitted for test purpose */
284 {0x66, 0xca, 0xa8, 0xf0},
285 .data5
= /* this could be removed later */
286 {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
288 {0x0b, 0x04, 0x0a, 0x78},
292 {0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a,
295 {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
298 {0x66, 0x00, 0xa8, 0xa8},
300 {0x0c, 0x03, 0xab, 0x29, 0x81, 0x69},
302 {0x0b, 0x04, 0x0a, 0x00},
306 {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
309 {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
311 .data4
= /* Freq (50/60Hz). Splitted for test purpose */
312 {0x66, 0x00, 0xa8, 0xe8},
314 {0x0c, 0x03, 0xab, 0x10, 0x81, 0x20},
316 {0x0b, 0x04, 0x0a, 0x40},
320 #define MAX_EFFECTS 7
321 /* easily done by soft, this table could be removed,
322 * i keep it here just in case */
323 static const u8 effects_table
[MAX_EFFECTS
][6] = {
324 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */
325 {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */
326 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */
327 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80}, /* Sepia */
328 {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02}, /* Croquis */
329 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10}, /* Sun Effect */
330 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */
333 static const u8 gamma_table
[GAMMA_MAX
][17] = {
334 {0x00, 0x3e, 0x69, 0x85, 0x95, 0xa1, 0xae, 0xb9, /* 0 */
335 0xc2, 0xcb, 0xd4, 0xdb, 0xe3, 0xea, 0xf1, 0xf8,
337 {0x00, 0x33, 0x5a, 0x75, 0x85, 0x93, 0xa1, 0xad, /* 1 */
338 0xb7, 0xc2, 0xcb, 0xd4, 0xde, 0xe7, 0xf0, 0xf7,
340 {0x00, 0x2f, 0x51, 0x6b, 0x7c, 0x8a, 0x99, 0xa6, /* 2 */
341 0xb1, 0xbc, 0xc6, 0xd0, 0xdb, 0xe4, 0xed, 0xf6,
343 {0x00, 0x29, 0x48, 0x60, 0x72, 0x81, 0x90, 0x9e, /* 3 */
344 0xaa, 0xb5, 0xbf, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
346 {0x00, 0x23, 0x3f, 0x55, 0x68, 0x77, 0x86, 0x95, /* 4 */
347 0xa2, 0xad, 0xb9, 0xc6, 0xd2, 0xde, 0xe9, 0xf4,
349 {0x00, 0x1b, 0x33, 0x48, 0x59, 0x69, 0x79, 0x87, /* 5 */
350 0x96, 0xa3, 0xb1, 0xbe, 0xcc, 0xda, 0xe7, 0xf3,
352 {0x00, 0x02, 0x10, 0x20, 0x32, 0x40, 0x57, 0x67, /* 6 */
353 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
355 {0x00, 0x02, 0x14, 0x26, 0x38, 0x4a, 0x60, 0x70, /* 7 */
356 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
358 {0x00, 0x10, 0x22, 0x35, 0x47, 0x5a, 0x69, 0x79, /* 8 */
359 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe0, 0xf0,
361 {0x00, 0x10, 0x26, 0x40, 0x54, 0x65, 0x75, 0x84, /* 9 */
362 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd6, 0xe0, 0xf0,
364 {0x00, 0x18, 0x2b, 0x44, 0x60, 0x70, 0x80, 0x8e, /* 10 */
365 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xd8, 0xe2, 0xf0,
367 {0x00, 0x1a, 0x34, 0x52, 0x66, 0x7e, 0x8D, 0x9B, /* 11 */
368 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
370 {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8, /* 12 */
371 0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6,
373 {0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7, /* 13 */
374 0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9,
376 {0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6, /* 14 */
377 0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa,
379 {0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8, /* 15 */
380 0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc,
384 static const u8 tas5130a_sensor_init
[][8] = {
385 {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
386 {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
387 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
388 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
392 static u8 sensor_reset
[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
395 static u8
reg_r(struct gspca_dev
*gspca_dev
,
398 usb_control_msg(gspca_dev
->dev
,
399 usb_rcvctrlpipe(gspca_dev
->dev
, 0),
401 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
404 gspca_dev
->usb_buf
, 1, 500);
405 return gspca_dev
->usb_buf
[0];
408 static void reg_w(struct gspca_dev
*gspca_dev
,
411 usb_control_msg(gspca_dev
->dev
,
412 usb_sndctrlpipe(gspca_dev
->dev
, 0),
414 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
419 static void reg_w_buf(struct gspca_dev
*gspca_dev
,
420 const u8
*buffer
, u16 len
)
422 if (len
<= USB_BUF_SZ
) {
423 memcpy(gspca_dev
->usb_buf
, buffer
, len
);
424 usb_control_msg(gspca_dev
->dev
,
425 usb_sndctrlpipe(gspca_dev
->dev
, 0),
427 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
429 gspca_dev
->usb_buf
, len
, 500);
433 tmpbuf
= kmalloc(len
, GFP_KERNEL
);
434 memcpy(tmpbuf
, buffer
, len
);
435 usb_control_msg(gspca_dev
->dev
,
436 usb_sndctrlpipe(gspca_dev
->dev
, 0),
438 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
445 /* write values to consecutive registers */
446 static void reg_w_ixbuf(struct gspca_dev
*gspca_dev
,
448 const u8
*buffer
, u16 len
)
453 if (len
* 2 <= USB_BUF_SZ
)
454 p
= tmpbuf
= gspca_dev
->usb_buf
;
456 p
= tmpbuf
= kmalloc(len
* 2, GFP_KERNEL
);
462 usb_control_msg(gspca_dev
->dev
,
463 usb_sndctrlpipe(gspca_dev
->dev
, 0),
465 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
467 tmpbuf
, len
* 2, 500);
468 if (len
* 2 > USB_BUF_SZ
)
472 /* Reported as OM6802*/
473 static void om6802_sensor_init(struct gspca_dev
*gspca_dev
)
478 u8 val
[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
479 static const u8 sensor_init
[] = {
497 reg_w_buf(gspca_dev
, sensor_reset
, sizeof sensor_reset
);
501 byte
= reg_r(gspca_dev
, 0x0060);
506 byte
= reg_r(gspca_dev
, 0x0063);
508 err("Bad sensor reset %02x", byte
);
517 reg_w(gspca_dev
, 0x3c80);
518 reg_w_buf(gspca_dev
, val
, sizeof val
);
522 byte
= reg_r(gspca_dev
, 0x60);
528 reg_w(gspca_dev
, 0x3c80);
531 /* this function is called at probe time */
532 static int sd_config(struct gspca_dev
*gspca_dev
,
533 const struct usb_device_id
*id
)
535 struct sd
*sd
= (struct sd
*) gspca_dev
;
538 cam
= &gspca_dev
->cam
;
540 cam
->cam_mode
= vga_mode_t16
;
541 cam
->nmodes
= ARRAY_SIZE(vga_mode_t16
);
543 sd
->brightness
= BRIGHTNESS_DEF
;
544 sd
->contrast
= CONTRAST_DEF
;
545 sd
->colors
= COLORS_DEF
;
546 sd
->gamma
= GAMMA_DEF
;
547 sd
->autogain
= AUTOGAIN_DEF
;
548 sd
->mirror
= MIRROR_DEF
;
550 sd
->whitebalance
= WHITE_BALANCE_DEF
;
551 sd
->sharpness
= SHARPNESS_DEF
;
552 sd
->effect
= EFFECTS_DEF
;
556 static void setbrightness(struct gspca_dev
*gspca_dev
)
558 struct sd
*sd
= (struct sd
*) gspca_dev
;
559 unsigned int brightness
;
560 u8 set6
[4] = { 0x8f, 0x24, 0xc3, 0x00 };
562 brightness
= sd
->brightness
;
563 if (brightness
< 7) {
565 set6
[3] = 0x70 - brightness
* 0x10;
567 set6
[3] = 0x00 + ((brightness
- 7) * 0x10);
570 reg_w_buf(gspca_dev
, set6
, sizeof set6
);
573 static void setcontrast(struct gspca_dev
*gspca_dev
)
575 struct sd
*sd
= (struct sd
*) gspca_dev
;
576 unsigned int contrast
= sd
->contrast
;
580 reg_to_write
= 0x8ea9 - contrast
* 0x200;
582 reg_to_write
= 0x00a9 + (contrast
- 7) * 0x200;
584 reg_w(gspca_dev
, reg_to_write
);
587 static void setcolors(struct gspca_dev
*gspca_dev
)
589 struct sd
*sd
= (struct sd
*) gspca_dev
;
592 reg_to_write
= 0x80bb + sd
->colors
* 0x100; /* was 0xc0 */
593 reg_w(gspca_dev
, reg_to_write
);
596 static void setgamma(struct gspca_dev
*gspca_dev
)
598 struct sd
*sd
= (struct sd
*) gspca_dev
;
600 PDEBUG(D_CONF
, "Gamma: %d", sd
->gamma
);
601 reg_w_ixbuf(gspca_dev
, 0x90,
602 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
;
641 static const u8 read_indexs
[] =
642 { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
643 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00 };
644 static const u8 n1
[] =
645 {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
646 static const u8 n2
[] =
648 static const u8 n3
[6] =
649 {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
650 static const u8 n3_other
[6] =
651 {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00};
652 static const u8 n4
[] =
653 {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
654 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
655 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
656 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
657 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
658 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
659 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
660 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
661 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
662 static const u8 n4_other
[] =
663 {0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69,
664 0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68,
665 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8,
666 0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8,
667 0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56,
668 0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5,
669 0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0,
670 0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00};
671 static const u8 nset8
[6] =
672 { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
673 static const u8 nset8_other
[6] =
674 { 0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00 };
675 static const u8 nset9
[4] =
676 { 0x0b, 0x04, 0x0a, 0x78 };
677 static const u8 nset9_other
[4] =
678 { 0x0b, 0x04, 0x0a, 0x00 };
680 sensor_id
= (reg_r(gspca_dev
, 0x06) << 8)
681 | reg_r(gspca_dev
, 0x07);
684 PDEBUG(D_CONF
, "sensor tas5130a");
685 sd
->sensor
= SENSOR_TAS5130A
;
688 PDEBUG(D_CONF
, "sensor 'other'");
689 sd
->sensor
= SENSOR_OTHER
;
692 PDEBUG(D_CONF
, "sensor om6802");
693 sd
->sensor
= SENSOR_OM6802
;
696 PDEBUG(D_CONF
, "unknown sensor %04x", sensor_id
);
700 if (sd
->sensor
!= SENSOR_OTHER
) {
701 reg_w_buf(gspca_dev
, n1
, sizeof n1
);
704 reg_w_buf(gspca_dev
, sensor_reset
, sizeof sensor_reset
);
705 test_byte
= reg_r(gspca_dev
, 0x0063);
707 if (test_byte
== 0x17)
711 err("Bad sensor reset %02x", test_byte
);
713 /*fixme: test - continue */
715 reg_w_buf(gspca_dev
, n2
, sizeof n2
);
719 while (read_indexs
[i
] != 0x00) {
720 test_byte
= reg_r(gspca_dev
, read_indexs
[i
]);
721 PDEBUG(D_STREAM
, "Reg 0x%02x = 0x%02x", read_indexs
[i
],
726 if (sd
->sensor
!= SENSOR_OTHER
) {
727 reg_w_buf(gspca_dev
, n3
, sizeof n3
);
728 reg_w_buf(gspca_dev
, n4
, sizeof n4
);
729 reg_r(gspca_dev
, 0x0080);
730 reg_w(gspca_dev
, 0x2c80);
734 reg_w_buf(gspca_dev
, n3_other
, sizeof n3_other
);
735 reg_w_buf(gspca_dev
, n4_other
, sizeof n4_other
);
741 reg_w_ixbuf(gspca_dev
, 0xd0, sensor_data
[sd
->sensor
].data1
,
742 sizeof sensor_data
[sd
->sensor
].data1
);
743 reg_w_ixbuf(gspca_dev
, 0xc7, sensor_data
[sd
->sensor
].data2
,
744 sizeof sensor_data
[sd
->sensor
].data2
);
745 reg_w_ixbuf(gspca_dev
, 0xe0, sensor_data
[sd
->sensor
].data2
,
746 sizeof sensor_data
[sd
->sensor
].data2
);
748 reg_w(gspca_dev
, reg80
);
749 reg_w(gspca_dev
, reg80
);
750 reg_w(gspca_dev
, reg8e
);
752 setbrightness(gspca_dev
);
753 setcontrast(gspca_dev
);
755 setcolors(gspca_dev
);
756 setsharpness(gspca_dev
);
757 setwhitebalance(gspca_dev
);
759 reg_w(gspca_dev
, 0x2087); /* tied to white balance? */
760 reg_w(gspca_dev
, 0x2088);
761 reg_w(gspca_dev
, 0x2089);
763 reg_w_buf(gspca_dev
, sensor_data
[sd
->sensor
].data4
,
764 sizeof sensor_data
[sd
->sensor
].data4
);
765 reg_w_buf(gspca_dev
, sensor_data
[sd
->sensor
].data5
,
766 sizeof sensor_data
[sd
->sensor
].data5
);
767 if (sd
->sensor
!= SENSOR_OTHER
) {
768 reg_w_buf(gspca_dev
, nset8
, sizeof nset8
);
769 reg_w_buf(gspca_dev
, nset9
, sizeof nset9
);
770 reg_w(gspca_dev
, 0x2880);
772 reg_w_buf(gspca_dev
, nset8_other
, sizeof nset8_other
);
773 reg_w_buf(gspca_dev
, nset9_other
, sizeof nset9_other
);
776 reg_w_ixbuf(gspca_dev
, 0xd0, sensor_data
[sd
->sensor
].data1
,
777 sizeof sensor_data
[sd
->sensor
].data1
);
778 reg_w_ixbuf(gspca_dev
, 0xc7, sensor_data
[sd
->sensor
].data2
,
779 sizeof sensor_data
[sd
->sensor
].data2
);
780 reg_w_ixbuf(gspca_dev
, 0xe0, sensor_data
[sd
->sensor
].data2
,
781 sizeof sensor_data
[sd
->sensor
].data2
);
786 static void setflip(struct gspca_dev
*gspca_dev
)
788 struct sd
*sd
= (struct sd
*) gspca_dev
;
790 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
795 reg_w_buf(gspca_dev
, flipcmd
, sizeof flipcmd
);
798 static void seteffect(struct gspca_dev
*gspca_dev
)
800 struct sd
*sd
= (struct sd
*) gspca_dev
;
802 reg_w_buf(gspca_dev
, effects_table
[sd
->effect
],
803 sizeof effects_table
[0]);
804 if (sd
->effect
== 1 || sd
->effect
== 5) {
806 "This effect have been disabled for webcam \"safety\"");
810 if (sd
->effect
== 1 || sd
->effect
== 4)
811 reg_w(gspca_dev
, 0x4aa6);
813 reg_w(gspca_dev
, 0xfaa6);
816 static void setlightfreq(struct gspca_dev
*gspca_dev
)
818 struct sd
*sd
= (struct sd
*) gspca_dev
;
819 u8 freq
[4] = { 0x66, 0x40, 0xa8, 0xe8 };
821 if (sd
->freq
== 2) /* 60hz */
824 reg_w_buf(gspca_dev
, freq
, sizeof freq
);
827 /* Is this really needed?
828 * i added some module parameters for test with some users */
829 static void poll_sensor(struct gspca_dev
*gspca_dev
)
831 struct sd
*sd
= (struct sd
*) gspca_dev
;
832 static const u8 poll1
[] =
833 {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
834 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
835 0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
837 static const u8 poll2
[] =
838 {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
839 0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
840 static const u8 poll3
[] =
841 {0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d};
842 static const u8 poll4
[] =
843 {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
844 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
845 0xc2, 0x80, 0xc3, 0x10};
847 if (sd
->sensor
== SENSOR_OM6802
) {
848 PDEBUG(D_STREAM
, "[Sensor requires polling]");
849 reg_w_buf(gspca_dev
, poll1
, sizeof poll1
);
850 reg_w_buf(gspca_dev
, poll2
, sizeof poll2
);
851 reg_w_buf(gspca_dev
, poll3
, sizeof poll3
);
852 reg_w_buf(gspca_dev
, poll4
, sizeof poll4
);
856 static int sd_start(struct gspca_dev
*gspca_dev
)
858 struct sd
*sd
= (struct sd
*) gspca_dev
;
860 u8 t2
[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
861 static const u8 t3
[] =
862 { 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 };
864 mode
= gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
]. priv
;
866 case 0: /* 640x480 (0x00) */
868 case 1: /* 352x288 */
871 case 2: /* 320x240 */
874 case 3: /* 176x144 */
878 /* case 4: * 160x120 */
883 switch (sd
->sensor
) {
885 om6802_sensor_init(gspca_dev
);
890 /* case SENSOR_TAS5130A: */
892 while (tas5130a_sensor_init
[i
][0] != 0) {
893 reg_w_buf(gspca_dev
, tas5130a_sensor_init
[i
],
894 sizeof tas5130a_sensor_init
[0]);
897 reg_w(gspca_dev
, 0x3c80);
898 /* just in case and to keep sync with logs (for mine) */
899 reg_w_buf(gspca_dev
, tas5130a_sensor_init
[3],
900 sizeof tas5130a_sensor_init
[0]);
901 reg_w(gspca_dev
, 0x3c80);
904 reg_w_buf(gspca_dev
, sensor_data
[sd
->sensor
].data4
,
905 sizeof sensor_data
[sd
->sensor
].data4
);
906 reg_r(gspca_dev
, 0x0012);
907 reg_w_buf(gspca_dev
, t2
, sizeof t2
);
908 reg_w_ixbuf(gspca_dev
, 0xb3, t3
, sizeof t3
);
909 reg_w(gspca_dev
, 0x0013);
911 reg_w_buf(gspca_dev
, sensor_data
[sd
->sensor
].stream
,
912 sizeof sensor_data
[sd
->sensor
].stream
);
913 poll_sensor(gspca_dev
);
915 /* restart on each start, just in case, sometimes regs goes wrong
916 * when using controls from app */
917 setbrightness(gspca_dev
);
918 setcontrast(gspca_dev
);
919 setcolors(gspca_dev
);
923 static void sd_stopN(struct gspca_dev
*gspca_dev
)
925 struct sd
*sd
= (struct sd
*) gspca_dev
;
927 reg_w_buf(gspca_dev
, sensor_data
[sd
->sensor
].stream
,
928 sizeof sensor_data
[sd
->sensor
].stream
);
930 reg_w_buf(gspca_dev
, sensor_data
[sd
->sensor
].stream
,
931 sizeof sensor_data
[sd
->sensor
].stream
);
932 if (sd
->sensor
!= SENSOR_OTHER
) {
934 reg_w(gspca_dev
, 0x0309);
938 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
939 struct gspca_frame
*frame
, /* target */
940 u8
*data
, /* isoc packet */
941 int len
) /* iso packet length */
943 static u8 ffd9
[] = { 0xff, 0xd9 };
945 if (data
[0] == 0x5a) {
946 /* Control Packet, after this came the header again,
947 * but extra bytes came in the packet before this,
948 * sometimes an EOF arrives, sometimes not... */
953 if (data
[0] == 0xff && data
[1] == 0xd8) {
954 /* extra bytes....., could be processed too but would be
955 * a waste of time, right now leave the application and
956 * libjpeg do it for ourserlves.. */
957 frame
= gspca_frame_add(gspca_dev
, LAST_PACKET
, frame
,
959 gspca_frame_add(gspca_dev
, FIRST_PACKET
, frame
, data
, len
);
963 if (data
[len
- 2] == 0xff && data
[len
- 1] == 0xd9) {
964 /* Just in case, i have seen packets with the marker,
965 * other's do not include it... */
968 gspca_frame_add(gspca_dev
, INTER_PACKET
, frame
, data
, len
);
971 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
)
973 struct sd
*sd
= (struct sd
*) gspca_dev
;
975 sd
->brightness
= val
;
976 if (gspca_dev
->streaming
)
977 setbrightness(gspca_dev
);
981 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
)
983 struct sd
*sd
= (struct sd
*) gspca_dev
;
985 *val
= sd
->brightness
;
989 static int sd_setwhitebalance(struct gspca_dev
*gspca_dev
, __s32 val
)
991 struct sd
*sd
= (struct sd
*) gspca_dev
;
993 sd
->whitebalance
= val
;
994 if (gspca_dev
->streaming
)
995 setwhitebalance(gspca_dev
);
999 static int sd_getwhitebalance(struct gspca_dev
*gspca_dev
, __s32
*val
)
1001 struct sd
*sd
= (struct sd
*) gspca_dev
;
1003 *val
= sd
->whitebalance
;
1007 static int sd_setflip(struct gspca_dev
*gspca_dev
, __s32 val
)
1009 struct sd
*sd
= (struct sd
*) gspca_dev
;
1012 if (gspca_dev
->streaming
)
1017 static int sd_getflip(struct gspca_dev
*gspca_dev
, __s32
*val
)
1019 struct sd
*sd
= (struct sd
*) gspca_dev
;
1025 static int sd_seteffect(struct gspca_dev
*gspca_dev
, __s32 val
)
1027 struct sd
*sd
= (struct sd
*) gspca_dev
;
1030 if (gspca_dev
->streaming
)
1031 seteffect(gspca_dev
);
1035 static int sd_geteffect(struct gspca_dev
*gspca_dev
, __s32
*val
)
1037 struct sd
*sd
= (struct sd
*) gspca_dev
;
1043 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
)
1045 struct sd
*sd
= (struct sd
*) gspca_dev
;
1048 if (gspca_dev
->streaming
)
1049 setcontrast(gspca_dev
);
1053 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
)
1055 struct sd
*sd
= (struct sd
*) gspca_dev
;
1057 *val
= sd
->contrast
;
1061 static int sd_setcolors(struct gspca_dev
*gspca_dev
, __s32 val
)
1063 struct sd
*sd
= (struct sd
*) gspca_dev
;
1066 if (gspca_dev
->streaming
)
1067 setcolors(gspca_dev
);
1071 static int sd_getcolors(struct gspca_dev
*gspca_dev
, __s32
*val
)
1073 struct sd
*sd
= (struct sd
*) gspca_dev
;
1079 static int sd_setgamma(struct gspca_dev
*gspca_dev
, __s32 val
)
1081 struct sd
*sd
= (struct sd
*) gspca_dev
;
1084 if (gspca_dev
->streaming
)
1085 setgamma(gspca_dev
);
1089 static int sd_getgamma(struct gspca_dev
*gspca_dev
, __s32
*val
)
1091 struct sd
*sd
= (struct sd
*) gspca_dev
;
1097 static int sd_setfreq(struct gspca_dev
*gspca_dev
, __s32 val
)
1099 struct sd
*sd
= (struct sd
*) gspca_dev
;
1102 if (gspca_dev
->streaming
)
1103 setlightfreq(gspca_dev
);
1107 static int sd_getfreq(struct gspca_dev
*gspca_dev
, __s32
*val
)
1109 struct sd
*sd
= (struct sd
*) gspca_dev
;
1115 static int sd_setsharpness(struct gspca_dev
*gspca_dev
, __s32 val
)
1117 struct sd
*sd
= (struct sd
*) gspca_dev
;
1119 sd
->sharpness
= val
;
1120 if (gspca_dev
->streaming
)
1121 setsharpness(gspca_dev
);
1125 static int sd_getsharpness(struct gspca_dev
*gspca_dev
, __s32
*val
)
1127 struct sd
*sd
= (struct sd
*) gspca_dev
;
1129 *val
= sd
->sharpness
;
1133 /* Low Light set here......*/
1134 static int sd_setlowlight(struct gspca_dev
*gspca_dev
, __s32 val
)
1136 struct sd
*sd
= (struct sd
*) gspca_dev
;
1140 reg_w(gspca_dev
, 0xf48e);
1142 reg_w(gspca_dev
, 0xb48e);
1146 static int sd_getlowlight(struct gspca_dev
*gspca_dev
, __s32
*val
)
1148 struct sd
*sd
= (struct sd
*) gspca_dev
;
1150 *val
= sd
->autogain
;
1154 static int sd_querymenu(struct gspca_dev
*gspca_dev
,
1155 struct v4l2_querymenu
*menu
)
1158 case V4L2_CID_POWER_LINE_FREQUENCY
:
1159 switch (menu
->index
) {
1160 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1161 strcpy((char *) menu
->name
, "50 Hz");
1163 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1164 strcpy((char *) menu
->name
, "60 Hz");
1168 case V4L2_CID_EFFECTS
:
1169 if ((unsigned) menu
->index
< ARRAY_SIZE(effects_control
)) {
1170 strncpy((char *) menu
->name
,
1171 effects_control
[menu
->index
], 32);
1179 /* sub-driver description */
1180 static const struct sd_desc sd_desc
= {
1181 .name
= MODULE_NAME
,
1183 .nctrls
= ARRAY_SIZE(sd_ctrls
),
1184 .config
= sd_config
,
1188 .pkt_scan
= sd_pkt_scan
,
1189 .querymenu
= sd_querymenu
,
1192 /* -- module initialisation -- */
1193 static const __devinitdata
struct usb_device_id device_table
[] = {
1194 {USB_DEVICE(0x17a1, 0x0128)},
1197 MODULE_DEVICE_TABLE(usb
, device_table
);
1199 /* -- device connect -- */
1200 static int sd_probe(struct usb_interface
*intf
,
1201 const struct usb_device_id
*id
)
1203 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
1207 static struct usb_driver sd_driver
= {
1208 .name
= MODULE_NAME
,
1209 .id_table
= device_table
,
1211 .disconnect
= gspca_disconnect
,
1213 .suspend
= gspca_suspend
,
1214 .resume
= gspca_resume
,
1218 /* -- module insert / remove -- */
1219 static int __init
sd_mod_init(void)
1222 ret
= usb_register(&sd_driver
);
1225 PDEBUG(D_PROBE
, "registered");
1228 static void __exit
sd_mod_exit(void)
1230 usb_deregister(&sd_driver
);
1231 PDEBUG(D_PROBE
, "deregistered");
1234 module_init(sd_mod_init
);
1235 module_exit(sd_mod_exit
);