aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/etoms.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/etoms.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/etoms.c')
-rw-r--r--drivers/media/video/gspca/etoms.c1062
1 files changed, 1062 insertions, 0 deletions
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
new file mode 100644
index 000000000000..c479f638413e
--- /dev/null
+++ b/drivers/media/video/gspca/etoms.c
@@ -0,0 +1,1062 @@
1/*
2 * Etoms Et61x151 GPL Linux driver by Michel Xhaard (09/09/2004)
3 *
4 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#define MODULE_NAME "etoms"
22
23#include "gspca.h"
24
25#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0)
26static const char version[] = "2.1.0";
27
28MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
29MODULE_DESCRIPTION("Etoms USB Camera Driver");
30MODULE_LICENSE("GPL");
31
32/* specific webcam descriptor */
33struct sd {
34 struct gspca_dev gspca_dev; /* !! must be the first item */
35
36 unsigned char brightness;
37 unsigned char contrast;
38 unsigned char colors;
39 unsigned char autogain;
40
41 char sensor;
42#define SENSOR_PAS106 0
43#define SENSOR_TAS5130CXX 1
44 signed char ag_cnt;
45#define AG_CNT_START 13
46};
47
48/* V4L2 controls supported by the driver */
49static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
50static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
51static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
52static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
53static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
54static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
55static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
56static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
57
58static struct ctrl sd_ctrls[] = {
59#define SD_BRIGHTNESS 0
60 {
61 {
62 .id = V4L2_CID_BRIGHTNESS,
63 .type = V4L2_CTRL_TYPE_INTEGER,
64 .name = "Brightness",
65 .minimum = 1,
66 .maximum = 127,
67 .step = 1,
68 .default_value = 63,
69 },
70 .set = sd_setbrightness,
71 .get = sd_getbrightness,
72 },
73#define SD_CONTRAST 1
74 {
75 {
76 .id = V4L2_CID_CONTRAST,
77 .type = V4L2_CTRL_TYPE_INTEGER,
78 .name = "Contrast",
79 .minimum = 0,
80 .maximum = 255,
81 .step = 1,
82 .default_value = 127,
83 },
84 .set = sd_setcontrast,
85 .get = sd_getcontrast,
86 },
87#define SD_COLOR 2
88 {
89 {
90 .id = V4L2_CID_SATURATION,
91 .type = V4L2_CTRL_TYPE_INTEGER,
92 .name = "Color",
93 .minimum = 0,
94 .maximum = 15,
95 .step = 1,
96 .default_value = 7,
97 },
98 .set = sd_setcolors,
99 .get = sd_getcolors,
100 },
101#define SD_AUTOGAIN 3
102 {
103 {
104 .id = V4L2_CID_AUTOGAIN,
105 .type = V4L2_CTRL_TYPE_BOOLEAN,
106 .name = "Auto Gain",
107 .minimum = 0,
108 .maximum = 1,
109 .step = 1,
110 .default_value = 1,
111 },
112 .set = sd_setautogain,
113 .get = sd_getautogain,
114 },
115};
116
117static struct cam_mode vga_mode[] = {
118 {V4L2_PIX_FMT_SBGGR8, 320, 240, 1},
119/* {V4L2_PIX_FMT_SBGGR8, 640, 480, 0}, */
120};
121
122static struct cam_mode sif_mode[] = {
123 {V4L2_PIX_FMT_SBGGR8, 176, 144, 1},
124 {V4L2_PIX_FMT_SBGGR8, 352, 288, 0},
125};
126
127#define ETOMS_ALT_SIZE_1000 12
128
129#define ET_GPIO_DIR_CTRL 0x04 /* Control IO bit[0..5] (0 in 1 out) */
130#define ET_GPIO_OUT 0x05 /* Only IO data */
131#define ET_GPIO_IN 0x06 /* Read Only IO data */
132#define ET_RESET_ALL 0x03
133#define ET_ClCK 0x01
134#define ET_CTRL 0x02 /* enable i2c OutClck Powerdown mode */
135
136#define ET_COMP 0x12 /* Compression register */
137#define ET_MAXQt 0x13
138#define ET_MINQt 0x14
139#define ET_COMP_VAL0 0x02
140#define ET_COMP_VAL1 0x03
141
142#define ET_REG1d 0x1d
143#define ET_REG1e 0x1e
144#define ET_REG1f 0x1f
145#define ET_REG20 0x20
146#define ET_REG21 0x21
147#define ET_REG22 0x22
148#define ET_REG23 0x23
149#define ET_REG24 0x24
150#define ET_REG25 0x25
151/* base registers for luma calculation */
152#define ET_LUMA_CENTER 0x39
153
154#define ET_G_RED 0x4d
155#define ET_G_GREEN1 0x4e
156#define ET_G_BLUE 0x4f
157#define ET_G_GREEN2 0x50
158#define ET_G_GR_H 0x51
159#define ET_G_GB_H 0x52
160
161#define ET_O_RED 0x34
162#define ET_O_GREEN1 0x35
163#define ET_O_BLUE 0x36
164#define ET_O_GREEN2 0x37
165
166#define ET_SYNCHRO 0x68
167#define ET_STARTX 0x69
168#define ET_STARTY 0x6a
169#define ET_WIDTH_LOW 0x6b
170#define ET_HEIGTH_LOW 0x6c
171#define ET_W_H_HEIGTH 0x6d
172
173#define ET_REG6e 0x6e /* OBW */
174#define ET_REG6f 0x6f /* OBW */
175#define ET_REG70 0x70 /* OBW_AWB */
176#define ET_REG71 0x71 /* OBW_AWB */
177#define ET_REG72 0x72 /* OBW_AWB */
178#define ET_REG73 0x73 /* Clkdelay ns */
179#define ET_REG74 0x74 /* test pattern */
180#define ET_REG75 0x75 /* test pattern */
181
182#define ET_I2C_CLK 0x8c
183#define ET_PXL_CLK 0x60
184
185#define ET_I2C_BASE 0x89
186#define ET_I2C_COUNT 0x8a
187#define ET_I2C_PREFETCH 0x8b
188#define ET_I2C_REG 0x88
189#define ET_I2C_DATA7 0x87
190#define ET_I2C_DATA6 0x86
191#define ET_I2C_DATA5 0x85
192#define ET_I2C_DATA4 0x84
193#define ET_I2C_DATA3 0x83
194#define ET_I2C_DATA2 0x82
195#define ET_I2C_DATA1 0x81
196#define ET_I2C_DATA0 0x80
197
198#define PAS106_REG2 0x02 /* pxlClk = systemClk/(reg2) */
199#define PAS106_REG3 0x03 /* line/frame H [11..4] */
200#define PAS106_REG4 0x04 /* line/frame L [3..0] */
201#define PAS106_REG5 0x05 /* exposure time line offset(default 5) */
202#define PAS106_REG6 0x06 /* exposure time pixel offset(default 6) */
203#define PAS106_REG7 0x07 /* signbit Dac (default 0) */
204#define PAS106_REG9 0x09
205#define PAS106_REG0e 0x0e /* global gain [4..0](default 0x0e) */
206#define PAS106_REG13 0x13 /* end i2c write */
207
208static __u8 GainRGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 };
209
210static __u8 I2c2[] = { 0x08, 0x08, 0x08, 0x08, 0x0d };
211
212static __u8 I2c3[] = { 0x12, 0x05 };
213
214static __u8 I2c4[] = { 0x41, 0x08 };
215
216static void Et_RegRead(struct usb_device *dev,
217 __u16 index, __u8 *buffer, int len)
218{
219 usb_control_msg(dev,
220 usb_rcvctrlpipe(dev, 0),
221 0,
222 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
223 0, index, buffer, len, 500);
224}
225
226static void Et_RegWrite(struct usb_device *dev,
227 __u16 index, __u8 *buffer, __u16 len)
228{
229 usb_control_msg(dev,
230 usb_sndctrlpipe(dev, 0),
231 0,
232 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
233 0, index, buffer, len, 500);
234}
235
236static int Et_i2cwrite(struct usb_device *dev, __u8 reg, __u8 * buffer,
237 __u16 length, __u8 mode)
238{
239/* buffer should be [D0..D7] */
240 int i, j;
241 __u8 base = 0x40; /* sensor base for the pas106 */
242 __u8 ptchcount = 0;
243
244 ptchcount = (((length & 0x07) << 4) | (mode & 0x03));
245/* set the base address */
246 Et_RegWrite(dev, ET_I2C_BASE, &base, 1);
247/* set count and prefetch */
248 Et_RegWrite(dev, ET_I2C_COUNT, &ptchcount, 1);
249/* set the register base */
250 Et_RegWrite(dev, ET_I2C_REG, &reg, 1);
251 j = length - 1;
252 for (i = 0; i < length; i++) {
253 Et_RegWrite(dev, (ET_I2C_DATA0 + j), &buffer[j], 1);
254 j--;
255 }
256 return 0;
257}
258
259static int Et_i2cread(struct usb_device *dev, __u8 reg, __u8 * buffer,
260 __u16 length, __u8 mode)
261{
262/* buffer should be [D0..D7] */
263 int i, j;
264 __u8 base = 0x40; /* sensor base for the pas106 */
265 __u8 ptchcount;
266 __u8 prefetch = 0x02;
267
268 ptchcount = (((length & 0x07) << 4) | (mode & 0x03));
269/* set the base address */
270 Et_RegWrite(dev, ET_I2C_BASE, &base, 1);
271/* set count and prefetch */
272 Et_RegWrite(dev, ET_I2C_COUNT, &ptchcount, 1);
273/* set the register base */
274 Et_RegWrite(dev, ET_I2C_REG, &reg, 1);
275 Et_RegWrite(dev, ET_I2C_PREFETCH, &prefetch, 1);
276 prefetch = 0x00;
277 Et_RegWrite(dev, ET_I2C_PREFETCH, &prefetch, 1);
278 j = length - 1;
279 for (i = 0; i < length; i++) {
280 Et_RegRead(dev, (ET_I2C_DATA0 + j), &buffer[j], 1);
281 j--;
282 }
283 return 0;
284}
285
286static int Et_WaitStatus(struct usb_device *dev)
287{
288 __u8 bytereceived;
289 int retry = 10;
290
291 while (retry--) {
292 Et_RegRead(dev, ET_ClCK, &bytereceived, 1);
293 if (bytereceived != 0)
294 return 1;
295 }
296 return 0;
297}
298
299static int Et_videoOff(struct usb_device *dev)
300{
301 int err;
302 __u8 stopvideo = 0;
303
304 Et_RegWrite(dev, ET_GPIO_OUT, &stopvideo, 1);
305 err = Et_WaitStatus(dev);
306 if (!err)
307 PDEBUG(D_ERR, "timeout Et_waitStatus VideoON");
308 return err;
309}
310
311static int Et_videoOn(struct usb_device *dev)
312{
313 int err;
314 __u8 startvideo = 0x10; /* set Bit5 */
315
316 Et_RegWrite(dev, ET_GPIO_OUT, &startvideo, 1);
317 err = Et_WaitStatus(dev);
318 if (!err)
319 PDEBUG(D_ERR, "timeout Et_waitStatus VideoOFF");
320 return err;
321}
322
323static void Et_init2(struct gspca_dev *gspca_dev)
324{
325 struct usb_device *dev = gspca_dev->dev;
326 __u8 value = 0x00;
327 __u8 received = 0x00;
328 __u8 FormLine[] = { 0x84, 0x03, 0x14, 0xf4, 0x01, 0x05 };
329
330 PDEBUG(D_STREAM, "Open Init2 ET");
331 value = 0x2f;
332 Et_RegWrite(dev, ET_GPIO_DIR_CTRL, &value, 1);
333 value = 0x10;
334 Et_RegWrite(dev, ET_GPIO_OUT, &value, 1);
335 Et_RegRead(dev, ET_GPIO_IN, &received, 1);
336 value = 0x14; /* 0x14 // 0x16 enabled pattern */
337 Et_RegWrite(dev, ET_ClCK, &value, 1);
338 value = 0x1b;
339 Et_RegWrite(dev, ET_CTRL, &value, 1);
340
341 /* compression et subsampling */
342 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode)
343 value = ET_COMP_VAL1; /* 320 */
344 else
345 value = ET_COMP_VAL0; /* 640 */
346 Et_RegWrite(dev, ET_COMP, &value, 1);
347 value = 0x1f;
348 Et_RegWrite(dev, ET_MAXQt, &value, 1);
349 value = 0x04;
350 Et_RegWrite(dev, ET_MINQt, &value, 1);
351 /* undocumented registers */
352 value = 0xff;
353 Et_RegWrite(dev, ET_REG1d, &value, 1);
354 value = 0xff;
355 Et_RegWrite(dev, ET_REG1e, &value, 1);
356 value = 0xff;
357 Et_RegWrite(dev, ET_REG1f, &value, 1);
358 value = 0x35;
359 Et_RegWrite(dev, ET_REG20, &value, 1);
360 value = 0x01;
361 Et_RegWrite(dev, ET_REG21, &value, 1);
362 value = 0x00;
363 Et_RegWrite(dev, ET_REG22, &value, 1);
364 value = 0xff;
365 Et_RegWrite(dev, ET_REG23, &value, 1);
366 value = 0xff;
367 Et_RegWrite(dev, ET_REG24, &value, 1);
368 value = 0x0f;
369 Et_RegWrite(dev, ET_REG25, &value, 1);
370 /* colors setting */
371 value = 0x11;
372 Et_RegWrite(dev, 0x30, &value, 1); /* 0x30 */
373 value = 0x40;
374 Et_RegWrite(dev, 0x31, &value, 1);
375 value = 0x00;
376 Et_RegWrite(dev, 0x32, &value, 1);
377 value = 0x00;
378 Et_RegWrite(dev, ET_O_RED, &value, 1); /* 0x34 */
379 value = 0x00;
380 Et_RegWrite(dev, ET_O_GREEN1, &value, 1);
381 value = 0x00;
382 Et_RegWrite(dev, ET_O_BLUE, &value, 1);
383 value = 0x00;
384 Et_RegWrite(dev, ET_O_GREEN2, &value, 1);
385 /*************/
386 value = 0x80;
387 Et_RegWrite(dev, ET_G_RED, &value, 1); /* 0x4d */
388 value = 0x80;
389 Et_RegWrite(dev, ET_G_GREEN1, &value, 1);
390 value = 0x80;
391 Et_RegWrite(dev, ET_G_BLUE, &value, 1);
392 value = 0x80;
393 Et_RegWrite(dev, ET_G_GREEN2, &value, 1);
394 value = 0x00;
395 Et_RegWrite(dev, ET_G_GR_H, &value, 1);
396 value = 0x00;
397 Et_RegWrite(dev, ET_G_GB_H, &value, 1); /* 0x52 */
398 /* Window control registers */
399
400 value = 0x80; /* use cmc_out */
401 Et_RegWrite(dev, 0x61, &value, 1);
402
403 value = 0x02;
404 Et_RegWrite(dev, 0x62, &value, 1);
405 value = 0x03;
406 Et_RegWrite(dev, 0x63, &value, 1);
407 value = 0x14;
408 Et_RegWrite(dev, 0x64, &value, 1);
409 value = 0x0e;
410 Et_RegWrite(dev, 0x65, &value, 1);
411 value = 0x02;
412 Et_RegWrite(dev, 0x66, &value, 1);
413 value = 0x02;
414 Et_RegWrite(dev, 0x67, &value, 1);
415
416 /**************************************/
417 value = 0x8f;
418 Et_RegWrite(dev, ET_SYNCHRO, &value, 1); /* 0x68 */
419 value = 0x69; /* 0x6a //0x69 */
420 Et_RegWrite(dev, ET_STARTX, &value, 1);
421 value = 0x0d; /* 0x0d //0x0c */
422 Et_RegWrite(dev, ET_STARTY, &value, 1);
423 value = 0x80;
424 Et_RegWrite(dev, ET_WIDTH_LOW, &value, 1);
425 value = 0xe0;
426 Et_RegWrite(dev, ET_HEIGTH_LOW, &value, 1);
427 value = 0x60;
428 Et_RegWrite(dev, ET_W_H_HEIGTH, &value, 1); /* 6d */
429 value = 0x86;
430 Et_RegWrite(dev, ET_REG6e, &value, 1);
431 value = 0x01;
432 Et_RegWrite(dev, ET_REG6f, &value, 1);
433 value = 0x26;
434 Et_RegWrite(dev, ET_REG70, &value, 1);
435 value = 0x7a;
436 Et_RegWrite(dev, ET_REG71, &value, 1);
437 value = 0x01;
438 Et_RegWrite(dev, ET_REG72, &value, 1);
439 /* Clock Pattern registers ***************** */
440 value = 0x00;
441 Et_RegWrite(dev, ET_REG73, &value, 1);
442 value = 0x18; /* 0x28 */
443 Et_RegWrite(dev, ET_REG74, &value, 1);
444 value = 0x0f; /* 0x01 */
445 Et_RegWrite(dev, ET_REG75, &value, 1);
446 /**********************************************/
447 value = 0x20;
448 Et_RegWrite(dev, 0x8a, &value, 1);
449 value = 0x0f;
450 Et_RegWrite(dev, 0x8d, &value, 1);
451 value = 0x08;
452 Et_RegWrite(dev, 0x8e, &value, 1);
453 /**************************************/
454 value = 0x08;
455 Et_RegWrite(dev, 0x03, &value, 1);
456 value = 0x03;
457 Et_RegWrite(dev, ET_PXL_CLK, &value, 1);
458 value = 0xff;
459 Et_RegWrite(dev, 0x81, &value, 1);
460 value = 0x00;
461 Et_RegWrite(dev, 0x80, &value, 1);
462 value = 0xff;
463 Et_RegWrite(dev, 0x81, &value, 1);
464 value = 0x20;
465 Et_RegWrite(dev, 0x80, &value, 1);
466 value = 0x01;
467 Et_RegWrite(dev, 0x03, &value, 1);
468 value = 0x00;
469 Et_RegWrite(dev, 0x03, &value, 1);
470 value = 0x08;
471 Et_RegWrite(dev, 0x03, &value, 1);
472 /********************************************/
473
474 /* Et_RegRead(dev,0x0,ET_I2C_BASE,&received,1);
475 always 0x40 as the pas106 ??? */
476 /* set the sensor */
477 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) {
478 value = 0x04; /* 320 */
479 Et_RegWrite(dev, ET_PXL_CLK, &value, 1);
480 /* now set by fifo the FormatLine setting */
481 Et_RegWrite(dev, 0x62, FormLine, 6);
482 } else { /* 640 */
483 /* setting PixelClock
484 0x03 mean 24/(3+1) = 6 Mhz
485 0x05 -> 24/(5+1) = 4 Mhz
486 0x0b -> 24/(11+1) = 2 Mhz
487 0x17 -> 24/(23+1) = 1 Mhz
488 */
489 value = 0x1e; /* 0x17 */
490 Et_RegWrite(dev, ET_PXL_CLK, &value, 1);
491 /* now set by fifo the FormatLine setting */
492 Et_RegWrite(dev, 0x62, FormLine, 6);
493 }
494
495 /* set exposure times [ 0..0x78] 0->longvalue 0x78->shortvalue */
496 value = 0x47; /* 0x47; */
497 Et_RegWrite(dev, 0x81, &value, 1);
498 value = 0x40; /* 0x40; */
499 Et_RegWrite(dev, 0x80, &value, 1);
500 /* Pedro change */
501 /* Brightness change Brith+ decrease value */
502 /* Brigth- increase value */
503 /* original value = 0x70; */
504 value = 0x30; /* 0x20; */
505 Et_RegWrite(dev, 0x81, &value, 1); /* set brightness */
506 value = 0x20; /* 0x20; */
507 Et_RegWrite(dev, 0x80, &value, 1);
508}
509
510static void setcolors(struct gspca_dev *gspca_dev)
511{
512 struct sd *sd = (struct sd *) gspca_dev;
513 struct usb_device *dev = gspca_dev->dev;
514 static __u8 I2cc[] = { 0x05, 0x02, 0x02, 0x05, 0x0d };
515 __u8 i2cflags = 0x01;
516 /* __u8 green = 0; */
517 __u8 colors = sd->colors;
518
519 I2cc[3] = colors; /* red */
520 I2cc[0] = 15 - colors; /* blue */
521 /* green = 15 - ((((7*I2cc[0]) >> 2 ) + I2cc[3]) >> 1); */
522 /* I2cc[1] = I2cc[2] = green; */
523 if (sd->sensor == SENSOR_PAS106) {
524 Et_i2cwrite(dev, PAS106_REG13, &i2cflags, 1, 3);
525 Et_i2cwrite(dev, PAS106_REG9, I2cc, sizeof(I2cc), 1);
526 }
527/* PDEBUG(D_CONF , "Etoms red %d blue %d green %d",
528 I2cc[3], I2cc[0], green); */
529}
530
531static void getcolors(struct gspca_dev *gspca_dev)
532{
533 struct sd *sd = (struct sd *) gspca_dev;
534 /* __u8 valblue = 0; */
535 __u8 valred;
536
537 if (sd->sensor == SENSOR_PAS106) {
538 /* Et_i2cread(gspca_dev->dev,PAS106_REG9,&valblue,1,1); */
539 Et_i2cread(gspca_dev->dev, PAS106_REG9 + 3, &valred, 1, 1);
540 sd->colors = valred & 0x0f;
541 }
542}
543
544static void Et_init1(struct gspca_dev *gspca_dev)
545{
546 struct usb_device *dev = gspca_dev->dev;
547 __u8 value = 0x00;
548 __u8 received = 0x00;
549/* __u8 I2c0 [] ={0x0a,0x12,0x05,0x22,0xac,0x00,0x01,0x00}; */
550 __u8 I2c0[] = { 0x0a, 0x12, 0x05, 0x6d, 0xcd, 0x00, 0x01, 0x00 };
551 /* try 1/120 0x6d 0xcd 0x40 */
552/* __u8 I2c0 [] ={0x0a,0x12,0x05,0xfe,0xfe,0xc0,0x01,0x00};
553 * 1/60000 hmm ?? */
554
555 PDEBUG(D_STREAM, "Open Init1 ET");
556 value = 7;
557 Et_RegWrite(dev, ET_GPIO_DIR_CTRL, &value, 1);
558 Et_RegRead(dev, ET_GPIO_IN, &received, 1);
559 value = 1;
560 Et_RegWrite(dev, ET_RESET_ALL, &value, 1);
561 value = 0;
562 Et_RegWrite(dev, ET_RESET_ALL, &value, 1);
563 value = 0x10;
564 Et_RegWrite(dev, ET_ClCK, &value, 1);
565 value = 0x19;
566 Et_RegWrite(dev, ET_CTRL, &value, 1);
567 /* compression et subsampling */
568 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode)
569 value = ET_COMP_VAL1;
570 else
571 value = ET_COMP_VAL0;
572
573 PDEBUG(D_STREAM, "Open mode %d Compression %d",
574 gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode,
575 value);
576 Et_RegWrite(dev, ET_COMP, &value, 1);
577 value = 0x1d;
578 Et_RegWrite(dev, ET_MAXQt, &value, 1);
579 value = 0x02;
580 Et_RegWrite(dev, ET_MINQt, &value, 1);
581 /* undocumented registers */
582 value = 0xff;
583 Et_RegWrite(dev, ET_REG1d, &value, 1);
584 value = 0xff;
585 Et_RegWrite(dev, ET_REG1e, &value, 1);
586 value = 0xff;
587 Et_RegWrite(dev, ET_REG1f, &value, 1);
588 value = 0x35;
589 Et_RegWrite(dev, ET_REG20, &value, 1);
590 value = 0x01;
591 Et_RegWrite(dev, ET_REG21, &value, 1);
592 value = 0x00;
593 Et_RegWrite(dev, ET_REG22, &value, 1);
594 value = 0xf7;
595 Et_RegWrite(dev, ET_REG23, &value, 1);
596 value = 0xff;
597 Et_RegWrite(dev, ET_REG24, &value, 1);
598 value = 0x07;
599 Et_RegWrite(dev, ET_REG25, &value, 1);
600 /* colors setting */
601 value = 0x80;
602 Et_RegWrite(dev, ET_G_RED, &value, 1);
603 value = 0x80;
604 Et_RegWrite(dev, ET_G_GREEN1, &value, 1);
605 value = 0x80;
606 Et_RegWrite(dev, ET_G_BLUE, &value, 1);
607 value = 0x80;
608 Et_RegWrite(dev, ET_G_GREEN2, &value, 1);
609 value = 0x00;
610 Et_RegWrite(dev, ET_G_GR_H, &value, 1);
611 value = 0x00;
612 Et_RegWrite(dev, ET_G_GB_H, &value, 1);
613 /* Window control registers */
614 value = 0xf0;
615 Et_RegWrite(dev, ET_SYNCHRO, &value, 1);
616 value = 0x56; /* 0x56 */
617 Et_RegWrite(dev, ET_STARTX, &value, 1);
618 value = 0x05; /* 0x04 */
619 Et_RegWrite(dev, ET_STARTY, &value, 1);
620 value = 0x60;
621 Et_RegWrite(dev, ET_WIDTH_LOW, &value, 1);
622 value = 0x20;
623 Et_RegWrite(dev, ET_HEIGTH_LOW, &value, 1);
624 value = 0x50;
625 Et_RegWrite(dev, ET_W_H_HEIGTH, &value, 1);
626 value = 0x86;
627 Et_RegWrite(dev, ET_REG6e, &value, 1);
628 value = 0x01;
629 Et_RegWrite(dev, ET_REG6f, &value, 1);
630 value = 0x86;
631 Et_RegWrite(dev, ET_REG70, &value, 1);
632 value = 0x14;
633 Et_RegWrite(dev, ET_REG71, &value, 1);
634 value = 0x00;
635 Et_RegWrite(dev, ET_REG72, &value, 1);
636 /* Clock Pattern registers */
637 value = 0x00;
638 Et_RegWrite(dev, ET_REG73, &value, 1);
639 value = 0x00;
640 Et_RegWrite(dev, ET_REG74, &value, 1);
641 value = 0x0a;
642 Et_RegWrite(dev, ET_REG75, &value, 1);
643 value = 0x04;
644 Et_RegWrite(dev, ET_I2C_CLK, &value, 1);
645 value = 0x01;
646 Et_RegWrite(dev, ET_PXL_CLK, &value, 1);
647 /* set the sensor */
648 if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) {
649 I2c0[0] = 0x06;
650 Et_i2cwrite(dev, PAS106_REG2, I2c0, sizeof(I2c0), 1);
651 Et_i2cwrite(dev, PAS106_REG9, I2c2, sizeof(I2c2), 1);
652 value = 0x06;
653 Et_i2cwrite(dev, PAS106_REG2, &value, 1, 1);
654 Et_i2cwrite(dev, PAS106_REG3, I2c3, sizeof(I2c3), 1);
655 /* value = 0x1f; */
656 value = 0x04;
657 Et_i2cwrite(dev, PAS106_REG0e, &value, 1, 1);
658 } else {
659 I2c0[0] = 0x0a;
660
661 Et_i2cwrite(dev, PAS106_REG2, I2c0, sizeof(I2c0), 1);
662 Et_i2cwrite(dev, PAS106_REG9, I2c2, sizeof(I2c2), 1);
663 value = 0x0a;
664
665 Et_i2cwrite(dev, PAS106_REG2, &value, 1, 1);
666 Et_i2cwrite(dev, PAS106_REG3, I2c3, sizeof(I2c3), 1);
667 value = 0x04;
668 /* value = 0x10; */
669 Et_i2cwrite(dev, PAS106_REG0e, &value, 1, 1);
670 /* bit 2 enable bit 1:2 select 0 1 2 3
671 value = 0x07; * curve 0 *
672 Et_i2cwrite(dev,PAS106_REG0f,&value,1,1);
673 */
674 }
675
676/* value = 0x01; */
677/* value = 0x22; */
678/* Et_i2cwrite(dev, PAS106_REG5, &value, 1, 1); */
679 /* magnetude and sign bit for DAC */
680 Et_i2cwrite(dev, PAS106_REG7, I2c4, sizeof I2c4, 1);
681 /* now set by fifo the whole colors setting */
682 Et_RegWrite(dev, ET_G_RED, GainRGBG, 6);
683 getcolors(gspca_dev);
684 setcolors(gspca_dev);
685}
686
687/* this function is called at probe time */
688static int sd_config(struct gspca_dev *gspca_dev,
689 const struct usb_device_id *id)
690{
691 struct sd *sd = (struct sd *) gspca_dev;
692 struct cam *cam;
693 __u16 vendor;
694 __u16 product;
695
696 vendor = id->idVendor;
697 product = id->idProduct;
698/* switch (vendor) { */
699/* case 0x102c: * Etoms */
700 switch (product) {
701 case 0x6151:
702 sd->sensor = SENSOR_PAS106; /* Etoms61x151 */
703 break;
704 case 0x6251:
705 sd->sensor = SENSOR_TAS5130CXX; /* Etoms61x251 */
706 break;
707/* } */
708/* break; */
709 }
710 cam = &gspca_dev->cam;
711 cam->dev_name = (char *) id->driver_info;
712 cam->epaddr = 1;
713 if (sd->sensor == SENSOR_PAS106) {
714 cam->cam_mode = sif_mode;
715 cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
716 } else {
717 cam->cam_mode = vga_mode;
718 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
719 }
720 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
721 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
722 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
723 sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value;
724 return 0;
725}
726
727/* this function is called at open time */
728static int sd_open(struct gspca_dev *gspca_dev)
729{
730 struct sd *sd = (struct sd *) gspca_dev;
731 struct usb_device *dev = gspca_dev->dev;
732 int err;
733 __u8 value;
734
735 PDEBUG(D_STREAM, "Initialize ET1");
736 if (sd->sensor == SENSOR_PAS106)
737 Et_init1(gspca_dev);
738 else
739 Et_init2(gspca_dev);
740 value = 0x08;
741 Et_RegWrite(dev, ET_RESET_ALL, &value, 1);
742 err = Et_videoOff(dev);
743 PDEBUG(D_STREAM, "Et_Init_VideoOff %d", err);
744 return 0;
745}
746
747/* -- start the camera -- */
748static void sd_start(struct gspca_dev *gspca_dev)
749{
750 struct sd *sd = (struct sd *) gspca_dev;
751 struct usb_device *dev = gspca_dev->dev;
752 int err;
753 __u8 value;
754
755 if (sd->sensor == SENSOR_PAS106)
756 Et_init1(gspca_dev);
757 else
758 Et_init2(gspca_dev);
759
760 value = 0x08;
761 Et_RegWrite(dev, ET_RESET_ALL, &value, 1);
762 err = Et_videoOn(dev);
763 PDEBUG(D_STREAM, "Et_VideoOn %d", err);
764}
765
766static void sd_stopN(struct gspca_dev *gspca_dev)
767{
768 int err;
769
770 err = Et_videoOff(gspca_dev->dev);
771 PDEBUG(D_STREAM, "Et_VideoOff %d", err);
772
773}
774
775static void sd_stop0(struct gspca_dev *gspca_dev)
776{
777}
778
779static void sd_close(struct gspca_dev *gspca_dev)
780{
781}
782
783static void setbrightness(struct gspca_dev *gspca_dev)
784{
785 struct sd *sd = (struct sd *) gspca_dev;
786 int i;
787 __u8 brightness = sd->brightness;
788
789 for (i = 0; i < 4; i++)
790 Et_RegWrite(gspca_dev->dev, (ET_O_RED + i), &brightness, 1);
791}
792
793static void getbrightness(struct gspca_dev *gspca_dev)
794{
795 struct sd *sd = (struct sd *) gspca_dev;
796 int i;
797 int brightness = 0;
798 __u8 value = 0;
799
800 for (i = 0; i < 4; i++) {
801 Et_RegRead(gspca_dev->dev, (ET_O_RED + i), &value, 1);
802 brightness += value;
803 }
804 sd->brightness = brightness >> 3;
805}
806
807static void setcontrast(struct gspca_dev *gspca_dev)
808{
809 struct sd *sd = (struct sd *) gspca_dev;
810 __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 };
811 __u8 contrast = sd->contrast;
812
813 memset(RGBG, contrast, sizeof RGBG - 2);
814 Et_RegWrite(gspca_dev->dev, ET_G_RED, RGBG, 6);
815}
816
817static void getcontrast(struct gspca_dev *gspca_dev)
818{
819 struct sd *sd = (struct sd *) gspca_dev;
820 int i;
821 int contrast = 0;
822 __u8 value = 0;
823
824 for (i = 0; i < 4; i++) {
825 Et_RegRead(gspca_dev->dev, (ET_G_RED + i), &value, 1);
826 contrast += value;
827 }
828 sd->contrast = contrast >> 2;
829}
830
831static __u8 Et_getgainG(struct gspca_dev *gspca_dev)
832{
833 struct sd *sd = (struct sd *) gspca_dev;
834 __u8 value = 0;
835
836 if (sd->sensor == SENSOR_PAS106) {
837 Et_i2cread(gspca_dev->dev, PAS106_REG0e, &value, 1, 1);
838 PDEBUG(D_CONF, "Etoms gain G %d", value);
839 return value;
840 }
841 return 0x1f;
842}
843
844static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain)
845{
846 struct sd *sd = (struct sd *) gspca_dev;
847 struct usb_device *dev = gspca_dev->dev;
848 __u8 i2cflags = 0x01;
849
850 if (sd->sensor == SENSOR_PAS106) {
851 Et_i2cwrite(dev, PAS106_REG13, &i2cflags, 1, 3);
852 Et_i2cwrite(dev, PAS106_REG0e, &gain, 1, 1);
853 }
854}
855
856#define BLIMIT(bright) \
857 (__u8)((bright > 0x1f)?0x1f:((bright < 4)?3:bright))
858#define LIMIT(color) \
859 (unsigned char)((color > 0xff)?0xff:((color < 0)?0:color))
860
861static void setautogain(struct gspca_dev *gspca_dev)
862{
863 struct usb_device *dev = gspca_dev->dev;
864 __u8 GRBG[] = { 0, 0, 0, 0 };
865 __u8 luma = 0;
866 __u8 luma_mean = 128;
867 __u8 luma_delta = 20;
868 __u8 spring = 4;
869 int Gbright = 0;
870 __u8 r, g, b;
871
872 Gbright = Et_getgainG(gspca_dev);
873 Et_RegRead(dev, ET_LUMA_CENTER, GRBG, 4);
874 g = (GRBG[0] + GRBG[3]) >> 1;
875 r = GRBG[1];
876 b = GRBG[2];
877 r = ((r << 8) - (r << 4) - (r << 3)) >> 10;
878 b = ((b << 7) >> 10);
879 g = ((g << 9) + (g << 7) + (g << 5)) >> 10;
880 luma = LIMIT(r + g + b);
881 PDEBUG(D_FRAM, "Etoms luma G %d", luma);
882 if (luma < luma_mean - luma_delta || luma > luma_mean + luma_delta) {
883 Gbright += (luma_mean - luma) >> spring;
884 Gbright = BLIMIT(Gbright);
885 PDEBUG(D_FRAM, "Etoms Gbright %d", Gbright);
886 Et_setgainG(gspca_dev, (__u8) Gbright);
887 }
888}
889
890#undef BLIMIT
891#undef LIMIT
892
893static void sd_pkt_scan(struct gspca_dev *gspca_dev,
894 struct gspca_frame *frame, /* target */
895 unsigned char *data, /* isoc packet */
896 int len) /* iso packet length */
897{
898 struct sd *sd;
899 int seqframe;
900
901 seqframe = data[0] & 0x3f;
902 len = (int) (((data[0] & 0xc0) << 2) | data[1]);
903 if (seqframe == 0x3f) {
904 PDEBUG(D_FRAM,
905 "header packet found datalength %d !!", len);
906 PDEBUG(D_FRAM, "G %d R %d G %d B %d",
907 data[2], data[3], data[4], data[5]);
908 data += 30;
909 /* don't change datalength as the chips provided it */
910 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
911 data, 0);
912 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
913 sd = (struct sd *) gspca_dev;
914 if (sd->ag_cnt >= 0) {
915 if (--sd->ag_cnt < 0) {
916 sd->ag_cnt = AG_CNT_START;
917 setautogain(gspca_dev);
918 }
919 }
920 return;
921 }
922 if (len) {
923 data += 8;
924 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
925 } else { /* Drop Packet */
926 gspca_dev->last_packet_type = DISCARD_PACKET;
927 }
928}
929
930static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
931{
932 struct sd *sd = (struct sd *) gspca_dev;
933
934 sd->brightness = val;
935 if (gspca_dev->streaming)
936 setbrightness(gspca_dev);
937 return 0;
938}
939
940static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
941{
942 struct sd *sd = (struct sd *) gspca_dev;
943
944 getbrightness(gspca_dev);
945 *val = sd->brightness;
946 return 0;
947}
948
949static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
950{
951 struct sd *sd = (struct sd *) gspca_dev;
952
953 sd->contrast = val;
954 if (gspca_dev->streaming)
955 setcontrast(gspca_dev);
956 return 0;
957}
958
959static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
960{
961 struct sd *sd = (struct sd *) gspca_dev;
962
963 getcontrast(gspca_dev);
964 *val = sd->contrast;
965 return 0;
966}
967
968static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
969{
970 struct sd *sd = (struct sd *) gspca_dev;
971
972 sd->colors = val;
973 if (gspca_dev->streaming)
974 setcolors(gspca_dev);
975 return 0;
976}
977
978static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
979{
980 struct sd *sd = (struct sd *) gspca_dev;
981
982 getcolors(gspca_dev);
983 *val = sd->colors;
984 return 0;
985}
986
987static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
988{
989 struct sd *sd = (struct sd *) gspca_dev;
990
991 sd->autogain = val;
992 if (val)
993 sd->ag_cnt = AG_CNT_START;
994 else
995 sd->ag_cnt = -1;
996 return 0;
997}
998
999static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1000{
1001 struct sd *sd = (struct sd *) gspca_dev;
1002
1003 *val = sd->autogain;
1004 return 0;
1005}
1006
1007/* sub-driver description */
1008static struct sd_desc sd_desc = {
1009 .name = MODULE_NAME,
1010 .ctrls = sd_ctrls,
1011 .nctrls = ARRAY_SIZE(sd_ctrls),
1012 .config = sd_config,
1013 .open = sd_open,
1014 .start = sd_start,
1015 .stopN = sd_stopN,
1016 .stop0 = sd_stop0,
1017 .close = sd_close,
1018 .pkt_scan = sd_pkt_scan,
1019};
1020
1021/* -- module initialisation -- */
1022#define DVNM(name) .driver_info = (kernel_ulong_t) name
1023static __devinitdata struct usb_device_id device_table[] = {
1024 {USB_DEVICE(0x102c, 0x6151), DVNM("Qcam Sangha CIF")},
1025 {USB_DEVICE(0x102c, 0x6251), DVNM("Qcam xxxxxx VGA")},
1026 {}
1027};
1028
1029MODULE_DEVICE_TABLE(usb, device_table);
1030
1031/* -- device connect -- */
1032static int sd_probe(struct usb_interface *intf,
1033 const struct usb_device_id *id)
1034{
1035 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1036 THIS_MODULE);
1037}
1038
1039static struct usb_driver sd_driver = {
1040 .name = MODULE_NAME,
1041 .id_table = device_table,
1042 .probe = sd_probe,
1043 .disconnect = gspca_disconnect,
1044};
1045
1046/* -- module insert / remove -- */
1047static int __init sd_mod_init(void)
1048{
1049 if (usb_register(&sd_driver) < 0)
1050 return -1;
1051 PDEBUG(D_PROBE, "v%s registered", version);
1052 return 0;
1053}
1054
1055static void __exit sd_mod_exit(void)
1056{
1057 usb_deregister(&sd_driver);
1058 PDEBUG(D_PROBE, "deregistered");
1059}
1060
1061module_init(sd_mod_init);
1062module_exit(sd_mod_exit);