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 + 0)
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 * 4 / 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 <= USB_BUF_SZ) {
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 /* this function is called at probe and resume time */
556 static int sd_init(struct gspca_dev *gspca_dev)
558 init_default_parameters(gspca_dev);
562 static void setbrightness(struct gspca_dev *gspca_dev)
564 struct sd *sd = (struct sd *) gspca_dev;
565 unsigned int brightness;
566 __u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x80 };
567 brightness = sd->brightness;
569 if (brightness < 7) {
570 set6[3] = 0x70 - (brightness * 0xa);
573 set6[3] = 0x00 + ((brightness - 7) * 0xa);
576 reg_w(gspca_dev, 0x01, 0x0000, set6, 4);
579 static void setflip(struct gspca_dev *gspca_dev)
581 struct sd *sd = (struct sd *) gspca_dev;
584 { 0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09 };
589 reg_w(gspca_dev, 0x01, 0x0000, flipcmd, 8);
592 static void seteffect(struct gspca_dev *gspca_dev)
594 struct sd *sd = (struct sd *) gspca_dev;
596 reg_w(gspca_dev, 0x01, 0x0000, effects_table[sd->effect], 0x06);
597 if (sd->effect == 1 || sd->effect == 5) {
599 "This effect have been disabled for webcam \"safety\"");
603 if (sd->effect == 1 || sd->effect == 4)
604 reg_w(gspca_dev, 0x00, 0x4aa6, NULL, 0);
606 reg_w(gspca_dev, 0x00, 0xfaa6, NULL, 0);
609 static void setwhitebalance(struct gspca_dev *gspca_dev)
611 struct sd *sd = (struct sd *) gspca_dev;
613 __u8 white_balance[8] =
614 { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
616 if (sd->whitebalance == 1)
617 white_balance[7] = 0x3c;
619 reg_w(gspca_dev, 0x01, 0x0000, white_balance, 8);
622 static void setlightfreq(struct gspca_dev *gspca_dev)
624 struct sd *sd = (struct sd *) gspca_dev;
625 __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
627 if (sd->freq == 2) /* 60hz */
630 reg_w(gspca_dev, 0x1, 0x0000, freq, 0x4);
633 static void setcontrast(struct gspca_dev *gspca_dev)
635 struct sd *sd = (struct sd *) gspca_dev;
636 unsigned int contrast = sd->contrast;
637 __u16 reg_to_write = 0x00;
640 reg_to_write = 0x8ea9 - (0x200 * contrast);
642 reg_to_write = (0x00a9 + ((contrast - 7) * 0x200));
644 reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
647 static void setcolors(struct gspca_dev *gspca_dev)
649 struct sd *sd = (struct sd *) gspca_dev;
652 reg_to_write = 0xc0bb + sd->colors * 0x100;
653 reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
656 static void setgamma(struct gspca_dev *gspca_dev)
660 static void setsharpness(struct gspca_dev *gspca_dev)
662 struct sd *sd = (struct sd *) gspca_dev;
665 reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
667 reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
670 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
672 struct sd *sd = (struct sd *) gspca_dev;
674 sd->brightness = val;
675 if (gspca_dev->streaming)
676 setbrightness(gspca_dev);
680 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
682 struct sd *sd = (struct sd *) gspca_dev;
684 *val = sd->brightness;
688 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
690 struct sd *sd = (struct sd *) gspca_dev;
692 sd->whitebalance = val;
693 if (gspca_dev->streaming)
694 setwhitebalance(gspca_dev);
698 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
700 struct sd *sd = (struct sd *) gspca_dev;
702 *val = sd->whitebalance;
706 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val)
708 struct sd *sd = (struct sd *) gspca_dev;
711 if (gspca_dev->streaming)
716 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val)
718 struct sd *sd = (struct sd *) gspca_dev;
724 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val)
726 struct sd *sd = (struct sd *) gspca_dev;
729 if (gspca_dev->streaming)
730 seteffect(gspca_dev);
734 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val)
736 struct sd *sd = (struct sd *) gspca_dev;
742 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
744 struct sd *sd = (struct sd *) gspca_dev;
747 if (gspca_dev->streaming)
748 setcontrast(gspca_dev);
752 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
754 struct sd *sd = (struct sd *) gspca_dev;
760 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
762 struct sd *sd = (struct sd *) gspca_dev;
765 if (gspca_dev->streaming)
766 setcolors(gspca_dev);
770 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
772 struct sd *sd = (struct sd *) gspca_dev;
778 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
780 struct sd *sd = (struct sd *) gspca_dev;
783 if (gspca_dev->streaming)
788 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
790 struct sd *sd = (struct sd *) gspca_dev;
795 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
797 struct sd *sd = (struct sd *) gspca_dev;
800 if (gspca_dev->streaming)
801 setlightfreq(gspca_dev);
805 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
807 struct sd *sd = (struct sd *) gspca_dev;
813 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
815 struct sd *sd = (struct sd *) gspca_dev;
818 if (gspca_dev->streaming)
819 setsharpness(gspca_dev);
823 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
825 struct sd *sd = (struct sd *) gspca_dev;
827 *val = sd->sharpness;
831 /* Low Light set here......*/
832 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
834 struct sd *sd = (struct sd *) gspca_dev;
838 reg_w(gspca_dev, 0x00, 0xf48e, NULL, 0);
840 reg_w(gspca_dev, 0x00, 0xb48e, NULL, 0);
844 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
846 struct sd *sd = (struct sd *) gspca_dev;
852 static void sd_start(struct gspca_dev *gspca_dev)
856 static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 };
857 __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
858 static const __u8 t3[] =
859 { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
860 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
861 static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 };
863 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
865 case 1: /* 352x288 */
868 case 2: /* 320x240 */
871 case 3: /* 176x144 */
874 case 4: /* 160x120 */
877 default: /* 640x480 (0x00) */
881 reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[0], 0x8);
882 reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[1], 0x8);
883 reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[2], 0x8);
884 reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
885 reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0);
886 /* just in case and to keep sync with logs (for mine) */
887 reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
888 reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0);
889 /* just in case and to keep sync with logs (for mine) */
890 reg_w(gspca_dev, 0x01, 0x0000, t1, 4);
891 reg_w(gspca_dev, 0x01, 0x0000, t2, 6);
892 reg_r_1(gspca_dev, 0x0012);
893 reg_w(gspca_dev, 0x01, 0x0000, t3, 0x10);
894 reg_w(gspca_dev, 0x00, 0x0013, NULL, 0);
895 reg_w(gspca_dev, 0x01, 0x0000, t4, 0x4);
896 /* restart on each start, just in case, sometimes regs goes wrong
897 * when using controls from app */
898 setbrightness(gspca_dev);
899 setcontrast(gspca_dev);
900 setcolors(gspca_dev);
903 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
904 struct gspca_frame *frame, /* target */
905 __u8 *data, /* isoc packet */
906 int len) /* iso packet length */
909 static __u8 ffd9[] = { 0xff, 0xd9 };
911 if (data[0] == 0x5a) {
912 /* Control Packet, after this came the header again,
913 * but extra bytes came in the packet before this,
914 * sometimes an EOF arrives, sometimes not... */
918 if (data[len - 1] == 0xff && data[len] == 0xd9) {
919 /* Just in case, i have seen packets with the marker,
920 * other's do not include it... */
923 } else if (data[2] == 0xff && data[3] == 0xd8) {
933 /* extra bytes....., could be processed too but would be
934 * a waste of time, right now leave the application and
935 * libjpeg do it for ourserlves.. */
936 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
938 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
942 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
945 static int sd_querymenu(struct gspca_dev *gspca_dev,
946 struct v4l2_querymenu *menu)
949 case V4L2_CID_POWER_LINE_FREQUENCY:
950 switch (menu->index) {
951 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
952 strcpy((char *) menu->name, "50 Hz");
954 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
955 strcpy((char *) menu->name, "60 Hz");
959 case V4L2_CID_EFFECTS:
960 if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
961 strncpy((char *) menu->name,
962 effects_control[menu->index], 32);
970 /* sub-driver description */
971 static const struct sd_desc sd_desc = {
974 .nctrls = ARRAY_SIZE(sd_ctrls),
978 .pkt_scan = sd_pkt_scan,
979 .querymenu = sd_querymenu,
982 /* -- module initialisation -- */
983 static const __devinitdata struct usb_device_id device_table[] = {
984 {USB_DEVICE(0x17a1, 0x0128)},
987 MODULE_DEVICE_TABLE(usb, device_table);
989 /* -- device connect -- */
990 static int sd_probe(struct usb_interface *intf,
991 const struct usb_device_id *id)
993 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
997 static struct usb_driver sd_driver = {
999 .id_table = device_table,
1001 .disconnect = gspca_disconnect,
1003 .suspend = gspca_suspend,
1004 .resume = gspca_resume,
1008 /* -- module insert / remove -- */
1009 static int __init sd_mod_init(void)
1011 if (usb_register(&sd_driver) < 0)
1013 PDEBUG(D_PROBE, "registered");
1016 static void __exit sd_mod_exit(void)
1018 usb_deregister(&sd_driver);
1019 PDEBUG(D_PROBE, "deregistered");
1022 module_init(sd_mod_init);
1023 module_exit(sd_mod_exit);