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 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 #define MAX_EFFECTS 7
265 /* easily done by soft, this table could be removed,
266 * i keep it here just in case */
267 static const __u8 effects_table[MAX_EFFECTS][6] = {
268 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */
269 {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */
270 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */
271 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80}, /* Sepia */
272 {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02}, /* Croquis */
273 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10}, /* Sun Effect */
274 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */
277 static const __u8 gamma_table[GAMMA_MAX][34] = {
278 {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85, /* 0 */
279 0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9,
280 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb,
281 0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8,
283 {0x90, 0x00, 0x91, 0x33, 0x92, 0x5a, 0x93, 0x75, /* 1 */
284 0x94, 0x85, 0x95, 0x93, 0x96, 0xa1, 0x97, 0xad,
285 0x98, 0xb7, 0x99, 0xc2, 0x9a, 0xcb, 0x9b, 0xd4,
286 0x9c, 0xde, 0x9D, 0xe7, 0x9e, 0xf0, 0x9f, 0xf7,
288 {0x90, 0x00, 0x91, 0x2f, 0x92, 0x51, 0x93, 0x6b, /* 2 */
289 0x94, 0x7c, 0x95, 0x8a, 0x96, 0x99, 0x97, 0xa6,
290 0x98, 0xb1, 0x99, 0xbc, 0x9a, 0xc6, 0x9b, 0xd0,
291 0x9c, 0xdb, 0x9d, 0xe4, 0x9e, 0xed, 0x9f, 0xf6,
293 {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60, /* 3 */
294 0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9e,
295 0x98, 0xaa, 0x99, 0xb5, 0x9a, 0xbf, 0x9b, 0xcb,
296 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5,
298 {0x90, 0x00, 0x91, 0x23, 0x92, 0x3f, 0x93, 0x55, /* 4 */
299 0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95,
300 0x98, 0xa2, 0x99, 0xad, 0x9a, 0xb9, 0x9b, 0xc6,
301 0x9c, 0xd2, 0x9d, 0xde, 0x9e, 0xe9, 0x9f, 0xf4,
303 {0x90, 0x00, 0x91, 0x1b, 0x92, 0x33, 0x93, 0x48, /* 5 */
304 0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87,
305 0x98, 0x96, 0x99, 0xa3, 0x9a, 0xb1, 0x9b, 0xbe,
306 0x9c, 0xcc, 0x9d, 0xda, 0x9e, 0xe7, 0x9f, 0xf3,
308 {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20, /* 6 */
309 0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67,
310 0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa,
311 0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee,
313 {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26, /* 7 */
314 0x94, 0x38, 0x95, 0x4a, 0x96, 0x60, 0x97, 0x70,
315 0x98, 0x80, 0x99, 0x90, 0x9a, 0xa0, 0x9b, 0xb0,
316 0x9c, 0xc0, 0x9D, 0xd0, 0x9e, 0xe0, 0x9f, 0xf0,
318 {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35, /* 8 */
319 0x94, 0x47, 0x95, 0x5a, 0x96, 0x69, 0x97, 0x79,
320 0x98, 0x88, 0x99, 0x97, 0x9a, 0xa7, 0x9b, 0xb6,
321 0x9c, 0xc4, 0x9d, 0xd3, 0x9e, 0xe0, 0x9f, 0xf0,
323 {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40, /* 9 */
324 0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
325 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd,
326 0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0,
328 {0x90, 0x00, 0x91, 0x18, 0x92, 0x2b, 0x93, 0x44, /* 10 */
329 0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8e,
330 0x98, 0x9c, 0x99, 0xaa, 0x9a, 0xb7, 0x9b, 0xc4,
331 0x9c, 0xd0, 0x9d, 0xd8, 0x9e, 0xe2, 0x9f, 0xf0,
333 {0x90, 0x00, 0x91, 0x1a, 0x92, 0x34, 0x93, 0x52, /* 11 */
334 0x94, 0x66, 0x95, 0x7e, 0x96, 0x8D, 0x97, 0x9B,
335 0x98, 0xa8, 0x99, 0xb4, 0x9a, 0xc0, 0x9b, 0xcb,
336 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5,
338 {0x90, 0x00, 0x91, 0x3f, 0x92, 0x5a, 0x93, 0x6e, /* 12 */
339 0x94, 0x7f, 0x95, 0x8e, 0x96, 0x9c, 0x97, 0xa8,
340 0x98, 0xb4, 0x99, 0xbf, 0x9a, 0xc9, 0x9b, 0xd3,
341 0x9c, 0xdc, 0x9d, 0xe5, 0x9e, 0xee, 0x9f, 0xf6,
343 {0x90, 0x00, 0x91, 0x54, 0x92, 0x6f, 0x93, 0x83, /* 13 */
344 0x94, 0x93, 0x95, 0xa0, 0x96, 0xad, 0x97, 0xb7,
345 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdc,
346 0x9c, 0xe4, 0x9d, 0xeb, 0x9e, 0xf2, 0x9f, 0xf9,
348 {0x90, 0x00, 0x91, 0x6e, 0x92, 0x88, 0x93, 0x9a, /* 14 */
349 0x94, 0xa8, 0x95, 0xb3, 0x96, 0xbd, 0x97, 0xc6,
350 0x98, 0xcf, 0x99, 0xd6, 0x9a, 0xdd, 0x9b, 0xe3,
351 0x9c, 0xe9, 0x9d, 0xef, 0x9e, 0xf4, 0x9f, 0xfa,
353 {0x90, 0x00, 0x91, 0x93, 0x92, 0xa8, 0x93, 0xb7, /* 15 */
354 0x94, 0xc1, 0x95, 0xca, 0x96, 0xd2, 0x97, 0xd8,
355 0x98, 0xde, 0x99, 0xe3, 0x9a, 0xe8, 0x9b, 0xed,
356 0x9c, 0xf1, 0x9d, 0xf5, 0x9e, 0xf8, 0x9f, 0xfc,
360 static const __u8 tas5130a_sensor_init[][8] = {
361 {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
362 {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
363 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
364 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
368 static __u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
371 static int reg_r(struct gspca_dev *gspca_dev,
374 usb_control_msg(gspca_dev->dev,
375 usb_rcvctrlpipe(gspca_dev->dev, 0),
377 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
380 gspca_dev->usb_buf, 1, 500);
381 return gspca_dev->usb_buf[0];
384 static void reg_w(struct gspca_dev *gspca_dev,
387 usb_control_msg(gspca_dev->dev,
388 usb_sndctrlpipe(gspca_dev->dev, 0),
390 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
395 static void reg_w_buf(struct gspca_dev *gspca_dev,
396 const __u8 *buffer, __u16 len)
398 if (len <= USB_BUF_SZ) {
399 memcpy(gspca_dev->usb_buf, buffer, len);
400 usb_control_msg(gspca_dev->dev,
401 usb_sndctrlpipe(gspca_dev->dev, 0),
403 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
405 gspca_dev->usb_buf, len, 500);
409 tmpbuf = kmalloc(len, GFP_KERNEL);
410 memcpy(tmpbuf, buffer, len);
411 usb_control_msg(gspca_dev->dev,
412 usb_sndctrlpipe(gspca_dev->dev, 0),
414 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
421 /* Reported as OM6802*/
422 static void om6802_sensor_init(struct gspca_dev *gspca_dev)
427 __u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
428 static const __u8 sensor_init[] = {
446 reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
450 byte = reg_r(gspca_dev, 0x0060);
455 byte = reg_r(gspca_dev, 0x0063);
457 err("Bad sensor reset %02x", byte);
466 reg_w(gspca_dev, 0x3c80);
467 reg_w_buf(gspca_dev, val, sizeof val);
471 byte = reg_r(gspca_dev, 0x60);
477 reg_w(gspca_dev, 0x3c80);
480 /* this function is called at probe time */
481 static int sd_config(struct gspca_dev *gspca_dev,
482 const struct usb_device_id *id)
484 struct sd *sd = (struct sd *) gspca_dev;
487 cam = &gspca_dev->cam;
490 cam->cam_mode = vga_mode_t16;
491 cam->nmodes = ARRAY_SIZE(vga_mode_t16);
493 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
494 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
495 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
496 sd->gamma = GAMMA_DEF;
497 sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value;
498 sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value;
499 sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value;
500 sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
501 sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value;
505 static void setbrightness(struct gspca_dev *gspca_dev)
507 struct sd *sd = (struct sd *) gspca_dev;
508 unsigned int brightness;
509 __u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
511 brightness = sd->brightness;
512 if (brightness < 7) {
514 set6[3] = 0x70 - brightness * 0x10;
516 set6[3] = 0x00 + ((brightness - 7) * 0x10);
519 reg_w_buf(gspca_dev, set6, sizeof set6);
522 static void setcontrast(struct gspca_dev *gspca_dev)
524 struct sd *sd = (struct sd *) gspca_dev;
525 unsigned int contrast = sd->contrast;
529 reg_to_write = 0x8ea9 - contrast * 0x200;
531 reg_to_write = 0x00a9 + (contrast - 7) * 0x200;
533 reg_w(gspca_dev, reg_to_write);
536 static void setcolors(struct gspca_dev *gspca_dev)
538 struct sd *sd = (struct sd *) gspca_dev;
541 reg_to_write = 0x80bb + sd->colors * 0x100; /* was 0xc0 */
542 reg_w(gspca_dev, reg_to_write);
545 static void setgamma(struct gspca_dev *gspca_dev)
547 struct sd *sd = (struct sd *) gspca_dev;
549 PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
550 reg_w_buf(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]);
553 static void setwhitebalance(struct gspca_dev *gspca_dev)
555 struct sd *sd = (struct sd *) gspca_dev;
557 __u8 white_balance[8] =
558 {0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38};
560 if (sd->whitebalance)
561 white_balance[7] = 0x3c;
563 reg_w_buf(gspca_dev, white_balance, sizeof white_balance);
566 static void setsharpness(struct gspca_dev *gspca_dev)
568 struct sd *sd = (struct sd *) gspca_dev;
571 reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
573 reg_w(gspca_dev, reg_to_write);
576 /* this function is called at probe and resume time */
577 static int sd_init(struct gspca_dev *gspca_dev)
579 /* some of this registers are not really neded, because
580 * they are overriden by setbrigthness, setcontrast, etc,
581 * but wont hurt anyway, and can help someone with similar webcam
582 * to see the initial parameters.*/
583 struct sd *sd = (struct sd *) gspca_dev;
585 __u8 byte, test_byte;
587 static const __u8 read_indexs[] =
588 { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
589 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 };
590 static const __u8 n1[] =
591 {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
592 static const __u8 n2[] =
594 static const __u8 n3[] =
595 {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
596 static const __u8 n4[] =
597 {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
598 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
599 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
600 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
601 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
602 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
603 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
604 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
605 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
606 static const __u8 nset4[] = {
607 0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, 0xe4, 0xa8,
608 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
611 /* ojo puede ser 0xe6 en vez de 0xe9 */
612 static const __u8 nset2[] = {
613 0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, 0xd4, 0xbb,
614 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
615 0xd8, 0xc8, 0xd9, 0xfc
617 static const __u8 nset3[] = {
618 0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, 0xcb, 0xa8,
619 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
622 static const __u8 nset5[] =
623 { 0x8f, 0x24, 0xc3, 0x00 }; /* bright */
624 static const __u8 nset7[4] =
625 { 0x66, 0xca, 0xa8, 0xf8 }; /* 50/60 Hz */
626 static const __u8 nset9[4] =
627 { 0x0b, 0x04, 0x0a, 0x78 };
628 static const __u8 nset8[6] =
629 { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
630 static const __u8 nset10[6] =
631 { 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 };
633 byte = reg_r(gspca_dev, 0x06);
634 test_byte = reg_r(gspca_dev, 0x07);
635 if (byte == 0x08 && test_byte == 0x07) {
636 PDEBUG(D_CONF, "sensor om6802");
637 sd->sensor = SENSOR_OM6802;
638 } else if (byte == 0x08 && test_byte == 0x01) {
639 PDEBUG(D_CONF, "sensor tas5130a");
640 sd->sensor = SENSOR_TAS5130A;
642 PDEBUG(D_CONF, "unknown sensor %02x %02x", byte, test_byte);
643 sd->sensor = SENSOR_TAS5130A;
646 reg_w_buf(gspca_dev, n1, sizeof n1);
650 reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
651 test_byte = reg_r(gspca_dev, 0x0063);
653 if (test_byte == 0x17)
657 err("Bad sensor reset %02x", test_byte);
659 /*fixme: test - continue */
661 reg_w_buf(gspca_dev, n2, sizeof n2);
664 while (read_indexs[i] != 0x00) {
665 test_byte = reg_r(gspca_dev, read_indexs[i]);
666 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i],
671 reg_w_buf(gspca_dev, n3, sizeof n3);
672 reg_w_buf(gspca_dev, n4, sizeof n4);
673 reg_r(gspca_dev, 0x0080);
674 reg_w(gspca_dev, 0x2c80);
675 reg_w_buf(gspca_dev, nset2, sizeof nset2);
676 reg_w_buf(gspca_dev, nset3, sizeof nset3);
677 reg_w_buf(gspca_dev, nset4, sizeof nset4);
678 reg_w(gspca_dev, 0x3880);
679 reg_w(gspca_dev, 0x3880);
680 reg_w(gspca_dev, 0x338e);
682 setbrightness(gspca_dev);
683 setcontrast(gspca_dev);
685 setcolors(gspca_dev);
686 setsharpness(gspca_dev);
687 setwhitebalance(gspca_dev);
689 reg_w(gspca_dev, 0x2087); /* tied to white balance? */
690 reg_w(gspca_dev, 0x2088);
691 reg_w(gspca_dev, 0x2089);
693 reg_w_buf(gspca_dev, nset7, sizeof nset7);
694 reg_w_buf(gspca_dev, nset10, sizeof nset10);
695 reg_w_buf(gspca_dev, nset8, sizeof nset8);
696 reg_w_buf(gspca_dev, nset9, sizeof nset9);
698 reg_w(gspca_dev, 0x2880);
699 reg_w_buf(gspca_dev, nset2, sizeof nset2);
700 reg_w_buf(gspca_dev, nset3, sizeof nset3);
701 reg_w_buf(gspca_dev, nset4, sizeof nset4);
706 static void setflip(struct gspca_dev *gspca_dev)
708 struct sd *sd = (struct sd *) gspca_dev;
710 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
715 reg_w_buf(gspca_dev, flipcmd, sizeof flipcmd);
718 static void seteffect(struct gspca_dev *gspca_dev)
720 struct sd *sd = (struct sd *) gspca_dev;
722 reg_w_buf(gspca_dev, effects_table[sd->effect],
723 sizeof effects_table[0]);
724 if (sd->effect == 1 || sd->effect == 5) {
726 "This effect have been disabled for webcam \"safety\"");
730 if (sd->effect == 1 || sd->effect == 4)
731 reg_w(gspca_dev, 0x4aa6);
733 reg_w(gspca_dev, 0xfaa6);
736 static void setlightfreq(struct gspca_dev *gspca_dev)
738 struct sd *sd = (struct sd *) gspca_dev;
739 __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
741 if (sd->freq == 2) /* 60hz */
744 reg_w_buf(gspca_dev, freq, sizeof freq);
747 static int sd_start(struct gspca_dev *gspca_dev)
749 struct sd *sd = (struct sd *) gspca_dev;
751 static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 };
752 __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
753 static const __u8 t3[] =
754 { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
755 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
756 static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 };
758 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
760 case 1: /* 352x288 */
763 case 2: /* 320x240 */
766 case 3: /* 176x144 */
769 case 4: /* 160x120 */
772 default: /* 640x480 (0x00) */
776 if (sd->sensor == SENSOR_TAS5130A) {
778 while (tas5130a_sensor_init[i][0] != 0) {
779 reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
780 sizeof tas5130a_sensor_init[0]);
783 reg_w(gspca_dev, 0x3c80);
784 /* just in case and to keep sync with logs (for mine) */
785 reg_w_buf(gspca_dev, tas5130a_sensor_init[3],
786 sizeof tas5130a_sensor_init[0]);
787 reg_w(gspca_dev, 0x3c80);
789 om6802_sensor_init(gspca_dev);
791 /* just in case and to keep sync with logs (for mine) */
792 reg_w_buf(gspca_dev, t1, sizeof t1);
793 reg_w_buf(gspca_dev, t2, sizeof t2);
794 reg_r(gspca_dev, 0x0012);
795 reg_w_buf(gspca_dev, t3, sizeof t3);
796 reg_w(gspca_dev, 0x0013);
797 reg_w_buf(gspca_dev, t4, sizeof t4);
798 /* restart on each start, just in case, sometimes regs goes wrong
799 * when using controls from app */
800 setbrightness(gspca_dev);
801 setcontrast(gspca_dev);
802 setcolors(gspca_dev);
806 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
807 struct gspca_frame *frame, /* target */
808 __u8 *data, /* isoc packet */
809 int len) /* iso packet length */
811 static __u8 ffd9[] = { 0xff, 0xd9 };
813 if (data[0] == 0x5a) {
814 /* Control Packet, after this came the header again,
815 * but extra bytes came in the packet before this,
816 * sometimes an EOF arrives, sometimes not... */
821 if (data[0] == 0xff && data[1] == 0xd8) {
822 /* extra bytes....., could be processed too but would be
823 * a waste of time, right now leave the application and
824 * libjpeg do it for ourserlves.. */
825 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
827 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
831 if (data[len - 2] == 0xff && data[len - 1] == 0xd9) {
832 /* Just in case, i have seen packets with the marker,
833 * other's do not include it... */
836 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
839 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
841 struct sd *sd = (struct sd *) gspca_dev;
843 sd->brightness = val;
844 if (gspca_dev->streaming)
845 setbrightness(gspca_dev);
849 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
851 struct sd *sd = (struct sd *) gspca_dev;
853 *val = sd->brightness;
857 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
859 struct sd *sd = (struct sd *) gspca_dev;
861 sd->whitebalance = val;
862 if (gspca_dev->streaming)
863 setwhitebalance(gspca_dev);
867 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
869 struct sd *sd = (struct sd *) gspca_dev;
871 *val = sd->whitebalance;
875 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val)
877 struct sd *sd = (struct sd *) gspca_dev;
880 if (gspca_dev->streaming)
885 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val)
887 struct sd *sd = (struct sd *) gspca_dev;
893 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val)
895 struct sd *sd = (struct sd *) gspca_dev;
898 if (gspca_dev->streaming)
899 seteffect(gspca_dev);
903 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val)
905 struct sd *sd = (struct sd *) gspca_dev;
911 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
913 struct sd *sd = (struct sd *) gspca_dev;
916 if (gspca_dev->streaming)
917 setcontrast(gspca_dev);
921 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
923 struct sd *sd = (struct sd *) gspca_dev;
929 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
931 struct sd *sd = (struct sd *) gspca_dev;
934 if (gspca_dev->streaming)
935 setcolors(gspca_dev);
939 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
941 struct sd *sd = (struct sd *) gspca_dev;
947 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
949 struct sd *sd = (struct sd *) gspca_dev;
952 if (gspca_dev->streaming)
957 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
959 struct sd *sd = (struct sd *) gspca_dev;
965 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
967 struct sd *sd = (struct sd *) gspca_dev;
970 if (gspca_dev->streaming)
971 setlightfreq(gspca_dev);
975 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
977 struct sd *sd = (struct sd *) gspca_dev;
983 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
985 struct sd *sd = (struct sd *) gspca_dev;
988 if (gspca_dev->streaming)
989 setsharpness(gspca_dev);
993 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
995 struct sd *sd = (struct sd *) gspca_dev;
997 *val = sd->sharpness;
1001 /* Low Light set here......*/
1002 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
1004 struct sd *sd = (struct sd *) gspca_dev;
1008 reg_w(gspca_dev, 0xf48e);
1010 reg_w(gspca_dev, 0xb48e);
1014 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
1016 struct sd *sd = (struct sd *) gspca_dev;
1018 *val = sd->autogain;
1022 static int sd_querymenu(struct gspca_dev *gspca_dev,
1023 struct v4l2_querymenu *menu)
1026 case V4L2_CID_POWER_LINE_FREQUENCY:
1027 switch (menu->index) {
1028 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1029 strcpy((char *) menu->name, "50 Hz");
1031 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1032 strcpy((char *) menu->name, "60 Hz");
1036 case V4L2_CID_EFFECTS:
1037 if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
1038 strncpy((char *) menu->name,
1039 effects_control[menu->index], 32);
1047 /* sub-driver description */
1048 static const struct sd_desc sd_desc = {
1049 .name = MODULE_NAME,
1051 .nctrls = ARRAY_SIZE(sd_ctrls),
1052 .config = sd_config,
1055 .pkt_scan = sd_pkt_scan,
1056 .querymenu = sd_querymenu,
1059 /* -- module initialisation -- */
1060 static const __devinitdata struct usb_device_id device_table[] = {
1061 {USB_DEVICE(0x17a1, 0x0128)},
1064 MODULE_DEVICE_TABLE(usb, device_table);
1066 /* -- device connect -- */
1067 static int sd_probe(struct usb_interface *intf,
1068 const struct usb_device_id *id)
1070 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1074 static struct usb_driver sd_driver = {
1075 .name = MODULE_NAME,
1076 .id_table = device_table,
1078 .disconnect = gspca_disconnect,
1080 .suspend = gspca_suspend,
1081 .resume = gspca_resume,
1085 /* -- module insert / remove -- */
1086 static int __init sd_mod_init(void)
1088 if (usb_register(&sd_driver) < 0)
1090 PDEBUG(D_PROBE, "registered");
1093 static void __exit sd_mod_exit(void)
1095 usb_deregister(&sd_driver);
1096 PDEBUG(D_PROBE, "deregistered");
1099 module_init(sd_mod_init);
1100 module_exit(sd_mod_exit);