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_OTHER 1
56 /* V4L2 controls supported by the driver */
57 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
58 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
59 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
60 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
61 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
62 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
63 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val);
64 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val);
65 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
66 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
67 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
68 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
69 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
70 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
71 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val);
72 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val);
73 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val);
74 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val);
75 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val);
76 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val);
77 static int sd_querymenu(struct gspca_dev *gspca_dev,
78 struct v4l2_querymenu *menu);
80 static struct ctrl sd_ctrls[] = {
81 #define SD_BRIGHTNESS 0
84 .id = V4L2_CID_BRIGHTNESS,
85 .type = V4L2_CTRL_TYPE_INTEGER,
92 .set = sd_setbrightness,
93 .get = sd_getbrightness,
98 .id = V4L2_CID_CONTRAST,
99 .type = V4L2_CTRL_TYPE_INTEGER,
104 .default_value = 0x07,
106 .set = sd_setcontrast,
107 .get = sd_getcontrast,
112 .id = V4L2_CID_SATURATION,
113 .type = V4L2_CTRL_TYPE_INTEGER,
118 .default_value = 0x05,
127 .id = V4L2_CID_GAMMA, /* (gamma on win) */
128 .type = V4L2_CTRL_TYPE_INTEGER,
131 .maximum = GAMMA_MAX - 1,
133 .default_value = GAMMA_DEF,
138 #define SD_AUTOGAIN 4
141 .id = V4L2_CID_GAIN, /* here, i activate only the lowlight,
142 * some apps dont bring up the
143 * backligth_compensation control) */
144 .type = V4L2_CTRL_TYPE_INTEGER,
149 .default_value = 0x01,
151 .set = sd_setlowlight,
152 .get = sd_getlowlight,
157 .id = V4L2_CID_HFLIP,
158 .type = V4L2_CTRL_TYPE_BOOLEAN,
159 .name = "Mirror Image",
168 #define SD_LIGHTFREQ 6
171 .id = V4L2_CID_POWER_LINE_FREQUENCY,
172 .type = V4L2_CTRL_TYPE_MENU,
173 .name = "Light Frequency Filter",
174 .minimum = 1, /* 1 -> 0x50, 2->0x60 */
182 #define SD_WHITE_BALANCE 7
185 .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
186 .type = V4L2_CTRL_TYPE_INTEGER,
187 .name = "White Balance",
193 .set = sd_setwhitebalance,
194 .get = sd_getwhitebalance
196 #define SD_SHARPNESS 8 /* (aka definition on win) */
199 .id = V4L2_CID_SHARPNESS,
200 .type = V4L2_CTRL_TYPE_INTEGER,
205 .default_value = 0x06,
207 .set = sd_setsharpness,
208 .get = sd_getsharpness,
213 .id = V4L2_CID_EFFECTS,
214 .type = V4L2_CTRL_TYPE_MENU,
215 .name = "Webcam Effects",
226 static char *effects_control[] = {
228 "Emboss", /* disabled */
232 "Sun Effect", /* disabled */
236 static struct v4l2_pix_format vga_mode_t16[] = {
237 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
239 .sizeimage = 160 * 120 * 4 / 8 + 590,
240 .colorspace = V4L2_COLORSPACE_JPEG,
242 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
244 .sizeimage = 176 * 144 * 3 / 8 + 590,
245 .colorspace = V4L2_COLORSPACE_JPEG,
247 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
249 .sizeimage = 320 * 240 * 3 / 8 + 590,
250 .colorspace = V4L2_COLORSPACE_JPEG,
252 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
254 .sizeimage = 352 * 288 * 3 / 8 + 590,
255 .colorspace = V4L2_COLORSPACE_JPEG,
257 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
259 .sizeimage = 640 * 480 * 3 / 8 + 590,
260 .colorspace = V4L2_COLORSPACE_JPEG,
264 #define MAX_EFFECTS 7
265 /* easily done by soft, this table could be removed,
266 * i keep it here just in case */
267 static const __u8 effects_table[MAX_EFFECTS][6] = {
268 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */
269 {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */
270 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */
271 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80}, /* Sepia */
272 {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02}, /* Croquis */
273 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10}, /* Sun Effect */
274 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */
277 static const __u8 gamma_table[GAMMA_MAX][34] = {
278 {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85, /* 0 */
279 0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9,
280 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb,
281 0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8,
283 {0x90, 0x00, 0x91, 0x33, 0x92, 0x5a, 0x93, 0x75, /* 1 */
284 0x94, 0x85, 0x95, 0x93, 0x96, 0xa1, 0x97, 0xad,
285 0x98, 0xb7, 0x99, 0xc2, 0x9a, 0xcb, 0x9b, 0xd4,
286 0x9c, 0xde, 0x9D, 0xe7, 0x9e, 0xf0, 0x9f, 0xf7,
288 {0x90, 0x00, 0x91, 0x2f, 0x92, 0x51, 0x93, 0x6b, /* 2 */
289 0x94, 0x7c, 0x95, 0x8a, 0x96, 0x99, 0x97, 0xa6,
290 0x98, 0xb1, 0x99, 0xbc, 0x9a, 0xc6, 0x9b, 0xd0,
291 0x9c, 0xdb, 0x9d, 0xe4, 0x9e, 0xed, 0x9f, 0xf6,
293 {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60, /* 3 */
294 0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9e,
295 0x98, 0xaa, 0x99, 0xb5, 0x9a, 0xbf, 0x9b, 0xcb,
296 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5,
298 {0x90, 0x00, 0x91, 0x23, 0x92, 0x3f, 0x93, 0x55, /* 4 */
299 0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95,
300 0x98, 0xa2, 0x99, 0xad, 0x9a, 0xb9, 0x9b, 0xc6,
301 0x9c, 0xd2, 0x9d, 0xde, 0x9e, 0xe9, 0x9f, 0xf4,
303 {0x90, 0x00, 0x91, 0x1b, 0x92, 0x33, 0x93, 0x48, /* 5 */
304 0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87,
305 0x98, 0x96, 0x99, 0xa3, 0x9a, 0xb1, 0x9b, 0xbe,
306 0x9c, 0xcc, 0x9d, 0xda, 0x9e, 0xe7, 0x9f, 0xf3,
308 {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20, /* 6 */
309 0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67,
310 0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa,
311 0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee,
313 {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26, /* 7 */
314 0x94, 0x38, 0x95, 0x4a, 0x96, 0x60, 0x97, 0x70,
315 0x98, 0x80, 0x99, 0x90, 0x9a, 0xa0, 0x9b, 0xb0,
316 0x9c, 0xc0, 0x9D, 0xd0, 0x9e, 0xe0, 0x9f, 0xf0,
318 {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35, /* 8 */
319 0x94, 0x47, 0x95, 0x5a, 0x96, 0x69, 0x97, 0x79,
320 0x98, 0x88, 0x99, 0x97, 0x9a, 0xa7, 0x9b, 0xb6,
321 0x9c, 0xc4, 0x9d, 0xd3, 0x9e, 0xe0, 0x9f, 0xf0,
323 {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40, /* 9 */
324 0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
325 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd,
326 0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0,
328 {0x90, 0x00, 0x91, 0x18, 0x92, 0x2b, 0x93, 0x44, /* 10 */
329 0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8e,
330 0x98, 0x9c, 0x99, 0xaa, 0x9a, 0xb7, 0x9b, 0xc4,
331 0x9c, 0xd0, 0x9d, 0xd8, 0x9e, 0xe2, 0x9f, 0xf0,
333 {0x90, 0x00, 0x91, 0x1a, 0x92, 0x34, 0x93, 0x52, /* 11 */
334 0x94, 0x66, 0x95, 0x7e, 0x96, 0x8D, 0x97, 0x9B,
335 0x98, 0xa8, 0x99, 0xb4, 0x9a, 0xc0, 0x9b, 0xcb,
336 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5,
338 {0x90, 0x00, 0x91, 0x3f, 0x92, 0x5a, 0x93, 0x6e, /* 12 */
339 0x94, 0x7f, 0x95, 0x8e, 0x96, 0x9c, 0x97, 0xa8,
340 0x98, 0xb4, 0x99, 0xbf, 0x9a, 0xc9, 0x9b, 0xd3,
341 0x9c, 0xdc, 0x9d, 0xe5, 0x9e, 0xee, 0x9f, 0xf6,
343 {0x90, 0x00, 0x91, 0x54, 0x92, 0x6f, 0x93, 0x83, /* 13 */
344 0x94, 0x93, 0x95, 0xa0, 0x96, 0xad, 0x97, 0xb7,
345 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdc,
346 0x9c, 0xe4, 0x9d, 0xeb, 0x9e, 0xf2, 0x9f, 0xf9,
348 {0x90, 0x00, 0x91, 0x6e, 0x92, 0x88, 0x93, 0x9a, /* 14 */
349 0x94, 0xa8, 0x95, 0xb3, 0x96, 0xbd, 0x97, 0xc6,
350 0x98, 0xcf, 0x99, 0xd6, 0x9a, 0xdd, 0x9b, 0xe3,
351 0x9c, 0xe9, 0x9d, 0xef, 0x9e, 0xf4, 0x9f, 0xfa,
353 {0x90, 0x00, 0x91, 0x93, 0x92, 0xa8, 0x93, 0xb7, /* 15 */
354 0x94, 0xc1, 0x95, 0xca, 0x96, 0xd2, 0x97, 0xd8,
355 0x98, 0xde, 0x99, 0xe3, 0x9a, 0xe8, 0x9b, 0xed,
356 0x9c, 0xf1, 0x9d, 0xf5, 0x9e, 0xf8, 0x9f, 0xfc,
360 static const __u8 tas5130a_sensor_init[][8] = {
361 {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
362 {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
363 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
364 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
369 static int reg_r(struct gspca_dev *gspca_dev,
372 usb_control_msg(gspca_dev->dev,
373 usb_rcvctrlpipe(gspca_dev->dev, 0),
375 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
378 gspca_dev->usb_buf, 1, 500);
379 return gspca_dev->usb_buf[0];
382 static void reg_w(struct gspca_dev *gspca_dev,
385 usb_control_msg(gspca_dev->dev,
386 usb_sndctrlpipe(gspca_dev->dev, 0),
388 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
393 static void i2c_w(struct gspca_dev *gspca_dev,
394 const __u8 *buffer, __u16 len)
396 if (len <= USB_BUF_SZ) {
397 memcpy(gspca_dev->usb_buf, buffer, len);
398 usb_control_msg(gspca_dev->dev,
399 usb_sndctrlpipe(gspca_dev->dev, 0),
401 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
403 gspca_dev->usb_buf, len, 500);
407 tmpbuf = kmalloc(len, GFP_KERNEL);
408 memcpy(tmpbuf, buffer, len);
409 usb_control_msg(gspca_dev->dev,
410 usb_sndctrlpipe(gspca_dev->dev, 0),
412 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
419 static void other_sensor_init(struct gspca_dev *gspca_dev)
424 __u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
425 static const __u8 sensor_init[] = {
450 reg_w(gspca_dev, 0x3c80);
451 i2c_w(gspca_dev, val, sizeof val);
455 byte = reg_r(gspca_dev, 0x60);
460 reg_w(gspca_dev, 0x3c80);
463 /* this function is called at probe time */
464 static int sd_config(struct gspca_dev *gspca_dev,
465 const struct usb_device_id *id)
467 struct sd *sd = (struct sd *) gspca_dev;
470 cam = &gspca_dev->cam;
473 cam->cam_mode = vga_mode_t16;
474 cam->nmodes = ARRAY_SIZE(vga_mode_t16);
476 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
477 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
478 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
479 sd->gamma = GAMMA_DEF;
480 sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value;
481 sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value;
482 sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value;
483 sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
484 sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value;
488 static void setgamma(struct gspca_dev *gspca_dev)
490 struct sd *sd = (struct sd *) gspca_dev;
492 PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
493 i2c_w(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]);
496 /* this function is called at probe and resume time */
497 static int sd_init(struct gspca_dev *gspca_dev)
499 /* some of this registers are not really neded, because
500 * they are overriden by setbrigthness, setcontrast, etc,
501 * but wont hurt anyway, and can help someone with similar webcam
502 * to see the initial parameters.*/
503 struct sd *sd = (struct sd *) gspca_dev;
505 __u8 byte, test_byte;
507 static const __u8 read_indexs[] =
508 { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
509 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 };
510 static const __u8 n1[] =
511 {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
512 static const __u8 n2[] =
514 static const __u8 nset[] =
515 { 0x61, 0x68, 0x62, 0xff, 0x60, 0x07 };
516 static const __u8 n3[] =
517 {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
518 static const __u8 n4[] =
519 {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
520 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
521 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
522 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
523 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
524 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
525 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
526 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
527 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
528 static const __u8 nset4[] = {
529 0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, 0xe4, 0xa8,
530 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
533 /* ojo puede ser 0xe6 en vez de 0xe9 */
534 static const __u8 nset2[] = {
535 0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, 0xd4, 0xbb,
536 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
537 0xd8, 0xc8, 0xd9, 0xfc
539 static const __u8 missing[] =
540 { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
541 static const __u8 nset3[] = {
542 0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, 0xcb, 0xa8,
543 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
546 static const __u8 nset5[] =
547 { 0x8f, 0x24, 0xc3, 0x00 }; /* bright */
548 static const __u8 nset7[4] =
549 { 0x66, 0xca, 0xa8, 0xf8 }; /* 50/60 Hz */
550 static const __u8 nset9[4] =
551 { 0x0b, 0x04, 0x0a, 0x78 };
552 static const __u8 nset8[6] =
553 { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
554 static const __u8 nset10[6] =
555 { 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 };
557 byte = reg_r(gspca_dev, 0x06);
558 test_byte = reg_r(gspca_dev, 0x07);
559 if (byte == 0x08 && test_byte == 0x07) {
560 PDEBUG(D_CONF, "other sensor");
561 sd->sensor = SENSOR_OTHER;
563 PDEBUG(D_CONF, "sensor %02x %02x", byte, test_byte);
564 sd->sensor = SENSOR_TAS5130A;
567 i2c_w(gspca_dev, n1, sizeof n1);
571 i2c_w(gspca_dev, nset, sizeof nset);
573 test_byte = reg_r(gspca_dev, 0x0063);
575 if (test_byte == 0x17)
579 err("Bad sensor reset %02x", test_byte);
581 /*fixme: test - continue */
583 i2c_w(gspca_dev, n2, sizeof n2);
586 while (read_indexs[i] != 0x00) {
587 test_byte = reg_r(gspca_dev, read_indexs[i]);
588 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i],
593 i2c_w(gspca_dev, n3, sizeof n3);
594 i2c_w(gspca_dev, n4, sizeof n4);
595 reg_r(gspca_dev, 0x0080);
596 reg_w(gspca_dev, 0x2c80);
597 i2c_w(gspca_dev, nset2, sizeof nset2);
598 i2c_w(gspca_dev, nset3, sizeof nset3);
599 i2c_w(gspca_dev, nset4, sizeof nset4);
600 reg_w(gspca_dev, 0x3880);
601 reg_w(gspca_dev, 0x3880);
602 reg_w(gspca_dev, 0x338e);
603 i2c_w(gspca_dev, nset5, sizeof nset5);
604 reg_w(gspca_dev, 0x00a9);
606 reg_w(gspca_dev, 0x86bb);
607 reg_w(gspca_dev, 0x4aa6);
609 i2c_w(gspca_dev, missing, sizeof missing);
611 reg_w(gspca_dev, 0x2087);
612 reg_w(gspca_dev, 0x2088);
613 reg_w(gspca_dev, 0x2089);
615 i2c_w(gspca_dev, nset7, sizeof nset7);
616 i2c_w(gspca_dev, nset10, sizeof nset10);
617 i2c_w(gspca_dev, nset8, sizeof nset8);
618 i2c_w(gspca_dev, nset9, sizeof nset9);
620 reg_w(gspca_dev, 0x2880);
621 i2c_w(gspca_dev, nset2, sizeof nset2);
622 i2c_w(gspca_dev, nset3, sizeof nset3);
623 i2c_w(gspca_dev, nset4, sizeof nset4);
628 static void setbrightness(struct gspca_dev *gspca_dev)
630 struct sd *sd = (struct sd *) gspca_dev;
631 unsigned int brightness;
632 __u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x00 };
634 brightness = sd->brightness;
635 if (brightness < 7) {
636 set6[3] = 0x70 - brightness * 0x10;
639 set6[3] = 0x00 + ((brightness - 7) * 0x10);
642 i2c_w(gspca_dev, set6, sizeof set6);
645 static void setflip(struct gspca_dev *gspca_dev)
647 struct sd *sd = (struct sd *) gspca_dev;
649 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
654 i2c_w(gspca_dev, flipcmd, sizeof flipcmd);
657 static void seteffect(struct gspca_dev *gspca_dev)
659 struct sd *sd = (struct sd *) gspca_dev;
661 i2c_w(gspca_dev, effects_table[sd->effect], sizeof effects_table[0]);
662 if (sd->effect == 1 || sd->effect == 5) {
664 "This effect have been disabled for webcam \"safety\"");
668 if (sd->effect == 1 || sd->effect == 4)
669 reg_w(gspca_dev, 0x4aa6);
671 reg_w(gspca_dev, 0xfaa6);
674 static void setwhitebalance(struct gspca_dev *gspca_dev)
676 struct sd *sd = (struct sd *) gspca_dev;
678 __u8 white_balance[8] =
679 { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
681 if (sd->whitebalance == 1)
682 white_balance[7] = 0x3c;
684 i2c_w(gspca_dev, white_balance, sizeof white_balance);
687 static void setlightfreq(struct gspca_dev *gspca_dev)
689 struct sd *sd = (struct sd *) gspca_dev;
690 __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
692 if (sd->freq == 2) /* 60hz */
695 i2c_w(gspca_dev, freq, sizeof freq);
698 static void setcontrast(struct gspca_dev *gspca_dev)
700 struct sd *sd = (struct sd *) gspca_dev;
701 unsigned int contrast = sd->contrast;
705 reg_to_write = 0x8ea9 - (0x200 * contrast);
707 reg_to_write = (0x00a9 + ((contrast - 7) * 0x200));
709 reg_w(gspca_dev, reg_to_write);
712 static void setcolors(struct gspca_dev *gspca_dev)
714 struct sd *sd = (struct sd *) gspca_dev;
717 reg_to_write = 0xc0bb + sd->colors * 0x100;
718 reg_w(gspca_dev, reg_to_write);
721 static void setsharpness(struct gspca_dev *gspca_dev)
723 struct sd *sd = (struct sd *) gspca_dev;
726 reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
728 reg_w(gspca_dev, reg_to_write);
731 static int sd_start(struct gspca_dev *gspca_dev)
733 struct sd *sd = (struct sd *) gspca_dev;
735 static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 };
736 __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
737 static const __u8 t3[] =
738 { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
739 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
740 static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 };
742 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
744 case 1: /* 352x288 */
747 case 2: /* 320x240 */
750 case 3: /* 176x144 */
753 case 4: /* 160x120 */
756 default: /* 640x480 (0x00) */
760 if (sd->sensor == SENSOR_TAS5130A) {
762 while (tas5130a_sensor_init[i][0] != 0) {
763 i2c_w(gspca_dev, tas5130a_sensor_init[i],
764 sizeof tas5130a_sensor_init[0]);
767 reg_w(gspca_dev, 0x3c80);
768 /* just in case and to keep sync with logs (for mine) */
769 i2c_w(gspca_dev, tas5130a_sensor_init[3],
770 sizeof tas5130a_sensor_init[0]);
771 reg_w(gspca_dev, 0x3c80);
773 other_sensor_init(gspca_dev);
775 /* just in case and to keep sync with logs (for mine) */
776 i2c_w(gspca_dev, t1, sizeof t1);
777 i2c_w(gspca_dev, t2, sizeof t2);
778 reg_r(gspca_dev, 0x0012);
779 i2c_w(gspca_dev, t3, sizeof t3);
780 reg_w(gspca_dev, 0x0013);
781 i2c_w(gspca_dev, t4, sizeof t4);
782 /* restart on each start, just in case, sometimes regs goes wrong
783 * when using controls from app */
784 setbrightness(gspca_dev);
785 setcontrast(gspca_dev);
786 setcolors(gspca_dev);
790 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
791 struct gspca_frame *frame, /* target */
792 __u8 *data, /* isoc packet */
793 int len) /* iso packet length */
795 static __u8 ffd9[] = { 0xff, 0xd9 };
797 if (data[0] == 0x5a) {
798 /* Control Packet, after this came the header again,
799 * but extra bytes came in the packet before this,
800 * sometimes an EOF arrives, sometimes not... */
805 if (data[0] == 0xff && data[1] == 0xd8) {
806 /* extra bytes....., could be processed too but would be
807 * a waste of time, right now leave the application and
808 * libjpeg do it for ourserlves.. */
809 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
811 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
815 if (data[len - 2] == 0xff && data[len - 1] == 0xd9) {
816 /* Just in case, i have seen packets with the marker,
817 * other's do not include it... */
820 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
823 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
825 struct sd *sd = (struct sd *) gspca_dev;
827 sd->brightness = val;
828 if (gspca_dev->streaming)
829 setbrightness(gspca_dev);
833 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
835 struct sd *sd = (struct sd *) gspca_dev;
837 *val = sd->brightness;
841 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
843 struct sd *sd = (struct sd *) gspca_dev;
845 sd->whitebalance = val;
846 if (gspca_dev->streaming)
847 setwhitebalance(gspca_dev);
851 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
853 struct sd *sd = (struct sd *) gspca_dev;
855 *val = sd->whitebalance;
859 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val)
861 struct sd *sd = (struct sd *) gspca_dev;
864 if (gspca_dev->streaming)
869 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val)
871 struct sd *sd = (struct sd *) gspca_dev;
877 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val)
879 struct sd *sd = (struct sd *) gspca_dev;
882 if (gspca_dev->streaming)
883 seteffect(gspca_dev);
887 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val)
889 struct sd *sd = (struct sd *) gspca_dev;
895 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
897 struct sd *sd = (struct sd *) gspca_dev;
900 if (gspca_dev->streaming)
901 setcontrast(gspca_dev);
905 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
907 struct sd *sd = (struct sd *) gspca_dev;
913 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
915 struct sd *sd = (struct sd *) gspca_dev;
918 if (gspca_dev->streaming)
919 setcolors(gspca_dev);
923 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
925 struct sd *sd = (struct sd *) gspca_dev;
931 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
933 struct sd *sd = (struct sd *) gspca_dev;
936 if (gspca_dev->streaming)
941 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
943 struct sd *sd = (struct sd *) gspca_dev;
949 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
951 struct sd *sd = (struct sd *) gspca_dev;
954 if (gspca_dev->streaming)
955 setlightfreq(gspca_dev);
959 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
961 struct sd *sd = (struct sd *) gspca_dev;
967 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
969 struct sd *sd = (struct sd *) gspca_dev;
972 if (gspca_dev->streaming)
973 setsharpness(gspca_dev);
977 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
979 struct sd *sd = (struct sd *) gspca_dev;
981 *val = sd->sharpness;
985 /* Low Light set here......*/
986 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
988 struct sd *sd = (struct sd *) gspca_dev;
992 reg_w(gspca_dev, 0xf48e);
994 reg_w(gspca_dev, 0xb48e);
998 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
1000 struct sd *sd = (struct sd *) gspca_dev;
1002 *val = sd->autogain;
1006 static int sd_querymenu(struct gspca_dev *gspca_dev,
1007 struct v4l2_querymenu *menu)
1010 case V4L2_CID_POWER_LINE_FREQUENCY:
1011 switch (menu->index) {
1012 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1013 strcpy((char *) menu->name, "50 Hz");
1015 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1016 strcpy((char *) menu->name, "60 Hz");
1020 case V4L2_CID_EFFECTS:
1021 if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
1022 strncpy((char *) menu->name,
1023 effects_control[menu->index], 32);
1031 /* sub-driver description */
1032 static const struct sd_desc sd_desc = {
1033 .name = MODULE_NAME,
1035 .nctrls = ARRAY_SIZE(sd_ctrls),
1036 .config = sd_config,
1039 .pkt_scan = sd_pkt_scan,
1040 .querymenu = sd_querymenu,
1043 /* -- module initialisation -- */
1044 static const __devinitdata struct usb_device_id device_table[] = {
1045 {USB_DEVICE(0x17a1, 0x0128)},
1048 MODULE_DEVICE_TABLE(usb, device_table);
1050 /* -- device connect -- */
1051 static int sd_probe(struct usb_interface *intf,
1052 const struct usb_device_id *id)
1054 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1058 static struct usb_driver sd_driver = {
1059 .name = MODULE_NAME,
1060 .id_table = device_table,
1062 .disconnect = gspca_disconnect,
1064 .suspend = gspca_suspend,
1065 .resume = gspca_resume,
1069 /* -- module insert / remove -- */
1070 static int __init sd_mod_init(void)
1072 if (usb_register(&sd_driver) < 0)
1074 PDEBUG(D_PROBE, "registered");
1077 static void __exit sd_mod_exit(void)
1079 usb_deregister(&sd_driver);
1080 PDEBUG(D_PROBE, "deregistered");
1083 module_init(sd_mod_init);
1084 module_exit(sd_mod_exit);