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 MAX_GAMMA 0x10 /* 0 to 15 */
33 #define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 3)
35 MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
36 MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver");
37 MODULE_LICENSE("GPL");
40 struct gspca_dev gspca_dev; /* !! must be the first item */
42 unsigned char brightness;
43 unsigned char contrast;
45 unsigned char autogain;
47 unsigned char sharpness;
49 unsigned char whitebalance;
54 /* V4L2 controls supported by the driver */
55 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
56 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
57 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
58 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
59 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
60 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
61 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val);
62 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val);
63 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
64 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
65 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
66 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
67 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
68 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
69 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val);
70 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val);
71 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val);
72 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val);
73 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val);
74 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val);
75 static int sd_querymenu(struct gspca_dev *gspca_dev,
76 struct v4l2_querymenu *menu);
78 static struct ctrl sd_ctrls[] = {
79 #define SD_BRIGHTNESS 0
82 .id = V4L2_CID_BRIGHTNESS,
83 .type = V4L2_CTRL_TYPE_INTEGER,
88 .default_value = 0x09,
90 .set = sd_setbrightness,
91 .get = sd_getbrightness,
96 .id = V4L2_CID_CONTRAST,
97 .type = V4L2_CTRL_TYPE_INTEGER,
102 .default_value = 0x07,
104 .set = sd_setcontrast,
105 .get = sd_getcontrast,
110 .id = V4L2_CID_SATURATION,
111 .type = V4L2_CTRL_TYPE_INTEGER,
116 .default_value = 0x05,
124 .id = V4L2_CID_GAMMA, /* (gamma on win) */
125 .type = V4L2_CTRL_TYPE_INTEGER,
126 .name = "Gamma (Untested)",
128 .maximum = MAX_GAMMA,
130 .default_value = 0x09,
135 #define SD_AUTOGAIN 4
138 .id = V4L2_CID_GAIN, /* here, i activate only the lowlight,
139 * some apps dont bring up the
140 * backligth_compensation control) */
141 .type = V4L2_CTRL_TYPE_INTEGER,
146 .default_value = 0x01,
148 .set = sd_setlowlight,
149 .get = sd_getlowlight,
154 .id = V4L2_CID_HFLIP,
155 .type = V4L2_CTRL_TYPE_BOOLEAN,
156 .name = "Mirror Image",
165 #define SD_LIGHTFREQ 6
168 .id = V4L2_CID_POWER_LINE_FREQUENCY,
169 .type = V4L2_CTRL_TYPE_MENU,
170 .name = "Light Frequency Filter",
171 .minimum = 1, /* 1 -> 0x50, 2->0x60 */
179 #define SD_WHITE_BALANCE 7
182 .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
183 .type = V4L2_CTRL_TYPE_INTEGER,
184 .name = "White Balance",
190 .set = sd_setwhitebalance,
191 .get = sd_getwhitebalance
193 #define SD_SHARPNESS 8 /* (aka definition on win) */
196 .id = V4L2_CID_SHARPNESS,
197 .type = V4L2_CTRL_TYPE_INTEGER,
200 .maximum = MAX_GAMMA, /* 0 to 16 */
202 .default_value = 0x06,
204 .set = sd_setsharpness,
205 .get = sd_getsharpness,
210 .id = V4L2_CID_EFFECTS,
211 .type = V4L2_CTRL_TYPE_MENU,
212 .name = "Webcam Effects",
223 static char *effects_control[] = {
225 "Emboss", /* disabled */
229 "Sun Effect", /* disabled */
233 static struct v4l2_pix_format vga_mode_t16[] = {
234 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
236 .sizeimage = 160 * 120 * 3 / 8 + 590,
237 .colorspace = V4L2_COLORSPACE_JPEG,
239 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
241 .sizeimage = 176 * 144 * 3 / 8 + 590,
242 .colorspace = V4L2_COLORSPACE_JPEG,
244 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
246 .sizeimage = 320 * 240 * 3 / 8 + 590,
247 .colorspace = V4L2_COLORSPACE_JPEG,
249 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
251 .sizeimage = 352 * 288 * 3 / 8 + 590,
252 .colorspace = V4L2_COLORSPACE_JPEG,
254 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
256 .sizeimage = 640 * 480 * 3 / 8 + 590,
257 .colorspace = V4L2_COLORSPACE_JPEG,
261 #define T16_OFFSET_DATA 631
262 #define MAX_EFFECTS 7
263 /* easily done by soft, this table could be removed,
264 * i keep it here just in case */
265 static const __u8 effects_table[MAX_EFFECTS][6] = {
266 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */
267 {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */
268 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */
269 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80}, /* Sepia */
270 {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02}, /* Croquis */
271 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10}, /* Sun Effect */
272 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */
275 static const __u8 gamma_table[MAX_GAMMA][34] = {
276 {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85,
277 0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9,
278 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb,
279 0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8,
281 {0x90, 0x00, 0x91, 0x33, 0x92, 0x5A, 0x93, 0x75,
282 0x94, 0x85, 0x95, 0x93, 0x96, 0xA1, 0x97, 0xAD,
283 0x98, 0xB7, 0x99, 0xC2, 0x9A, 0xCB, 0x9B, 0xD4,
284 0x9C, 0xDE, 0x9D, 0xE7, 0x9E, 0xF0, 0x9F, 0xF7,
286 {0x90, 0x00, 0x91, 0x2F, 0x92, 0x51, 0x93, 0x6B,
287 0x94, 0x7C, 0x95, 0x8A, 0x96, 0x99, 0x97, 0xA6,
288 0x98, 0xB1, 0x99, 0xBC, 0x9A, 0xC6, 0x9B, 0xD0,
289 0x9C, 0xDB, 0x9D, 0xE4, 0x9E, 0xED, 0x9F, 0xF6,
291 {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60,
292 0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9E,
293 0x98, 0xAA, 0x99, 0xB5, 0x9A, 0xBF, 0x9B, 0xCB,
294 0x9C, 0xD6, 0x9D, 0xE1, 0x9E, 0xEB, 0x9F, 0xF5,
296 {0x90, 0x00, 0x91, 0x23, 0x92, 0x3F, 0x93, 0x55,
297 0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95,
298 0x98, 0xA2, 0x99, 0xAD, 0x9A, 0xB9, 0x9B, 0xC6,
299 0x9C, 0xD2, 0x9D, 0xDE, 0x9E, 0xE9, 0x9F, 0xF4,
301 {0x90, 0x00, 0x91, 0x1B, 0x92, 0x33, 0x93, 0x48,
302 0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87,
303 0x98, 0x96, 0x99, 0xA3, 0x9A, 0xB1, 0x9B, 0xBE,
304 0x9C, 0xCC, 0x9D, 0xDA, 0x9E, 0xE7, 0x9F, 0xF3,
306 {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20,
307 0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67,
308 0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa,
309 0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee,
311 {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26,
312 0x94, 0x38, 0x95, 0x4A, 0x96, 0x60, 0x97, 0x70,
313 0x98, 0x80, 0x99, 0x90, 0x9A, 0xA0, 0x9B, 0xB0,
314 0x9C, 0xC0, 0x9D, 0xD0, 0x9E, 0xE0, 0x9F, 0xF0,
316 {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35,
317 0x94, 0x47, 0x95, 0x5A, 0x96, 0x69, 0x97, 0x79,
318 0x98, 0x88, 0x99, 0x97, 0x9A, 0xA7, 0x9B, 0xB6,
319 0x9C, 0xC4, 0x9D, 0xD3, 0x9E, 0xE0, 0x9F, 0xF0,
321 {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40,
322 0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
323 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd,
324 0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0,
326 {0x90, 0x00, 0x91, 0x18, 0x92, 0x2B, 0x93, 0x44,
327 0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8E,
328 0x98, 0x9C, 0x99, 0xAA, 0x9A, 0xB7, 0x9B, 0xC4,
329 0x9C, 0xD0, 0x9D, 0xD8, 0x9E, 0xE2, 0x9F, 0xF0,
331 {0x90, 0x00, 0x91, 0x1A, 0x92, 0x34, 0x93, 0x52,
332 0x94, 0x66, 0x95, 0x7E, 0x96, 0x8D, 0x97, 0x9B,
333 0x98, 0xA8, 0x99, 0xB4, 0x9A, 0xC0, 0x9B, 0xCB,
334 0x9C, 0xD6, 0x9D, 0xE1, 0x9E, 0xEB, 0x9F, 0xF5,
336 {0x90, 0x00, 0x91, 0x3F, 0x92, 0x5A, 0x93, 0x6E,
337 0x94, 0x7F, 0x95, 0x8E, 0x96, 0x9C, 0x97, 0xA8,
338 0x98, 0xB4, 0x99, 0xBF, 0x9A, 0xC9, 0x9B, 0xD3,
339 0x9C, 0xDC, 0x9D, 0xE5, 0x9E, 0xEE, 0x9F, 0xF6,
341 {0x90, 0x00, 0x91, 0x54, 0x92, 0x6F, 0x93, 0x83,
342 0x94, 0x93, 0x95, 0xA0, 0x96, 0xAD, 0x97, 0xB7,
343 0x98, 0xC2, 0x99, 0xCB, 0x9A, 0xD4, 0x9B, 0xDC,
344 0x9C, 0xE4, 0x9D, 0xEB, 0x9E, 0xF2, 0x9F, 0xF9,
346 {0x90, 0x00, 0x91, 0x6E, 0x92, 0x88, 0x93, 0x9A,
347 0x94, 0xA8, 0x95, 0xB3, 0x96, 0xBD, 0x97, 0xC6,
348 0x98, 0xCF, 0x99, 0xD6, 0x9A, 0xDD, 0x9B, 0xE3,
349 0x9C, 0xE9, 0x9D, 0xEF, 0x9E, 0xF4, 0x9F, 0xFA,
351 {0x90, 0x00, 0x91, 0x93, 0x92, 0xA8, 0x93, 0xB7,
352 0x94, 0xC1, 0x95, 0xCA, 0x96, 0xD2, 0x97, 0xD8,
353 0x98, 0xDE, 0x99, 0xE3, 0x9A, 0xE8, 0x9B, 0xED,
354 0x9C, 0xF1, 0x9D, 0xF5, 0x9E, 0xF8, 0x9F, 0xFC,
358 static const __u8 tas5130a_sensor_init[][8] = {
359 {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
360 {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
361 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
362 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
367 static int reg_r_1(struct gspca_dev *gspca_dev,
370 usb_control_msg(gspca_dev->dev,
371 usb_rcvctrlpipe(gspca_dev->dev, 0),
373 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
376 gspca_dev->usb_buf, 1, 500);
377 return gspca_dev->usb_buf[0];
380 static void reg_w(struct gspca_dev *gspca_dev,
383 const __u8 *buffer, __u16 len)
385 if (buffer == NULL) {
386 usb_control_msg(gspca_dev->dev,
387 usb_sndctrlpipe(gspca_dev->dev, 0),
389 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
394 if (len <= sizeof gspca_dev->usb_buf) {
395 memcpy(gspca_dev->usb_buf, buffer, len);
396 usb_control_msg(gspca_dev->dev,
397 usb_sndctrlpipe(gspca_dev->dev, 0),
399 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
401 gspca_dev->usb_buf, len, 500);
405 tmpbuf = kmalloc(len, GFP_KERNEL);
406 memcpy(tmpbuf, buffer, len);
407 usb_control_msg(gspca_dev->dev,
408 usb_sndctrlpipe(gspca_dev->dev, 0),
410 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
417 /* this function is called at probe time */
418 static int sd_config(struct gspca_dev *gspca_dev,
419 const struct usb_device_id *id)
421 struct sd *sd = (struct sd *) gspca_dev;
424 cam = &gspca_dev->cam;
427 cam->cam_mode = vga_mode_t16;
428 cam->nmodes = ARRAY_SIZE(vga_mode_t16);
430 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
431 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
432 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
433 sd->gamma = sd_ctrls[SD_GAMMA].qctrl.default_value;
434 sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value;
435 sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value;
436 sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value;
437 sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
438 sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value;
442 static int init_default_parameters(struct gspca_dev *gspca_dev)
444 /* some of this registers are not really neded, because
445 * they are overriden by setbrigthness, setcontrast, etc,
446 * but wont hurt anyway, and can help someone with similar webcam
447 * to see the initial parameters.*/
451 static const __u8 read_indexs[] =
452 { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
453 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 };
454 static const __u8 n1[6] =
455 {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
456 static const __u8 n2[2] =
458 static const __u8 nset[6] =
459 { 0x61, 0x68, 0x62, 0xff, 0x60, 0x07 };
460 static const __u8 n3[6] =
461 {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
462 static const __u8 n4[0x46] =
463 {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
464 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
465 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
466 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
467 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
468 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
469 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
470 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
471 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
472 static const __u8 nset4[18] = {
473 0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, 0xe4, 0xa8,
474 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
477 /* ojo puede ser 0xe6 en vez de 0xe9 */
478 static const __u8 nset2[20] = {
479 0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, 0xd4, 0xbb,
480 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
481 0xd8, 0xc8, 0xd9, 0xfc
483 static const __u8 missing[8] =
484 { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
485 static const __u8 nset3[18] = {
486 0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, 0xcb, 0xa8,
487 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
490 static const __u8 nset5[4] =
491 { 0x8f, 0x24, 0xc3, 0x00 }; /* bright */
492 static const __u8 nset6[34] = {
493 0x90, 0x00, 0x91, 0x1c, 0x92, 0x30, 0x93, 0x43, 0x94, 0x54,
494 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
495 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd, 0x9c, 0xca,
496 0x9d, 0xd8, 0x9e, 0xe5, 0x9f, 0xf2,
499 static const __u8 nset7[4] =
500 { 0x66, 0xca, 0xa8, 0xf8 }; /* 50/60 Hz */
501 static const __u8 nset9[4] =
502 { 0x0b, 0x04, 0x0a, 0x78 };
503 static const __u8 nset8[6] =
504 { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
505 static const __u8 nset10[6] =
506 { 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 };
508 reg_w(gspca_dev, 0x01, 0x0000, n1, 0x06);
509 reg_w(gspca_dev, 0x01, 0x0000, nset, 0x06);
510 reg_r_1(gspca_dev, 0x0063);
511 reg_w(gspca_dev, 0x01, 0x0000, n2, 0x02);
513 while (read_indexs[i] != 0x00) {
514 test_byte = reg_r_1(gspca_dev, read_indexs[i]);
515 PDEBUG(D_CONF, "Reg 0x%02x => 0x%02x", read_indexs[i],
520 reg_w(gspca_dev, 0x01, 0x0000, n3, 0x06);
521 reg_w(gspca_dev, 0x01, 0x0000, n4, 0x46);
522 reg_r_1(gspca_dev, 0x0080);
523 reg_w(gspca_dev, 0x00, 0x2c80, NULL, 0);
524 reg_w(gspca_dev, 0x01, 0x0000, nset2, 0x14);
525 reg_w(gspca_dev, 0x01, 0x0000, nset3, 0x12);
526 reg_w(gspca_dev, 0x01, 0x0000, nset4, 0x12);
527 reg_w(gspca_dev, 0x00, 0x3880, NULL, 0);
528 reg_w(gspca_dev, 0x00, 0x3880, NULL, 0);
529 reg_w(gspca_dev, 0x00, 0x338e, NULL, 0);
530 reg_w(gspca_dev, 0x01, 0x0000, nset5, 0x04);
531 reg_w(gspca_dev, 0x00, 0x00a9, NULL, 0);
532 reg_w(gspca_dev, 0x01, 0x0000, nset6, 0x22);
533 reg_w(gspca_dev, 0x00, 0x86bb, NULL, 0);
534 reg_w(gspca_dev, 0x00, 0x4aa6, NULL, 0);
536 reg_w(gspca_dev, 0x01, 0x0000, missing, 0x08);
538 reg_w(gspca_dev, 0x00, 0x2087, NULL, 0);
539 reg_w(gspca_dev, 0x00, 0x2088, NULL, 0);
540 reg_w(gspca_dev, 0x00, 0x2089, NULL, 0);
542 reg_w(gspca_dev, 0x01, 0x0000, nset7, 0x04);
543 reg_w(gspca_dev, 0x01, 0x0000, nset10, 0x06);
544 reg_w(gspca_dev, 0x01, 0x0000, nset8, 0x06);
545 reg_w(gspca_dev, 0x01, 0x0000, nset9, 0x04);
547 reg_w(gspca_dev, 0x00, 0x2880, NULL, 0);
548 reg_w(gspca_dev, 0x01, 0x0000, nset2, 0x14);
549 reg_w(gspca_dev, 0x01, 0x0000, nset3, 0x12);
550 reg_w(gspca_dev, 0x01, 0x0000, nset4, 0x12);
555 static void setbrightness(struct gspca_dev *gspca_dev)
557 struct sd *sd = (struct sd *) gspca_dev;
558 unsigned int brightness;
559 __u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x80 };
560 brightness = sd->brightness;
562 if (brightness < 7) {
563 set6[3] = 0x70 - (brightness * 0xa);
566 set6[3] = 0x00 + ((brightness - 7) * 0xa);
569 reg_w(gspca_dev, 0x01, 0x0000, set6, 4);
572 static void setflip(struct gspca_dev *gspca_dev)
574 struct sd *sd = (struct sd *) gspca_dev;
577 { 0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09 };
582 reg_w(gspca_dev, 0x01, 0x0000, flipcmd, 8);
585 static void seteffect(struct gspca_dev *gspca_dev)
587 struct sd *sd = (struct sd *) gspca_dev;
589 reg_w(gspca_dev, 0x01, 0x0000, effects_table[sd->effect], 0x06);
590 if (sd->effect == 1 || sd->effect == 5) {
592 "This effect have been disabled for webcam \"safety\"");
596 if (sd->effect == 1 || sd->effect == 4)
597 reg_w(gspca_dev, 0x00, 0x4aa6, NULL, 0);
599 reg_w(gspca_dev, 0x00, 0xfaa6, NULL, 0);
602 static void setwhitebalance(struct gspca_dev *gspca_dev)
604 struct sd *sd = (struct sd *) gspca_dev;
606 __u8 white_balance[8] =
607 { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
609 if (sd->whitebalance == 1)
610 white_balance[7] = 0x3c;
612 reg_w(gspca_dev, 0x01, 0x0000, white_balance, 8);
615 static void setlightfreq(struct gspca_dev *gspca_dev)
617 struct sd *sd = (struct sd *) gspca_dev;
618 __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
620 if (sd->freq == 2) /* 60hz */
623 reg_w(gspca_dev, 0x1, 0x0000, freq, 0x4);
626 static void setcontrast(struct gspca_dev *gspca_dev)
628 struct sd *sd = (struct sd *) gspca_dev;
629 unsigned int contrast = sd->contrast;
630 __u16 reg_to_write = 0x00;
633 reg_to_write = 0x8ea9 - (0x200 * contrast);
635 reg_to_write = (0x00a9 + ((contrast - 7) * 0x200));
637 reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
640 static void setcolors(struct gspca_dev *gspca_dev)
642 struct sd *sd = (struct sd *) gspca_dev;
645 reg_to_write = 0xc0bb + sd->colors * 0x100;
646 reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
649 static void setgamma(struct gspca_dev *gspca_dev)
653 static void setsharpness(struct gspca_dev *gspca_dev)
655 struct sd *sd = (struct sd *) gspca_dev;
658 reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
660 reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
663 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
665 struct sd *sd = (struct sd *) gspca_dev;
667 sd->brightness = val;
668 if (gspca_dev->streaming)
669 setbrightness(gspca_dev);
673 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
675 struct sd *sd = (struct sd *) gspca_dev;
677 *val = sd->brightness;
681 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
683 struct sd *sd = (struct sd *) gspca_dev;
685 sd->whitebalance = val;
686 if (gspca_dev->streaming)
687 setwhitebalance(gspca_dev);
691 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
693 struct sd *sd = (struct sd *) gspca_dev;
695 *val = sd->whitebalance;
699 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val)
701 struct sd *sd = (struct sd *) gspca_dev;
704 if (gspca_dev->streaming)
709 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val)
711 struct sd *sd = (struct sd *) gspca_dev;
717 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val)
719 struct sd *sd = (struct sd *) gspca_dev;
722 if (gspca_dev->streaming)
723 seteffect(gspca_dev);
727 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val)
729 struct sd *sd = (struct sd *) gspca_dev;
735 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
737 struct sd *sd = (struct sd *) gspca_dev;
740 if (gspca_dev->streaming)
741 setcontrast(gspca_dev);
745 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
747 struct sd *sd = (struct sd *) gspca_dev;
753 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
755 struct sd *sd = (struct sd *) gspca_dev;
758 if (gspca_dev->streaming)
759 setcolors(gspca_dev);
763 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
765 struct sd *sd = (struct sd *) gspca_dev;
771 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
773 struct sd *sd = (struct sd *) gspca_dev;
776 if (gspca_dev->streaming)
781 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
783 struct sd *sd = (struct sd *) gspca_dev;
788 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
790 struct sd *sd = (struct sd *) gspca_dev;
793 if (gspca_dev->streaming)
794 setlightfreq(gspca_dev);
798 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
800 struct sd *sd = (struct sd *) gspca_dev;
806 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
808 struct sd *sd = (struct sd *) gspca_dev;
811 if (gspca_dev->streaming)
812 setsharpness(gspca_dev);
816 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
818 struct sd *sd = (struct sd *) gspca_dev;
820 *val = sd->sharpness;
824 /* Low Light set here......*/
825 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
827 struct sd *sd = (struct sd *) gspca_dev;
831 reg_w(gspca_dev, 0x00, 0xf48e, NULL, 0);
833 reg_w(gspca_dev, 0x00, 0xb48e, NULL, 0);
837 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
839 struct sd *sd = (struct sd *) gspca_dev;
845 static void sd_start(struct gspca_dev *gspca_dev)
849 static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 };
850 __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
851 static const __u8 t3[] =
852 { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
853 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
854 static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 };
856 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
858 case 1: /* 352x288 */
861 case 2: /* 320x240 */
864 case 3: /* 176x144 */
867 case 4: /* 160x120 */
870 default: /* 640x480 (0x00) */
874 reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[0], 0x8);
875 reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[1], 0x8);
876 reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[2], 0x8);
877 reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
878 reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0);
879 /* just in case and to keep sync with logs (for mine) */
880 reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
881 reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0);
882 /* just in case and to keep sync with logs (for mine) */
883 reg_w(gspca_dev, 0x01, 0x0000, t1, 4);
884 reg_w(gspca_dev, 0x01, 0x0000, t2, 6);
885 reg_r_1(gspca_dev, 0x0012);
886 reg_w(gspca_dev, 0x01, 0x0000, t3, 0x10);
887 reg_w(gspca_dev, 0x00, 0x0013, NULL, 0);
888 reg_w(gspca_dev, 0x01, 0x0000, t4, 0x4);
889 /* restart on each start, just in case, sometimes regs goes wrong
890 * when using controls from app */
891 setbrightness(gspca_dev);
892 setcontrast(gspca_dev);
893 setcolors(gspca_dev);
896 static void sd_stopN(struct gspca_dev *gspca_dev)
900 static void sd_stop0(struct gspca_dev *gspca_dev)
904 static void sd_close(struct gspca_dev *gspca_dev)
908 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
909 struct gspca_frame *frame, /* target */
910 __u8 *data, /* isoc packet */
911 int len) /* iso packet length */
914 static __u8 ffd9[] = { 0xff, 0xd9 };
916 if (data[0] == 0x5a) {
917 /* Control Packet, after this came the header again,
918 * but extra bytes came in the packet before this,
919 * sometimes an EOF arrives, sometimes not... */
923 if (data[len - 1] == 0xff && data[len] == 0xd9) {
924 /* Just in case, i have seen packets with the marker,
925 * other's do not include it... */
928 } else if (data[2] == 0xff && data[3] == 0xd8) {
938 /* extra bytes....., could be processed too but would be
939 * a waste of time, right now leave the application and
940 * libjpeg do it for ourserlves.. */
941 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
943 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
947 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
950 static int sd_querymenu(struct gspca_dev *gspca_dev,
951 struct v4l2_querymenu *menu)
954 case V4L2_CID_POWER_LINE_FREQUENCY:
955 switch (menu->index) {
956 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
957 strcpy((char *) menu->name, "50 Hz");
959 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
960 strcpy((char *) menu->name, "60 Hz");
964 case V4L2_CID_EFFECTS:
965 if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
966 strncpy((char *) menu->name,
967 effects_control[menu->index], 32);
975 /* this function is called at open time */
976 static int sd_open(struct gspca_dev *gspca_dev)
978 init_default_parameters(gspca_dev);
982 /* sub-driver description */
983 static const struct sd_desc sd_desc = {
986 .nctrls = ARRAY_SIZE(sd_ctrls),
993 .pkt_scan = sd_pkt_scan,
994 .querymenu = sd_querymenu,
997 /* -- module initialisation -- */
998 static const __devinitdata struct usb_device_id device_table[] = {
999 {USB_DEVICE(0x17a1, 0x0128)},
1002 MODULE_DEVICE_TABLE(usb, device_table);
1004 /* -- device connect -- */
1005 static int sd_probe(struct usb_interface *intf,
1006 const struct usb_device_id *id)
1008 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1012 static struct usb_driver sd_driver = {
1013 .name = MODULE_NAME,
1014 .id_table = device_table,
1016 .disconnect = gspca_disconnect,
1019 /* -- module insert / remove -- */
1020 static int __init sd_mod_init(void)
1022 if (usb_register(&sd_driver) < 0)
1024 PDEBUG(D_PROBE, "registered");
1027 static void __exit sd_mod_exit(void)
1029 usb_deregister(&sd_driver);
1030 PDEBUG(D_PROBE, "deregistered");
1033 module_init(sd_mod_init);
1034 module_exit(sd_mod_exit);