V4L/DVB (8201): gspca: v4l2_pix_format in each subdriver.
[firewire-audio.git] / drivers / media / video / gspca / t613.c
blob299f84584e82ae202124040fef51599c982892ba
1 /*
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.
8 * Costantino Leandro
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
15 * any later version.
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"
28 #include "gspca.h"
29 #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5)
30 static const char version[] = "2.1.5";
32 #define MAX_GAMMA 0x10 /* 0 to 15 */
34 /* From LUVCVIEW */
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");
41 struct sd {
42 struct gspca_dev gspca_dev; /* !! must be the first item */
44 unsigned char brightness;
45 unsigned char contrast;
46 unsigned char colors;
47 unsigned char autogain;
48 unsigned char gamma;
49 unsigned char sharpness;
50 unsigned char freq;
51 unsigned char whitebalance;
52 unsigned char mirror;
53 unsigned char effect;
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,
86 .name = "Brightness",
87 .minimum = 0,
88 .maximum = 0x0f,
89 .step = 1,
90 .default_value = 0x09,
92 .set = sd_setbrightness,
93 .get = sd_getbrightness,
95 #define SD_CONTRAST 1
98 .id = V4L2_CID_CONTRAST,
99 .type = V4L2_CTRL_TYPE_INTEGER,
100 .name = "Contrast",
101 .minimum = 0,
102 .maximum = 0x0d,
103 .step = 1,
104 .default_value = 0x07,
106 .set = sd_setcontrast,
107 .get = sd_getcontrast,
109 #define SD_COLOR 2
112 .id = V4L2_CID_SATURATION,
113 .type = V4L2_CTRL_TYPE_INTEGER,
114 .name = "Color",
115 .minimum = 0,
116 .maximum = 0x0f,
117 .step = 1,
118 .default_value = 0x05,
120 .set = sd_setcolors,
121 .get = sd_getcolors,
123 #define SD_GAMMA 3
126 .id = V4L2_CID_GAMMA, /* (gamma on win) */
127 .type = V4L2_CTRL_TYPE_INTEGER,
128 .name = "Gamma (Untested)",
129 .minimum = 0,
130 .maximum = MAX_GAMMA,
131 .step = 1,
132 .default_value = 0x09,
134 .set = sd_setgamma,
135 .get = sd_getgamma,
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,
144 .name = "Low Light",
145 .minimum = 0,
146 .maximum = 1,
147 .step = 1,
148 .default_value = 0x01,
150 .set = sd_setlowlight,
151 .get = sd_getlowlight,
153 #define SD_MIRROR 5
156 .id = V4L2_CID_HFLIP,
157 .type = V4L2_CTRL_TYPE_BOOLEAN,
158 .name = "Mirror Image",
159 .minimum = 0,
160 .maximum = 1,
161 .step = 1,
162 .default_value = 0,
164 .set = sd_setflip,
165 .get = sd_getflip
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 */
174 .maximum = 2,
175 .step = 1,
176 .default_value = 1,
178 .set = sd_setfreq,
179 .get = sd_getfreq},
181 #define SD_WHITE_BALANCE 7
184 .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
185 .type = V4L2_CTRL_TYPE_INTEGER,
186 .name = "White Balance",
187 .minimum = 0,
188 .maximum = 1,
189 .step = 1,
190 .default_value = 1,
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,
200 .name = "Sharpness",
201 .minimum = 0,
202 .maximum = MAX_GAMMA, /* 0 to 16 */
203 .step = 1,
204 .default_value = 0x06,
206 .set = sd_setsharpness,
207 .get = sd_getsharpness,
209 #define SD_EFFECTS 9
212 .id = V4L2_CID_EFFECTS,
213 .type = V4L2_CTRL_TYPE_MENU,
214 .name = "Webcam Effects",
215 .minimum = 0,
216 .maximum = 4,
217 .step = 1,
218 .default_value = 0,
220 .set = sd_seteffect,
221 .get = sd_geteffect
225 static char *effects_control[] = {
226 "Normal",
227 "Emboss", /* disabled */
228 "Monochrome",
229 "Sepia",
230 "Sketch",
231 "Sun Effect", /* disabled */
232 "Negative",
235 static struct v4l2_pix_format vga_mode_t16[] = {
236 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
237 .bytesperline = 160,
238 .sizeimage = 160 * 120 * 3 / 8 + 590,
239 .colorspace = V4L2_COLORSPACE_JPEG,
240 .priv = 4},
241 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
242 .bytesperline = 176,
243 .sizeimage = 176 * 144 * 3 / 8 + 590,
244 .colorspace = V4L2_COLORSPACE_JPEG,
245 .priv = 3},
246 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
247 .bytesperline = 320,
248 .sizeimage = 320 * 240 * 3 / 8 + 590,
249 .colorspace = V4L2_COLORSPACE_JPEG,
250 .priv = 2},
251 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
252 .bytesperline = 352,
253 .sizeimage = 352 * 288 * 3 / 8 + 590,
254 .colorspace = V4L2_COLORSPACE_JPEG,
255 .priv = 1},
256 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
257 .bytesperline = 640,
258 .sizeimage = 640 * 480 * 3 / 8 + 590,
259 .colorspace = V4L2_COLORSPACE_JPEG,
260 .priv = 0},
263 #define T16_OFFSET_DATA 631
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[MAX_GAMMA][34] = {
278 {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85,
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,
282 0xa0, 0xff},
283 {0x90, 0x00, 0x91, 0x33, 0x92, 0x5A, 0x93, 0x75,
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,
287 0xa0, 0xff},
288 {0x90, 0x00, 0x91, 0x2F, 0x92, 0x51, 0x93, 0x6B,
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,
292 0xa0, 0xff},
293 {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60,
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,
297 0xa0, 0xff},
298 {0x90, 0x00, 0x91, 0x23, 0x92, 0x3F, 0x93, 0x55,
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,
302 0xa0, 0xff},
303 {0x90, 0x00, 0x91, 0x1B, 0x92, 0x33, 0x93, 0x48,
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,
307 0xa0, 0xff},
308 {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20,
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,
312 0xa0, 0xff},
313 {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26,
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,
317 0xa0, 0xff},
318 {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35,
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,
322 0xa0, 0xff},
323 {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40,
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,
327 0xa0, 0xff},
328 {0x90, 0x00, 0x91, 0x18, 0x92, 0x2B, 0x93, 0x44,
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,
332 0xa0, 0xff},
333 {0x90, 0x00, 0x91, 0x1A, 0x92, 0x34, 0x93, 0x52,
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,
337 0xa0, 0xff},
338 {0x90, 0x00, 0x91, 0x3F, 0x92, 0x5A, 0x93, 0x6E,
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,
342 0xA0, 0xFF},
343 {0x90, 0x00, 0x91, 0x54, 0x92, 0x6F, 0x93, 0x83,
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,
347 0xa0, 0xff},
348 {0x90, 0x00, 0x91, 0x6E, 0x92, 0x88, 0x93, 0x9A,
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,
352 0xa0, 0xff},
353 {0x90, 0x00, 0x91, 0x93, 0x92, 0xA8, 0x93, 0xB7,
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,
357 0xA0, 0xFF}
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},
368 static void t16RegRead(struct usb_device *dev,
369 __u16 index, __u8 *buffer, __u16 length)
371 usb_control_msg(dev,
372 usb_rcvctrlpipe(dev, 0),
373 0, /* request */
374 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
375 0, /* value */
376 index, buffer, length, 500);
379 static void t16RegWrite(struct usb_device *dev,
380 __u16 value,
381 __u16 index,
382 const __u8 *buffer, __u16 len)
384 if (buffer == NULL) {
385 usb_control_msg(dev,
386 usb_sndctrlpipe(dev, 0),
388 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
389 value, index,
390 NULL, 0, 500);
391 return;
393 if (len < 16) {
394 __u8 tmpbuf[16];
396 memcpy(tmpbuf, buffer, len);
397 usb_control_msg(dev,
398 usb_sndctrlpipe(dev, 0),
400 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
401 value, index,
402 tmpbuf, len, 500);
403 } else {
404 __u8 *tmpbuf;
406 tmpbuf = kmalloc(len, GFP_KERNEL);
407 memcpy(tmpbuf, buffer, len);
408 usb_control_msg(dev,
409 usb_sndctrlpipe(dev, 0),
411 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
412 value, index,
413 tmpbuf, len, 500);
414 kfree(tmpbuf);
418 /* this function is called at probe time */
419 static int sd_config(struct gspca_dev *gspca_dev,
420 const struct usb_device_id *id)
422 struct sd *sd = (struct sd *) gspca_dev;
423 struct cam *cam;
425 cam = &gspca_dev->cam;
426 cam->dev_name = (char *) id->driver_info;
427 cam->epaddr = 0x01;
429 cam->cam_mode = vga_mode_t16;
430 cam->nmodes = ARRAY_SIZE(vga_mode_t16);
432 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
433 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
434 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
435 sd->gamma = sd_ctrls[SD_GAMMA].qctrl.default_value;
436 sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value;
437 sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value;
438 sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value;
439 sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
440 sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value;
441 return 0;
444 static int init_default_parameters(struct gspca_dev *gspca_dev)
446 struct usb_device *dev = gspca_dev->dev;
448 /* some of this registers are not really neded, because
449 * they are overriden by setbrigthness, setcontrast, etc,
450 * but wont hurt anyway, and can help someone with similar webcam
451 * to see the initial parameters.*/
452 int i = 0;
453 __u8 test_byte;
455 static const __u8 read_indexs[] =
456 { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
457 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 };
458 static const __u8 n1[6] =
459 {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
460 static const __u8 n2[2] =
461 {0x08, 0x00};
462 static const __u8 nset[6] =
463 { 0x61, 0x68, 0x62, 0xff, 0x60, 0x07 };
464 static const __u8 n3[6] =
465 {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
466 static const __u8 n4[0x46] =
467 {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
468 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
469 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
470 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
471 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
472 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
473 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
474 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
475 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
476 static const __u8 nset4[18] = {
477 0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, 0xe4, 0xa8,
478 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
479 0xe8, 0xe0
481 /* ojo puede ser 0xe6 en vez de 0xe9 */
482 static const __u8 nset2[20] = {
483 0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, 0xd4, 0xbb,
484 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
485 0xd8, 0xc8, 0xd9, 0xfc
487 static const __u8 missing[8] =
488 { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
489 static const __u8 nset3[18] = {
490 0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, 0xcb, 0xa8,
491 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
492 0xcf, 0xe0
494 static const __u8 nset5[4] =
495 { 0x8f, 0x24, 0xc3, 0x00 }; /* bright */
496 static const __u8 nset6[34] = {
497 0x90, 0x00, 0x91, 0x1c, 0x92, 0x30, 0x93, 0x43, 0x94, 0x54,
498 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
499 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd, 0x9c, 0xca,
500 0x9d, 0xd8, 0x9e, 0xe5, 0x9f, 0xf2,
501 0xa0, 0xff
502 }; /* Gamma */
503 static const __u8 nset7[4] =
504 { 0x66, 0xca, 0xa8, 0xf8 }; /* 50/60 Hz */
505 static const __u8 nset9[4] =
506 { 0x0b, 0x04, 0x0a, 0x78 };
507 static const __u8 nset8[6] =
508 { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
509 static const __u8 nset10[6] =
510 { 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 };
512 t16RegWrite(dev, 0x01, 0x0000, n1, 0x06);
513 t16RegWrite(dev, 0x01, 0x0000, nset, 0x06);
514 t16RegRead(dev, 0x0063, &test_byte, 1);
515 t16RegWrite(dev, 0x01, 0x0000, n2, 0x02);
517 while (read_indexs[i] != 0x00) {
518 t16RegRead(dev, read_indexs[i], &test_byte, 1);
519 PDEBUG(D_CONF, "Reg 0x%x => 0x%x", read_indexs[i],
520 test_byte);
521 i++;
524 t16RegWrite(dev, 0x01, 0x0000, n3, 0x06);
525 t16RegWrite(dev, 0x01, 0x0000, n4, 0x46);
526 t16RegRead(dev, 0x0080, &test_byte, 1);
527 t16RegWrite(dev, 0x00, 0x2c80, NULL, 0);
528 t16RegWrite(dev, 0x01, 0x0000, nset2, 0x14);
529 t16RegWrite(dev, 0x01, 0x0000, nset3, 0x12);
530 t16RegWrite(dev, 0x01, 0x0000, nset4, 0x12);
531 t16RegWrite(dev, 0x00, 0x3880, NULL, 0);
532 t16RegWrite(dev, 0x00, 0x3880, NULL, 0);
533 t16RegWrite(dev, 0x00, 0x338e, NULL, 0);
534 t16RegWrite(dev, 0x01, 0x0000, nset5, 0x04);
535 t16RegWrite(dev, 0x00, 0x00a9, NULL, 0);
536 t16RegWrite(dev, 0x01, 0x0000, nset6, 0x22);
537 t16RegWrite(dev, 0x00, 0x86bb, NULL, 0);
538 t16RegWrite(dev, 0x00, 0x4aa6, NULL, 0);
540 t16RegWrite(dev, 0x01, 0x0000, missing, 0x08);
542 t16RegWrite(dev, 0x00, 0x2087, NULL, 0);
543 t16RegWrite(dev, 0x00, 0x2088, NULL, 0);
544 t16RegWrite(dev, 0x00, 0x2089, NULL, 0);
546 t16RegWrite(dev, 0x01, 0x0000, nset7, 0x04);
547 t16RegWrite(dev, 0x01, 0x0000, nset10, 0x06);
548 t16RegWrite(dev, 0x01, 0x0000, nset8, 0x06);
549 t16RegWrite(dev, 0x01, 0x0000, nset9, 0x04);
551 t16RegWrite(dev, 0x00, 0x2880, NULL, 0);
552 t16RegWrite(dev, 0x01, 0x0000, nset2, 0x14);
553 t16RegWrite(dev, 0x01, 0x0000, nset3, 0x12);
554 t16RegWrite(dev, 0x01, 0x0000, nset4, 0x12);
556 return 0;
559 static void setbrightness(struct gspca_dev *gspca_dev)
561 struct sd *sd = (struct sd *) gspca_dev;
562 struct usb_device *dev = gspca_dev->dev;
563 unsigned int brightness;
564 __u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x80 };
565 brightness = sd->brightness;
567 if (brightness < 7) {
568 set6[3] = 0x70 - (brightness * 0xa);
569 } else {
570 set6[1] = 0x24;
571 set6[3] = 0x00 + ((brightness - 7) * 0xa);
574 t16RegWrite(dev, 0x01, 0x0000, set6, 4);
577 static void setflip(struct gspca_dev *gspca_dev)
579 struct sd *sd = (struct sd *) gspca_dev;
580 struct usb_device *dev = gspca_dev->dev;
582 __u8 flipcmd[8] =
583 { 0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09 };
585 if (sd->mirror == 1)
586 flipcmd[3] = 0x01;
588 t16RegWrite(dev, 0x01, 0x0000, flipcmd, 8);
591 static void seteffect(struct gspca_dev *gspca_dev)
593 struct sd *sd = (struct sd *) gspca_dev;
594 struct usb_device *dev = gspca_dev->dev;
596 t16RegWrite(dev, 0x01, 0x0000, effects_table[sd->effect], 0x06);
597 if (sd->effect == 1 || sd->effect == 5) {
598 PDEBUG(D_CONF,
599 "This effect have been disabled for webcam \"safety\"");
600 return;
603 if (sd->effect == 1 || sd->effect == 4)
604 t16RegWrite(dev, 0x00, 0x4aa6, NULL, 0);
605 else
606 t16RegWrite(dev, 0x00, 0xfaa6, NULL, 0);
609 static void setwhitebalance(struct gspca_dev *gspca_dev)
611 struct sd *sd = (struct sd *) gspca_dev;
612 struct usb_device *dev = gspca_dev->dev;
614 __u8 white_balance[8] =
615 { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
617 if (sd->whitebalance == 1)
618 white_balance[7] = 0x3c;
620 t16RegWrite(dev, 0x01, 0x0000, white_balance, 8);
623 static void setlightfreq(struct gspca_dev *gspca_dev)
625 struct sd *sd = (struct sd *) gspca_dev;
626 struct usb_device *dev = gspca_dev->dev;
627 __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
629 if (sd->freq == 2) /* 60hz */
630 freq[1] = 0x00;
632 t16RegWrite(dev, 0x1, 0x0000, freq, 0x4);
635 static void setcontrast(struct gspca_dev *gspca_dev)
637 struct sd *sd = (struct sd *) gspca_dev;
638 struct usb_device *dev = gspca_dev->dev;
639 unsigned int contrast = sd->contrast;
640 __u16 reg_to_write = 0x00;
642 if (contrast < 7)
643 reg_to_write = 0x8ea9 - (0x200 * contrast);
644 else
645 reg_to_write = (0x00a9 + ((contrast - 7) * 0x200));
647 t16RegWrite(dev, 0x00, reg_to_write, NULL, 0);
650 static void setcolors(struct gspca_dev *gspca_dev)
652 struct sd *sd = (struct sd *) gspca_dev;
653 struct usb_device *dev = gspca_dev->dev;
654 __u16 reg_to_write;
656 reg_to_write = 0xc0bb + sd->colors * 0x100;
657 t16RegWrite(dev, 0x00, reg_to_write, NULL, 0);
660 static void setgamma(struct gspca_dev *gspca_dev)
664 static void setsharpness(struct gspca_dev *gspca_dev)
666 struct sd *sd = (struct sd *) gspca_dev;
667 struct usb_device *dev = gspca_dev->dev;
668 __u16 reg_to_write;
670 reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
672 t16RegWrite(dev, 0x00, reg_to_write, NULL, 0);
675 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
677 struct sd *sd = (struct sd *) gspca_dev;
679 sd->brightness = val;
680 if (gspca_dev->streaming)
681 setbrightness(gspca_dev);
682 return 0;
685 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
687 struct sd *sd = (struct sd *) gspca_dev;
689 *val = sd->brightness;
690 return *val;
693 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
695 struct sd *sd = (struct sd *) gspca_dev;
697 sd->whitebalance = val;
698 if (gspca_dev->streaming)
699 setwhitebalance(gspca_dev);
700 return 0;
703 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
705 struct sd *sd = (struct sd *) gspca_dev;
707 *val = sd->whitebalance;
708 return *val;
711 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val)
713 struct sd *sd = (struct sd *) gspca_dev;
715 sd->mirror = val;
716 if (gspca_dev->streaming)
717 setflip(gspca_dev);
718 return 0;
721 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val)
723 struct sd *sd = (struct sd *) gspca_dev;
725 *val = sd->mirror;
726 return *val;
729 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val)
731 struct sd *sd = (struct sd *) gspca_dev;
733 sd->effect = val;
734 if (gspca_dev->streaming)
735 seteffect(gspca_dev);
736 return 0;
739 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val)
741 struct sd *sd = (struct sd *) gspca_dev;
743 *val = sd->effect;
744 return *val;
747 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
749 struct sd *sd = (struct sd *) gspca_dev;
751 sd->contrast = val;
752 if (gspca_dev->streaming)
753 setcontrast(gspca_dev);
754 return 0;
757 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
759 struct sd *sd = (struct sd *) gspca_dev;
761 *val = sd->contrast;
762 return *val;
765 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
767 struct sd *sd = (struct sd *) gspca_dev;
769 sd->colors = val;
770 if (gspca_dev->streaming)
771 setcolors(gspca_dev);
772 return 0;
775 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
777 struct sd *sd = (struct sd *) gspca_dev;
779 *val = sd->colors;
780 return 0;
783 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
785 struct sd *sd = (struct sd *) gspca_dev;
787 sd->gamma = val;
788 if (gspca_dev->streaming)
789 setgamma(gspca_dev);
790 return 0;
793 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
795 struct sd *sd = (struct sd *) gspca_dev;
796 *val = sd->gamma;
797 return 0;
800 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
802 struct sd *sd = (struct sd *) gspca_dev;
804 sd->freq = val;
805 if (gspca_dev->streaming)
806 setlightfreq(gspca_dev);
807 return 0;
810 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
812 struct sd *sd = (struct sd *) gspca_dev;
814 *val = sd->freq;
815 return 0;
818 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
820 struct sd *sd = (struct sd *) gspca_dev;
822 sd->sharpness = val;
823 if (gspca_dev->streaming)
824 setsharpness(gspca_dev);
825 return 0;
828 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
830 struct sd *sd = (struct sd *) gspca_dev;
832 *val = sd->sharpness;
833 return 0;
836 /* Low Light set here......*/
837 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
839 struct sd *sd = (struct sd *) gspca_dev;
840 struct usb_device *dev = gspca_dev->dev;
842 sd->autogain = val;
843 if (val != 0)
844 t16RegWrite(dev, 0x00, 0xf48e, NULL, 0);
845 else
846 t16RegWrite(dev, 0x00, 0xb48e, NULL, 0);
847 return 0;
850 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
852 struct sd *sd = (struct sd *) gspca_dev;
854 *val = sd->autogain;
855 return 0;
858 static void sd_start(struct gspca_dev *gspca_dev)
860 struct usb_device *dev = gspca_dev->dev;
861 int mode;
862 __u8 test_byte;
864 static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 };
865 __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
866 static const __u8 t3[] =
867 { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
868 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
869 static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 };
871 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
872 switch (mode) {
873 case 1: /* 352x288 */
874 t2[1] = 0x40;
875 break;
876 case 2: /* 320x240 */
877 t2[1] = 0x10;
878 break;
879 case 3: /* 176x144 */
880 t2[1] = 0x50;
881 break;
882 case 4: /* 160x120 */
883 t2[1] = 0x20;
884 break;
885 default: /* 640x480 (0x00) */
886 break;
889 t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[0], 0x8);
890 t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[1], 0x8);
891 t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[2], 0x8);
892 t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
893 t16RegWrite(dev, 0x00, 0x3c80, NULL, 0);
894 /* just in case and to keep sync with logs (for mine) */
895 t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
896 t16RegWrite(dev, 0x00, 0x3c80, NULL, 0);
897 /* just in case and to keep sync with logs (for mine) */
898 t16RegWrite(dev, 0x01, 0x0000, t1, 4);
899 t16RegWrite(dev, 0x01, 0x0000, t2, 6);
900 t16RegRead(dev, 0x0012, &test_byte, 0x01);
901 t16RegWrite(dev, 0x01, 0x0000, t3, 0x10);
902 t16RegWrite(dev, 0x00, 0x0013, NULL, 0);
903 t16RegWrite(dev, 0x01, 0x0000, t4, 0x4);
904 /* restart on each start, just in case, sometimes regs goes wrong
905 * when using controls from app */
906 setbrightness(gspca_dev);
907 setcontrast(gspca_dev);
908 setcolors(gspca_dev);
911 static void sd_stopN(struct gspca_dev *gspca_dev)
915 static void sd_stop0(struct gspca_dev *gspca_dev)
919 static void sd_close(struct gspca_dev *gspca_dev)
923 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
924 struct gspca_frame *frame, /* target */
925 __u8 *data, /* isoc packet */
926 int len) /* iso packet length */
928 int sof = 0;
929 static __u8 ffd9[] = { 0xff, 0xd9 };
931 if (data[0] == 0x5a) {
932 /* Control Packet, after this came the header again,
933 * but extra bytes came in the packet before this,
934 * sometimes an EOF arrives, sometimes not... */
935 return;
938 if (data[len - 1] == 0xff && data[len] == 0xd9) {
939 /* Just in case, i have seen packets with the marker,
940 * other's do not include it... */
941 data += 2;
942 len -= 4;
943 } else if (data[2] == 0xff && data[3] == 0xd8) {
944 sof = 1;
945 data += 2;
946 len -= 2;
947 } else {
948 data += 2;
949 len -= 2;
952 if (sof) {
953 /* extra bytes....., could be processed too but would be
954 * a waste of time, right now leave the application and
955 * libjpeg do it for ourserlves.. */
956 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
957 ffd9, 2);
958 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
959 return;
962 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
965 static int sd_querymenu(struct gspca_dev *gspca_dev,
966 struct v4l2_querymenu *menu)
968 switch (menu->id) {
969 case V4L2_CID_POWER_LINE_FREQUENCY:
970 switch (menu->index) {
971 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
972 strcpy((char *) menu->name, "50 Hz");
973 return 0;
974 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
975 strcpy((char *) menu->name, "60 Hz");
976 return 0;
978 break;
979 case V4L2_CID_EFFECTS:
980 if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
981 strncpy((char *) menu->name,
982 effects_control[menu->index], 32);
983 return 0;
985 break;
987 return -EINVAL;
990 /* this function is called at open time */
991 static int sd_open(struct gspca_dev *gspca_dev)
993 init_default_parameters(gspca_dev);
994 return 0;
997 /* sub-driver description */
998 static const struct sd_desc sd_desc = {
999 .name = MODULE_NAME,
1000 .ctrls = sd_ctrls,
1001 .nctrls = ARRAY_SIZE(sd_ctrls),
1002 .config = sd_config,
1003 .open = sd_open,
1004 .start = sd_start,
1005 .stopN = sd_stopN,
1006 .stop0 = sd_stop0,
1007 .close = sd_close,
1008 .pkt_scan = sd_pkt_scan,
1009 .querymenu = sd_querymenu,
1012 /* -- module initialisation -- */
1013 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1014 static const __devinitdata struct usb_device_id device_table[] = {
1015 {USB_DEVICE(0x17a1, 0x0128), DVNM("XPX Webcam")},
1018 MODULE_DEVICE_TABLE(usb, device_table);
1020 /* -- device connect -- */
1021 static int sd_probe(struct usb_interface *intf,
1022 const struct usb_device_id *id)
1024 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1025 THIS_MODULE);
1028 static struct usb_driver sd_driver = {
1029 .name = MODULE_NAME,
1030 .id_table = device_table,
1031 .probe = sd_probe,
1032 .disconnect = gspca_disconnect,
1035 /* -- module insert / remove -- */
1036 static int __init sd_mod_init(void)
1038 if (usb_register(&sd_driver) < 0)
1039 return -1;
1040 PDEBUG(D_PROBE, "v%s registered", version);
1041 return 0;
1043 static void __exit sd_mod_exit(void)
1045 usb_deregister(&sd_driver);
1046 PDEBUG(D_PROBE, "deregistered");
1049 module_init(sd_mod_init);
1050 module_exit(sd_mod_exit);