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_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[] = {
83 .id = V4L2_CID_BRIGHTNESS,
84 .type = V4L2_CTRL_TYPE_INTEGER,
89 #define BRIGHTNESS_DEF 8
90 .default_value = BRIGHTNESS_DEF,
92 .set = sd_setbrightness,
93 .get = sd_getbrightness,
97 .id = V4L2_CID_CONTRAST,
98 .type = V4L2_CTRL_TYPE_INTEGER,
103 #define CONTRAST_DEF 0x07
104 .default_value = CONTRAST_DEF,
106 .set = sd_setcontrast,
107 .get = sd_getcontrast,
111 .id = V4L2_CID_SATURATION,
112 .type = V4L2_CTRL_TYPE_INTEGER,
117 #define COLORS_DEF 0x05
118 .default_value = COLORS_DEF,
127 .id = V4L2_CID_GAMMA, /* (gamma on win) */
128 .type = V4L2_CTRL_TYPE_INTEGER,
131 .maximum = GAMMA_MAX - 1,
133 .default_value = GAMMA_DEF,
140 .id = V4L2_CID_GAIN, /* here, i activate only the lowlight,
141 * some apps dont bring up the
142 * backligth_compensation control) */
143 .type = V4L2_CTRL_TYPE_INTEGER,
148 #define AUTOGAIN_DEF 0x01
149 .default_value = AUTOGAIN_DEF,
151 .set = sd_setlowlight,
152 .get = sd_getlowlight,
156 .id = V4L2_CID_HFLIP,
157 .type = V4L2_CTRL_TYPE_BOOLEAN,
158 .name = "Mirror Image",
163 .default_value = MIRROR_DEF,
170 .id = V4L2_CID_POWER_LINE_FREQUENCY,
171 .type = V4L2_CTRL_TYPE_MENU,
172 .name = "Light Frequency Filter",
173 .minimum = 1, /* 1 -> 0x50, 2->0x60 */
177 .default_value = FREQ_DEF,
184 .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
185 .type = V4L2_CTRL_TYPE_INTEGER,
186 .name = "White Balance",
190 #define WHITE_BALANCE_DEF 0
191 .default_value = WHITE_BALANCE_DEF,
193 .set = sd_setwhitebalance,
194 .get = sd_getwhitebalance
198 .id = V4L2_CID_SHARPNESS,
199 .type = V4L2_CTRL_TYPE_INTEGER,
204 #define SHARPNESS_DEF 0x06
205 .default_value = SHARPNESS_DEF,
207 .set = sd_setsharpness,
208 .get = sd_getsharpness,
212 .id = V4L2_CID_EFFECTS,
213 .type = V4L2_CTRL_TYPE_MENU,
214 .name = "Webcam Effects",
218 #define EFFECTS_DEF 0
219 .default_value = EFFECTS_DEF,
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 {
274 const static struct additional_sensor_data sensor_data[] = {
277 {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
280 {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
282 .data4 = /* Freq (50/60Hz). Splitted for test purpose */
283 {0x66, 0x00, 0xa8, 0xe8},
285 {0x0c, 0x03, 0xab, 0x10, 0x81, 0x20},
287 {0x0b, 0x04, 0x0a, 0x40},
291 {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06,
294 {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
296 .data4 = /*Freq (50/60Hz). Splitted for test purpose */
297 {0x66, 0xca, 0xa8, 0xf0 },
298 .data5 = /* this could be removed later */
299 {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
301 {0x0b, 0x04, 0x0a, 0x78},
305 #define MAX_EFFECTS 7
306 /* easily done by soft, this table could be removed,
307 * i keep it here just in case */
308 static const u8 effects_table[MAX_EFFECTS][6] = {
309 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */
310 {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */
311 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */
312 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80}, /* Sepia */
313 {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02}, /* Croquis */
314 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10}, /* Sun Effect */
315 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */
318 static const u8 gamma_table[GAMMA_MAX][17] = {
319 {0x00, 0x3e, 0x69, 0x85, 0x95, 0xa1, 0xae, 0xb9, /* 0 */
320 0xc2, 0xcb, 0xd4, 0xdb, 0xe3, 0xea, 0xf1, 0xf8,
322 {0x00, 0x33, 0x5a, 0x75, 0x85, 0x93, 0xa1, 0xad, /* 1 */
323 0xb7, 0xc2, 0xcb, 0xd4, 0xde, 0xe7, 0xf0, 0xf7,
325 {0x00, 0x2f, 0x51, 0x6b, 0x7c, 0x8a, 0x99, 0xa6, /* 2 */
326 0xb1, 0xbc, 0xc6, 0xd0, 0xdb, 0xe4, 0xed, 0xf6,
328 {0x00, 0x29, 0x48, 0x60, 0x72, 0x81, 0x90, 0x9e, /* 3 */
329 0xaa, 0xb5, 0xbf, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
331 {0x00, 0x23, 0x3f, 0x55, 0x68, 0x77, 0x86, 0x95, /* 4 */
332 0xa2, 0xad, 0xb9, 0xc6, 0xd2, 0xde, 0xe9, 0xf4,
334 {0x00, 0x1b, 0x33, 0x48, 0x59, 0x69, 0x79, 0x87, /* 5 */
335 0x96, 0xa3, 0xb1, 0xbe, 0xcc, 0xda, 0xe7, 0xf3,
337 {0x00, 0x02, 0x10, 0x20, 0x32, 0x40, 0x57, 0x67, /* 6 */
338 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
340 {0x00, 0x02, 0x14, 0x26, 0x38, 0x4a, 0x60, 0x70, /* 7 */
341 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
343 {0x00, 0x10, 0x22, 0x35, 0x47, 0x5a, 0x69, 0x79, /* 8 */
344 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe0, 0xf0,
346 {0x00, 0x10, 0x26, 0x40, 0x54, 0x65, 0x75, 0x84, /* 9 */
347 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd6, 0xe0, 0xf0,
349 {0x00, 0x18, 0x2b, 0x44, 0x60, 0x70, 0x80, 0x8e, /* 10 */
350 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xd8, 0xe2, 0xf0,
352 {0x00, 0x1a, 0x34, 0x52, 0x66, 0x7e, 0x8D, 0x9B, /* 11 */
353 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
355 {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8, /* 12 */
356 0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6,
358 {0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7, /* 13 */
359 0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9,
361 {0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6, /* 14 */
362 0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa,
364 {0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8, /* 15 */
365 0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc,
369 static const u8 tas5130a_sensor_init[][8] = {
370 {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
371 {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
372 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
373 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
377 static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
380 static u8 reg_r(struct gspca_dev *gspca_dev,
383 usb_control_msg(gspca_dev->dev,
384 usb_rcvctrlpipe(gspca_dev->dev, 0),
386 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
389 gspca_dev->usb_buf, 1, 500);
390 return gspca_dev->usb_buf[0];
393 static void reg_w(struct gspca_dev *gspca_dev,
396 usb_control_msg(gspca_dev->dev,
397 usb_sndctrlpipe(gspca_dev->dev, 0),
399 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
404 static void reg_w_buf(struct gspca_dev *gspca_dev,
405 const u8 *buffer, u16 len)
407 if (len <= USB_BUF_SZ) {
408 memcpy(gspca_dev->usb_buf, buffer, len);
409 usb_control_msg(gspca_dev->dev,
410 usb_sndctrlpipe(gspca_dev->dev, 0),
412 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
414 gspca_dev->usb_buf, len, 500);
418 tmpbuf = kmalloc(len, GFP_KERNEL);
419 memcpy(tmpbuf, buffer, len);
420 usb_control_msg(gspca_dev->dev,
421 usb_sndctrlpipe(gspca_dev->dev, 0),
423 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
430 /* write values to consecutive registers */
431 static void reg_w_ixbuf(struct gspca_dev *gspca_dev,
433 const u8 *buffer, u16 len)
438 if (len * 2 <= USB_BUF_SZ)
439 p = tmpbuf = gspca_dev->usb_buf;
441 p = tmpbuf = kmalloc(len * 2, GFP_KERNEL);
447 usb_control_msg(gspca_dev->dev,
448 usb_sndctrlpipe(gspca_dev->dev, 0),
450 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
452 tmpbuf, len * 2, 500);
453 if (len * 2 > USB_BUF_SZ)
457 /* Reported as OM6802*/
458 static void om6802_sensor_init(struct gspca_dev *gspca_dev)
463 u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
464 static const u8 sensor_init[] = {
482 reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
486 byte = reg_r(gspca_dev, 0x0060);
491 byte = reg_r(gspca_dev, 0x0063);
493 err("Bad sensor reset %02x", byte);
502 reg_w(gspca_dev, 0x3c80);
503 reg_w_buf(gspca_dev, val, sizeof val);
507 byte = reg_r(gspca_dev, 0x60);
513 reg_w(gspca_dev, 0x3c80);
516 /* this function is called at probe time */
517 static int sd_config(struct gspca_dev *gspca_dev,
518 const struct usb_device_id *id)
520 struct sd *sd = (struct sd *) gspca_dev;
523 cam = &gspca_dev->cam;
525 cam->cam_mode = vga_mode_t16;
526 cam->nmodes = ARRAY_SIZE(vga_mode_t16);
528 sd->brightness = BRIGHTNESS_DEF;
529 sd->contrast = CONTRAST_DEF;
530 sd->colors = COLORS_DEF;
531 sd->gamma = GAMMA_DEF;
532 sd->autogain = AUTOGAIN_DEF;
533 sd->mirror = MIRROR_DEF;
535 sd->whitebalance = WHITE_BALANCE_DEF;
536 sd->sharpness = SHARPNESS_DEF;
537 sd->effect = EFFECTS_DEF;
541 static void setbrightness(struct gspca_dev *gspca_dev)
543 struct sd *sd = (struct sd *) gspca_dev;
544 unsigned int brightness;
545 u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
547 brightness = sd->brightness;
548 if (brightness < 7) {
550 set6[3] = 0x70 - brightness * 0x10;
552 set6[3] = 0x00 + ((brightness - 7) * 0x10);
555 reg_w_buf(gspca_dev, set6, sizeof set6);
558 static void setcontrast(struct gspca_dev *gspca_dev)
560 struct sd *sd = (struct sd *) gspca_dev;
561 unsigned int contrast = sd->contrast;
565 reg_to_write = 0x8ea9 - contrast * 0x200;
567 reg_to_write = 0x00a9 + (contrast - 7) * 0x200;
569 reg_w(gspca_dev, reg_to_write);
572 static void setcolors(struct gspca_dev *gspca_dev)
574 struct sd *sd = (struct sd *) gspca_dev;
577 reg_to_write = 0x80bb + sd->colors * 0x100; /* was 0xc0 */
578 reg_w(gspca_dev, reg_to_write);
581 static void setgamma(struct gspca_dev *gspca_dev)
583 struct sd *sd = (struct sd *) gspca_dev;
585 PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
586 reg_w_ixbuf(gspca_dev, 0x90,
587 gamma_table[sd->gamma], sizeof gamma_table[0]);
590 static void setwhitebalance(struct gspca_dev *gspca_dev)
592 struct sd *sd = (struct sd *) gspca_dev;
594 u8 white_balance[8] =
595 {0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38};
597 if (sd->whitebalance)
598 white_balance[7] = 0x3c;
600 reg_w_buf(gspca_dev, white_balance, sizeof white_balance);
603 static void setsharpness(struct gspca_dev *gspca_dev)
605 struct sd *sd = (struct sd *) gspca_dev;
608 reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
610 reg_w(gspca_dev, reg_to_write);
613 /* this function is called at probe and resume time */
614 static int sd_init(struct gspca_dev *gspca_dev)
616 /* some of this registers are not really neded, because
617 * they are overriden by setbrigthness, setcontrast, etc,
618 * but wont hurt anyway, and can help someone with similar webcam
619 * to see the initial parameters.*/
620 struct sd *sd = (struct sd *) gspca_dev;
624 static const u8 read_indexs[] =
625 { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
626 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00 };
627 static const u8 n1[] =
628 {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
629 static const u8 n2[] =
631 static const u8 n3[] =
632 {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
633 static const u8 n4[] =
634 {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
635 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
636 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
637 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
638 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
639 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
640 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
641 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
642 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
643 static const u8 nset8[6] =
644 { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
645 static const u8 nset9[4] =
646 { 0x0b, 0x04, 0x0a, 0x78 };
648 byte = reg_r(gspca_dev, 0x06);
649 test_byte = reg_r(gspca_dev, 0x07);
650 if (byte == 0x08 && test_byte == 0x07) {
651 PDEBUG(D_CONF, "sensor om6802");
652 sd->sensor = SENSOR_OM6802;
653 } else if (byte == 0x08 && test_byte == 0x01) {
654 PDEBUG(D_CONF, "sensor tas5130a");
655 sd->sensor = SENSOR_TAS5130A;
657 PDEBUG(D_CONF, "unknown sensor %02x %02x", byte, test_byte);
658 sd->sensor = SENSOR_TAS5130A;
661 reg_w_buf(gspca_dev, n1, sizeof n1);
665 reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
666 test_byte = reg_r(gspca_dev, 0x0063);
668 if (test_byte == 0x17)
672 err("Bad sensor reset %02x", test_byte);
674 /*fixme: test - continue */
676 reg_w_buf(gspca_dev, n2, sizeof n2);
679 while (read_indexs[i] != 0x00) {
680 test_byte = reg_r(gspca_dev, read_indexs[i]);
681 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i],
686 reg_w_buf(gspca_dev, n3, sizeof n3);
687 reg_w_buf(gspca_dev, n4, sizeof n4);
688 reg_r(gspca_dev, 0x0080);
689 reg_w(gspca_dev, 0x2c80);
691 reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1,
692 sizeof sensor_data[sd->sensor].data1);
693 reg_w_ixbuf(gspca_dev, 0xc7, sensor_data[sd->sensor].data2,
694 sizeof sensor_data[sd->sensor].data2);
695 reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2,
696 sizeof sensor_data[sd->sensor].data2);
698 reg_w(gspca_dev, 0x3880);
699 reg_w(gspca_dev, 0x3880);
700 reg_w(gspca_dev, 0x338e);
702 setbrightness(gspca_dev);
703 setcontrast(gspca_dev);
705 setcolors(gspca_dev);
706 setsharpness(gspca_dev);
707 setwhitebalance(gspca_dev);
709 reg_w(gspca_dev, 0x2087); /* tied to white balance? */
710 reg_w(gspca_dev, 0x2088);
711 reg_w(gspca_dev, 0x2089);
713 reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
714 sizeof sensor_data[sd->sensor].data4);
715 reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5,
716 sizeof sensor_data[sd->sensor].data5);
717 reg_w_buf(gspca_dev, nset8, sizeof nset8);
718 reg_w_buf(gspca_dev, nset9, sizeof nset9);
720 reg_w(gspca_dev, 0x2880);
722 reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1,
723 sizeof sensor_data[sd->sensor].data1);
724 reg_w_ixbuf(gspca_dev, 0xc7, sensor_data[sd->sensor].data2,
725 sizeof sensor_data[sd->sensor].data2);
726 reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2,
727 sizeof sensor_data[sd->sensor].data2);
732 static void setflip(struct gspca_dev *gspca_dev)
734 struct sd *sd = (struct sd *) gspca_dev;
736 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
741 reg_w_buf(gspca_dev, flipcmd, sizeof flipcmd);
744 static void seteffect(struct gspca_dev *gspca_dev)
746 struct sd *sd = (struct sd *) gspca_dev;
748 reg_w_buf(gspca_dev, effects_table[sd->effect],
749 sizeof effects_table[0]);
750 if (sd->effect == 1 || sd->effect == 5) {
752 "This effect have been disabled for webcam \"safety\"");
756 if (sd->effect == 1 || sd->effect == 4)
757 reg_w(gspca_dev, 0x4aa6);
759 reg_w(gspca_dev, 0xfaa6);
762 static void setlightfreq(struct gspca_dev *gspca_dev)
764 struct sd *sd = (struct sd *) gspca_dev;
765 u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
767 if (sd->freq == 2) /* 60hz */
770 reg_w_buf(gspca_dev, freq, sizeof freq);
773 /* Is this really needed?
774 * i added some module parameters for test with some users */
775 static void poll_sensor(struct gspca_dev *gspca_dev)
777 struct sd *sd = (struct sd *) gspca_dev;
778 static const u8 poll1[] =
779 {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
780 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
781 0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
783 static const u8 poll2[] =
784 {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
785 0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
786 static const u8 poll3[] =
787 {0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d};
788 static const u8 poll4[] =
789 {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
790 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
791 0xc2, 0x80, 0xc3, 0x10};
793 if (sd->sensor != SENSOR_TAS5130A) {
794 PDEBUG(D_STREAM, "[Sensor requires polling]");
795 reg_w_buf(gspca_dev, poll1, sizeof poll1);
796 reg_w_buf(gspca_dev, poll2, sizeof poll2);
797 reg_w_buf(gspca_dev, poll3, sizeof poll3);
798 reg_w_buf(gspca_dev, poll4, sizeof poll4);
802 static int sd_start(struct gspca_dev *gspca_dev)
804 struct sd *sd = (struct sd *) gspca_dev;
806 u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
807 static const u8 t3[] =
808 { 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 };
810 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
812 case 0: /* 640x480 (0x00) */
814 case 1: /* 352x288 */
817 case 2: /* 320x240 */
820 case 3: /* 176x144 */
824 /* case 4: * 160x120 */
829 if (sd->sensor == SENSOR_TAS5130A) {
831 while (tas5130a_sensor_init[i][0] != 0) {
832 reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
833 sizeof tas5130a_sensor_init[0]);
836 reg_w(gspca_dev, 0x3c80);
837 /* just in case and to keep sync with logs (for mine) */
838 reg_w_buf(gspca_dev, tas5130a_sensor_init[3],
839 sizeof tas5130a_sensor_init[0]);
840 reg_w(gspca_dev, 0x3c80);
842 om6802_sensor_init(gspca_dev);
844 reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
845 sizeof sensor_data[sd->sensor].data4);
846 reg_r(gspca_dev, 0x0012);
847 reg_w_buf(gspca_dev, t2, sizeof t2);
848 reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3);
849 reg_w(gspca_dev, 0x0013);
851 reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
852 sizeof sensor_data[sd->sensor].stream);
853 poll_sensor(gspca_dev);
855 /* restart on each start, just in case, sometimes regs goes wrong
856 * when using controls from app */
857 setbrightness(gspca_dev);
858 setcontrast(gspca_dev);
859 setcolors(gspca_dev);
863 static void sd_stopN(struct gspca_dev *gspca_dev)
865 struct sd *sd = (struct sd *) gspca_dev;
867 reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
868 sizeof sensor_data[sd->sensor].stream);
870 reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
871 sizeof sensor_data[sd->sensor].stream);
873 reg_w(gspca_dev, 0x0309);
876 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
877 struct gspca_frame *frame, /* target */
878 u8 *data, /* isoc packet */
879 int len) /* iso packet length */
881 static u8 ffd9[] = { 0xff, 0xd9 };
883 if (data[0] == 0x5a) {
884 /* Control Packet, after this came the header again,
885 * but extra bytes came in the packet before this,
886 * sometimes an EOF arrives, sometimes not... */
891 if (data[0] == 0xff && data[1] == 0xd8) {
892 /* extra bytes....., could be processed too but would be
893 * a waste of time, right now leave the application and
894 * libjpeg do it for ourserlves.. */
895 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
897 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
901 if (data[len - 2] == 0xff && data[len - 1] == 0xd9) {
902 /* Just in case, i have seen packets with the marker,
903 * other's do not include it... */
906 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
909 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
911 struct sd *sd = (struct sd *) gspca_dev;
913 sd->brightness = val;
914 if (gspca_dev->streaming)
915 setbrightness(gspca_dev);
919 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
921 struct sd *sd = (struct sd *) gspca_dev;
923 *val = sd->brightness;
927 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
929 struct sd *sd = (struct sd *) gspca_dev;
931 sd->whitebalance = val;
932 if (gspca_dev->streaming)
933 setwhitebalance(gspca_dev);
937 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
939 struct sd *sd = (struct sd *) gspca_dev;
941 *val = sd->whitebalance;
945 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val)
947 struct sd *sd = (struct sd *) gspca_dev;
950 if (gspca_dev->streaming)
955 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val)
957 struct sd *sd = (struct sd *) gspca_dev;
963 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val)
965 struct sd *sd = (struct sd *) gspca_dev;
968 if (gspca_dev->streaming)
969 seteffect(gspca_dev);
973 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val)
975 struct sd *sd = (struct sd *) gspca_dev;
981 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
983 struct sd *sd = (struct sd *) gspca_dev;
986 if (gspca_dev->streaming)
987 setcontrast(gspca_dev);
991 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
993 struct sd *sd = (struct sd *) gspca_dev;
999 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1001 struct sd *sd = (struct sd *) gspca_dev;
1004 if (gspca_dev->streaming)
1005 setcolors(gspca_dev);
1009 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1011 struct sd *sd = (struct sd *) gspca_dev;
1017 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
1019 struct sd *sd = (struct sd *) gspca_dev;
1022 if (gspca_dev->streaming)
1023 setgamma(gspca_dev);
1027 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
1029 struct sd *sd = (struct sd *) gspca_dev;
1035 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1037 struct sd *sd = (struct sd *) gspca_dev;
1040 if (gspca_dev->streaming)
1041 setlightfreq(gspca_dev);
1045 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1047 struct sd *sd = (struct sd *) gspca_dev;
1053 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
1055 struct sd *sd = (struct sd *) gspca_dev;
1057 sd->sharpness = val;
1058 if (gspca_dev->streaming)
1059 setsharpness(gspca_dev);
1063 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
1065 struct sd *sd = (struct sd *) gspca_dev;
1067 *val = sd->sharpness;
1071 /* Low Light set here......*/
1072 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
1074 struct sd *sd = (struct sd *) gspca_dev;
1078 reg_w(gspca_dev, 0xf48e);
1080 reg_w(gspca_dev, 0xb48e);
1084 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
1086 struct sd *sd = (struct sd *) gspca_dev;
1088 *val = sd->autogain;
1092 static int sd_querymenu(struct gspca_dev *gspca_dev,
1093 struct v4l2_querymenu *menu)
1096 case V4L2_CID_POWER_LINE_FREQUENCY:
1097 switch (menu->index) {
1098 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1099 strcpy((char *) menu->name, "50 Hz");
1101 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1102 strcpy((char *) menu->name, "60 Hz");
1106 case V4L2_CID_EFFECTS:
1107 if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
1108 strncpy((char *) menu->name,
1109 effects_control[menu->index], 32);
1117 /* sub-driver description */
1118 static const struct sd_desc sd_desc = {
1119 .name = MODULE_NAME,
1121 .nctrls = ARRAY_SIZE(sd_ctrls),
1122 .config = sd_config,
1126 .pkt_scan = sd_pkt_scan,
1127 .querymenu = sd_querymenu,
1130 /* -- module initialisation -- */
1131 static const __devinitdata struct usb_device_id device_table[] = {
1132 {USB_DEVICE(0x17a1, 0x0128)},
1135 MODULE_DEVICE_TABLE(usb, device_table);
1137 /* -- device connect -- */
1138 static int sd_probe(struct usb_interface *intf,
1139 const struct usb_device_id *id)
1141 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1145 static struct usb_driver sd_driver = {
1146 .name = MODULE_NAME,
1147 .id_table = device_table,
1149 .disconnect = gspca_disconnect,
1151 .suspend = gspca_suspend,
1152 .resume = gspca_resume,
1156 /* -- module insert / remove -- */
1157 static int __init sd_mod_init(void)
1160 ret = usb_register(&sd_driver);
1163 PDEBUG(D_PROBE, "registered");
1166 static void __exit sd_mod_exit(void)
1168 usb_deregister(&sd_driver);
1169 PDEBUG(D_PROBE, "deregistered");
1172 module_init(sd_mod_init);
1173 module_exit(sd_mod_exit);