diff options
author | Jean-Francois Moine <moinejf@free.fr> | 2008-06-30 14:50:11 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-20 06:14:49 -0400 |
commit | 6a7eba24e4f0ff725d33159f6265e3a79d53a833 (patch) | |
tree | 3e50d669cb91affbcfad9333d74ddc452783094f /drivers/media/video/gspca/etoms.c | |
parent | d43fa32fec442571f10f5d0c3b553413288728de (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.c | 1062 |
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) | ||
26 | static const char version[] = "2.1.0"; | ||
27 | |||
28 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
29 | MODULE_DESCRIPTION("Etoms USB Camera Driver"); | ||
30 | MODULE_LICENSE("GPL"); | ||
31 | |||
32 | /* specific webcam descriptor */ | ||
33 | struct 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 */ | ||
49 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
50 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
51 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
52 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
53 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
54 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
55 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
56 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
57 | |||
58 | static 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 | |||
117 | static struct cam_mode vga_mode[] = { | ||
118 | {V4L2_PIX_FMT_SBGGR8, 320, 240, 1}, | ||
119 | /* {V4L2_PIX_FMT_SBGGR8, 640, 480, 0}, */ | ||
120 | }; | ||
121 | |||
122 | static 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 | |||
208 | static __u8 GainRGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; | ||
209 | |||
210 | static __u8 I2c2[] = { 0x08, 0x08, 0x08, 0x08, 0x0d }; | ||
211 | |||
212 | static __u8 I2c3[] = { 0x12, 0x05 }; | ||
213 | |||
214 | static __u8 I2c4[] = { 0x41, 0x08 }; | ||
215 | |||
216 | static 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 | |||
226 | static 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 | |||
236 | static 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, ®, 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 | |||
259 | static 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, ®, 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 | |||
286 | static 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 | |||
299 | static 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 | |||
311 | static 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 | |||
323 | static 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 | |||
510 | static 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 | |||
531 | static 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 | |||
544 | static 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 */ | ||
688 | static 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 */ | ||
728 | static 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 -- */ | ||
748 | static 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 | |||
766 | static 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 | |||
775 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
776 | { | ||
777 | } | ||
778 | |||
779 | static void sd_close(struct gspca_dev *gspca_dev) | ||
780 | { | ||
781 | } | ||
782 | |||
783 | static 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 | |||
793 | static 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 | |||
807 | static 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 | |||
817 | static 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 | |||
831 | static __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 | |||
844 | static 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 | |||
861 | static 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 | |||
893 | static 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 | |||
930 | static 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 | |||
940 | static 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 | |||
949 | static 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 | |||
959 | static 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 | |||
968 | static 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 | |||
978 | static 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 | |||
987 | static 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 | |||
999 | static 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 */ | ||
1008 | static 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 | ||
1023 | static __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 | |||
1029 | MODULE_DEVICE_TABLE(usb, device_table); | ||
1030 | |||
1031 | /* -- device connect -- */ | ||
1032 | static 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 | |||
1039 | static 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 -- */ | ||
1047 | static 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 | |||
1055 | static void __exit sd_mod_exit(void) | ||
1056 | { | ||
1057 | usb_deregister(&sd_driver); | ||
1058 | PDEBUG(D_PROBE, "deregistered"); | ||
1059 | } | ||
1060 | |||
1061 | module_init(sd_mod_init); | ||
1062 | module_exit(sd_mod_exit); | ||