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 /* 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;
543 cam->cam_mode = vga_mode_t16;
544 cam->nmodes = ARRAY_SIZE(vga_mode_t16);
546 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
547 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
548 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
549 sd->gamma = GAMMA_DEF;
550 sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value;
551 sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value;
552 sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value;
553 sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
554 sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value;
558 static void setbrightness(struct gspca_dev *gspca_dev)
560 struct sd *sd = (struct sd *) gspca_dev;
561 unsigned int brightness;
562 __u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
564 brightness = sd->brightness;
565 if (brightness < 7) {
567 set6[3] = 0x70 - brightness * 0x10;
569 set6[3] = 0x00 + ((brightness - 7) * 0x10);
572 reg_w_buf(gspca_dev, set6, sizeof set6);
575 static void setcontrast(struct gspca_dev *gspca_dev)
577 struct sd *sd = (struct sd *) gspca_dev;
578 unsigned int contrast = sd->contrast;
582 reg_to_write = 0x8ea9 - contrast * 0x200;
584 reg_to_write = 0x00a9 + (contrast - 7) * 0x200;
586 reg_w(gspca_dev, reg_to_write);
589 static void setcolors(struct gspca_dev *gspca_dev)
591 struct sd *sd = (struct sd *) gspca_dev;
594 reg_to_write = 0x80bb + sd->colors * 0x100; /* was 0xc0 */
595 reg_w(gspca_dev, reg_to_write);
598 static void setgamma(struct gspca_dev *gspca_dev)
600 struct sd *sd = (struct sd *) gspca_dev;
602 PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
603 reg_w_buf(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]);
606 static void setwhitebalance(struct gspca_dev *gspca_dev)
608 struct sd *sd = (struct sd *) gspca_dev;
610 __u8 white_balance[8] =
611 {0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38};
613 if (sd->whitebalance)
614 white_balance[7] = 0x3c;
616 reg_w_buf(gspca_dev, white_balance, sizeof white_balance);
619 static void setsharpness(struct gspca_dev *gspca_dev)
621 struct sd *sd = (struct sd *) gspca_dev;
624 reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
626 reg_w(gspca_dev, reg_to_write);
629 /* this function is called at probe and resume time */
630 static int sd_init(struct gspca_dev *gspca_dev)
632 /* some of this registers are not really neded, because
633 * they are overriden by setbrigthness, setcontrast, etc,
634 * but wont hurt anyway, and can help someone with similar webcam
635 * to see the initial parameters.*/
636 struct sd *sd = (struct sd *) gspca_dev;
638 __u8 byte, test_byte;
640 static const __u8 read_indexs[] =
641 { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
642 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 };
643 static const __u8 n1[] =
644 {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
645 static const __u8 n2[] =
647 static const __u8 n3[] =
648 {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
649 static const __u8 n4[] =
650 {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
651 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
652 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
653 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
654 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
655 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
656 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
657 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
658 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
659 static const __u8 nset9[4] =
660 { 0x0b, 0x04, 0x0a, 0x78 };
661 static const __u8 nset8[6] =
662 { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
664 byte = reg_r(gspca_dev, 0x06);
665 test_byte = reg_r(gspca_dev, 0x07);
666 if (byte == 0x08 && test_byte == 0x07) {
667 PDEBUG(D_CONF, "sensor om6802");
668 sd->sensor = SENSOR_OM6802;
669 } else if (byte == 0x08 && test_byte == 0x01) {
670 PDEBUG(D_CONF, "sensor tas5130a");
671 sd->sensor = SENSOR_TAS5130A;
673 PDEBUG(D_CONF, "unknown sensor %02x %02x", byte, test_byte);
674 sd->sensor = SENSOR_TAS5130A;
677 reg_w_buf(gspca_dev, n1, sizeof n1);
681 reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
682 test_byte = reg_r(gspca_dev, 0x0063);
684 if (test_byte == 0x17)
688 err("Bad sensor reset %02x", test_byte);
690 /*fixme: test - continue */
692 reg_w_buf(gspca_dev, n2, sizeof n2);
695 while (read_indexs[i] != 0x00) {
696 test_byte = reg_r(gspca_dev, read_indexs[i]);
697 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i],
702 reg_w_buf(gspca_dev, n3, sizeof n3);
703 reg_w_buf(gspca_dev, n4, sizeof n4);
704 reg_r(gspca_dev, 0x0080);
705 reg_w(gspca_dev, 0x2c80);
707 reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,
708 sizeof sensor_data[sd->sensor].data1);
709 reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,
710 sizeof sensor_data[sd->sensor].data3);
711 reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,
712 sizeof sensor_data[sd->sensor].data2);
714 reg_w(gspca_dev, 0x3880);
715 reg_w(gspca_dev, 0x3880);
716 reg_w(gspca_dev, 0x338e);
718 setbrightness(gspca_dev);
719 setcontrast(gspca_dev);
721 setcolors(gspca_dev);
722 setsharpness(gspca_dev);
723 setwhitebalance(gspca_dev);
725 reg_w(gspca_dev, 0x2087); /* tied to white balance? */
726 reg_w(gspca_dev, 0x2088);
727 reg_w(gspca_dev, 0x2089);
729 reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
730 sizeof sensor_data[sd->sensor].data4);
731 reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5,
732 sizeof sensor_data[sd->sensor].data5);
733 reg_w_buf(gspca_dev, nset8, sizeof nset8);
734 reg_w_buf(gspca_dev, nset9, sizeof nset9);
736 reg_w(gspca_dev, 0x2880);
738 reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,
739 sizeof sensor_data[sd->sensor].data1);
740 reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,
741 sizeof sensor_data[sd->sensor].data3);
742 reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,
743 sizeof sensor_data[sd->sensor].data2);
748 static void setflip(struct gspca_dev *gspca_dev)
750 struct sd *sd = (struct sd *) gspca_dev;
752 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
757 reg_w_buf(gspca_dev, flipcmd, sizeof flipcmd);
760 static void seteffect(struct gspca_dev *gspca_dev)
762 struct sd *sd = (struct sd *) gspca_dev;
764 reg_w_buf(gspca_dev, effects_table[sd->effect],
765 sizeof effects_table[0]);
766 if (sd->effect == 1 || sd->effect == 5) {
768 "This effect have been disabled for webcam \"safety\"");
772 if (sd->effect == 1 || sd->effect == 4)
773 reg_w(gspca_dev, 0x4aa6);
775 reg_w(gspca_dev, 0xfaa6);
778 static void setlightfreq(struct gspca_dev *gspca_dev)
780 struct sd *sd = (struct sd *) gspca_dev;
781 __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
783 if (sd->freq == 2) /* 60hz */
786 reg_w_buf(gspca_dev, freq, sizeof freq);
789 /* Is this really needed?
790 * i added some module parameters for test with some users */
791 static void poll_sensor(struct gspca_dev *gspca_dev)
793 struct sd *sd = (struct sd *) gspca_dev;
794 static const __u8 poll1[] =
795 {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
796 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
797 0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
799 static const __u8 poll2[] =
800 {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
801 0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
802 static const __u8 poll3[] =
803 {0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d};
804 static const __u8 poll4[] =
805 {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
806 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
807 0xc2, 0x80, 0xc3, 0x10};
809 if (sd->sensor != SENSOR_TAS5130A) {
810 PDEBUG(D_STREAM, "[Sensor requires polling]");
811 reg_w_buf(gspca_dev, poll1, sizeof poll1);
812 reg_w_buf(gspca_dev, poll2, sizeof poll2);
813 reg_w_buf(gspca_dev, poll3, sizeof poll3);
814 reg_w_buf(gspca_dev, poll4, sizeof poll4);
818 static int sd_start(struct gspca_dev *gspca_dev)
820 struct sd *sd = (struct sd *) gspca_dev;
822 __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
823 static const __u8 t3[] =
824 { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
825 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
827 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
829 case 1: /* 352x288 */
832 case 2: /* 320x240 */
835 case 3: /* 176x144 */
838 case 4: /* 160x120 */
841 default: /* 640x480 (0x00) */
845 if (sd->sensor == SENSOR_TAS5130A) {
847 while (tas5130a_sensor_init[i][0] != 0) {
848 reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
849 sizeof tas5130a_sensor_init[0]);
852 reg_w(gspca_dev, 0x3c80);
853 /* just in case and to keep sync with logs (for mine) */
854 reg_w_buf(gspca_dev, tas5130a_sensor_init[3],
855 sizeof tas5130a_sensor_init[0]);
856 reg_w(gspca_dev, 0x3c80);
858 om6802_sensor_init(gspca_dev);
860 reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
861 sizeof sensor_data[sd->sensor].data4);
862 reg_r(gspca_dev, 0x0012);
863 reg_w_buf(gspca_dev, t2, sizeof t2);
864 reg_w_buf(gspca_dev, t3, sizeof t3);
865 reg_w(gspca_dev, 0x0013);
867 reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
868 sizeof sensor_data[sd->sensor].stream);
869 poll_sensor(gspca_dev);
871 /* restart on each start, just in case, sometimes regs goes wrong
872 * when using controls from app */
873 setbrightness(gspca_dev);
874 setcontrast(gspca_dev);
875 setcolors(gspca_dev);
879 static void sd_stopN(struct gspca_dev *gspca_dev)
881 struct sd *sd = (struct sd *) gspca_dev;
883 reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
884 sizeof sensor_data[sd->sensor].stream);
886 reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
887 sizeof sensor_data[sd->sensor].stream);
889 reg_w(gspca_dev, 0x0309);
892 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
893 struct gspca_frame *frame, /* target */
894 __u8 *data, /* isoc packet */
895 int len) /* iso packet length */
897 static __u8 ffd9[] = { 0xff, 0xd9 };
899 if (data[0] == 0x5a) {
900 /* Control Packet, after this came the header again,
901 * but extra bytes came in the packet before this,
902 * sometimes an EOF arrives, sometimes not... */
907 if (data[0] == 0xff && data[1] == 0xd8) {
908 /* extra bytes....., could be processed too but would be
909 * a waste of time, right now leave the application and
910 * libjpeg do it for ourserlves.. */
911 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
913 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
917 if (data[len - 2] == 0xff && data[len - 1] == 0xd9) {
918 /* Just in case, i have seen packets with the marker,
919 * other's do not include it... */
922 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
925 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
927 struct sd *sd = (struct sd *) gspca_dev;
929 sd->brightness = val;
930 if (gspca_dev->streaming)
931 setbrightness(gspca_dev);
935 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
937 struct sd *sd = (struct sd *) gspca_dev;
939 *val = sd->brightness;
943 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
945 struct sd *sd = (struct sd *) gspca_dev;
947 sd->whitebalance = val;
948 if (gspca_dev->streaming)
949 setwhitebalance(gspca_dev);
953 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
955 struct sd *sd = (struct sd *) gspca_dev;
957 *val = sd->whitebalance;
961 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val)
963 struct sd *sd = (struct sd *) gspca_dev;
966 if (gspca_dev->streaming)
971 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val)
973 struct sd *sd = (struct sd *) gspca_dev;
979 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val)
981 struct sd *sd = (struct sd *) gspca_dev;
984 if (gspca_dev->streaming)
985 seteffect(gspca_dev);
989 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val)
991 struct sd *sd = (struct sd *) gspca_dev;
997 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
999 struct sd *sd = (struct sd *) gspca_dev;
1002 if (gspca_dev->streaming)
1003 setcontrast(gspca_dev);
1007 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1009 struct sd *sd = (struct sd *) gspca_dev;
1011 *val = sd->contrast;
1015 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1017 struct sd *sd = (struct sd *) gspca_dev;
1020 if (gspca_dev->streaming)
1021 setcolors(gspca_dev);
1025 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1027 struct sd *sd = (struct sd *) gspca_dev;
1033 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
1035 struct sd *sd = (struct sd *) gspca_dev;
1038 if (gspca_dev->streaming)
1039 setgamma(gspca_dev);
1043 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
1045 struct sd *sd = (struct sd *) gspca_dev;
1051 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1053 struct sd *sd = (struct sd *) gspca_dev;
1056 if (gspca_dev->streaming)
1057 setlightfreq(gspca_dev);
1061 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1063 struct sd *sd = (struct sd *) gspca_dev;
1069 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
1071 struct sd *sd = (struct sd *) gspca_dev;
1073 sd->sharpness = val;
1074 if (gspca_dev->streaming)
1075 setsharpness(gspca_dev);
1079 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
1081 struct sd *sd = (struct sd *) gspca_dev;
1083 *val = sd->sharpness;
1087 /* Low Light set here......*/
1088 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
1090 struct sd *sd = (struct sd *) gspca_dev;
1094 reg_w(gspca_dev, 0xf48e);
1096 reg_w(gspca_dev, 0xb48e);
1100 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
1102 struct sd *sd = (struct sd *) gspca_dev;
1104 *val = sd->autogain;
1108 static int sd_querymenu(struct gspca_dev *gspca_dev,
1109 struct v4l2_querymenu *menu)
1112 case V4L2_CID_POWER_LINE_FREQUENCY:
1113 switch (menu->index) {
1114 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1115 strcpy((char *) menu->name, "50 Hz");
1117 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1118 strcpy((char *) menu->name, "60 Hz");
1122 case V4L2_CID_EFFECTS:
1123 if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
1124 strncpy((char *) menu->name,
1125 effects_control[menu->index], 32);
1133 /* sub-driver description */
1134 static const struct sd_desc sd_desc = {
1135 .name = MODULE_NAME,
1137 .nctrls = ARRAY_SIZE(sd_ctrls),
1138 .config = sd_config,
1142 .pkt_scan = sd_pkt_scan,
1143 .querymenu = sd_querymenu,
1146 /* -- module initialisation -- */
1147 static const __devinitdata struct usb_device_id device_table[] = {
1148 {USB_DEVICE(0x17a1, 0x0128)},
1151 MODULE_DEVICE_TABLE(usb, device_table);
1153 /* -- device connect -- */
1154 static int sd_probe(struct usb_interface *intf,
1155 const struct usb_device_id *id)
1157 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1161 static struct usb_driver sd_driver = {
1162 .name = MODULE_NAME,
1163 .id_table = device_table,
1165 .disconnect = gspca_disconnect,
1167 .suspend = gspca_suspend,
1168 .resume = gspca_resume,
1172 /* -- module insert / remove -- */
1173 static int __init sd_mod_init(void)
1175 if (usb_register(&sd_driver) < 0)
1177 PDEBUG(D_PROBE, "registered");
1180 static void __exit sd_mod_exit(void)
1182 usb_deregister(&sd_driver);
1183 PDEBUG(D_PROBE, "deregistered");
1186 module_init(sd_mod_init);
1187 module_exit(sd_mod_exit);