aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/t613.c
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2008-06-30 14:50:11 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-07-20 06:14:49 -0400
commit6a7eba24e4f0ff725d33159f6265e3a79d53a833 (patch)
tree3e50d669cb91affbcfad9333d74ddc452783094f /drivers/media/video/gspca/t613.c
parentd43fa32fec442571f10f5d0c3b553413288728de (diff)
V4L/DVB (8157): gspca: all subdrivers
- remaning subdrivers added - remove the decoding helper and some specific frame decodings Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/gspca/t613.c')
-rw-r--r--drivers/media/video/gspca/t613.c1013
1 files changed, 1013 insertions, 0 deletions
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
new file mode 100644
index 00000000000..c22b301ebae
--- /dev/null
+++ b/drivers/media/video/gspca/t613.c
@@ -0,0 +1,1013 @@
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
9 *
10 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
11 *
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.
16 *
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.
21 *
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
25 */
26
27#define MODULE_NAME "t613"
28#include "gspca.h"
29#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0)
30static const char version[] = "2.1.0";
31
32struct control_menu_info {
33 int value;
34 char name[32];
35};
36
37#define MAX_GAMMA 0x10 /* 0 to 15 */
38
39/* From LUVCVIEW */
40#define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 3)
41
42MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
43MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver");
44MODULE_LICENSE("GPL");
45
46struct sd {
47 struct gspca_dev gspca_dev; /* !! must be the first item */
48
49 unsigned char brightness;
50 unsigned char contrast;
51 unsigned char colors;
52 unsigned char autogain;
53 unsigned char gamma;
54 unsigned char sharpness;
55 unsigned char freq;
56 unsigned char whitebalance;
57 unsigned char mirror;
58 unsigned char effect;
59};
60
61/* V4L2 controls supported by the driver */
62static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
63static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
64static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
65static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
66static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
67static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
68static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val);
69static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val);
70static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
71static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
72static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
73static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
74static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
75static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
76static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val);
77static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val);
78static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val);
79static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val);
80static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val);
81static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val);
82static int sd_querymenu(struct gspca_dev *gspca_dev,
83 struct v4l2_querymenu *menu);
84
85static struct ctrl sd_ctrls[] = {
86#define SD_BRIGHTNESS 0
87 {
88 {
89 .id = V4L2_CID_BRIGHTNESS,
90 .type = V4L2_CTRL_TYPE_INTEGER,
91 .name = "Brightness",
92 .minimum = 0,
93 .maximum = 0x0f,
94 .step = 1,
95 .default_value = 0x09,
96 },
97 .set = sd_setbrightness,
98 .get = sd_getbrightness,
99 },
100#define SD_CONTRAST 1
101 {
102 {
103 .id = V4L2_CID_CONTRAST,
104 .type = V4L2_CTRL_TYPE_INTEGER,
105 .name = "Contrast",
106 .minimum = 0,
107 .maximum = 0x0d,
108 .step = 1,
109 .default_value = 0x07,
110 },
111 .set = sd_setcontrast,
112 .get = sd_getcontrast,
113 },
114#define SD_COLOR 2
115 {
116 {
117 .id = V4L2_CID_SATURATION,
118 .type = V4L2_CTRL_TYPE_INTEGER,
119 .name = "Color",
120 .minimum = 0,
121 .maximum = 0x0f,
122 .step = 1,
123 .default_value = 0x05,
124 },
125 .set = sd_setcolors,
126 .get = sd_getcolors,
127 },
128#define SD_GAMMA 3
129 {
130 {
131 .id = V4L2_CID_GAMMA, /* (gamma on win) */
132 .type = V4L2_CTRL_TYPE_INTEGER,
133 .name = "Gamma (Untested)",
134 .minimum = 0,
135 .maximum = MAX_GAMMA,
136 .step = 1,
137 .default_value = 0x09,
138 },
139 .set = sd_setgamma,
140 .get = sd_getgamma,
141 },
142#define SD_AUTOGAIN 4
143 {
144 {
145 .id = V4L2_CID_GAIN, /* here, i activate only the lowlight,
146 * some apps dont bring up the
147 * backligth_compensation control) */
148 .type = V4L2_CTRL_TYPE_INTEGER,
149 .name = "Low Light",
150 .minimum = 0,
151 .maximum = 1,
152 .step = 1,
153 .default_value = 0x01,
154 },
155 .set = sd_setlowlight,
156 .get = sd_getlowlight,
157 },
158#define SD_MIRROR 5
159 {
160 {
161 .id = V4L2_CID_HFLIP,
162 .type = V4L2_CTRL_TYPE_BOOLEAN,
163 .name = "Mirror Image",
164 .minimum = 0,
165 .maximum = 1,
166 .step = 1,
167 .default_value = 0,
168 },
169 .set = sd_setflip,
170 .get = sd_getflip
171 },
172#define SD_LIGHTFREQ 6
173 {
174 {
175 .id = V4L2_CID_POWER_LINE_FREQUENCY,
176 .type = V4L2_CTRL_TYPE_MENU,
177 .name = "Light Frequency Filter",
178 .minimum = 1, /* 1 -> 0x50, 2->0x60 */
179 .maximum = 2,
180 .step = 1,
181 .default_value = 1,
182 },
183 .set = sd_setfreq,
184 .get = sd_getfreq},
185
186#define SD_WHITE_BALANCE 7
187 {
188 {
189 .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
190 .type = V4L2_CTRL_TYPE_INTEGER,
191 .name = "White Balance",
192 .minimum = 0,
193 .maximum = 1,
194 .step = 1,
195 .default_value = 1,
196 },
197 .set = sd_setwhitebalance,
198 .get = sd_getwhitebalance
199 },
200#define SD_SHARPNESS 8 /* (aka definition on win) */
201 {
202 {
203 .id = V4L2_CID_SHARPNESS,
204 .type = V4L2_CTRL_TYPE_INTEGER,
205 .name = "Sharpness",
206 .minimum = 0,
207 .maximum = MAX_GAMMA, /* 0 to 16 */
208 .step = 1,
209 .default_value = 0x06,
210 },
211 .set = sd_setsharpness,
212 .get = sd_getsharpness,
213 },
214#define SD_EFFECTS 9
215 {
216 {
217 .id = V4L2_CID_EFFECTS,
218 .type = V4L2_CTRL_TYPE_MENU,
219 .name = "Webcam Effects",
220 .minimum = 0,
221 .maximum = 4,
222 .step = 1,
223 .default_value = 0,
224 },
225 .set = sd_seteffect,
226 .get = sd_geteffect
227 },
228};
229
230static struct control_menu_info effects_control[] = {
231 {0, "Normal"},
232 {1, "Emboss"}, /* disabled */
233 {2, "Monochrome"},
234 {3, "Sepia"},
235 {4, "Sketch"},
236 {5, "Sun Effect"}, /* disabled */
237 {6, "Negative"},
238};
239
240#define NUM_EFFECTS_CONTROL \
241 (sizeof(effects_control)/sizeof(effects_control[0]))
242
243static struct cam_mode vga_mode_t16[] = {
244 {V4L2_PIX_FMT_JPEG, 160, 120, 4},
245 {V4L2_PIX_FMT_JPEG, 176, 144, 3},
246 {V4L2_PIX_FMT_JPEG, 320, 240, 2},
247 {V4L2_PIX_FMT_JPEG, 352, 288, 1},
248 {V4L2_PIX_FMT_JPEG, 640, 480, 0},
249};
250
251#define T16_OFFSET_DATA 631
252#define MAX_EFFECTS 7
253/* easily done by soft, this table could be removed,
254 * i keep it here just in case */
255unsigned char effects_table[MAX_EFFECTS][6] = {
256 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */
257 {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */
258 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */
259 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80}, /* Sepia */
260 {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02}, /* Croquis */
261 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10}, /* Sun Effect */
262 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */
263};
264
265unsigned char gamma_table[MAX_GAMMA][34] = {
266 {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85,
267 0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9,
268 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb,
269 0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8,
270 0xa0, 0xff},
271 {0x90, 0x00, 0x91, 0x33, 0x92, 0x5A, 0x93, 0x75,
272 0x94, 0x85, 0x95, 0x93, 0x96, 0xA1, 0x97, 0xAD,
273 0x98, 0xB7, 0x99, 0xC2, 0x9A, 0xCB, 0x9B, 0xD4,
274 0x9C, 0xDE, 0x9D, 0xE7, 0x9E, 0xF0, 0x9F, 0xF7,
275 0xa0, 0xff},
276 {0x90, 0x00, 0x91, 0x2F, 0x92, 0x51, 0x93, 0x6B,
277 0x94, 0x7C, 0x95, 0x8A, 0x96, 0x99, 0x97, 0xA6,
278 0x98, 0xB1, 0x99, 0xBC, 0x9A, 0xC6, 0x9B, 0xD0,
279 0x9C, 0xDB, 0x9D, 0xE4, 0x9E, 0xED, 0x9F, 0xF6,
280 0xa0, 0xff},
281 {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60,
282 0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9E,
283 0x98, 0xAA, 0x99, 0xB5, 0x9A, 0xBF, 0x9B, 0xCB,
284 0x9C, 0xD6, 0x9D, 0xE1, 0x9E, 0xEB, 0x9F, 0xF5,
285 0xa0, 0xff},
286 {0x90, 0x00, 0x91, 0x23, 0x92, 0x3F, 0x93, 0x55,
287 0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95,
288 0x98, 0xA2, 0x99, 0xAD, 0x9A, 0xB9, 0x9B, 0xC6,
289 0x9C, 0xD2, 0x9D, 0xDE, 0x9E, 0xE9, 0x9F, 0xF4,
290 0xa0, 0xff},
291 {0x90, 0x00, 0x91, 0x1B, 0x92, 0x33, 0x93, 0x48,
292 0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87,
293 0x98, 0x96, 0x99, 0xA3, 0x9A, 0xB1, 0x9B, 0xBE,
294 0x9C, 0xCC, 0x9D, 0xDA, 0x9E, 0xE7, 0x9F, 0xF3,
295 0xa0, 0xff},
296 {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20,
297 0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67,
298 0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa,
299 0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee,
300 0xa0, 0xff},
301 {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26,
302 0x94, 0x38, 0x95, 0x4A, 0x96, 0x60, 0x97, 0x70,
303 0x98, 0x80, 0x99, 0x90, 0x9A, 0xA0, 0x9B, 0xB0,
304 0x9C, 0xC0, 0x9D, 0xD0, 0x9E, 0xE0, 0x9F, 0xF0,
305 0xa0, 0xff},
306 {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35,
307 0x94, 0x47, 0x95, 0x5A, 0x96, 0x69, 0x97, 0x79,
308 0x98, 0x88, 0x99, 0x97, 0x9A, 0xA7, 0x9B, 0xB6,
309 0x9C, 0xC4, 0x9D, 0xD3, 0x9E, 0xE0, 0x9F, 0xF0,
310 0xa0, 0xff},
311 {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40,
312 0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
313 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd,
314 0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0,
315 0xa0, 0xff},
316 {0x90, 0x00, 0x91, 0x18, 0x92, 0x2B, 0x93, 0x44,
317 0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8E,
318 0x98, 0x9C, 0x99, 0xAA, 0x9A, 0xB7, 0x9B, 0xC4,
319 0x9C, 0xD0, 0x9D, 0xD8, 0x9E, 0xE2, 0x9F, 0xF0,
320 0xa0, 0xff},
321 {0x90, 0x00, 0x91, 0x1A, 0x92, 0x34, 0x93, 0x52,
322 0x94, 0x66, 0x95, 0x7E, 0x96, 0x8D, 0x97, 0x9B,
323 0x98, 0xA8, 0x99, 0xB4, 0x9A, 0xC0, 0x9B, 0xCB,
324 0x9C, 0xD6, 0x9D, 0xE1, 0x9E, 0xEB, 0x9F, 0xF5,
325 0xa0, 0xff},
326 {0x90, 0x00, 0x91, 0x3F, 0x92, 0x5A, 0x93, 0x6E,
327 0x94, 0x7F, 0x95, 0x8E, 0x96, 0x9C, 0x97, 0xA8,
328 0x98, 0xB4, 0x99, 0xBF, 0x9A, 0xC9, 0x9B, 0xD3,
329 0x9C, 0xDC, 0x9D, 0xE5, 0x9E, 0xEE, 0x9F, 0xF6,
330 0xA0, 0xFF},
331 {0x90, 0x00, 0x91, 0x54, 0x92, 0x6F, 0x93, 0x83,
332 0x94, 0x93, 0x95, 0xA0, 0x96, 0xAD, 0x97, 0xB7,
333 0x98, 0xC2, 0x99, 0xCB, 0x9A, 0xD4, 0x9B, 0xDC,
334 0x9C, 0xE4, 0x9D, 0xEB, 0x9E, 0xF2, 0x9F, 0xF9,
335 0xa0, 0xff},
336 {0x90, 0x00, 0x91, 0x6E, 0x92, 0x88, 0x93, 0x9A,
337 0x94, 0xA8, 0x95, 0xB3, 0x96, 0xBD, 0x97, 0xC6,
338 0x98, 0xCF, 0x99, 0xD6, 0x9A, 0xDD, 0x9B, 0xE3,
339 0x9C, 0xE9, 0x9D, 0xEF, 0x9E, 0xF4, 0x9F, 0xFA,
340 0xa0, 0xff},
341 {0x90, 0x00, 0x91, 0x93, 0x92, 0xA8, 0x93, 0xB7,
342 0x94, 0xC1, 0x95, 0xCA, 0x96, 0xD2, 0x97, 0xD8,
343 0x98, 0xDE, 0x99, 0xE3, 0x9A, 0xE8, 0x9B, 0xED,
344 0x9C, 0xF1, 0x9D, 0xF5, 0x9E, 0xF8, 0x9F, 0xFC,
345 0xA0, 0xFF}
346};
347
348static __u8 tas5130a_sensor_init[][8] = {
349 {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
350 {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
351 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
352 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
353 {},
354};
355
356static void t16RegRead(struct usb_device *dev,
357 __u16 index, __u8 *buffer, __u16 length)
358{
359 usb_control_msg(dev,
360 usb_rcvctrlpipe(dev, 0),
361 0, /* request */
362 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
363 0, /* value */
364 index, buffer, length, 500);
365}
366
367static void t16RegWrite(struct usb_device *dev,
368 __u16 value,
369 __u16 index, __u8 *buffer, __u16 length)
370{
371 usb_control_msg(dev,
372 usb_sndctrlpipe(dev, 0),
373 0, /* request */
374 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
375 value, index, buffer, length, 500);
376}
377
378/* this function is called at probe time */
379static int sd_config(struct gspca_dev *gspca_dev,
380 const struct usb_device_id *id)
381{
382 struct sd *sd = (struct sd *) gspca_dev;
383 struct cam *cam;
384
385 cam = &gspca_dev->cam;
386 cam->dev_name = (char *) id->driver_info;
387 cam->epaddr = 0x01;
388
389 cam->cam_mode = vga_mode_t16;
390 cam->nmodes = ARRAY_SIZE(vga_mode_t16);
391
392 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
393 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
394 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
395 sd->gamma = sd_ctrls[SD_GAMMA].qctrl.default_value;
396 sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value;
397 sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value;
398 sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value;
399 sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
400 sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value;
401 return 0;
402}
403
404static int init_default_parameters(struct gspca_dev *gspca_dev)
405{
406 struct usb_device *dev = gspca_dev->dev;
407
408 /* some of this registers are not really neded, because
409 * they are overriden by setbrigthness, setcontrast, etc,
410 * but wont hurt anyway, and can help someone with similar webcam
411 * to see the initial parameters.*/
412 int i = 0;
413 __u8 test_byte;
414
415 static unsigned char read_indexs[] =
416 { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
417 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 };
418 static unsigned char n1[6] =
419 {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
420 static unsigned char n2[2] =
421 {0x08, 0x00};
422 static unsigned char nset[6] =
423 { 0x61, 0x68, 0x62, 0xff, 0x60, 0x07 };
424 static unsigned char n3[6] =
425 {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
426 static unsigned char n4[0x46] =
427 {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
428 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
429 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
430 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
431 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
432 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
433 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
434 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
435 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
436 static unsigned char nset4[18] = {
437 0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, 0xe4, 0xa8,
438 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
439 0xe8, 0xe0
440 };
441 /* ojo puede ser 0xe6 en vez de 0xe9 */
442 static unsigned char nset2[20] = {
443 0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, 0xd4, 0xbb,
444 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
445 0xd8, 0xc8, 0xd9, 0xfc
446 };
447 static unsigned char missing[8] =
448 { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
449 static unsigned char nset3[18] = {
450 0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, 0xcb, 0xa8,
451 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
452 0xcf, 0xe0
453 };
454 static unsigned char nset5[4] =
455 { 0x8f, 0x24, 0xc3, 0x00 }; /* bright */
456 static unsigned char nset6[34] = {
457 0x90, 0x00, 0x91, 0x1c, 0x92, 0x30, 0x93, 0x43, 0x94, 0x54,
458 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
459 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd, 0x9c, 0xca,
460 0x9d, 0xd8, 0x9e, 0xe5, 0x9f, 0xf2,
461 0xa0, 0xff
462 }; /* Gamma */
463 static unsigned char nset7[4] =
464 { 0x66, 0xca, 0xa8, 0xf8 }; /* 50/60 Hz */
465 static unsigned char nset9[4] =
466 { 0x0b, 0x04, 0x0a, 0x78 };
467 static unsigned char nset8[6] =
468 { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
469 static unsigned char nset10[6] =
470 { 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 };
471
472 t16RegWrite(dev, 0x01, 0x0000, n1, 0x06);
473 t16RegWrite(dev, 0x01, 0x0000, nset, 0x06);
474 t16RegRead(dev, 0x0063, &test_byte, 1);
475 t16RegWrite(dev, 0x01, 0x0000, n2, 0x02);
476
477 while (read_indexs[i] != 0x00) {
478 t16RegRead(dev, read_indexs[i], &test_byte, 1);
479 PDEBUG(D_CONF, "Reg 0x%x => 0x%x", read_indexs[i],
480 test_byte);
481 i++;
482 }
483
484 t16RegWrite(dev, 0x01, 0x0000, n3, 0x06);
485 t16RegWrite(dev, 0x01, 0x0000, n4, 0x46);
486 t16RegRead(dev, 0x0080, &test_byte, 1);
487 t16RegWrite(dev, 0x00, 0x2c80, 0x00, 0x0);
488 t16RegWrite(dev, 0x01, 0x0000, nset2, 0x14);
489 t16RegWrite(dev, 0x01, 0x0000, nset3, 0x12);
490 t16RegWrite(dev, 0x01, 0x0000, nset4, 0x12);
491 t16RegWrite(dev, 0x00, 0x3880, 0x00, 0x0);
492 t16RegWrite(dev, 0x00, 0x3880, 0x00, 0x0);
493 t16RegWrite(dev, 0x00, 0x338e, 0x00, 0x0);
494 t16RegWrite(dev, 0x01, 00, nset5, 0x04);
495 t16RegWrite(dev, 0x00, 0x00a9, 0x00, 0x0);
496 t16RegWrite(dev, 0x01, 00, nset6, 0x22);
497 t16RegWrite(dev, 0x00, 0x86bb, 0x00, 0x0);
498 t16RegWrite(dev, 0x00, 0x4aa6, 0x00, 0x0);
499
500 t16RegWrite(dev, 0x01, 00, missing, 0x08);
501
502 t16RegWrite(dev, 0x00, 0x2087, 0x00, 0x0);
503 t16RegWrite(dev, 0x00, 0x2088, 0x00, 0x0);
504 t16RegWrite(dev, 0x00, 0x2089, 0x00, 0x0);
505
506 t16RegWrite(dev, 0x01, 00, nset7, 0x4);
507 t16RegWrite(dev, 0x01, 00, nset10, 0x06);
508 t16RegWrite(dev, 0x01, 00, nset8, 0x06);
509 t16RegWrite(dev, 0x01, 00, nset9, 0x04);
510
511 t16RegWrite(dev, 0x00, 0x2880, 0x00, 0x0);
512 t16RegWrite(dev, 0x01, 0x0000, nset2, 0x14);
513 t16RegWrite(dev, 0x01, 0x0000, nset3, 0x12);
514 t16RegWrite(dev, 0x01, 0x0000, nset4, 0x12);
515
516 return 0;
517}
518
519static void setbrightness(struct gspca_dev *gspca_dev)
520{
521 struct sd *sd = (struct sd *) gspca_dev;
522 struct usb_device *dev = gspca_dev->dev;
523 unsigned int brightness;
524 unsigned char set6[4] = { 0x8f, 0x26, 0xc3, 0x80 };
525 brightness = sd->brightness;
526
527 if (brightness < 7) {
528 set6[3] = 0x70 - (brightness * 0xa);
529 } else {
530 set6[1] = 0x24;
531 set6[3] = 0x00 + ((brightness - 7) * 0xa);
532 }
533
534 t16RegWrite(dev, 0x01, 0x0000, set6, 4);
535}
536
537static void setflip(struct gspca_dev *gspca_dev)
538{
539 struct sd *sd = (struct sd *) gspca_dev;
540 struct usb_device *dev = gspca_dev->dev;
541
542 unsigned char flipcmd[8] =
543 { 0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09 };
544
545 if (sd->mirror == 1)
546 flipcmd[3] = 0x01;
547
548 t16RegWrite(dev, 0x01, 0x0000, flipcmd, 8);
549}
550
551static void seteffect(struct gspca_dev *gspca_dev)
552{
553 struct sd *sd = (struct sd *) gspca_dev;
554 struct usb_device *dev = gspca_dev->dev;
555
556 t16RegWrite(dev, 0x01, 0x0000, effects_table[sd->effect], 0x06);
557 if (sd->effect == 1 || sd->effect == 5) {
558 PDEBUG(D_CONF,
559 "This effect have been disabled for webcam \"safety\"");
560 return;
561 }
562
563 if (sd->effect == 1 || sd->effect == 4)
564 t16RegWrite(dev, 0x00, 0x4aa6, 0x00, 0x00);
565 else
566 t16RegWrite(dev, 0x00, 0xfaa6, 0x00, 0x00);
567}
568
569static void setwhitebalance(struct gspca_dev *gspca_dev)
570{
571 struct sd *sd = (struct sd *) gspca_dev;
572 struct usb_device *dev = gspca_dev->dev;
573
574 unsigned char white_balance[8] =
575 { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
576
577 if (sd->whitebalance == 1)
578 white_balance[7] = 0x3c;
579
580 t16RegWrite(dev, 0x01, 0x0000, white_balance, 8);
581}
582
583static void setlightfreq(struct gspca_dev *gspca_dev)
584{
585 struct sd *sd = (struct sd *) gspca_dev;
586 struct usb_device *dev = gspca_dev->dev;
587 __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
588
589 if (sd->freq == 2) /* 60hz */
590 freq[1] = 0x00;
591
592 t16RegWrite(dev, 0x1, 0x0000, freq, 0x4);
593}
594
595static void setcontrast(struct gspca_dev *gspca_dev)
596{
597 struct sd *sd = (struct sd *) gspca_dev;
598 struct usb_device *dev = gspca_dev->dev;
599 unsigned int contrast = sd->contrast;
600 __u16 reg_to_write = 0x00;
601
602 if (contrast < 7)
603 reg_to_write = 0x8ea9 - (0x200 * contrast);
604 else
605 reg_to_write = (0x00a9 + ((contrast - 7) * 0x200));
606
607 t16RegWrite(dev, 0x00, reg_to_write, 0x00, 0);
608
609}
610
611static void setcolors(struct gspca_dev *gspca_dev)
612{
613 struct sd *sd = (struct sd *) gspca_dev;
614 struct usb_device *dev = gspca_dev->dev;
615 __u16 reg_to_write = 0x00;
616
617 reg_to_write = 0xc0bb + sd->colors * 0x100;
618 t16RegWrite(dev, 0x00, reg_to_write, 0x00, 0);
619}
620
621static void setgamma(struct gspca_dev *gspca_dev)
622{
623}
624
625static void setsharpness(struct gspca_dev *gspca_dev)
626{
627 struct sd *sd = (struct sd *) gspca_dev;
628 struct usb_device *dev = gspca_dev->dev;
629 __u16 reg_to_write = 0x00;
630
631 reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
632
633 t16RegWrite(dev, 0x00, reg_to_write, 0x00, 0x00);
634}
635
636static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
637{
638 struct sd *sd = (struct sd *) gspca_dev;
639
640 sd->brightness = val;
641 if (gspca_dev->streaming)
642 setbrightness(gspca_dev);
643 return 0;
644}
645
646static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
647{
648 struct sd *sd = (struct sd *) gspca_dev;
649 *val = sd->brightness;
650 return *val;
651}
652
653static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
654{
655 struct sd *sd = (struct sd *) gspca_dev;
656
657 sd->whitebalance = val;
658 if (gspca_dev->streaming)
659 setwhitebalance(gspca_dev);
660 return 0;
661}
662
663static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
664{
665 struct sd *sd = (struct sd *) gspca_dev;
666
667 *val = sd->whitebalance;
668 return *val;
669}
670
671
672static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val)
673{
674 struct sd *sd = (struct sd *) gspca_dev;
675
676 sd->mirror = val;
677 if (gspca_dev->streaming)
678 setflip(gspca_dev);
679 return 0;
680}
681
682static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val)
683{
684 struct sd *sd = (struct sd *) gspca_dev;
685
686 *val = sd->mirror;
687 return *val;
688}
689
690static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val)
691{
692 struct sd *sd = (struct sd *) gspca_dev;
693
694 sd->effect = val;
695 if (gspca_dev->streaming)
696 seteffect(gspca_dev);
697 return 0;
698}
699
700static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val)
701{
702 struct sd *sd = (struct sd *) gspca_dev;
703
704 *val = sd->effect;
705 return *val;
706}
707
708static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
709{
710 struct sd *sd = (struct sd *) gspca_dev;
711
712 sd->contrast = val;
713 if (gspca_dev->streaming)
714 setcontrast(gspca_dev);
715 return 0;
716}
717
718static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
719{
720 struct sd *sd = (struct sd *) gspca_dev;
721
722 *val = sd->contrast;
723 return *val;
724}
725
726static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
727{
728 struct sd *sd = (struct sd *) gspca_dev;
729
730 sd->colors = val;
731 if (gspca_dev->streaming)
732 setcolors(gspca_dev);
733 return 0;
734}
735
736static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
737{
738 struct sd *sd = (struct sd *) gspca_dev;
739
740 *val = sd->colors;
741 return 0;
742}
743
744static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
745{
746 struct sd *sd = (struct sd *) gspca_dev;
747
748 sd->gamma = val;
749 if (gspca_dev->streaming)
750 setgamma(gspca_dev);
751 return 0;
752}
753
754static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
755{
756 struct sd *sd = (struct sd *) gspca_dev;
757 *val = sd->gamma;
758 return 0;
759}
760
761static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
762{
763 struct sd *sd = (struct sd *) gspca_dev;
764
765 sd->freq = val;
766 if (gspca_dev->streaming)
767 setlightfreq(gspca_dev);
768 return 0;
769}
770
771static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
772{
773 struct sd *sd = (struct sd *) gspca_dev;
774
775 *val = sd->freq;
776 return 0;
777}
778
779static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
780{
781 struct sd *sd = (struct sd *) gspca_dev;
782
783 sd->sharpness = val;
784 if (gspca_dev->streaming)
785 setsharpness(gspca_dev);
786 return 0;
787}
788
789static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
790{
791 struct sd *sd = (struct sd *) gspca_dev;
792
793 *val = sd->sharpness;
794 return 0;
795}
796
797/* Low Light set here......*/
798static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
799{
800 struct sd *sd = (struct sd *) gspca_dev;
801 struct usb_device *dev = gspca_dev->dev;
802
803 sd->autogain = val;
804 if (val != 0)
805 t16RegWrite(dev, 0x00, 0xf48e, 0x00, 0);
806 else
807 t16RegWrite(dev, 0x00, 0xb48e, 0x00, 0);
808 return 0;
809}
810
811static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
812{
813 struct sd *sd = (struct sd *) gspca_dev;
814
815 *val = sd->autogain;
816 return 0;
817}
818
819static void sd_start(struct gspca_dev *gspca_dev)
820{
821 struct usb_device *dev = gspca_dev->dev;
822 int mode;
823 __u8 test_byte;
824
825 static __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 };
826 __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
827 static __u8 t3[] =
828 { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
829 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
830 static __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 };
831
832 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. mode;
833 switch (mode) {
834 case 1: /* 352x288 */
835 t2[1] = 0x40;
836 break;
837 case 2: /* 320x240 */
838 t2[1] = 0x10;
839 break;
840 case 3: /* 176x144 */
841 t2[1] = 0x50;
842 break;
843 case 4: /* 160x120 */
844 t2[1] = 0x20;
845 break;
846 default: /* 640x480 (0x00) */
847 break;
848 }
849
850 t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[0], 0x8);
851 t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[1], 0x8);
852 t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[2], 0x8);
853 t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
854 t16RegWrite(dev, 0x00, 0x3c80, 0x00, 0x00);
855 /* just in case and to keep sync with logs (for mine) */
856 t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
857 t16RegWrite(dev, 0x00, 0x3c80, 0x00, 0x00);
858 /* just in case and to keep sync with logs (for mine) */
859 t16RegWrite(dev, 0x01, 0x0000, t1, 4);
860 t16RegWrite(dev, 0x01, 0x0000, t2, 6);
861 t16RegRead(dev, 0x0012, &test_byte, 0x1);
862 t16RegWrite(dev, 0x01, 0x0000, t3, 0x10);
863 t16RegWrite(dev, 0x00, 0x0013, 0x00, 0x00);
864 t16RegWrite(dev, 0x01, 0x0000, t4, 0x4);
865 /* restart on each start, just in case, sometimes regs goes wrong
866 * when using controls from app */
867 setbrightness(gspca_dev);
868 setcontrast(gspca_dev);
869 setcolors(gspca_dev);
870}
871
872static void sd_stopN(struct gspca_dev *gspca_dev)
873{
874}
875
876static void sd_stop0(struct gspca_dev *gspca_dev)
877{
878}
879
880static void sd_close(struct gspca_dev *gspca_dev)
881{
882}
883
884static void sd_pkt_scan(struct gspca_dev *gspca_dev,
885 struct gspca_frame *frame, /* target */
886 unsigned char *data, /* isoc packet */
887 int len) /* iso packet length */
888{
889 int sof = 0;
890 static unsigned char ffd9[] = { 0xff, 0xd9 };
891
892 if (data[0] == 0x5a) {
893 /* Control Packet, after this came the header again,
894 * but extra bytes came in the packet before this,
895 * sometimes an EOF arrives, sometimes not... */
896 return;
897 }
898
899 if (data[len - 1] == 0xff && data[len] == 0xd9) {
900 /* Just in case, i have seen packets with the marker,
901 * other's do not include it... */
902 data += 2;
903 len -= 4;
904 } else if (data[2] == 0xff && data[3] == 0xd8) {
905 sof = 1;
906 data += 2;
907 len -= 2;
908 } else {
909 data += 2;
910 len -= 2;
911 }
912
913 if (sof) {
914 /* extra bytes....., could be processed too but would be
915 * a waste of time, right now leave the application and
916 * libjpeg do it for ourserlves.. */
917 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
918 ffd9, 2);
919 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
920 return;
921 }
922
923 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
924}
925
926static int sd_querymenu(struct gspca_dev *gspca_dev,
927 struct v4l2_querymenu *menu)
928{
929 memset(menu->name, 0, sizeof menu->name);
930
931 switch (menu->id) {
932 case V4L2_CID_POWER_LINE_FREQUENCY:
933 switch (menu->index) {
934 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
935 strcpy(menu->name, "50 Hz");
936 return 0;
937 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
938 strcpy(menu->name, "60 Hz");
939 return 0;
940 }
941 break;
942 case V4L2_CID_EFFECTS:
943 if (menu->index < 0 || menu->index >= NUM_EFFECTS_CONTROL)
944 return -EINVAL;
945 strncpy((char *) menu->name,
946 effects_control[menu->index].name, 32);
947 break;
948 }
949 return 0;
950}
951
952/* this function is called at open time */
953static int sd_open(struct gspca_dev *gspca_dev)
954{
955 init_default_parameters(gspca_dev);
956 return 0;
957}
958
959/* sub-driver description */
960static struct sd_desc sd_desc = {
961 .name = MODULE_NAME,
962 .ctrls = sd_ctrls,
963 .nctrls = ARRAY_SIZE(sd_ctrls),
964 .config = sd_config,
965 .open = sd_open,
966 .start = sd_start,
967 .stopN = sd_stopN,
968 .stop0 = sd_stop0,
969 .close = sd_close,
970 .pkt_scan = sd_pkt_scan,
971 .querymenu = sd_querymenu,
972};
973
974/* -- module initialisation -- */
975#define DVNM(name) .driver_info = (kernel_ulong_t) name
976static __devinitdata struct usb_device_id device_table[] = {
977 {USB_DEVICE(0x17a1, 0x0128), DVNM("XPX Webcam")},
978 {}
979};
980
981MODULE_DEVICE_TABLE(usb, device_table);
982
983/* -- device connect -- */
984static int sd_probe(struct usb_interface *intf,
985 const struct usb_device_id *id)
986{
987 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
988 THIS_MODULE);
989}
990
991static struct usb_driver sd_driver = {
992 .name = MODULE_NAME,
993 .id_table = device_table,
994 .probe = sd_probe,
995 .disconnect = gspca_disconnect,
996};
997
998/* -- module insert / remove -- */
999static int __init sd_mod_init(void)
1000{
1001 if (usb_register(&sd_driver) < 0)
1002 return -1;
1003 PDEBUG(D_PROBE, "v%s registered", version);
1004 return 0;
1005}
1006static void __exit sd_mod_exit(void)
1007{
1008 usb_deregister(&sd_driver);
1009 PDEBUG(D_PROBE, "deregistered");
1010}
1011
1012module_init(sd_mod_init);
1013module_exit(sd_mod_exit);