2 *Notes: * t613 + tas5130A
3 * * Focus to light do not balance well as in win.
4 * Quality in win is not good, but its kinda better.
5 * * Fix some "extraneous bytes", most of apps will show the image anyway
6 * * Gamma table, is there, but its really doing something?
7 * * 7~8 Fps, its ok, max on win its 10.
10 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #define MODULE_NAME "t613"
29 #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4)
30 static const char version[] = "2.1.4";
32 #define MAX_GAMMA 0x10 /* 0 to 15 */
35 #define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 3)
37 MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
38 MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver");
39 MODULE_LICENSE("GPL");
42 struct gspca_dev gspca_dev; /* !! must be the first item */
44 unsigned char brightness;
45 unsigned char contrast;
47 unsigned char autogain;
49 unsigned char sharpness;
51 unsigned char whitebalance;
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,
90 .default_value = 0x09,
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,
126 .id = V4L2_CID_GAMMA, /* (gamma on win) */
127 .type = V4L2_CTRL_TYPE_INTEGER,
128 .name = "Gamma (Untested)",
130 .maximum = MAX_GAMMA,
132 .default_value = 0x09,
137 #define SD_AUTOGAIN 4
140 .id = V4L2_CID_GAIN, /* here, i activate only the lowlight,
141 * some apps dont bring up the
142 * backligth_compensation control) */
143 .type = V4L2_CTRL_TYPE_INTEGER,
148 .default_value = 0x01,
150 .set = sd_setlowlight,
151 .get = sd_getlowlight,
156 .id = V4L2_CID_HFLIP,
157 .type = V4L2_CTRL_TYPE_BOOLEAN,
158 .name = "Mirror Image",
167 #define SD_LIGHTFREQ 6
170 .id = V4L2_CID_POWER_LINE_FREQUENCY,
171 .type = V4L2_CTRL_TYPE_MENU,
172 .name = "Light Frequency Filter",
173 .minimum = 1, /* 1 -> 0x50, 2->0x60 */
181 #define SD_WHITE_BALANCE 7
184 .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
185 .type = V4L2_CTRL_TYPE_INTEGER,
186 .name = "White Balance",
192 .set = sd_setwhitebalance,
193 .get = sd_getwhitebalance
195 #define SD_SHARPNESS 8 /* (aka definition on win) */
198 .id = V4L2_CID_SHARPNESS,
199 .type = V4L2_CTRL_TYPE_INTEGER,
202 .maximum = MAX_GAMMA, /* 0 to 16 */
204 .default_value = 0x06,
206 .set = sd_setsharpness,
207 .get = sd_getsharpness,
212 .id = V4L2_CID_EFFECTS,
213 .type = V4L2_CTRL_TYPE_MENU,
214 .name = "Webcam Effects",
225 static char *effects_control[] = {
227 "Emboss", /* disabled */
231 "Sun Effect", /* disabled */
235 static struct cam_mode vga_mode_t16[] = {
236 {V4L2_PIX_FMT_JPEG, 160, 120, 4},
237 {V4L2_PIX_FMT_JPEG, 176, 144, 3},
238 {V4L2_PIX_FMT_JPEG, 320, 240, 2},
239 {V4L2_PIX_FMT_JPEG, 352, 288, 1},
240 {V4L2_PIX_FMT_JPEG, 640, 480, 0},
243 #define T16_OFFSET_DATA 631
244 #define MAX_EFFECTS 7
245 /* easily done by soft, this table could be removed,
246 * i keep it here just in case */
247 static const __u8 effects_table[MAX_EFFECTS][6] = {
248 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */
249 {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */
250 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */
251 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80}, /* Sepia */
252 {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02}, /* Croquis */
253 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10}, /* Sun Effect */
254 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */
257 static const __u8 gamma_table[MAX_GAMMA][34] = {
258 {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85,
259 0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9,
260 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb,
261 0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8,
263 {0x90, 0x00, 0x91, 0x33, 0x92, 0x5A, 0x93, 0x75,
264 0x94, 0x85, 0x95, 0x93, 0x96, 0xA1, 0x97, 0xAD,
265 0x98, 0xB7, 0x99, 0xC2, 0x9A, 0xCB, 0x9B, 0xD4,
266 0x9C, 0xDE, 0x9D, 0xE7, 0x9E, 0xF0, 0x9F, 0xF7,
268 {0x90, 0x00, 0x91, 0x2F, 0x92, 0x51, 0x93, 0x6B,
269 0x94, 0x7C, 0x95, 0x8A, 0x96, 0x99, 0x97, 0xA6,
270 0x98, 0xB1, 0x99, 0xBC, 0x9A, 0xC6, 0x9B, 0xD0,
271 0x9C, 0xDB, 0x9D, 0xE4, 0x9E, 0xED, 0x9F, 0xF6,
273 {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60,
274 0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9E,
275 0x98, 0xAA, 0x99, 0xB5, 0x9A, 0xBF, 0x9B, 0xCB,
276 0x9C, 0xD6, 0x9D, 0xE1, 0x9E, 0xEB, 0x9F, 0xF5,
278 {0x90, 0x00, 0x91, 0x23, 0x92, 0x3F, 0x93, 0x55,
279 0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95,
280 0x98, 0xA2, 0x99, 0xAD, 0x9A, 0xB9, 0x9B, 0xC6,
281 0x9C, 0xD2, 0x9D, 0xDE, 0x9E, 0xE9, 0x9F, 0xF4,
283 {0x90, 0x00, 0x91, 0x1B, 0x92, 0x33, 0x93, 0x48,
284 0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87,
285 0x98, 0x96, 0x99, 0xA3, 0x9A, 0xB1, 0x9B, 0xBE,
286 0x9C, 0xCC, 0x9D, 0xDA, 0x9E, 0xE7, 0x9F, 0xF3,
288 {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20,
289 0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67,
290 0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa,
291 0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee,
293 {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26,
294 0x94, 0x38, 0x95, 0x4A, 0x96, 0x60, 0x97, 0x70,
295 0x98, 0x80, 0x99, 0x90, 0x9A, 0xA0, 0x9B, 0xB0,
296 0x9C, 0xC0, 0x9D, 0xD0, 0x9E, 0xE0, 0x9F, 0xF0,
298 {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35,
299 0x94, 0x47, 0x95, 0x5A, 0x96, 0x69, 0x97, 0x79,
300 0x98, 0x88, 0x99, 0x97, 0x9A, 0xA7, 0x9B, 0xB6,
301 0x9C, 0xC4, 0x9D, 0xD3, 0x9E, 0xE0, 0x9F, 0xF0,
303 {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40,
304 0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
305 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd,
306 0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0,
308 {0x90, 0x00, 0x91, 0x18, 0x92, 0x2B, 0x93, 0x44,
309 0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8E,
310 0x98, 0x9C, 0x99, 0xAA, 0x9A, 0xB7, 0x9B, 0xC4,
311 0x9C, 0xD0, 0x9D, 0xD8, 0x9E, 0xE2, 0x9F, 0xF0,
313 {0x90, 0x00, 0x91, 0x1A, 0x92, 0x34, 0x93, 0x52,
314 0x94, 0x66, 0x95, 0x7E, 0x96, 0x8D, 0x97, 0x9B,
315 0x98, 0xA8, 0x99, 0xB4, 0x9A, 0xC0, 0x9B, 0xCB,
316 0x9C, 0xD6, 0x9D, 0xE1, 0x9E, 0xEB, 0x9F, 0xF5,
318 {0x90, 0x00, 0x91, 0x3F, 0x92, 0x5A, 0x93, 0x6E,
319 0x94, 0x7F, 0x95, 0x8E, 0x96, 0x9C, 0x97, 0xA8,
320 0x98, 0xB4, 0x99, 0xBF, 0x9A, 0xC9, 0x9B, 0xD3,
321 0x9C, 0xDC, 0x9D, 0xE5, 0x9E, 0xEE, 0x9F, 0xF6,
323 {0x90, 0x00, 0x91, 0x54, 0x92, 0x6F, 0x93, 0x83,
324 0x94, 0x93, 0x95, 0xA0, 0x96, 0xAD, 0x97, 0xB7,
325 0x98, 0xC2, 0x99, 0xCB, 0x9A, 0xD4, 0x9B, 0xDC,
326 0x9C, 0xE4, 0x9D, 0xEB, 0x9E, 0xF2, 0x9F, 0xF9,
328 {0x90, 0x00, 0x91, 0x6E, 0x92, 0x88, 0x93, 0x9A,
329 0x94, 0xA8, 0x95, 0xB3, 0x96, 0xBD, 0x97, 0xC6,
330 0x98, 0xCF, 0x99, 0xD6, 0x9A, 0xDD, 0x9B, 0xE3,
331 0x9C, 0xE9, 0x9D, 0xEF, 0x9E, 0xF4, 0x9F, 0xFA,
333 {0x90, 0x00, 0x91, 0x93, 0x92, 0xA8, 0x93, 0xB7,
334 0x94, 0xC1, 0x95, 0xCA, 0x96, 0xD2, 0x97, 0xD8,
335 0x98, 0xDE, 0x99, 0xE3, 0x9A, 0xE8, 0x9B, 0xED,
336 0x9C, 0xF1, 0x9D, 0xF5, 0x9E, 0xF8, 0x9F, 0xFC,
340 static const __u8 tas5130a_sensor_init[][8] = {
341 {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
342 {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
343 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
344 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
348 static void t16RegRead(struct usb_device *dev,
349 __u16 index, __u8 *buffer, __u16 length)
352 usb_rcvctrlpipe(dev, 0),
354 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
356 index, buffer, length, 500);
359 static void t16RegWrite(struct usb_device *dev,
362 const __u8 *buffer, __u16 len)
364 if (buffer == NULL) {
366 usb_sndctrlpipe(dev, 0),
368 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
376 memcpy(tmpbuf, buffer, len);
378 usb_sndctrlpipe(dev, 0),
380 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
386 tmpbuf = kmalloc(len, GFP_KERNEL);
387 memcpy(tmpbuf, buffer, len);
389 usb_sndctrlpipe(dev, 0),
391 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
398 /* this function is called at probe time */
399 static int sd_config(struct gspca_dev *gspca_dev,
400 const struct usb_device_id *id)
402 struct sd *sd = (struct sd *) gspca_dev;
405 cam = &gspca_dev->cam;
406 cam->dev_name = (char *) id->driver_info;
409 cam->cam_mode = vga_mode_t16;
410 cam->nmodes = ARRAY_SIZE(vga_mode_t16);
412 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
413 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
414 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
415 sd->gamma = sd_ctrls[SD_GAMMA].qctrl.default_value;
416 sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value;
417 sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value;
418 sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value;
419 sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
420 sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value;
424 static int init_default_parameters(struct gspca_dev *gspca_dev)
426 struct usb_device *dev = gspca_dev->dev;
428 /* some of this registers are not really neded, because
429 * they are overriden by setbrigthness, setcontrast, etc,
430 * but wont hurt anyway, and can help someone with similar webcam
431 * to see the initial parameters.*/
435 static const __u8 read_indexs[] =
436 { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
437 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 };
438 static const __u8 n1[6] =
439 {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
440 static const __u8 n2[2] =
442 static const __u8 nset[6] =
443 { 0x61, 0x68, 0x62, 0xff, 0x60, 0x07 };
444 static const __u8 n3[6] =
445 {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
446 static const __u8 n4[0x46] =
447 {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
448 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
449 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
450 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
451 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
452 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
453 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
454 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
455 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
456 static const __u8 nset4[18] = {
457 0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, 0xe4, 0xa8,
458 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
461 /* ojo puede ser 0xe6 en vez de 0xe9 */
462 static const __u8 nset2[20] = {
463 0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, 0xd4, 0xbb,
464 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
465 0xd8, 0xc8, 0xd9, 0xfc
467 static const __u8 missing[8] =
468 { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
469 static const __u8 nset3[18] = {
470 0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, 0xcb, 0xa8,
471 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
474 static const __u8 nset5[4] =
475 { 0x8f, 0x24, 0xc3, 0x00 }; /* bright */
476 static const __u8 nset6[34] = {
477 0x90, 0x00, 0x91, 0x1c, 0x92, 0x30, 0x93, 0x43, 0x94, 0x54,
478 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
479 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd, 0x9c, 0xca,
480 0x9d, 0xd8, 0x9e, 0xe5, 0x9f, 0xf2,
483 static const __u8 nset7[4] =
484 { 0x66, 0xca, 0xa8, 0xf8 }; /* 50/60 Hz */
485 static const __u8 nset9[4] =
486 { 0x0b, 0x04, 0x0a, 0x78 };
487 static const __u8 nset8[6] =
488 { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
489 static const __u8 nset10[6] =
490 { 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 };
492 t16RegWrite(dev, 0x01, 0x0000, n1, 0x06);
493 t16RegWrite(dev, 0x01, 0x0000, nset, 0x06);
494 t16RegRead(dev, 0x0063, &test_byte, 1);
495 t16RegWrite(dev, 0x01, 0x0000, n2, 0x02);
497 while (read_indexs[i] != 0x00) {
498 t16RegRead(dev, read_indexs[i], &test_byte, 1);
499 PDEBUG(D_CONF, "Reg 0x%x => 0x%x", read_indexs[i],
504 t16RegWrite(dev, 0x01, 0x0000, n3, 0x06);
505 t16RegWrite(dev, 0x01, 0x0000, n4, 0x46);
506 t16RegRead(dev, 0x0080, &test_byte, 1);
507 t16RegWrite(dev, 0x00, 0x2c80, NULL, 0x0);
508 t16RegWrite(dev, 0x01, 0x0000, nset2, 0x14);
509 t16RegWrite(dev, 0x01, 0x0000, nset3, 0x12);
510 t16RegWrite(dev, 0x01, 0x0000, nset4, 0x12);
511 t16RegWrite(dev, 0x00, 0x3880, NULL, 0x0);
512 t16RegWrite(dev, 0x00, 0x3880, NULL, 0x0);
513 t16RegWrite(dev, 0x00, 0x338e, NULL, 0x0);
514 t16RegWrite(dev, 0x01, 0x0000, nset5, 0x04);
515 t16RegWrite(dev, 0x00, 0x00a9, NULL, 0x0);
516 t16RegWrite(dev, 0x01, 0x0000, nset6, 0x22);
517 t16RegWrite(dev, 0x00, 0x86bb, NULL, 0x0);
518 t16RegWrite(dev, 0x00, 0x4aa6, NULL, 0x0);
520 t16RegWrite(dev, 0x01, 0x0000, missing, 0x08);
522 t16RegWrite(dev, 0x00, 0x2087, NULL, 0x0);
523 t16RegWrite(dev, 0x00, 0x2088, NULL, 0x0);
524 t16RegWrite(dev, 0x00, 0x2089, NULL, 0x0);
526 t16RegWrite(dev, 0x01, 0x0000, nset7, 0x04);
527 t16RegWrite(dev, 0x01, 0x0000, nset10, 0x06);
528 t16RegWrite(dev, 0x01, 0x0000, nset8, 0x06);
529 t16RegWrite(dev, 0x01, 0x0000, nset9, 0x04);
531 t16RegWrite(dev, 0x00, 0x2880, NULL, 0x00);
532 t16RegWrite(dev, 0x01, 0x0000, nset2, 0x14);
533 t16RegWrite(dev, 0x01, 0x0000, nset3, 0x12);
534 t16RegWrite(dev, 0x01, 0x0000, nset4, 0x12);
539 static void setbrightness(struct gspca_dev *gspca_dev)
541 struct sd *sd = (struct sd *) gspca_dev;
542 struct usb_device *dev = gspca_dev->dev;
543 unsigned int brightness;
544 __u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x80 };
545 brightness = sd->brightness;
547 if (brightness < 7) {
548 set6[3] = 0x70 - (brightness * 0xa);
551 set6[3] = 0x00 + ((brightness - 7) * 0xa);
554 t16RegWrite(dev, 0x01, 0x0000, set6, 4);
557 static void setflip(struct gspca_dev *gspca_dev)
559 struct sd *sd = (struct sd *) gspca_dev;
560 struct usb_device *dev = gspca_dev->dev;
563 { 0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09 };
568 t16RegWrite(dev, 0x01, 0x0000, flipcmd, 8);
571 static void seteffect(struct gspca_dev *gspca_dev)
573 struct sd *sd = (struct sd *) gspca_dev;
574 struct usb_device *dev = gspca_dev->dev;
576 t16RegWrite(dev, 0x01, 0x0000, effects_table[sd->effect], 0x06);
577 if (sd->effect == 1 || sd->effect == 5) {
579 "This effect have been disabled for webcam \"safety\"");
583 if (sd->effect == 1 || sd->effect == 4)
584 t16RegWrite(dev, 0x00, 0x4aa6, NULL, 0x00);
586 t16RegWrite(dev, 0x00, 0xfaa6, NULL, 0x00);
589 static void setwhitebalance(struct gspca_dev *gspca_dev)
591 struct sd *sd = (struct sd *) gspca_dev;
592 struct usb_device *dev = gspca_dev->dev;
594 __u8 white_balance[8] =
595 { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
597 if (sd->whitebalance == 1)
598 white_balance[7] = 0x3c;
600 t16RegWrite(dev, 0x01, 0x0000, white_balance, 8);
603 static void setlightfreq(struct gspca_dev *gspca_dev)
605 struct sd *sd = (struct sd *) gspca_dev;
606 struct usb_device *dev = gspca_dev->dev;
607 __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
609 if (sd->freq == 2) /* 60hz */
612 t16RegWrite(dev, 0x1, 0x0000, freq, 0x4);
615 static void setcontrast(struct gspca_dev *gspca_dev)
617 struct sd *sd = (struct sd *) gspca_dev;
618 struct usb_device *dev = gspca_dev->dev;
619 unsigned int contrast = sd->contrast;
620 __u16 reg_to_write = 0x00;
623 reg_to_write = 0x8ea9 - (0x200 * contrast);
625 reg_to_write = (0x00a9 + ((contrast - 7) * 0x200));
627 t16RegWrite(dev, 0x00, reg_to_write, NULL, 0);
630 static void setcolors(struct gspca_dev *gspca_dev)
632 struct sd *sd = (struct sd *) gspca_dev;
633 struct usb_device *dev = gspca_dev->dev;
636 reg_to_write = 0xc0bb + sd->colors * 0x100;
637 t16RegWrite(dev, 0x00, reg_to_write, NULL, 0);
640 static void setgamma(struct gspca_dev *gspca_dev)
644 static void setsharpness(struct gspca_dev *gspca_dev)
646 struct sd *sd = (struct sd *) gspca_dev;
647 struct usb_device *dev = gspca_dev->dev;
650 reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
652 t16RegWrite(dev, 0x00, reg_to_write, NULL, 0x00);
655 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
657 struct sd *sd = (struct sd *) gspca_dev;
659 sd->brightness = val;
660 if (gspca_dev->streaming)
661 setbrightness(gspca_dev);
665 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
667 struct sd *sd = (struct sd *) gspca_dev;
669 *val = sd->brightness;
673 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
675 struct sd *sd = (struct sd *) gspca_dev;
677 sd->whitebalance = val;
678 if (gspca_dev->streaming)
679 setwhitebalance(gspca_dev);
683 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
685 struct sd *sd = (struct sd *) gspca_dev;
687 *val = sd->whitebalance;
691 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val)
693 struct sd *sd = (struct sd *) gspca_dev;
696 if (gspca_dev->streaming)
701 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val)
703 struct sd *sd = (struct sd *) gspca_dev;
709 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val)
711 struct sd *sd = (struct sd *) gspca_dev;
714 if (gspca_dev->streaming)
715 seteffect(gspca_dev);
719 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val)
721 struct sd *sd = (struct sd *) gspca_dev;
727 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
729 struct sd *sd = (struct sd *) gspca_dev;
732 if (gspca_dev->streaming)
733 setcontrast(gspca_dev);
737 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
739 struct sd *sd = (struct sd *) gspca_dev;
745 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
747 struct sd *sd = (struct sd *) gspca_dev;
750 if (gspca_dev->streaming)
751 setcolors(gspca_dev);
755 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
757 struct sd *sd = (struct sd *) gspca_dev;
763 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
765 struct sd *sd = (struct sd *) gspca_dev;
768 if (gspca_dev->streaming)
773 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
775 struct sd *sd = (struct sd *) gspca_dev;
780 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
782 struct sd *sd = (struct sd *) gspca_dev;
785 if (gspca_dev->streaming)
786 setlightfreq(gspca_dev);
790 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
792 struct sd *sd = (struct sd *) gspca_dev;
798 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
800 struct sd *sd = (struct sd *) gspca_dev;
803 if (gspca_dev->streaming)
804 setsharpness(gspca_dev);
808 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
810 struct sd *sd = (struct sd *) gspca_dev;
812 *val = sd->sharpness;
816 /* Low Light set here......*/
817 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
819 struct sd *sd = (struct sd *) gspca_dev;
820 struct usb_device *dev = gspca_dev->dev;
824 t16RegWrite(dev, 0x00, 0xf48e, NULL, 0);
826 t16RegWrite(dev, 0x00, 0xb48e, NULL, 0);
830 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
832 struct sd *sd = (struct sd *) gspca_dev;
838 static void sd_start(struct gspca_dev *gspca_dev)
840 struct usb_device *dev = gspca_dev->dev;
844 static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 };
845 __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
846 static const __u8 t3[] =
847 { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
848 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
849 static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 };
851 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. mode;
853 case 1: /* 352x288 */
856 case 2: /* 320x240 */
859 case 3: /* 176x144 */
862 case 4: /* 160x120 */
865 default: /* 640x480 (0x00) */
869 t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[0], 0x8);
870 t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[1], 0x8);
871 t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[2], 0x8);
872 t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
873 t16RegWrite(dev, 0x00, 0x3c80, NULL, 0x00);
874 /* just in case and to keep sync with logs (for mine) */
875 t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
876 t16RegWrite(dev, 0x00, 0x3c80, NULL, 0x00);
877 /* just in case and to keep sync with logs (for mine) */
878 t16RegWrite(dev, 0x01, 0x0000, t1, 4);
879 t16RegWrite(dev, 0x01, 0x0000, t2, 6);
880 t16RegRead(dev, 0x0012, &test_byte, 0x1);
881 t16RegWrite(dev, 0x01, 0x0000, t3, 0x10);
882 t16RegWrite(dev, 0x00, 0x0013, NULL, 0x00);
883 t16RegWrite(dev, 0x01, 0x0000, t4, 0x4);
884 /* restart on each start, just in case, sometimes regs goes wrong
885 * when using controls from app */
886 setbrightness(gspca_dev);
887 setcontrast(gspca_dev);
888 setcolors(gspca_dev);
891 static void sd_stopN(struct gspca_dev *gspca_dev)
895 static void sd_stop0(struct gspca_dev *gspca_dev)
899 static void sd_close(struct gspca_dev *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 /* this function is called at open time */
971 static int sd_open(struct gspca_dev *gspca_dev)
973 init_default_parameters(gspca_dev);
977 /* sub-driver description */
978 static const struct sd_desc sd_desc = {
981 .nctrls = ARRAY_SIZE(sd_ctrls),
988 .pkt_scan = sd_pkt_scan,
989 .querymenu = sd_querymenu,
992 /* -- module initialisation -- */
993 #define DVNM(name) .driver_info = (kernel_ulong_t) name
994 static const __devinitdata struct usb_device_id device_table[] = {
995 {USB_DEVICE(0x17a1, 0x0128), DVNM("XPX Webcam")},
998 MODULE_DEVICE_TABLE(usb, device_table);
1000 /* -- device connect -- */
1001 static int sd_probe(struct usb_interface *intf,
1002 const struct usb_device_id *id)
1004 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1008 static struct usb_driver sd_driver = {
1009 .name = MODULE_NAME,
1010 .id_table = device_table,
1012 .disconnect = gspca_disconnect,
1015 /* -- module insert / remove -- */
1016 static int __init sd_mod_init(void)
1018 if (usb_register(&sd_driver) < 0)
1020 PDEBUG(D_PROBE, "v%s registered", version);
1023 static void __exit sd_mod_exit(void)
1025 usb_deregister(&sd_driver);
1026 PDEBUG(D_PROBE, "deregistered");
1029 module_init(sd_mod_init);
1030 module_exit(sd_mod_exit);