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_DEVICE,
393 static void reg_w_buf(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_DEVICE,
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_DEVICE,
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 reg_w_buf(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 reg_w_buf(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 reg_w_buf(gspca_dev, n1, sizeof n1);
571 reg_w_buf(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 reg_w_buf(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 reg_w_buf(gspca_dev, n3, sizeof n3);
594 reg_w_buf(gspca_dev, n4, sizeof n4);
595 reg_r(gspca_dev, 0x0080);
596 reg_w(gspca_dev, 0x2c80);
597 reg_w_buf(gspca_dev, nset2, sizeof nset2);
598 reg_w_buf(gspca_dev, nset3, sizeof nset3);
599 reg_w_buf(gspca_dev, nset4, sizeof nset4);
600 reg_w(gspca_dev, 0x3880);
601 reg_w(gspca_dev, 0x3880);
602 reg_w(gspca_dev, 0x338e);
603 reg_w_buf(gspca_dev, nset5, sizeof nset5);
604 reg_w(gspca_dev, 0x00a9);
606 reg_w(gspca_dev, 0x86bb);
607 reg_w(gspca_dev, 0x4aa6);
609 reg_w_buf(gspca_dev, missing, sizeof missing);
611 reg_w(gspca_dev, 0x2087);
612 reg_w(gspca_dev, 0x2088);
613 reg_w(gspca_dev, 0x2089);
615 reg_w_buf(gspca_dev, nset7, sizeof nset7);
616 reg_w_buf(gspca_dev, nset10, sizeof nset10);
617 reg_w_buf(gspca_dev, nset8, sizeof nset8);
618 reg_w_buf(gspca_dev, nset9, sizeof nset9);
620 reg_w(gspca_dev, 0x2880);
621 reg_w_buf(gspca_dev, nset2, sizeof nset2);
622 reg_w_buf(gspca_dev, nset3, sizeof nset3);
623 reg_w_buf(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 reg_w_buf(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 reg_w_buf(gspca_dev, flipcmd, sizeof flipcmd);
657 static void seteffect(struct gspca_dev *gspca_dev)
659 struct sd *sd = (struct sd *) gspca_dev;
661 reg_w_buf(gspca_dev, effects_table[sd->effect],
662 sizeof effects_table[0]);
663 if (sd->effect == 1 || sd->effect == 5) {
665 "This effect have been disabled for webcam \"safety\"");
669 if (sd->effect == 1 || sd->effect == 4)
670 reg_w(gspca_dev, 0x4aa6);
672 reg_w(gspca_dev, 0xfaa6);
675 static void setwhitebalance(struct gspca_dev *gspca_dev)
677 struct sd *sd = (struct sd *) gspca_dev;
679 __u8 white_balance[8] =
680 { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
682 if (sd->whitebalance == 1)
683 white_balance[7] = 0x3c;
685 reg_w_buf(gspca_dev, white_balance, sizeof white_balance);
688 static void setlightfreq(struct gspca_dev *gspca_dev)
690 struct sd *sd = (struct sd *) gspca_dev;
691 __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
693 if (sd->freq == 2) /* 60hz */
696 reg_w_buf(gspca_dev, freq, sizeof freq);
699 static void setcontrast(struct gspca_dev *gspca_dev)
701 struct sd *sd = (struct sd *) gspca_dev;
702 unsigned int contrast = sd->contrast;
706 reg_to_write = 0x8ea9 - (0x200 * contrast);
708 reg_to_write = (0x00a9 + ((contrast - 7) * 0x200));
710 reg_w(gspca_dev, reg_to_write);
713 static void setcolors(struct gspca_dev *gspca_dev)
715 struct sd *sd = (struct sd *) gspca_dev;
718 reg_to_write = 0xc0bb + sd->colors * 0x100;
719 reg_w(gspca_dev, reg_to_write);
722 static void setsharpness(struct gspca_dev *gspca_dev)
724 struct sd *sd = (struct sd *) gspca_dev;
727 reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
729 reg_w(gspca_dev, reg_to_write);
732 static int sd_start(struct gspca_dev *gspca_dev)
734 struct sd *sd = (struct sd *) gspca_dev;
736 static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 };
737 __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
738 static const __u8 t3[] =
739 { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
740 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
741 static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 };
743 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
745 case 1: /* 352x288 */
748 case 2: /* 320x240 */
751 case 3: /* 176x144 */
754 case 4: /* 160x120 */
757 default: /* 640x480 (0x00) */
761 if (sd->sensor == SENSOR_TAS5130A) {
763 while (tas5130a_sensor_init[i][0] != 0) {
764 reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
765 sizeof tas5130a_sensor_init[0]);
768 reg_w(gspca_dev, 0x3c80);
769 /* just in case and to keep sync with logs (for mine) */
770 reg_w_buf(gspca_dev, tas5130a_sensor_init[3],
771 sizeof tas5130a_sensor_init[0]);
772 reg_w(gspca_dev, 0x3c80);
774 other_sensor_init(gspca_dev);
776 /* just in case and to keep sync with logs (for mine) */
777 reg_w_buf(gspca_dev, t1, sizeof t1);
778 reg_w_buf(gspca_dev, t2, sizeof t2);
779 reg_r(gspca_dev, 0x0012);
780 reg_w_buf(gspca_dev, t3, sizeof t3);
781 reg_w(gspca_dev, 0x0013);
782 reg_w_buf(gspca_dev, t4, sizeof t4);
783 /* restart on each start, just in case, sometimes regs goes wrong
784 * when using controls from app */
785 setbrightness(gspca_dev);
786 setcontrast(gspca_dev);
787 setcolors(gspca_dev);
791 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
792 struct gspca_frame *frame, /* target */
793 __u8 *data, /* isoc packet */
794 int len) /* iso packet length */
796 static __u8 ffd9[] = { 0xff, 0xd9 };
798 if (data[0] == 0x5a) {
799 /* Control Packet, after this came the header again,
800 * but extra bytes came in the packet before this,
801 * sometimes an EOF arrives, sometimes not... */
806 if (data[0] == 0xff && data[1] == 0xd8) {
807 /* extra bytes....., could be processed too but would be
808 * a waste of time, right now leave the application and
809 * libjpeg do it for ourserlves.. */
810 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
812 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
816 if (data[len - 2] == 0xff && data[len - 1] == 0xd9) {
817 /* Just in case, i have seen packets with the marker,
818 * other's do not include it... */
821 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
824 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
826 struct sd *sd = (struct sd *) gspca_dev;
828 sd->brightness = val;
829 if (gspca_dev->streaming)
830 setbrightness(gspca_dev);
834 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
836 struct sd *sd = (struct sd *) gspca_dev;
838 *val = sd->brightness;
842 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
844 struct sd *sd = (struct sd *) gspca_dev;
846 sd->whitebalance = val;
847 if (gspca_dev->streaming)
848 setwhitebalance(gspca_dev);
852 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
854 struct sd *sd = (struct sd *) gspca_dev;
856 *val = sd->whitebalance;
860 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val)
862 struct sd *sd = (struct sd *) gspca_dev;
865 if (gspca_dev->streaming)
870 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val)
872 struct sd *sd = (struct sd *) gspca_dev;
878 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val)
880 struct sd *sd = (struct sd *) gspca_dev;
883 if (gspca_dev->streaming)
884 seteffect(gspca_dev);
888 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val)
890 struct sd *sd = (struct sd *) gspca_dev;
896 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
898 struct sd *sd = (struct sd *) gspca_dev;
901 if (gspca_dev->streaming)
902 setcontrast(gspca_dev);
906 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
908 struct sd *sd = (struct sd *) gspca_dev;
914 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
916 struct sd *sd = (struct sd *) gspca_dev;
919 if (gspca_dev->streaming)
920 setcolors(gspca_dev);
924 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
926 struct sd *sd = (struct sd *) gspca_dev;
932 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
934 struct sd *sd = (struct sd *) gspca_dev;
937 if (gspca_dev->streaming)
942 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
944 struct sd *sd = (struct sd *) gspca_dev;
950 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
952 struct sd *sd = (struct sd *) gspca_dev;
955 if (gspca_dev->streaming)
956 setlightfreq(gspca_dev);
960 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
962 struct sd *sd = (struct sd *) gspca_dev;
968 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
970 struct sd *sd = (struct sd *) gspca_dev;
973 if (gspca_dev->streaming)
974 setsharpness(gspca_dev);
978 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
980 struct sd *sd = (struct sd *) gspca_dev;
982 *val = sd->sharpness;
986 /* Low Light set here......*/
987 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
989 struct sd *sd = (struct sd *) gspca_dev;
993 reg_w(gspca_dev, 0xf48e);
995 reg_w(gspca_dev, 0xb48e);
999 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
1001 struct sd *sd = (struct sd *) gspca_dev;
1003 *val = sd->autogain;
1007 static int sd_querymenu(struct gspca_dev *gspca_dev,
1008 struct v4l2_querymenu *menu)
1011 case V4L2_CID_POWER_LINE_FREQUENCY:
1012 switch (menu->index) {
1013 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1014 strcpy((char *) menu->name, "50 Hz");
1016 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1017 strcpy((char *) menu->name, "60 Hz");
1021 case V4L2_CID_EFFECTS:
1022 if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
1023 strncpy((char *) menu->name,
1024 effects_control[menu->index], 32);
1032 /* sub-driver description */
1033 static const struct sd_desc sd_desc = {
1034 .name = MODULE_NAME,
1036 .nctrls = ARRAY_SIZE(sd_ctrls),
1037 .config = sd_config,
1040 .pkt_scan = sd_pkt_scan,
1041 .querymenu = sd_querymenu,
1044 /* -- module initialisation -- */
1045 static const __devinitdata struct usb_device_id device_table[] = {
1046 {USB_DEVICE(0x17a1, 0x0128)},
1049 MODULE_DEVICE_TABLE(usb, device_table);
1051 /* -- device connect -- */
1052 static int sd_probe(struct usb_interface *intf,
1053 const struct usb_device_id *id)
1055 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1059 static struct usb_driver sd_driver = {
1060 .name = MODULE_NAME,
1061 .id_table = device_table,
1063 .disconnect = gspca_disconnect,
1065 .suspend = gspca_suspend,
1066 .resume = gspca_resume,
1070 /* -- module insert / remove -- */
1071 static int __init sd_mod_init(void)
1073 if (usb_register(&sd_driver) < 0)
1075 PDEBUG(D_PROBE, "registered");
1078 static void __exit sd_mod_exit(void)
1080 usb_deregister(&sd_driver);
1081 PDEBUG(D_PROBE, "deregistered");
1084 module_init(sd_mod_init);
1085 module_exit(sd_mod_exit);