diff options
Diffstat (limited to 'drivers/media/video/gspca')
26 files changed, 33376 insertions, 0 deletions
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig new file mode 100644 index 000000000000..42b90742b40b --- /dev/null +++ b/drivers/media/video/gspca/Kconfig | |||
@@ -0,0 +1,13 @@ | |||
1 | config USB_GSPCA | ||
2 | tristate "USB GSPCA driver" | ||
3 | depends on VIDEO_V4L2 | ||
4 | ---help--- | ||
5 | Say Y here if you want support for various USB webcams. | ||
6 | |||
7 | See <file:Documentation/video4linux/gspca.txt> for more info. | ||
8 | |||
9 | This driver uses the Video For Linux API. You must say Y or M to | ||
10 | "Video For Linux" to use this driver. | ||
11 | |||
12 | To compile this driver as modules, choose M here: the | ||
13 | modules will be called gspca_xxxx. | ||
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile new file mode 100644 index 000000000000..e68a8965297a --- /dev/null +++ b/drivers/media/video/gspca/Makefile | |||
@@ -0,0 +1,29 @@ | |||
1 | obj-$(CONFIG_USB_GSPCA) += gspca_main.o \ | ||
2 | gspca_conex.o gspca_etoms.o gspca_mars.o \ | ||
3 | gspca_ov519.o gspca_pac207.o gspca_pac7311.o \ | ||
4 | gspca_sonixb.o gspca_sonixj.o gspca_spca500.o gspca_spca501.o \ | ||
5 | gspca_spca505.o gspca_spca506.o gspca_spca508.o gspca_spca561.o \ | ||
6 | gspca_sunplus.o gspca_stk014.o gspca_t613.o gspca_tv8532.o \ | ||
7 | gspca_vc032x.o gspca_zc3xx.o | ||
8 | |||
9 | gspca_main-objs := gspca.o | ||
10 | gspca_conex-objs := conex.o | ||
11 | gspca_etoms-objs := etoms.o | ||
12 | gspca_mars-objs := mars.o | ||
13 | gspca_ov519-objs := ov519.o | ||
14 | gspca_pac207-objs := pac207.o | ||
15 | gspca_pac7311-objs := pac7311.o | ||
16 | gspca_sonixb-objs := sonixb.o | ||
17 | gspca_sonixj-objs := sonixj.o | ||
18 | gspca_spca500-objs := spca500.o | ||
19 | gspca_spca501-objs := spca501.o | ||
20 | gspca_spca505-objs := spca505.o | ||
21 | gspca_spca506-objs := spca506.o | ||
22 | gspca_spca508-objs := spca508.o | ||
23 | gspca_spca561-objs := spca561.o | ||
24 | gspca_stk014-objs := stk014.o | ||
25 | gspca_sunplus-objs := sunplus.o | ||
26 | gspca_t613-objs := t613.o | ||
27 | gspca_tv8532-objs := tv8532.o | ||
28 | gspca_vc032x-objs := vc032x.o | ||
29 | gspca_zc3xx-objs := zc3xx.o | ||
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c new file mode 100644 index 000000000000..013d593b0c67 --- /dev/null +++ b/drivers/media/video/gspca/conex.c | |||
@@ -0,0 +1,1051 @@ | |||
1 | /* | ||
2 | * Connexant Cx11646 library | ||
3 | * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr | ||
4 | * | ||
5 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #define MODULE_NAME "conex" | ||
23 | |||
24 | #include "gspca.h" | ||
25 | #define CONEX_CAM 1 /* special JPEG header */ | ||
26 | #include "jpeg.h" | ||
27 | |||
28 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) | ||
29 | static const char version[] = "2.1.7"; | ||
30 | |||
31 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
32 | MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver"); | ||
33 | MODULE_LICENSE("GPL"); | ||
34 | |||
35 | /* specific webcam descriptor */ | ||
36 | struct sd { | ||
37 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
38 | |||
39 | unsigned char brightness; | ||
40 | unsigned char contrast; | ||
41 | unsigned char colors; | ||
42 | |||
43 | unsigned char qindex; | ||
44 | }; | ||
45 | |||
46 | /* V4L2 controls supported by the driver */ | ||
47 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
48 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
49 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
50 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
51 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
52 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
53 | |||
54 | static struct ctrl sd_ctrls[] = { | ||
55 | { | ||
56 | { | ||
57 | .id = V4L2_CID_BRIGHTNESS, | ||
58 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
59 | .name = "Brightness", | ||
60 | .minimum = 0, | ||
61 | .maximum = 255, | ||
62 | .step = 1, | ||
63 | #define BRIGHTNESS_DEF 0xd4 | ||
64 | .default_value = BRIGHTNESS_DEF, | ||
65 | }, | ||
66 | .set = sd_setbrightness, | ||
67 | .get = sd_getbrightness, | ||
68 | }, | ||
69 | { | ||
70 | { | ||
71 | .id = V4L2_CID_CONTRAST, | ||
72 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
73 | .name = "Contrast", | ||
74 | .minimum = 0x0a, | ||
75 | .maximum = 0x1f, | ||
76 | .step = 1, | ||
77 | #define CONTRAST_DEF 0x0c | ||
78 | .default_value = CONTRAST_DEF, | ||
79 | }, | ||
80 | .set = sd_setcontrast, | ||
81 | .get = sd_getcontrast, | ||
82 | }, | ||
83 | { | ||
84 | { | ||
85 | .id = V4L2_CID_SATURATION, | ||
86 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
87 | .name = "Color", | ||
88 | .minimum = 0, | ||
89 | .maximum = 7, | ||
90 | .step = 1, | ||
91 | #define COLOR_DEF 3 | ||
92 | .default_value = COLOR_DEF, | ||
93 | }, | ||
94 | .set = sd_setcolors, | ||
95 | .get = sd_getcolors, | ||
96 | }, | ||
97 | }; | ||
98 | |||
99 | static struct v4l2_pix_format vga_mode[] = { | ||
100 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
101 | .bytesperline = 176, | ||
102 | .sizeimage = 176 * 144 * 3 / 8 + 590, | ||
103 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
104 | .priv = 3}, | ||
105 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
106 | .bytesperline = 320, | ||
107 | .sizeimage = 320 * 240 * 3 / 8 + 590, | ||
108 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
109 | .priv = 2}, | ||
110 | {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
111 | .bytesperline = 352, | ||
112 | .sizeimage = 352 * 288 * 3 / 8 + 590, | ||
113 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
114 | .priv = 1}, | ||
115 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
116 | .bytesperline = 640, | ||
117 | .sizeimage = 640 * 480 * 3 / 8 + 590, | ||
118 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
119 | .priv = 0}, | ||
120 | }; | ||
121 | |||
122 | /* the read bytes are found in gspca_dev->usb_buf */ | ||
123 | static void reg_r(struct gspca_dev *gspca_dev, | ||
124 | __u16 index, | ||
125 | __u16 len) | ||
126 | { | ||
127 | struct usb_device *dev = gspca_dev->dev; | ||
128 | |||
129 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
130 | if (len > sizeof gspca_dev->usb_buf) { | ||
131 | err("reg_r: buffer overflow"); | ||
132 | return; | ||
133 | } | ||
134 | #endif | ||
135 | usb_control_msg(dev, | ||
136 | usb_rcvctrlpipe(dev, 0), | ||
137 | 0, | ||
138 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
139 | 0, | ||
140 | index, gspca_dev->usb_buf, len, | ||
141 | 500); | ||
142 | PDEBUG(D_USBI, "reg read [%02x] -> %02x ..", | ||
143 | index, gspca_dev->usb_buf[0]); | ||
144 | } | ||
145 | |||
146 | /* the bytes to write are in gspca_dev->usb_buf */ | ||
147 | static void reg_w_val(struct gspca_dev *gspca_dev, | ||
148 | __u16 index, | ||
149 | __u8 val) | ||
150 | { | ||
151 | struct usb_device *dev = gspca_dev->dev; | ||
152 | |||
153 | gspca_dev->usb_buf[0] = val; | ||
154 | usb_control_msg(dev, | ||
155 | usb_sndctrlpipe(dev, 0), | ||
156 | 0, | ||
157 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
158 | 0, | ||
159 | index, gspca_dev->usb_buf, 1, 500); | ||
160 | } | ||
161 | |||
162 | static void reg_w(struct gspca_dev *gspca_dev, | ||
163 | __u16 index, | ||
164 | const __u8 *buffer, | ||
165 | __u16 len) | ||
166 | { | ||
167 | struct usb_device *dev = gspca_dev->dev; | ||
168 | |||
169 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
170 | if (len > sizeof gspca_dev->usb_buf) { | ||
171 | err("reg_w: buffer overflow"); | ||
172 | return; | ||
173 | } | ||
174 | PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer); | ||
175 | #endif | ||
176 | memcpy(gspca_dev->usb_buf, buffer, len); | ||
177 | usb_control_msg(dev, | ||
178 | usb_sndctrlpipe(dev, 0), | ||
179 | 0, | ||
180 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
181 | 0, | ||
182 | index, gspca_dev->usb_buf, len, 500); | ||
183 | } | ||
184 | |||
185 | static const __u8 cx_sensor_init[][4] = { | ||
186 | {0x88, 0x11, 0x01, 0x01}, | ||
187 | {0x88, 0x12, 0x70, 0x01}, | ||
188 | {0x88, 0x0f, 0x00, 0x01}, | ||
189 | {0x88, 0x05, 0x01, 0x01}, | ||
190 | {} | ||
191 | }; | ||
192 | |||
193 | static const __u8 cx11646_fw1[][3] = { | ||
194 | {0x00, 0x02, 0x00}, | ||
195 | {0x01, 0x43, 0x00}, | ||
196 | {0x02, 0xA7, 0x00}, | ||
197 | {0x03, 0x8B, 0x01}, | ||
198 | {0x04, 0xE9, 0x02}, | ||
199 | {0x05, 0x08, 0x04}, | ||
200 | {0x06, 0x08, 0x05}, | ||
201 | {0x07, 0x07, 0x06}, | ||
202 | {0x08, 0xE7, 0x06}, | ||
203 | {0x09, 0xC6, 0x07}, | ||
204 | {0x0A, 0x86, 0x08}, | ||
205 | {0x0B, 0x46, 0x09}, | ||
206 | {0x0C, 0x05, 0x0A}, | ||
207 | {0x0D, 0xA5, 0x0A}, | ||
208 | {0x0E, 0x45, 0x0B}, | ||
209 | {0x0F, 0xE5, 0x0B}, | ||
210 | {0x10, 0x85, 0x0C}, | ||
211 | {0x11, 0x25, 0x0D}, | ||
212 | {0x12, 0xC4, 0x0D}, | ||
213 | {0x13, 0x45, 0x0E}, | ||
214 | {0x14, 0xE4, 0x0E}, | ||
215 | {0x15, 0x64, 0x0F}, | ||
216 | {0x16, 0xE4, 0x0F}, | ||
217 | {0x17, 0x64, 0x10}, | ||
218 | {0x18, 0xE4, 0x10}, | ||
219 | {0x19, 0x64, 0x11}, | ||
220 | {0x1A, 0xE4, 0x11}, | ||
221 | {0x1B, 0x64, 0x12}, | ||
222 | {0x1C, 0xE3, 0x12}, | ||
223 | {0x1D, 0x44, 0x13}, | ||
224 | {0x1E, 0xC3, 0x13}, | ||
225 | {0x1F, 0x24, 0x14}, | ||
226 | {0x20, 0xA3, 0x14}, | ||
227 | {0x21, 0x04, 0x15}, | ||
228 | {0x22, 0x83, 0x15}, | ||
229 | {0x23, 0xE3, 0x15}, | ||
230 | {0x24, 0x43, 0x16}, | ||
231 | {0x25, 0xA4, 0x16}, | ||
232 | {0x26, 0x23, 0x17}, | ||
233 | {0x27, 0x83, 0x17}, | ||
234 | {0x28, 0xE3, 0x17}, | ||
235 | {0x29, 0x43, 0x18}, | ||
236 | {0x2A, 0xA3, 0x18}, | ||
237 | {0x2B, 0x03, 0x19}, | ||
238 | {0x2C, 0x63, 0x19}, | ||
239 | {0x2D, 0xC3, 0x19}, | ||
240 | {0x2E, 0x22, 0x1A}, | ||
241 | {0x2F, 0x63, 0x1A}, | ||
242 | {0x30, 0xC3, 0x1A}, | ||
243 | {0x31, 0x23, 0x1B}, | ||
244 | {0x32, 0x83, 0x1B}, | ||
245 | {0x33, 0xE2, 0x1B}, | ||
246 | {0x34, 0x23, 0x1C}, | ||
247 | {0x35, 0x83, 0x1C}, | ||
248 | {0x36, 0xE2, 0x1C}, | ||
249 | {0x37, 0x23, 0x1D}, | ||
250 | {0x38, 0x83, 0x1D}, | ||
251 | {0x39, 0xE2, 0x1D}, | ||
252 | {0x3A, 0x23, 0x1E}, | ||
253 | {0x3B, 0x82, 0x1E}, | ||
254 | {0x3C, 0xC3, 0x1E}, | ||
255 | {0x3D, 0x22, 0x1F}, | ||
256 | {0x3E, 0x63, 0x1F}, | ||
257 | {0x3F, 0xC1, 0x1F}, | ||
258 | {} | ||
259 | }; | ||
260 | static void cx11646_fw(struct gspca_dev*gspca_dev) | ||
261 | { | ||
262 | int i = 0; | ||
263 | |||
264 | reg_w_val(gspca_dev, 0x006a, 0x02); | ||
265 | while (cx11646_fw1[i][1]) { | ||
266 | reg_w(gspca_dev, 0x006b, cx11646_fw1[i], 3); | ||
267 | i++; | ||
268 | } | ||
269 | reg_w_val(gspca_dev, 0x006a, 0x00); | ||
270 | } | ||
271 | |||
272 | static const __u8 cxsensor[] = { | ||
273 | 0x88, 0x12, 0x70, 0x01, | ||
274 | 0x88, 0x0d, 0x02, 0x01, | ||
275 | 0x88, 0x0f, 0x00, 0x01, | ||
276 | 0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */ | ||
277 | 0x88, 0x02, 0x10, 0x01, | ||
278 | 0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */ | ||
279 | 0x88, 0x0B, 0x00, 0x01, | ||
280 | 0x88, 0x0A, 0x0A, 0x01, | ||
281 | 0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */ | ||
282 | 0x88, 0x05, 0x01, 0x01, | ||
283 | 0xA1, 0x18, 0x00, 0x01, | ||
284 | 0x00 | ||
285 | }; | ||
286 | |||
287 | static const __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff }; | ||
288 | static const __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff }; | ||
289 | static const __u8 reg10[] = { 0xb1, 0xb1 }; | ||
290 | static const __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */ | ||
291 | static const __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f }; | ||
292 | /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */ | ||
293 | static const __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 }; | ||
294 | /* 320{0x04,0x0c,0x05,0x0f}; //320 */ | ||
295 | static const __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */ | ||
296 | static const __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }; | ||
297 | |||
298 | static void cx_sensor(struct gspca_dev*gspca_dev) | ||
299 | { | ||
300 | int i = 0; | ||
301 | int length; | ||
302 | const __u8 *ptsensor = cxsensor; | ||
303 | |||
304 | reg_w(gspca_dev, 0x0020, reg20, 8); | ||
305 | reg_w(gspca_dev, 0x0028, reg28, 8); | ||
306 | reg_w(gspca_dev, 0x0010, reg10, 8); | ||
307 | reg_w_val(gspca_dev, 0x0092, 0x03); | ||
308 | |||
309 | switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { | ||
310 | case 0: | ||
311 | reg_w(gspca_dev, 0x0071, reg71a, 4); | ||
312 | break; | ||
313 | case 1: | ||
314 | reg_w(gspca_dev, 0x0071, reg71b, 4); | ||
315 | break; | ||
316 | default: | ||
317 | /* case 2: */ | ||
318 | reg_w(gspca_dev, 0x0071, reg71c, 4); | ||
319 | break; | ||
320 | case 3: | ||
321 | reg_w(gspca_dev, 0x0071, reg71d, 4); | ||
322 | break; | ||
323 | } | ||
324 | reg_w(gspca_dev, 0x007b, reg7b, 6); | ||
325 | reg_w_val(gspca_dev, 0x00f8, 0x00); | ||
326 | reg_w(gspca_dev, 0x0010, reg10, 8); | ||
327 | reg_w_val(gspca_dev, 0x0098, 0x41); | ||
328 | for (i = 0; i < 11; i++) { | ||
329 | if (i == 3 || i == 5 || i == 8) | ||
330 | length = 8; | ||
331 | else | ||
332 | length = 4; | ||
333 | reg_w(gspca_dev, 0x00e5, ptsensor, length); | ||
334 | if (length == 4) | ||
335 | reg_r(gspca_dev, 0x00e8, 1); | ||
336 | else | ||
337 | reg_r(gspca_dev, 0x00e8, length); | ||
338 | ptsensor += length; | ||
339 | } | ||
340 | reg_r(gspca_dev, 0x00e7, 8); | ||
341 | } | ||
342 | |||
343 | static const __u8 cx_inits_176[] = { | ||
344 | 0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */ | ||
345 | 0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03, | ||
346 | 0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30, | ||
347 | 0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, | ||
348 | 0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF, | ||
349 | 0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02, | ||
350 | 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
351 | }; | ||
352 | static const __u8 cx_inits_320[] = { | ||
353 | 0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01, | ||
354 | 0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01, | ||
355 | 0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81, | ||
356 | 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, | ||
357 | 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff, | ||
358 | 0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02, | ||
359 | 0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
360 | }; | ||
361 | static const __u8 cx_inits_352[] = { | ||
362 | 0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03, | ||
363 | 0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b, | ||
364 | 0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25, | ||
365 | 0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00, | ||
366 | 0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff, | ||
367 | 0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02, | ||
368 | 0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
369 | }; | ||
370 | static const __u8 cx_inits_640[] = { | ||
371 | 0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01, | ||
372 | 0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01, | ||
373 | 0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81, | ||
374 | 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, | ||
375 | 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff, | ||
376 | 0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02, | ||
377 | 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
378 | }; | ||
379 | |||
380 | static void cx11646_initsize(struct gspca_dev *gspca_dev) | ||
381 | { | ||
382 | const __u8 *cxinit; | ||
383 | static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 }; | ||
384 | static const __u8 reg17[] = | ||
385 | { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 }; | ||
386 | |||
387 | switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { | ||
388 | case 0: | ||
389 | cxinit = cx_inits_640; | ||
390 | break; | ||
391 | case 1: | ||
392 | cxinit = cx_inits_352; | ||
393 | break; | ||
394 | default: | ||
395 | /* case 2: */ | ||
396 | cxinit = cx_inits_320; | ||
397 | break; | ||
398 | case 3: | ||
399 | cxinit = cx_inits_176; | ||
400 | break; | ||
401 | } | ||
402 | reg_w_val(gspca_dev, 0x009a, 0x01); | ||
403 | reg_w_val(gspca_dev, 0x0010, 0x10); | ||
404 | reg_w(gspca_dev, 0x0012, reg12, 5); | ||
405 | reg_w(gspca_dev, 0x0017, reg17, 8); | ||
406 | reg_w_val(gspca_dev, 0x00c0, 0x00); | ||
407 | reg_w_val(gspca_dev, 0x00c1, 0x04); | ||
408 | reg_w_val(gspca_dev, 0x00c2, 0x04); | ||
409 | |||
410 | reg_w(gspca_dev, 0x0061, cxinit, 8); | ||
411 | cxinit += 8; | ||
412 | reg_w(gspca_dev, 0x00ca, cxinit, 8); | ||
413 | cxinit += 8; | ||
414 | reg_w(gspca_dev, 0x00d2, cxinit, 8); | ||
415 | cxinit += 8; | ||
416 | reg_w(gspca_dev, 0x00da, cxinit, 6); | ||
417 | cxinit += 8; | ||
418 | reg_w(gspca_dev, 0x0041, cxinit, 8); | ||
419 | cxinit += 8; | ||
420 | reg_w(gspca_dev, 0x0049, cxinit, 8); | ||
421 | cxinit += 8; | ||
422 | reg_w(gspca_dev, 0x0051, cxinit, 2); | ||
423 | |||
424 | reg_r(gspca_dev, 0x0010, 1); | ||
425 | } | ||
426 | |||
427 | static const __u8 cx_jpeg_init[][8] = { | ||
428 | {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */ | ||
429 | {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11}, | ||
430 | {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22}, | ||
431 | {0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26}, | ||
432 | {0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a}, | ||
433 | {0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73}, | ||
434 | {0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D}, | ||
435 | {0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0}, | ||
436 | {0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01}, | ||
437 | {0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12}, | ||
438 | {0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35}, | ||
439 | {0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31}, | ||
440 | {0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43}, | ||
441 | {0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A}, | ||
442 | {0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73}, | ||
443 | {0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95}, | ||
444 | {0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83}, | ||
445 | {0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05}, | ||
446 | {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00}, | ||
447 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02}, | ||
448 | {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}, | ||
449 | {0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01}, | ||
450 | {0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00}, | ||
451 | {0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05}, | ||
452 | {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00}, | ||
453 | {0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05}, | ||
454 | {0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01}, | ||
455 | {0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21}, | ||
456 | {0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22}, | ||
457 | {0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23}, | ||
458 | {0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24}, | ||
459 | {0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17}, | ||
460 | {0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29}, | ||
461 | {0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A}, | ||
462 | {0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A}, | ||
463 | {0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A}, | ||
464 | {0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A}, | ||
465 | {0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A}, | ||
466 | {0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A}, | ||
467 | {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99}, | ||
468 | {0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8}, | ||
469 | {0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7}, | ||
470 | {0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6}, | ||
471 | {0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5}, | ||
472 | {0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3}, | ||
473 | {0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1}, | ||
474 | {0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9}, | ||
475 | {0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04}, | ||
476 | {0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01}, | ||
477 | {0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04}, | ||
478 | {0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07}, | ||
479 | {0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14}, | ||
480 | {0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33}, | ||
481 | {0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16}, | ||
482 | {0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19}, | ||
483 | {0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36}, | ||
484 | {0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46}, | ||
485 | {0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56}, | ||
486 | {0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66}, | ||
487 | {0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76}, | ||
488 | {0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85}, | ||
489 | {0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94}, | ||
490 | {0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3}, | ||
491 | {0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2}, | ||
492 | {0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA}, | ||
493 | {0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9}, | ||
494 | {0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8}, | ||
495 | {0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7}, | ||
496 | {0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6}, | ||
497 | {0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F}, | ||
498 | {0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00}, | ||
499 | {0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22}, | ||
500 | {0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11}, | ||
501 | {0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00}, | ||
502 | {0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08}, | ||
503 | {0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00}, | ||
504 | {0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA}, | ||
505 | {0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02}, | ||
506 | {0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00} /* 79 */ | ||
507 | }; | ||
508 | |||
509 | |||
510 | static const __u8 cxjpeg_640[][8] = { | ||
511 | {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */ | ||
512 | {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d}, | ||
513 | {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a}, | ||
514 | {0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d}, | ||
515 | {0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38}, | ||
516 | {0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57}, | ||
517 | {0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F}, | ||
518 | {0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79}, | ||
519 | {0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01}, | ||
520 | {0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E}, | ||
521 | {0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28}, | ||
522 | {0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25}, | ||
523 | {0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33}, | ||
524 | {0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44}, | ||
525 | {0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57}, | ||
526 | {0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71}, | ||
527 | {0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63}, | ||
528 | {0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 0x00, 0x00}, | ||
529 | {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00}, | ||
530 | {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22}, | ||
531 | {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55}, | ||
532 | {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x28, 0xFF}, | ||
533 | {0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80}, | ||
534 | {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02}, | ||
535 | {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00}, | ||
536 | {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00}, | ||
537 | {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */ | ||
538 | }; | ||
539 | static const __u8 cxjpeg_352[][8] = { | ||
540 | {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d}, | ||
541 | {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a}, | ||
542 | {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14}, | ||
543 | {0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17}, | ||
544 | {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C}, | ||
545 | {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44}, | ||
546 | {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A}, | ||
547 | {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F}, | ||
548 | {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01}, | ||
549 | {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B}, | ||
550 | {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F}, | ||
551 | {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D}, | ||
552 | {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28}, | ||
553 | {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35}, | ||
554 | {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44}, | ||
555 | {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58}, | ||
556 | {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D}, | ||
557 | {0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 0x00, 0x00}, | ||
558 | {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00}, | ||
559 | {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22}, | ||
560 | {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55}, | ||
561 | {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x16, 0xFF}, | ||
562 | {0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60}, | ||
563 | {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02}, | ||
564 | {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00}, | ||
565 | {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00}, | ||
566 | {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} | ||
567 | }; | ||
568 | static const __u8 cxjpeg_320[][8] = { | ||
569 | {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05}, | ||
570 | {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04}, | ||
571 | {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08}, | ||
572 | {0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09}, | ||
573 | {0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11}, | ||
574 | {0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A}, | ||
575 | {0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D}, | ||
576 | {0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24}, | ||
577 | {0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01}, | ||
578 | {0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04}, | ||
579 | {0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C}, | ||
580 | {0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B}, | ||
581 | {0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F}, | ||
582 | {0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14}, | ||
583 | {0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A}, | ||
584 | {0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22}, | ||
585 | {0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E}, | ||
586 | {0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00}, | ||
587 | {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00}, | ||
588 | {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22}, | ||
589 | {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55}, | ||
590 | {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF}, | ||
591 | {0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40}, | ||
592 | {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02}, | ||
593 | {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00}, | ||
594 | {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00}, | ||
595 | {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */ | ||
596 | }; | ||
597 | static const __u8 cxjpeg_176[][8] = { | ||
598 | {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d}, | ||
599 | {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A}, | ||
600 | {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14}, | ||
601 | {0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17}, | ||
602 | {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C}, | ||
603 | {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44}, | ||
604 | {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A}, | ||
605 | {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F}, | ||
606 | {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01}, | ||
607 | {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B}, | ||
608 | {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F}, | ||
609 | {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D}, | ||
610 | {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28}, | ||
611 | {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35}, | ||
612 | {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44}, | ||
613 | {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58}, | ||
614 | {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D}, | ||
615 | {0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00}, | ||
616 | {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00}, | ||
617 | {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22}, | ||
618 | {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55}, | ||
619 | {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF}, | ||
620 | {0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0}, | ||
621 | {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02}, | ||
622 | {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00}, | ||
623 | {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00}, | ||
624 | {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} | ||
625 | }; | ||
626 | /* 640 take with the zcx30x part */ | ||
627 | static const __u8 cxjpeg_qtable[][8] = { | ||
628 | {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08}, | ||
629 | {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07}, | ||
630 | {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a}, | ||
631 | {0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f}, | ||
632 | {0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c}, | ||
633 | {0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c}, | ||
634 | {0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30}, | ||
635 | {0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d}, | ||
636 | {0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01}, | ||
637 | {0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a}, | ||
638 | {0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32}, | ||
639 | {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, | ||
640 | {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, | ||
641 | {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, | ||
642 | {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, | ||
643 | {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, | ||
644 | {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, | ||
645 | {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 18 */ | ||
646 | }; | ||
647 | |||
648 | |||
649 | static void cx11646_jpegInit(struct gspca_dev*gspca_dev) | ||
650 | { | ||
651 | int i; | ||
652 | int length; | ||
653 | |||
654 | reg_w_val(gspca_dev, 0x00c0, 0x01); | ||
655 | reg_w_val(gspca_dev, 0x00c3, 0x00); | ||
656 | reg_w_val(gspca_dev, 0x00c0, 0x00); | ||
657 | reg_r(gspca_dev, 0x0001, 1); | ||
658 | length = 8; | ||
659 | for (i = 0; i < 79; i++) { | ||
660 | if (i == 78) | ||
661 | length = 6; | ||
662 | reg_w(gspca_dev, 0x0008, cx_jpeg_init[i], length); | ||
663 | } | ||
664 | reg_r(gspca_dev, 0x0002, 1); | ||
665 | reg_w_val(gspca_dev, 0x0055, 0x14); | ||
666 | } | ||
667 | |||
668 | static const __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 }; | ||
669 | static const __u8 regE5_8[] = | ||
670 | { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 }; | ||
671 | static const __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 }; | ||
672 | static const __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 }; | ||
673 | static const __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 }; | ||
674 | static const __u8 reg51[] = { 0x77, 0x03 }; | ||
675 | #define reg70 0x03 | ||
676 | |||
677 | static void cx11646_jpeg(struct gspca_dev*gspca_dev) | ||
678 | { | ||
679 | int i; | ||
680 | int length; | ||
681 | __u8 Reg55; | ||
682 | int retry; | ||
683 | |||
684 | reg_w_val(gspca_dev, 0x00c0, 0x01); | ||
685 | reg_w_val(gspca_dev, 0x00c3, 0x00); | ||
686 | reg_w_val(gspca_dev, 0x00c0, 0x00); | ||
687 | reg_r(gspca_dev, 0x0001, 1); | ||
688 | length = 8; | ||
689 | switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { | ||
690 | case 0: | ||
691 | for (i = 0; i < 27; i++) { | ||
692 | if (i == 26) | ||
693 | length = 2; | ||
694 | reg_w(gspca_dev, 0x0008, cxjpeg_640[i], length); | ||
695 | } | ||
696 | Reg55 = 0x28; | ||
697 | break; | ||
698 | case 1: | ||
699 | for (i = 0; i < 27; i++) { | ||
700 | if (i == 26) | ||
701 | length = 2; | ||
702 | reg_w(gspca_dev, 0x0008, cxjpeg_352[i], length); | ||
703 | } | ||
704 | Reg55 = 0x16; | ||
705 | break; | ||
706 | default: | ||
707 | /* case 2: */ | ||
708 | for (i = 0; i < 27; i++) { | ||
709 | if (i == 26) | ||
710 | length = 2; | ||
711 | reg_w(gspca_dev, 0x0008, cxjpeg_320[i], length); | ||
712 | } | ||
713 | Reg55 = 0x14; | ||
714 | break; | ||
715 | case 3: | ||
716 | for (i = 0; i < 27; i++) { | ||
717 | if (i == 26) | ||
718 | length = 2; | ||
719 | reg_w(gspca_dev, 0x0008, cxjpeg_176[i], length); | ||
720 | } | ||
721 | Reg55 = 0x0B; | ||
722 | break; | ||
723 | } | ||
724 | |||
725 | reg_r(gspca_dev, 0x0002, 1); | ||
726 | reg_w_val(gspca_dev, 0x0055, Reg55); | ||
727 | reg_r(gspca_dev, 0x0002, 1); | ||
728 | reg_w(gspca_dev, 0x0010, reg10, 2); | ||
729 | reg_w_val(gspca_dev, 0x0054, 0x02); | ||
730 | reg_w_val(gspca_dev, 0x0054, 0x01); | ||
731 | reg_w_val(gspca_dev, 0x0000, 0x94); | ||
732 | reg_w_val(gspca_dev, 0x0053, 0xc0); | ||
733 | reg_w_val(gspca_dev, 0x00fc, 0xe1); | ||
734 | reg_w_val(gspca_dev, 0x0000, 0x00); | ||
735 | /* wait for completion */ | ||
736 | retry = 50; | ||
737 | while (retry--) { | ||
738 | reg_r(gspca_dev, 0x0002, 1); | ||
739 | /* 0x07 until 0x00 */ | ||
740 | if (gspca_dev->usb_buf[0] == 0x00) | ||
741 | break; | ||
742 | reg_w_val(gspca_dev, 0x0053, 0x00); | ||
743 | } | ||
744 | if (retry == 0) | ||
745 | PDEBUG(D_ERR, "Damned Errors sending jpeg Table"); | ||
746 | /* send the qtable now */ | ||
747 | reg_r(gspca_dev, 0x0001, 1); /* -> 0x18 */ | ||
748 | length = 8; | ||
749 | for (i = 0; i < 18; i++) { | ||
750 | if (i == 17) | ||
751 | length = 2; | ||
752 | reg_w(gspca_dev, 0x0008, cxjpeg_qtable[i], length); | ||
753 | |||
754 | } | ||
755 | reg_r(gspca_dev, 0x0002, 1); /* 0x00 */ | ||
756 | reg_r(gspca_dev, 0x0053, 1); /* 0x00 */ | ||
757 | reg_w_val(gspca_dev, 0x0054, 0x02); | ||
758 | reg_w_val(gspca_dev, 0x0054, 0x01); | ||
759 | reg_w_val(gspca_dev, 0x0000, 0x94); | ||
760 | reg_w_val(gspca_dev, 0x0053, 0xc0); | ||
761 | |||
762 | reg_r(gspca_dev, 0x0038, 1); /* 0x40 */ | ||
763 | reg_r(gspca_dev, 0x0038, 1); /* 0x40 */ | ||
764 | reg_r(gspca_dev, 0x001f, 1); /* 0x38 */ | ||
765 | reg_w(gspca_dev, 0x0012, reg12, 5); | ||
766 | reg_w(gspca_dev, 0x00e5, regE5_8, 8); | ||
767 | reg_r(gspca_dev, 0x00e8, 8); | ||
768 | reg_w(gspca_dev, 0x00e5, regE5a, 4); | ||
769 | reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */ | ||
770 | reg_w_val(gspca_dev, 0x009a, 0x01); | ||
771 | reg_w(gspca_dev, 0x00e5, regE5b, 4); | ||
772 | reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */ | ||
773 | reg_w(gspca_dev, 0x00e5, regE5c, 4); | ||
774 | reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */ | ||
775 | |||
776 | reg_w(gspca_dev, 0x0051, reg51, 2); | ||
777 | reg_w(gspca_dev, 0x0010, reg10, 2); | ||
778 | reg_w_val(gspca_dev, 0x0070, reg70); | ||
779 | } | ||
780 | |||
781 | static void cx11646_init1(struct gspca_dev *gspca_dev) | ||
782 | { | ||
783 | int i = 0; | ||
784 | |||
785 | reg_w_val(gspca_dev, 0x0010, 0x00); | ||
786 | reg_w_val(gspca_dev, 0x0053, 0x00); | ||
787 | reg_w_val(gspca_dev, 0x0052, 0x00); | ||
788 | reg_w_val(gspca_dev, 0x009b, 0x2f); | ||
789 | reg_w_val(gspca_dev, 0x009c, 0x10); | ||
790 | reg_r(gspca_dev, 0x0098, 1); | ||
791 | reg_w_val(gspca_dev, 0x0098, 0x40); | ||
792 | reg_r(gspca_dev, 0x0099, 1); | ||
793 | reg_w_val(gspca_dev, 0x0099, 0x07); | ||
794 | reg_w_val(gspca_dev, 0x0039, 0x40); | ||
795 | reg_w_val(gspca_dev, 0x003c, 0xff); | ||
796 | reg_w_val(gspca_dev, 0x003f, 0x1f); | ||
797 | reg_w_val(gspca_dev, 0x003d, 0x40); | ||
798 | /* reg_w_val(gspca_dev, 0x003d, 0x60); */ | ||
799 | reg_r(gspca_dev, 0x0099, 1); /* ->0x07 */ | ||
800 | |||
801 | while (cx_sensor_init[i][0]) { | ||
802 | reg_w_val(gspca_dev, 0x00e5, cx_sensor_init[i][0]); | ||
803 | reg_r(gspca_dev, 0x00e8, 1); /* -> 0x00 */ | ||
804 | if (i == 1) { | ||
805 | reg_w_val(gspca_dev, 0x00ed, 0x01); | ||
806 | reg_r(gspca_dev, 0x00ed, 1); /* -> 0x01 */ | ||
807 | } | ||
808 | i++; | ||
809 | } | ||
810 | reg_w_val(gspca_dev, 0x00c3, 0x00); | ||
811 | } | ||
812 | |||
813 | /* this function is called at probe time */ | ||
814 | static int sd_config(struct gspca_dev *gspca_dev, | ||
815 | const struct usb_device_id *id) | ||
816 | { | ||
817 | struct sd *sd = (struct sd *) gspca_dev; | ||
818 | struct cam *cam; | ||
819 | |||
820 | cam = &gspca_dev->cam; | ||
821 | cam->dev_name = (char *) id->driver_info; | ||
822 | cam->epaddr = 0x01; | ||
823 | cam->cam_mode = vga_mode; | ||
824 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | ||
825 | |||
826 | sd->qindex = 0; /* set the quantization */ | ||
827 | sd->brightness = BRIGHTNESS_DEF; | ||
828 | sd->contrast = CONTRAST_DEF; | ||
829 | sd->colors = COLOR_DEF; | ||
830 | return 0; | ||
831 | } | ||
832 | |||
833 | /* this function is called at open time */ | ||
834 | static int sd_open(struct gspca_dev *gspca_dev) | ||
835 | { | ||
836 | cx11646_init1(gspca_dev); | ||
837 | cx11646_initsize(gspca_dev); | ||
838 | cx11646_fw(gspca_dev); | ||
839 | cx_sensor(gspca_dev); | ||
840 | cx11646_jpegInit(gspca_dev); | ||
841 | return 0; | ||
842 | } | ||
843 | |||
844 | static void sd_start(struct gspca_dev *gspca_dev) | ||
845 | { | ||
846 | cx11646_initsize(gspca_dev); | ||
847 | cx11646_fw(gspca_dev); | ||
848 | cx_sensor(gspca_dev); | ||
849 | cx11646_jpeg(gspca_dev); | ||
850 | } | ||
851 | |||
852 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
853 | { | ||
854 | } | ||
855 | |||
856 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
857 | { | ||
858 | int retry = 50; | ||
859 | |||
860 | reg_w_val(gspca_dev, 0x0000, 0x00); | ||
861 | reg_r(gspca_dev, 0x0002, 1); | ||
862 | reg_w_val(gspca_dev, 0x0053, 0x00); | ||
863 | |||
864 | while (retry--) { | ||
865 | /* reg_r(gspca_dev, 0x0002, 1);*/ | ||
866 | reg_r(gspca_dev, 0x0053, 1); | ||
867 | if (gspca_dev->usb_buf[0] == 0) | ||
868 | break; | ||
869 | } | ||
870 | reg_w_val(gspca_dev, 0x0000, 0x00); | ||
871 | reg_r(gspca_dev, 0x0002, 1); | ||
872 | |||
873 | reg_w_val(gspca_dev, 0x0010, 0x00); | ||
874 | reg_r(gspca_dev, 0x0033, 1); | ||
875 | reg_w_val(gspca_dev, 0x00fc, 0xe0); | ||
876 | } | ||
877 | |||
878 | static void sd_close(struct gspca_dev *gspca_dev) | ||
879 | { | ||
880 | } | ||
881 | |||
882 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
883 | struct gspca_frame *frame, /* target */ | ||
884 | __u8 *data, /* isoc packet */ | ||
885 | int len) /* iso packet length */ | ||
886 | { | ||
887 | if (data[0] == 0xff && data[1] == 0xd8) { | ||
888 | |||
889 | /* start of frame */ | ||
890 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | ||
891 | data, 0); | ||
892 | |||
893 | /* put the JPEG header in the new frame */ | ||
894 | jpeg_put_header(gspca_dev, frame, | ||
895 | ((struct sd *) gspca_dev)->qindex, | ||
896 | 0x22); | ||
897 | data += 2; | ||
898 | len -= 2; | ||
899 | } | ||
900 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
901 | } | ||
902 | |||
903 | static void setbrightness(struct gspca_dev*gspca_dev) | ||
904 | { | ||
905 | struct sd *sd = (struct sd *) gspca_dev; | ||
906 | __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 }; | ||
907 | __u8 reg51c[2]; | ||
908 | __u8 bright; | ||
909 | __u8 colors; | ||
910 | |||
911 | bright = sd->brightness; | ||
912 | regE5cbx[2] = bright; | ||
913 | reg_w(gspca_dev, 0x00e5, regE5cbx, 8); | ||
914 | reg_r(gspca_dev, 0x00e8, 8); | ||
915 | reg_w(gspca_dev, 0x00e5, regE5c, 4); | ||
916 | reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */ | ||
917 | |||
918 | colors = sd->colors; | ||
919 | reg51c[0] = 0x77; | ||
920 | reg51c[1] = colors; | ||
921 | reg_w(gspca_dev, 0x0051, reg51c, 2); | ||
922 | reg_w(gspca_dev, 0x0010, reg10, 2); | ||
923 | reg_w_val(gspca_dev, 0x0070, reg70); | ||
924 | } | ||
925 | |||
926 | static void setcontrast(struct gspca_dev*gspca_dev) | ||
927 | { | ||
928 | struct sd *sd = (struct sd *) gspca_dev; | ||
929 | __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */ | ||
930 | /* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */ | ||
931 | __u8 reg51c[2]; | ||
932 | |||
933 | regE5acx[2] = sd->contrast; | ||
934 | reg_w(gspca_dev, 0x00e5, regE5acx, 4); | ||
935 | reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */ | ||
936 | reg51c[0] = 0x77; | ||
937 | reg51c[1] = sd->colors; | ||
938 | reg_w(gspca_dev, 0x0051, reg51c, 2); | ||
939 | reg_w(gspca_dev, 0x0010, reg10, 2); | ||
940 | reg_w_val(gspca_dev, 0x0070, reg70); | ||
941 | } | ||
942 | |||
943 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
944 | { | ||
945 | struct sd *sd = (struct sd *) gspca_dev; | ||
946 | |||
947 | sd->brightness = val; | ||
948 | if (gspca_dev->streaming) | ||
949 | setbrightness(gspca_dev); | ||
950 | return 0; | ||
951 | } | ||
952 | |||
953 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
954 | { | ||
955 | struct sd *sd = (struct sd *) gspca_dev; | ||
956 | |||
957 | *val = sd->brightness; | ||
958 | return 0; | ||
959 | } | ||
960 | |||
961 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
962 | { | ||
963 | struct sd *sd = (struct sd *) gspca_dev; | ||
964 | |||
965 | sd->contrast = val; | ||
966 | if (gspca_dev->streaming) | ||
967 | setcontrast(gspca_dev); | ||
968 | return 0; | ||
969 | } | ||
970 | |||
971 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
972 | { | ||
973 | struct sd *sd = (struct sd *) gspca_dev; | ||
974 | |||
975 | *val = sd->contrast; | ||
976 | return 0; | ||
977 | } | ||
978 | |||
979 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
980 | { | ||
981 | struct sd *sd = (struct sd *) gspca_dev; | ||
982 | |||
983 | sd->colors = val; | ||
984 | if (gspca_dev->streaming) { | ||
985 | setbrightness(gspca_dev); | ||
986 | setcontrast(gspca_dev); | ||
987 | } | ||
988 | return 0; | ||
989 | } | ||
990 | |||
991 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
992 | { | ||
993 | struct sd *sd = (struct sd *) gspca_dev; | ||
994 | |||
995 | *val = sd->colors; | ||
996 | return 0; | ||
997 | } | ||
998 | |||
999 | /* sub-driver description */ | ||
1000 | static struct sd_desc sd_desc = { | ||
1001 | .name = MODULE_NAME, | ||
1002 | .ctrls = sd_ctrls, | ||
1003 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
1004 | .config = sd_config, | ||
1005 | .open = sd_open, | ||
1006 | .start = sd_start, | ||
1007 | .stopN = sd_stopN, | ||
1008 | .stop0 = sd_stop0, | ||
1009 | .close = sd_close, | ||
1010 | .pkt_scan = sd_pkt_scan, | ||
1011 | }; | ||
1012 | |||
1013 | /* -- module initialisation -- */ | ||
1014 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
1015 | static __devinitdata struct usb_device_id device_table[] = { | ||
1016 | {USB_DEVICE(0x0572, 0x0041), DVNM("Creative Notebook cx11646")}, | ||
1017 | {} | ||
1018 | }; | ||
1019 | MODULE_DEVICE_TABLE(usb, device_table); | ||
1020 | |||
1021 | /* -- device connect -- */ | ||
1022 | static int sd_probe(struct usb_interface *intf, | ||
1023 | const struct usb_device_id *id) | ||
1024 | { | ||
1025 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
1026 | THIS_MODULE); | ||
1027 | } | ||
1028 | |||
1029 | static struct usb_driver sd_driver = { | ||
1030 | .name = MODULE_NAME, | ||
1031 | .id_table = device_table, | ||
1032 | .probe = sd_probe, | ||
1033 | .disconnect = gspca_disconnect, | ||
1034 | }; | ||
1035 | |||
1036 | /* -- module insert / remove -- */ | ||
1037 | static int __init sd_mod_init(void) | ||
1038 | { | ||
1039 | if (usb_register(&sd_driver) < 0) | ||
1040 | return -1; | ||
1041 | PDEBUG(D_PROBE, "v%s registered", version); | ||
1042 | return 0; | ||
1043 | } | ||
1044 | static void __exit sd_mod_exit(void) | ||
1045 | { | ||
1046 | usb_deregister(&sd_driver); | ||
1047 | PDEBUG(D_PROBE, "deregistered"); | ||
1048 | } | ||
1049 | |||
1050 | module_init(sd_mod_init); | ||
1051 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c new file mode 100644 index 000000000000..8ab4ea7201a9 --- /dev/null +++ b/drivers/media/video/gspca/etoms.c | |||
@@ -0,0 +1,956 @@ | |||
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, 7) | ||
26 | static const char version[] = "2.1.7"; | ||
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 | { | ||
60 | { | ||
61 | .id = V4L2_CID_BRIGHTNESS, | ||
62 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
63 | .name = "Brightness", | ||
64 | .minimum = 1, | ||
65 | .maximum = 127, | ||
66 | .step = 1, | ||
67 | #define BRIGHTNESS_DEF 63 | ||
68 | .default_value = BRIGHTNESS_DEF, | ||
69 | }, | ||
70 | .set = sd_setbrightness, | ||
71 | .get = sd_getbrightness, | ||
72 | }, | ||
73 | { | ||
74 | { | ||
75 | .id = V4L2_CID_CONTRAST, | ||
76 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
77 | .name = "Contrast", | ||
78 | .minimum = 0, | ||
79 | .maximum = 255, | ||
80 | .step = 1, | ||
81 | #define CONTRAST_DEF 127 | ||
82 | .default_value = CONTRAST_DEF, | ||
83 | }, | ||
84 | .set = sd_setcontrast, | ||
85 | .get = sd_getcontrast, | ||
86 | }, | ||
87 | { | ||
88 | { | ||
89 | .id = V4L2_CID_SATURATION, | ||
90 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
91 | .name = "Color", | ||
92 | .minimum = 0, | ||
93 | .maximum = 15, | ||
94 | .step = 1, | ||
95 | #define COLOR_DEF 7 | ||
96 | .default_value = COLOR_DEF, | ||
97 | }, | ||
98 | .set = sd_setcolors, | ||
99 | .get = sd_getcolors, | ||
100 | }, | ||
101 | { | ||
102 | { | ||
103 | .id = V4L2_CID_AUTOGAIN, | ||
104 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
105 | .name = "Auto Gain", | ||
106 | .minimum = 0, | ||
107 | .maximum = 1, | ||
108 | .step = 1, | ||
109 | #define AUTOGAIN_DEF 1 | ||
110 | .default_value = AUTOGAIN_DEF, | ||
111 | }, | ||
112 | .set = sd_setautogain, | ||
113 | .get = sd_getautogain, | ||
114 | }, | ||
115 | }; | ||
116 | |||
117 | static struct v4l2_pix_format vga_mode[] = { | ||
118 | {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
119 | .bytesperline = 320, | ||
120 | .sizeimage = 320 * 240, | ||
121 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
122 | .priv = 1}, | ||
123 | /* {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
124 | .bytesperline = 640, | ||
125 | .sizeimage = 640 * 480, | ||
126 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
127 | .priv = 0}, */ | ||
128 | }; | ||
129 | |||
130 | static struct v4l2_pix_format sif_mode[] = { | ||
131 | {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
132 | .bytesperline = 176, | ||
133 | .sizeimage = 176 * 144, | ||
134 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
135 | .priv = 1}, | ||
136 | {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
137 | .bytesperline = 352, | ||
138 | .sizeimage = 352 * 288, | ||
139 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
140 | .priv = 0}, | ||
141 | }; | ||
142 | |||
143 | #define ETOMS_ALT_SIZE_1000 12 | ||
144 | |||
145 | #define ET_GPIO_DIR_CTRL 0x04 /* Control IO bit[0..5] (0 in 1 out) */ | ||
146 | #define ET_GPIO_OUT 0x05 /* Only IO data */ | ||
147 | #define ET_GPIO_IN 0x06 /* Read Only IO data */ | ||
148 | #define ET_RESET_ALL 0x03 | ||
149 | #define ET_ClCK 0x01 | ||
150 | #define ET_CTRL 0x02 /* enable i2c OutClck Powerdown mode */ | ||
151 | |||
152 | #define ET_COMP 0x12 /* Compression register */ | ||
153 | #define ET_MAXQt 0x13 | ||
154 | #define ET_MINQt 0x14 | ||
155 | #define ET_COMP_VAL0 0x02 | ||
156 | #define ET_COMP_VAL1 0x03 | ||
157 | |||
158 | #define ET_REG1d 0x1d | ||
159 | #define ET_REG1e 0x1e | ||
160 | #define ET_REG1f 0x1f | ||
161 | #define ET_REG20 0x20 | ||
162 | #define ET_REG21 0x21 | ||
163 | #define ET_REG22 0x22 | ||
164 | #define ET_REG23 0x23 | ||
165 | #define ET_REG24 0x24 | ||
166 | #define ET_REG25 0x25 | ||
167 | /* base registers for luma calculation */ | ||
168 | #define ET_LUMA_CENTER 0x39 | ||
169 | |||
170 | #define ET_G_RED 0x4d | ||
171 | #define ET_G_GREEN1 0x4e | ||
172 | #define ET_G_BLUE 0x4f | ||
173 | #define ET_G_GREEN2 0x50 | ||
174 | #define ET_G_GR_H 0x51 | ||
175 | #define ET_G_GB_H 0x52 | ||
176 | |||
177 | #define ET_O_RED 0x34 | ||
178 | #define ET_O_GREEN1 0x35 | ||
179 | #define ET_O_BLUE 0x36 | ||
180 | #define ET_O_GREEN2 0x37 | ||
181 | |||
182 | #define ET_SYNCHRO 0x68 | ||
183 | #define ET_STARTX 0x69 | ||
184 | #define ET_STARTY 0x6a | ||
185 | #define ET_WIDTH_LOW 0x6b | ||
186 | #define ET_HEIGTH_LOW 0x6c | ||
187 | #define ET_W_H_HEIGTH 0x6d | ||
188 | |||
189 | #define ET_REG6e 0x6e /* OBW */ | ||
190 | #define ET_REG6f 0x6f /* OBW */ | ||
191 | #define ET_REG70 0x70 /* OBW_AWB */ | ||
192 | #define ET_REG71 0x71 /* OBW_AWB */ | ||
193 | #define ET_REG72 0x72 /* OBW_AWB */ | ||
194 | #define ET_REG73 0x73 /* Clkdelay ns */ | ||
195 | #define ET_REG74 0x74 /* test pattern */ | ||
196 | #define ET_REG75 0x75 /* test pattern */ | ||
197 | |||
198 | #define ET_I2C_CLK 0x8c | ||
199 | #define ET_PXL_CLK 0x60 | ||
200 | |||
201 | #define ET_I2C_BASE 0x89 | ||
202 | #define ET_I2C_COUNT 0x8a | ||
203 | #define ET_I2C_PREFETCH 0x8b | ||
204 | #define ET_I2C_REG 0x88 | ||
205 | #define ET_I2C_DATA7 0x87 | ||
206 | #define ET_I2C_DATA6 0x86 | ||
207 | #define ET_I2C_DATA5 0x85 | ||
208 | #define ET_I2C_DATA4 0x84 | ||
209 | #define ET_I2C_DATA3 0x83 | ||
210 | #define ET_I2C_DATA2 0x82 | ||
211 | #define ET_I2C_DATA1 0x81 | ||
212 | #define ET_I2C_DATA0 0x80 | ||
213 | |||
214 | #define PAS106_REG2 0x02 /* pxlClk = systemClk/(reg2) */ | ||
215 | #define PAS106_REG3 0x03 /* line/frame H [11..4] */ | ||
216 | #define PAS106_REG4 0x04 /* line/frame L [3..0] */ | ||
217 | #define PAS106_REG5 0x05 /* exposure time line offset(default 5) */ | ||
218 | #define PAS106_REG6 0x06 /* exposure time pixel offset(default 6) */ | ||
219 | #define PAS106_REG7 0x07 /* signbit Dac (default 0) */ | ||
220 | #define PAS106_REG9 0x09 | ||
221 | #define PAS106_REG0e 0x0e /* global gain [4..0](default 0x0e) */ | ||
222 | #define PAS106_REG13 0x13 /* end i2c write */ | ||
223 | |||
224 | static const __u8 GainRGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; | ||
225 | |||
226 | static const __u8 I2c2[] = { 0x08, 0x08, 0x08, 0x08, 0x0d }; | ||
227 | |||
228 | static const __u8 I2c3[] = { 0x12, 0x05 }; | ||
229 | |||
230 | static const __u8 I2c4[] = { 0x41, 0x08 }; | ||
231 | |||
232 | /* read 'len' bytes to gspca_dev->usb_buf */ | ||
233 | static void reg_r(struct gspca_dev *gspca_dev, | ||
234 | __u16 index, | ||
235 | __u16 len) | ||
236 | { | ||
237 | struct usb_device *dev = gspca_dev->dev; | ||
238 | |||
239 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
240 | if (len > sizeof gspca_dev->usb_buf) { | ||
241 | err("reg_r: buffer overflow"); | ||
242 | return; | ||
243 | } | ||
244 | #endif | ||
245 | usb_control_msg(dev, | ||
246 | usb_rcvctrlpipe(dev, 0), | ||
247 | 0, | ||
248 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
249 | 0, | ||
250 | index, gspca_dev->usb_buf, len, 500); | ||
251 | PDEBUG(D_USBI, "reg read [%02x] -> %02x ..", | ||
252 | index, gspca_dev->usb_buf[0]); | ||
253 | } | ||
254 | |||
255 | static void reg_w_val(struct gspca_dev *gspca_dev, | ||
256 | __u16 index, | ||
257 | __u8 val) | ||
258 | { | ||
259 | struct usb_device *dev = gspca_dev->dev; | ||
260 | |||
261 | gspca_dev->usb_buf[0] = val; | ||
262 | usb_control_msg(dev, | ||
263 | usb_sndctrlpipe(dev, 0), | ||
264 | 0, | ||
265 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
266 | 0, | ||
267 | index, gspca_dev->usb_buf, 1, 500); | ||
268 | } | ||
269 | |||
270 | static void reg_w(struct gspca_dev *gspca_dev, | ||
271 | __u16 index, | ||
272 | const __u8 *buffer, | ||
273 | __u16 len) | ||
274 | { | ||
275 | struct usb_device *dev = gspca_dev->dev; | ||
276 | |||
277 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
278 | if (len > sizeof gspca_dev->usb_buf) { | ||
279 | err("reg_w: buffer overflow"); | ||
280 | return; | ||
281 | } | ||
282 | PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer); | ||
283 | #endif | ||
284 | memcpy(gspca_dev->usb_buf, buffer, len); | ||
285 | usb_control_msg(dev, | ||
286 | usb_sndctrlpipe(dev, 0), | ||
287 | 0, | ||
288 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
289 | 0, index, gspca_dev->usb_buf, len, 500); | ||
290 | } | ||
291 | |||
292 | static int i2c_w(struct gspca_dev *gspca_dev, | ||
293 | __u8 reg, | ||
294 | const __u8 *buffer, | ||
295 | int len, __u8 mode) | ||
296 | { | ||
297 | /* buffer should be [D0..D7] */ | ||
298 | __u8 ptchcount; | ||
299 | |||
300 | /* set the base address */ | ||
301 | reg_w_val(gspca_dev, ET_I2C_BASE, 0x40); | ||
302 | /* sensor base for the pas106 */ | ||
303 | /* set count and prefetch */ | ||
304 | ptchcount = ((len & 0x07) << 4) | (mode & 0x03); | ||
305 | reg_w_val(gspca_dev, ET_I2C_COUNT, ptchcount); | ||
306 | /* set the register base */ | ||
307 | reg_w_val(gspca_dev, ET_I2C_REG, reg); | ||
308 | while (--len >= 0) | ||
309 | reg_w_val(gspca_dev, ET_I2C_DATA0 + len, buffer[len]); | ||
310 | return 0; | ||
311 | } | ||
312 | |||
313 | static int i2c_r(struct gspca_dev *gspca_dev, | ||
314 | __u8 reg) | ||
315 | { | ||
316 | /* set the base address */ | ||
317 | reg_w_val(gspca_dev, ET_I2C_BASE, 0x40); | ||
318 | /* sensor base for the pas106 */ | ||
319 | /* set count and prefetch (cnd: 4 bits - mode: 4 bits) */ | ||
320 | reg_w_val(gspca_dev, ET_I2C_COUNT, 0x11); | ||
321 | reg_w_val(gspca_dev, ET_I2C_REG, reg); /* set the register base */ | ||
322 | reg_w_val(gspca_dev, ET_I2C_PREFETCH, 0x02); /* prefetch */ | ||
323 | reg_w_val(gspca_dev, ET_I2C_PREFETCH, 0x00); | ||
324 | reg_r(gspca_dev, ET_I2C_DATA0, 1); /* read one byte */ | ||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | static int Et_WaitStatus(struct gspca_dev *gspca_dev) | ||
329 | { | ||
330 | int retry = 10; | ||
331 | |||
332 | while (retry--) { | ||
333 | reg_r(gspca_dev, ET_ClCK, 1); | ||
334 | if (gspca_dev->usb_buf[0] != 0) | ||
335 | return 1; | ||
336 | } | ||
337 | return 0; | ||
338 | } | ||
339 | |||
340 | static int et_video(struct gspca_dev *gspca_dev, | ||
341 | int on) | ||
342 | { | ||
343 | int ret; | ||
344 | |||
345 | reg_w_val(gspca_dev, ET_GPIO_OUT, | ||
346 | on ? 0x10 /* startvideo - set Bit5 */ | ||
347 | : 0); /* stopvideo */ | ||
348 | ret = Et_WaitStatus(gspca_dev); | ||
349 | if (ret != 0) | ||
350 | PDEBUG(D_ERR, "timeout video on/off"); | ||
351 | return ret; | ||
352 | } | ||
353 | |||
354 | static void Et_init2(struct gspca_dev *gspca_dev) | ||
355 | { | ||
356 | __u8 value; | ||
357 | static const __u8 FormLine[] = { 0x84, 0x03, 0x14, 0xf4, 0x01, 0x05 }; | ||
358 | |||
359 | PDEBUG(D_STREAM, "Open Init2 ET"); | ||
360 | reg_w_val(gspca_dev, ET_GPIO_DIR_CTRL, 0x2f); | ||
361 | reg_w_val(gspca_dev, ET_GPIO_OUT, 0x10); | ||
362 | reg_r(gspca_dev, ET_GPIO_IN, 1); | ||
363 | reg_w_val(gspca_dev, ET_ClCK, 0x14); /* 0x14 // 0x16 enabled pattern */ | ||
364 | reg_w_val(gspca_dev, ET_CTRL, 0x1b); | ||
365 | |||
366 | /* compression et subsampling */ | ||
367 | if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) | ||
368 | value = ET_COMP_VAL1; /* 320 */ | ||
369 | else | ||
370 | value = ET_COMP_VAL0; /* 640 */ | ||
371 | reg_w_val(gspca_dev, ET_COMP, value); | ||
372 | reg_w_val(gspca_dev, ET_MAXQt, 0x1f); | ||
373 | reg_w_val(gspca_dev, ET_MINQt, 0x04); | ||
374 | /* undocumented registers */ | ||
375 | reg_w_val(gspca_dev, ET_REG1d, 0xff); | ||
376 | reg_w_val(gspca_dev, ET_REG1e, 0xff); | ||
377 | reg_w_val(gspca_dev, ET_REG1f, 0xff); | ||
378 | reg_w_val(gspca_dev, ET_REG20, 0x35); | ||
379 | reg_w_val(gspca_dev, ET_REG21, 0x01); | ||
380 | reg_w_val(gspca_dev, ET_REG22, 0x00); | ||
381 | reg_w_val(gspca_dev, ET_REG23, 0xff); | ||
382 | reg_w_val(gspca_dev, ET_REG24, 0xff); | ||
383 | reg_w_val(gspca_dev, ET_REG25, 0x0f); | ||
384 | /* colors setting */ | ||
385 | reg_w_val(gspca_dev, 0x30, 0x11); /* 0x30 */ | ||
386 | reg_w_val(gspca_dev, 0x31, 0x40); | ||
387 | reg_w_val(gspca_dev, 0x32, 0x00); | ||
388 | reg_w_val(gspca_dev, ET_O_RED, 0x00); /* 0x34 */ | ||
389 | reg_w_val(gspca_dev, ET_O_GREEN1, 0x00); | ||
390 | reg_w_val(gspca_dev, ET_O_BLUE, 0x00); | ||
391 | reg_w_val(gspca_dev, ET_O_GREEN2, 0x00); | ||
392 | /*************/ | ||
393 | reg_w_val(gspca_dev, ET_G_RED, 0x80); /* 0x4d */ | ||
394 | reg_w_val(gspca_dev, ET_G_GREEN1, 0x80); | ||
395 | reg_w_val(gspca_dev, ET_G_BLUE, 0x80); | ||
396 | reg_w_val(gspca_dev, ET_G_GREEN2, 0x80); | ||
397 | reg_w_val(gspca_dev, ET_G_GR_H, 0x00); | ||
398 | reg_w_val(gspca_dev, ET_G_GB_H, 0x00); /* 0x52 */ | ||
399 | /* Window control registers */ | ||
400 | reg_w_val(gspca_dev, 0x61, 0x80); /* use cmc_out */ | ||
401 | reg_w_val(gspca_dev, 0x62, 0x02); | ||
402 | reg_w_val(gspca_dev, 0x63, 0x03); | ||
403 | reg_w_val(gspca_dev, 0x64, 0x14); | ||
404 | reg_w_val(gspca_dev, 0x65, 0x0e); | ||
405 | reg_w_val(gspca_dev, 0x66, 0x02); | ||
406 | reg_w_val(gspca_dev, 0x67, 0x02); | ||
407 | |||
408 | /**************************************/ | ||
409 | reg_w_val(gspca_dev, ET_SYNCHRO, 0x8f); /* 0x68 */ | ||
410 | reg_w_val(gspca_dev, ET_STARTX, 0x69); /* 0x6a //0x69 */ | ||
411 | reg_w_val(gspca_dev, ET_STARTY, 0x0d); /* 0x0d //0x0c */ | ||
412 | reg_w_val(gspca_dev, ET_WIDTH_LOW, 0x80); | ||
413 | reg_w_val(gspca_dev, ET_HEIGTH_LOW, 0xe0); | ||
414 | reg_w_val(gspca_dev, ET_W_H_HEIGTH, 0x60); /* 6d */ | ||
415 | reg_w_val(gspca_dev, ET_REG6e, 0x86); | ||
416 | reg_w_val(gspca_dev, ET_REG6f, 0x01); | ||
417 | reg_w_val(gspca_dev, ET_REG70, 0x26); | ||
418 | reg_w_val(gspca_dev, ET_REG71, 0x7a); | ||
419 | reg_w_val(gspca_dev, ET_REG72, 0x01); | ||
420 | /* Clock Pattern registers ***************** */ | ||
421 | reg_w_val(gspca_dev, ET_REG73, 0x00); | ||
422 | reg_w_val(gspca_dev, ET_REG74, 0x18); /* 0x28 */ | ||
423 | reg_w_val(gspca_dev, ET_REG75, 0x0f); /* 0x01 */ | ||
424 | /**********************************************/ | ||
425 | reg_w_val(gspca_dev, 0x8a, 0x20); | ||
426 | reg_w_val(gspca_dev, 0x8d, 0x0f); | ||
427 | reg_w_val(gspca_dev, 0x8e, 0x08); | ||
428 | /**************************************/ | ||
429 | reg_w_val(gspca_dev, 0x03, 0x08); | ||
430 | reg_w_val(gspca_dev, ET_PXL_CLK, 0x03); | ||
431 | reg_w_val(gspca_dev, 0x81, 0xff); | ||
432 | reg_w_val(gspca_dev, 0x80, 0x00); | ||
433 | reg_w_val(gspca_dev, 0x81, 0xff); | ||
434 | reg_w_val(gspca_dev, 0x80, 0x20); | ||
435 | reg_w_val(gspca_dev, 0x03, 0x01); | ||
436 | reg_w_val(gspca_dev, 0x03, 0x00); | ||
437 | reg_w_val(gspca_dev, 0x03, 0x08); | ||
438 | /********************************************/ | ||
439 | |||
440 | /* reg_r(gspca_dev, ET_I2C_BASE, 1); | ||
441 | always 0x40 as the pas106 ??? */ | ||
442 | /* set the sensor */ | ||
443 | if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) | ||
444 | value = 0x04; /* 320 */ | ||
445 | else /* 640 */ | ||
446 | value = 0x1e; /* 0x17 * setting PixelClock | ||
447 | * 0x03 mean 24/(3+1) = 6 Mhz | ||
448 | * 0x05 -> 24/(5+1) = 4 Mhz | ||
449 | * 0x0b -> 24/(11+1) = 2 Mhz | ||
450 | * 0x17 -> 24/(23+1) = 1 Mhz | ||
451 | */ | ||
452 | reg_w_val(gspca_dev, ET_PXL_CLK, value); | ||
453 | /* now set by fifo the FormatLine setting */ | ||
454 | reg_w(gspca_dev, 0x62, FormLine, 6); | ||
455 | |||
456 | /* set exposure times [ 0..0x78] 0->longvalue 0x78->shortvalue */ | ||
457 | reg_w_val(gspca_dev, 0x81, 0x47); /* 0x47; */ | ||
458 | reg_w_val(gspca_dev, 0x80, 0x40); /* 0x40; */ | ||
459 | /* Pedro change */ | ||
460 | /* Brightness change Brith+ decrease value */ | ||
461 | /* Brigth- increase value */ | ||
462 | /* original value = 0x70; */ | ||
463 | reg_w_val(gspca_dev, 0x81, 0x30); /* 0x20; - set brightness */ | ||
464 | reg_w_val(gspca_dev, 0x80, 0x20); /* 0x20; */ | ||
465 | } | ||
466 | |||
467 | static void setcolors(struct gspca_dev *gspca_dev) | ||
468 | { | ||
469 | struct sd *sd = (struct sd *) gspca_dev; | ||
470 | __u8 I2cc[] = { 0x05, 0x02, 0x02, 0x05, 0x0d }; | ||
471 | __u8 i2cflags = 0x01; | ||
472 | /* __u8 green = 0; */ | ||
473 | __u8 colors = sd->colors; | ||
474 | |||
475 | I2cc[3] = colors; /* red */ | ||
476 | I2cc[0] = 15 - colors; /* blue */ | ||
477 | /* green = 15 - ((((7*I2cc[0]) >> 2 ) + I2cc[3]) >> 1); */ | ||
478 | /* I2cc[1] = I2cc[2] = green; */ | ||
479 | if (sd->sensor == SENSOR_PAS106) { | ||
480 | i2c_w(gspca_dev, PAS106_REG13, &i2cflags, 1, 3); | ||
481 | i2c_w(gspca_dev, PAS106_REG9, I2cc, sizeof I2cc, 1); | ||
482 | } | ||
483 | /* PDEBUG(D_CONF , "Etoms red %d blue %d green %d", | ||
484 | I2cc[3], I2cc[0], green); */ | ||
485 | } | ||
486 | |||
487 | static void getcolors(struct gspca_dev *gspca_dev) | ||
488 | { | ||
489 | struct sd *sd = (struct sd *) gspca_dev; | ||
490 | |||
491 | if (sd->sensor == SENSOR_PAS106) { | ||
492 | /* i2c_r(gspca_dev, PAS106_REG9); * blue */ | ||
493 | i2c_r(gspca_dev, PAS106_REG9 + 3); /* red */ | ||
494 | sd->colors = gspca_dev->usb_buf[0] & 0x0f; | ||
495 | } | ||
496 | } | ||
497 | |||
498 | static void Et_init1(struct gspca_dev *gspca_dev) | ||
499 | { | ||
500 | __u8 value; | ||
501 | /* __u8 I2c0 [] = {0x0a, 0x12, 0x05, 0x22, 0xac, 0x00, 0x01, 0x00}; */ | ||
502 | __u8 I2c0[] = { 0x0a, 0x12, 0x05, 0x6d, 0xcd, 0x00, 0x01, 0x00 }; | ||
503 | /* try 1/120 0x6d 0xcd 0x40 */ | ||
504 | /* __u8 I2c0 [] = {0x0a, 0x12, 0x05, 0xfe, 0xfe, 0xc0, 0x01, 0x00}; | ||
505 | * 1/60000 hmm ?? */ | ||
506 | |||
507 | PDEBUG(D_STREAM, "Open Init1 ET"); | ||
508 | reg_w_val(gspca_dev, ET_GPIO_DIR_CTRL, 7); | ||
509 | reg_r(gspca_dev, ET_GPIO_IN, 1); | ||
510 | reg_w_val(gspca_dev, ET_RESET_ALL, 1); | ||
511 | reg_w_val(gspca_dev, ET_RESET_ALL, 0); | ||
512 | reg_w_val(gspca_dev, ET_ClCK, 0x10); | ||
513 | reg_w_val(gspca_dev, ET_CTRL, 0x19); | ||
514 | /* compression et subsampling */ | ||
515 | if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) | ||
516 | value = ET_COMP_VAL1; | ||
517 | else | ||
518 | value = ET_COMP_VAL0; | ||
519 | PDEBUG(D_STREAM, "Open mode %d Compression %d", | ||
520 | gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv, | ||
521 | value); | ||
522 | reg_w_val(gspca_dev, ET_COMP, value); | ||
523 | reg_w_val(gspca_dev, ET_MAXQt, 0x1d); | ||
524 | reg_w_val(gspca_dev, ET_MINQt, 0x02); | ||
525 | /* undocumented registers */ | ||
526 | reg_w_val(gspca_dev, ET_REG1d, 0xff); | ||
527 | reg_w_val(gspca_dev, ET_REG1e, 0xff); | ||
528 | reg_w_val(gspca_dev, ET_REG1f, 0xff); | ||
529 | reg_w_val(gspca_dev, ET_REG20, 0x35); | ||
530 | reg_w_val(gspca_dev, ET_REG21, 0x01); | ||
531 | reg_w_val(gspca_dev, ET_REG22, 0x00); | ||
532 | reg_w_val(gspca_dev, ET_REG23, 0xf7); | ||
533 | reg_w_val(gspca_dev, ET_REG24, 0xff); | ||
534 | reg_w_val(gspca_dev, ET_REG25, 0x07); | ||
535 | /* colors setting */ | ||
536 | reg_w_val(gspca_dev, ET_G_RED, 0x80); | ||
537 | reg_w_val(gspca_dev, ET_G_GREEN1, 0x80); | ||
538 | reg_w_val(gspca_dev, ET_G_BLUE, 0x80); | ||
539 | reg_w_val(gspca_dev, ET_G_GREEN2, 0x80); | ||
540 | reg_w_val(gspca_dev, ET_G_GR_H, 0x00); | ||
541 | reg_w_val(gspca_dev, ET_G_GB_H, 0x00); | ||
542 | /* Window control registers */ | ||
543 | reg_w_val(gspca_dev, ET_SYNCHRO, 0xf0); | ||
544 | reg_w_val(gspca_dev, ET_STARTX, 0x56); /* 0x56 */ | ||
545 | reg_w_val(gspca_dev, ET_STARTY, 0x05); /* 0x04 */ | ||
546 | reg_w_val(gspca_dev, ET_WIDTH_LOW, 0x60); | ||
547 | reg_w_val(gspca_dev, ET_HEIGTH_LOW, 0x20); | ||
548 | reg_w_val(gspca_dev, ET_W_H_HEIGTH, 0x50); | ||
549 | reg_w_val(gspca_dev, ET_REG6e, 0x86); | ||
550 | reg_w_val(gspca_dev, ET_REG6f, 0x01); | ||
551 | reg_w_val(gspca_dev, ET_REG70, 0x86); | ||
552 | reg_w_val(gspca_dev, ET_REG71, 0x14); | ||
553 | reg_w_val(gspca_dev, ET_REG72, 0x00); | ||
554 | /* Clock Pattern registers */ | ||
555 | reg_w_val(gspca_dev, ET_REG73, 0x00); | ||
556 | reg_w_val(gspca_dev, ET_REG74, 0x00); | ||
557 | reg_w_val(gspca_dev, ET_REG75, 0x0a); | ||
558 | reg_w_val(gspca_dev, ET_I2C_CLK, 0x04); | ||
559 | reg_w_val(gspca_dev, ET_PXL_CLK, 0x01); | ||
560 | /* set the sensor */ | ||
561 | if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { | ||
562 | I2c0[0] = 0x06; | ||
563 | i2c_w(gspca_dev, PAS106_REG2, I2c0, sizeof I2c0, 1); | ||
564 | i2c_w(gspca_dev, PAS106_REG9, I2c2, sizeof I2c2, 1); | ||
565 | value = 0x06; | ||
566 | i2c_w(gspca_dev, PAS106_REG2, &value, 1, 1); | ||
567 | i2c_w(gspca_dev, PAS106_REG3, I2c3, sizeof I2c3, 1); | ||
568 | /* value = 0x1f; */ | ||
569 | value = 0x04; | ||
570 | i2c_w(gspca_dev, PAS106_REG0e, &value, 1, 1); | ||
571 | } else { | ||
572 | I2c0[0] = 0x0a; | ||
573 | |||
574 | i2c_w(gspca_dev, PAS106_REG2, I2c0, sizeof I2c0, 1); | ||
575 | i2c_w(gspca_dev, PAS106_REG9, I2c2, sizeof I2c2, 1); | ||
576 | value = 0x0a; | ||
577 | i2c_w(gspca_dev, PAS106_REG2, &value, 1, 1); | ||
578 | i2c_w(gspca_dev, PAS106_REG3, I2c3, sizeof I2c3, 1); | ||
579 | value = 0x04; | ||
580 | /* value = 0x10; */ | ||
581 | i2c_w(gspca_dev, PAS106_REG0e, &value, 1, 1); | ||
582 | /* bit 2 enable bit 1:2 select 0 1 2 3 | ||
583 | value = 0x07; * curve 0 * | ||
584 | i2c_w(gspca_dev, PAS106_REG0f, &value, 1, 1); | ||
585 | */ | ||
586 | } | ||
587 | |||
588 | /* value = 0x01; */ | ||
589 | /* value = 0x22; */ | ||
590 | /* i2c_w(gspca_dev, PAS106_REG5, &value, 1, 1); */ | ||
591 | /* magnetude and sign bit for DAC */ | ||
592 | i2c_w(gspca_dev, PAS106_REG7, I2c4, sizeof I2c4, 1); | ||
593 | /* now set by fifo the whole colors setting */ | ||
594 | reg_w(gspca_dev, ET_G_RED, GainRGBG, 6); | ||
595 | getcolors(gspca_dev); | ||
596 | setcolors(gspca_dev); | ||
597 | } | ||
598 | |||
599 | /* this function is called at probe time */ | ||
600 | static int sd_config(struct gspca_dev *gspca_dev, | ||
601 | const struct usb_device_id *id) | ||
602 | { | ||
603 | struct sd *sd = (struct sd *) gspca_dev; | ||
604 | struct cam *cam; | ||
605 | __u16 vendor; | ||
606 | __u16 product; | ||
607 | |||
608 | vendor = id->idVendor; | ||
609 | product = id->idProduct; | ||
610 | /* switch (vendor) { */ | ||
611 | /* case 0x102c: * Etoms */ | ||
612 | switch (product) { | ||
613 | case 0x6151: | ||
614 | sd->sensor = SENSOR_PAS106; /* Etoms61x151 */ | ||
615 | break; | ||
616 | case 0x6251: | ||
617 | sd->sensor = SENSOR_TAS5130CXX; /* Etoms61x251 */ | ||
618 | break; | ||
619 | /* } */ | ||
620 | /* break; */ | ||
621 | } | ||
622 | cam = &gspca_dev->cam; | ||
623 | cam->dev_name = (char *) id->driver_info; | ||
624 | cam->epaddr = 1; | ||
625 | if (sd->sensor == SENSOR_PAS106) { | ||
626 | cam->cam_mode = sif_mode; | ||
627 | cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; | ||
628 | } else { | ||
629 | cam->cam_mode = vga_mode; | ||
630 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | ||
631 | } | ||
632 | sd->brightness = BRIGHTNESS_DEF; | ||
633 | sd->contrast = CONTRAST_DEF; | ||
634 | sd->colors = COLOR_DEF; | ||
635 | sd->autogain = AUTOGAIN_DEF; | ||
636 | return 0; | ||
637 | } | ||
638 | |||
639 | /* this function is called at open time */ | ||
640 | static int sd_open(struct gspca_dev *gspca_dev) | ||
641 | { | ||
642 | struct sd *sd = (struct sd *) gspca_dev; | ||
643 | |||
644 | if (sd->sensor == SENSOR_PAS106) | ||
645 | Et_init1(gspca_dev); | ||
646 | else | ||
647 | Et_init2(gspca_dev); | ||
648 | reg_w_val(gspca_dev, ET_RESET_ALL, 0x08); | ||
649 | et_video(gspca_dev, 0); /* video off */ | ||
650 | return 0; | ||
651 | } | ||
652 | |||
653 | /* -- start the camera -- */ | ||
654 | static void sd_start(struct gspca_dev *gspca_dev) | ||
655 | { | ||
656 | struct sd *sd = (struct sd *) gspca_dev; | ||
657 | |||
658 | if (sd->sensor == SENSOR_PAS106) | ||
659 | Et_init1(gspca_dev); | ||
660 | else | ||
661 | Et_init2(gspca_dev); | ||
662 | |||
663 | reg_w_val(gspca_dev, ET_RESET_ALL, 0x08); | ||
664 | et_video(gspca_dev, 1); /* video on */ | ||
665 | } | ||
666 | |||
667 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
668 | { | ||
669 | et_video(gspca_dev, 0); /* video off */ | ||
670 | } | ||
671 | |||
672 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
673 | { | ||
674 | } | ||
675 | |||
676 | static void sd_close(struct gspca_dev *gspca_dev) | ||
677 | { | ||
678 | } | ||
679 | |||
680 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
681 | { | ||
682 | struct sd *sd = (struct sd *) gspca_dev; | ||
683 | int i; | ||
684 | __u8 brightness = sd->brightness; | ||
685 | |||
686 | for (i = 0; i < 4; i++) | ||
687 | reg_w_val(gspca_dev, ET_O_RED + i, brightness); | ||
688 | } | ||
689 | |||
690 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
691 | { | ||
692 | struct sd *sd = (struct sd *) gspca_dev; | ||
693 | int i; | ||
694 | int brightness = 0; | ||
695 | |||
696 | for (i = 0; i < 4; i++) { | ||
697 | reg_r(gspca_dev, ET_O_RED + i, 1); | ||
698 | brightness += gspca_dev->usb_buf[0]; | ||
699 | } | ||
700 | sd->brightness = brightness >> 3; | ||
701 | } | ||
702 | |||
703 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
704 | { | ||
705 | struct sd *sd = (struct sd *) gspca_dev; | ||
706 | __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; | ||
707 | __u8 contrast = sd->contrast; | ||
708 | |||
709 | memset(RGBG, contrast, sizeof(RGBG) - 2); | ||
710 | reg_w(gspca_dev, ET_G_RED, RGBG, 6); | ||
711 | } | ||
712 | |||
713 | static void getcontrast(struct gspca_dev *gspca_dev) | ||
714 | { | ||
715 | struct sd *sd = (struct sd *) gspca_dev; | ||
716 | int i; | ||
717 | int contrast = 0; | ||
718 | |||
719 | for (i = 0; i < 4; i++) { | ||
720 | reg_r(gspca_dev, ET_G_RED + i, 1); | ||
721 | contrast += gspca_dev->usb_buf[0]; | ||
722 | } | ||
723 | sd->contrast = contrast >> 2; | ||
724 | } | ||
725 | |||
726 | static __u8 Et_getgainG(struct gspca_dev *gspca_dev) | ||
727 | { | ||
728 | struct sd *sd = (struct sd *) gspca_dev; | ||
729 | |||
730 | if (sd->sensor == SENSOR_PAS106) { | ||
731 | i2c_r(gspca_dev, PAS106_REG0e); | ||
732 | PDEBUG(D_CONF, "Etoms gain G %d", gspca_dev->usb_buf[0]); | ||
733 | return gspca_dev->usb_buf[0]; | ||
734 | } | ||
735 | return 0x1f; | ||
736 | } | ||
737 | |||
738 | static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain) | ||
739 | { | ||
740 | struct sd *sd = (struct sd *) gspca_dev; | ||
741 | |||
742 | if (sd->sensor == SENSOR_PAS106) { | ||
743 | __u8 i2cflags = 0x01; | ||
744 | |||
745 | i2c_w(gspca_dev, PAS106_REG13, &i2cflags, 1, 3); | ||
746 | i2c_w(gspca_dev, PAS106_REG0e, &gain, 1, 1); | ||
747 | } | ||
748 | } | ||
749 | |||
750 | #define BLIMIT(bright) \ | ||
751 | (__u8)((bright > 0x1f)?0x1f:((bright < 4)?3:bright)) | ||
752 | #define LIMIT(color) \ | ||
753 | (unsigned char)((color > 0xff)?0xff:((color < 0)?0:color)) | ||
754 | |||
755 | static void setautogain(struct gspca_dev *gspca_dev) | ||
756 | { | ||
757 | __u8 luma = 0; | ||
758 | __u8 luma_mean = 128; | ||
759 | __u8 luma_delta = 20; | ||
760 | __u8 spring = 4; | ||
761 | int Gbright = 0; | ||
762 | __u8 r, g, b; | ||
763 | |||
764 | Gbright = Et_getgainG(gspca_dev); | ||
765 | reg_r(gspca_dev, ET_LUMA_CENTER, 4); | ||
766 | g = (gspca_dev->usb_buf[0] + gspca_dev->usb_buf[3]) >> 1; | ||
767 | r = gspca_dev->usb_buf[1]; | ||
768 | b = gspca_dev->usb_buf[2]; | ||
769 | r = ((r << 8) - (r << 4) - (r << 3)) >> 10; | ||
770 | b = ((b << 7) >> 10); | ||
771 | g = ((g << 9) + (g << 7) + (g << 5)) >> 10; | ||
772 | luma = LIMIT(r + g + b); | ||
773 | PDEBUG(D_FRAM, "Etoms luma G %d", luma); | ||
774 | if (luma < luma_mean - luma_delta || luma > luma_mean + luma_delta) { | ||
775 | Gbright += (luma_mean - luma) >> spring; | ||
776 | Gbright = BLIMIT(Gbright); | ||
777 | PDEBUG(D_FRAM, "Etoms Gbright %d", Gbright); | ||
778 | Et_setgainG(gspca_dev, (__u8) Gbright); | ||
779 | } | ||
780 | } | ||
781 | |||
782 | #undef BLIMIT | ||
783 | #undef LIMIT | ||
784 | |||
785 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
786 | struct gspca_frame *frame, /* target */ | ||
787 | __u8 *data, /* isoc packet */ | ||
788 | int len) /* iso packet length */ | ||
789 | { | ||
790 | struct sd *sd; | ||
791 | int seqframe; | ||
792 | |||
793 | seqframe = data[0] & 0x3f; | ||
794 | len = (int) (((data[0] & 0xc0) << 2) | data[1]); | ||
795 | if (seqframe == 0x3f) { | ||
796 | PDEBUG(D_FRAM, | ||
797 | "header packet found datalength %d !!", len); | ||
798 | PDEBUG(D_FRAM, "G %d R %d G %d B %d", | ||
799 | data[2], data[3], data[4], data[5]); | ||
800 | data += 30; | ||
801 | /* don't change datalength as the chips provided it */ | ||
802 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | ||
803 | data, 0); | ||
804 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); | ||
805 | sd = (struct sd *) gspca_dev; | ||
806 | if (sd->ag_cnt >= 0) { | ||
807 | if (--sd->ag_cnt < 0) { | ||
808 | sd->ag_cnt = AG_CNT_START; | ||
809 | setautogain(gspca_dev); | ||
810 | } | ||
811 | } | ||
812 | return; | ||
813 | } | ||
814 | if (len) { | ||
815 | data += 8; | ||
816 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
817 | } else { /* Drop Packet */ | ||
818 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
819 | } | ||
820 | } | ||
821 | |||
822 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
823 | { | ||
824 | struct sd *sd = (struct sd *) gspca_dev; | ||
825 | |||
826 | sd->brightness = val; | ||
827 | if (gspca_dev->streaming) | ||
828 | setbrightness(gspca_dev); | ||
829 | return 0; | ||
830 | } | ||
831 | |||
832 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
833 | { | ||
834 | struct sd *sd = (struct sd *) gspca_dev; | ||
835 | |||
836 | getbrightness(gspca_dev); | ||
837 | *val = sd->brightness; | ||
838 | return 0; | ||
839 | } | ||
840 | |||
841 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
842 | { | ||
843 | struct sd *sd = (struct sd *) gspca_dev; | ||
844 | |||
845 | sd->contrast = val; | ||
846 | if (gspca_dev->streaming) | ||
847 | setcontrast(gspca_dev); | ||
848 | return 0; | ||
849 | } | ||
850 | |||
851 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
852 | { | ||
853 | struct sd *sd = (struct sd *) gspca_dev; | ||
854 | |||
855 | getcontrast(gspca_dev); | ||
856 | *val = sd->contrast; | ||
857 | return 0; | ||
858 | } | ||
859 | |||
860 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
861 | { | ||
862 | struct sd *sd = (struct sd *) gspca_dev; | ||
863 | |||
864 | sd->colors = val; | ||
865 | if (gspca_dev->streaming) | ||
866 | setcolors(gspca_dev); | ||
867 | return 0; | ||
868 | } | ||
869 | |||
870 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
871 | { | ||
872 | struct sd *sd = (struct sd *) gspca_dev; | ||
873 | |||
874 | getcolors(gspca_dev); | ||
875 | *val = sd->colors; | ||
876 | return 0; | ||
877 | } | ||
878 | |||
879 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
880 | { | ||
881 | struct sd *sd = (struct sd *) gspca_dev; | ||
882 | |||
883 | sd->autogain = val; | ||
884 | if (val) | ||
885 | sd->ag_cnt = AG_CNT_START; | ||
886 | else | ||
887 | sd->ag_cnt = -1; | ||
888 | return 0; | ||
889 | } | ||
890 | |||
891 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | ||
892 | { | ||
893 | struct sd *sd = (struct sd *) gspca_dev; | ||
894 | |||
895 | *val = sd->autogain; | ||
896 | return 0; | ||
897 | } | ||
898 | |||
899 | /* sub-driver description */ | ||
900 | static struct sd_desc sd_desc = { | ||
901 | .name = MODULE_NAME, | ||
902 | .ctrls = sd_ctrls, | ||
903 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
904 | .config = sd_config, | ||
905 | .open = sd_open, | ||
906 | .start = sd_start, | ||
907 | .stopN = sd_stopN, | ||
908 | .stop0 = sd_stop0, | ||
909 | .close = sd_close, | ||
910 | .pkt_scan = sd_pkt_scan, | ||
911 | }; | ||
912 | |||
913 | /* -- module initialisation -- */ | ||
914 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
915 | static __devinitdata struct usb_device_id device_table[] = { | ||
916 | #ifndef CONFIG_USB_ET61X251 | ||
917 | {USB_DEVICE(0x102c, 0x6151), DVNM("Qcam Sangha CIF")}, | ||
918 | #endif | ||
919 | {USB_DEVICE(0x102c, 0x6251), DVNM("Qcam xxxxxx VGA")}, | ||
920 | {} | ||
921 | }; | ||
922 | |||
923 | MODULE_DEVICE_TABLE(usb, device_table); | ||
924 | |||
925 | /* -- device connect -- */ | ||
926 | static int sd_probe(struct usb_interface *intf, | ||
927 | const struct usb_device_id *id) | ||
928 | { | ||
929 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
930 | THIS_MODULE); | ||
931 | } | ||
932 | |||
933 | static struct usb_driver sd_driver = { | ||
934 | .name = MODULE_NAME, | ||
935 | .id_table = device_table, | ||
936 | .probe = sd_probe, | ||
937 | .disconnect = gspca_disconnect, | ||
938 | }; | ||
939 | |||
940 | /* -- module insert / remove -- */ | ||
941 | static int __init sd_mod_init(void) | ||
942 | { | ||
943 | if (usb_register(&sd_driver) < 0) | ||
944 | return -1; | ||
945 | PDEBUG(D_PROBE, "v%s registered", version); | ||
946 | return 0; | ||
947 | } | ||
948 | |||
949 | static void __exit sd_mod_exit(void) | ||
950 | { | ||
951 | usb_deregister(&sd_driver); | ||
952 | PDEBUG(D_PROBE, "deregistered"); | ||
953 | } | ||
954 | |||
955 | module_init(sd_mod_init); | ||
956 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c new file mode 100644 index 000000000000..16e367cec760 --- /dev/null +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -0,0 +1,1905 @@ | |||
1 | /* | ||
2 | * Main USB camera driver | ||
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 it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
14 | * 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 Foundation, | ||
18 | * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #define MODULE_NAME "gspca" | ||
22 | |||
23 | #include <linux/init.h> | ||
24 | #include <linux/fs.h> | ||
25 | #include <linux/vmalloc.h> | ||
26 | #include <linux/sched.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/mm.h> | ||
29 | #include <linux/string.h> | ||
30 | #include <linux/pagemap.h> | ||
31 | #include <linux/io.h> | ||
32 | #include <asm/page.h> | ||
33 | #include <linux/uaccess.h> | ||
34 | #include <linux/jiffies.h> | ||
35 | |||
36 | #include "gspca.h" | ||
37 | |||
38 | /* global values */ | ||
39 | #define DEF_NURBS 2 /* default number of URBs */ | ||
40 | |||
41 | MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); | ||
42 | MODULE_DESCRIPTION("GSPCA USB Camera Driver"); | ||
43 | MODULE_LICENSE("GPL"); | ||
44 | |||
45 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) | ||
46 | static const char version[] = "2.1.7"; | ||
47 | |||
48 | static int video_nr = -1; | ||
49 | |||
50 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
51 | int gspca_debug = D_ERR | D_PROBE; | ||
52 | EXPORT_SYMBOL(gspca_debug); | ||
53 | |||
54 | static void PDEBUG_MODE(char *txt, __u32 pixfmt, int w, int h) | ||
55 | { | ||
56 | if ((pixfmt >> 24) >= '0' && (pixfmt >> 24) <= 'z') { | ||
57 | PDEBUG(D_CONF|D_STREAM, "%s %c%c%c%c %dx%d", | ||
58 | txt, | ||
59 | pixfmt & 0xff, | ||
60 | (pixfmt >> 8) & 0xff, | ||
61 | (pixfmt >> 16) & 0xff, | ||
62 | pixfmt >> 24, | ||
63 | w, h); | ||
64 | } else { | ||
65 | PDEBUG(D_CONF|D_STREAM, "%s 0x%08x %dx%d", | ||
66 | txt, | ||
67 | pixfmt, | ||
68 | w, h); | ||
69 | } | ||
70 | } | ||
71 | #else | ||
72 | #define PDEBUG_MODE(txt, pixfmt, w, h) | ||
73 | #endif | ||
74 | |||
75 | /* specific memory types - !! should different from V4L2_MEMORY_xxx */ | ||
76 | #define GSPCA_MEMORY_NO 0 /* V4L2_MEMORY_xxx starts from 1 */ | ||
77 | #define GSPCA_MEMORY_READ 7 | ||
78 | |||
79 | #define BUF_ALL_FLAGS (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE) | ||
80 | |||
81 | /* | ||
82 | * VMA operations. | ||
83 | */ | ||
84 | static void gspca_vm_open(struct vm_area_struct *vma) | ||
85 | { | ||
86 | struct gspca_frame *frame = vma->vm_private_data; | ||
87 | |||
88 | frame->vma_use_count++; | ||
89 | frame->v4l2_buf.flags |= V4L2_BUF_FLAG_MAPPED; | ||
90 | } | ||
91 | |||
92 | static void gspca_vm_close(struct vm_area_struct *vma) | ||
93 | { | ||
94 | struct gspca_frame *frame = vma->vm_private_data; | ||
95 | |||
96 | if (--frame->vma_use_count <= 0) | ||
97 | frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_MAPPED; | ||
98 | } | ||
99 | |||
100 | static struct vm_operations_struct gspca_vm_ops = { | ||
101 | .open = gspca_vm_open, | ||
102 | .close = gspca_vm_close, | ||
103 | }; | ||
104 | |||
105 | /* | ||
106 | * fill a video frame from an URB and resubmit | ||
107 | */ | ||
108 | static void fill_frame(struct gspca_dev *gspca_dev, | ||
109 | struct urb *urb) | ||
110 | { | ||
111 | struct gspca_frame *frame; | ||
112 | __u8 *data; /* address of data in the iso message */ | ||
113 | int i, j, len, st; | ||
114 | cam_pkt_op pkt_scan; | ||
115 | |||
116 | if (urb->status != 0) { | ||
117 | PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); | ||
118 | return; /* disconnection ? */ | ||
119 | } | ||
120 | pkt_scan = gspca_dev->sd_desc->pkt_scan; | ||
121 | for (i = 0; i < urb->number_of_packets; i++) { | ||
122 | |||
123 | /* check the availability of the frame buffer */ | ||
124 | j = gspca_dev->fr_i; | ||
125 | j = gspca_dev->fr_queue[j]; | ||
126 | frame = &gspca_dev->frame[j]; | ||
127 | if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS) | ||
128 | != V4L2_BUF_FLAG_QUEUED) { | ||
129 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
130 | break; | ||
131 | } | ||
132 | |||
133 | /* check the packet status and length */ | ||
134 | len = urb->iso_frame_desc[i].actual_length; | ||
135 | if (len == 0) | ||
136 | continue; | ||
137 | st = urb->iso_frame_desc[i].status; | ||
138 | if (st) { | ||
139 | PDEBUG(D_ERR, | ||
140 | "ISOC data error: [%d] len=%d, status=%d", | ||
141 | i, len, st); | ||
142 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
143 | continue; | ||
144 | } | ||
145 | |||
146 | /* let the packet be analyzed by the subdriver */ | ||
147 | PDEBUG(D_PACK, "packet [%d] o:%d l:%d", | ||
148 | i, urb->iso_frame_desc[i].offset, len); | ||
149 | data = (__u8 *) urb->transfer_buffer | ||
150 | + urb->iso_frame_desc[i].offset; | ||
151 | pkt_scan(gspca_dev, frame, data, len); | ||
152 | } | ||
153 | |||
154 | /* resubmit the URB */ | ||
155 | urb->status = 0; | ||
156 | st = usb_submit_urb(urb, GFP_ATOMIC); | ||
157 | if (st < 0) | ||
158 | PDEBUG(D_ERR|D_PACK, "usb_submit_urb() ret %d", st); | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * ISOC message interrupt from the USB device | ||
163 | * | ||
164 | * Analyse each packet and call the subdriver for copy to the frame buffer. | ||
165 | */ | ||
166 | static void isoc_irq(struct urb *urb | ||
167 | ) | ||
168 | { | ||
169 | struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; | ||
170 | |||
171 | PDEBUG(D_PACK, "isoc irq"); | ||
172 | if (!gspca_dev->streaming) | ||
173 | return; | ||
174 | fill_frame(gspca_dev, urb); | ||
175 | } | ||
176 | |||
177 | /* | ||
178 | * add data to the current frame | ||
179 | * | ||
180 | * This function is called by the subdrivers at interrupt level. | ||
181 | * | ||
182 | * To build a frame, these ones must add | ||
183 | * - one FIRST_PACKET | ||
184 | * - 0 or many INTER_PACKETs | ||
185 | * - one LAST_PACKET | ||
186 | * DISCARD_PACKET invalidates the whole frame. | ||
187 | * On LAST_PACKET, a new frame is returned. | ||
188 | */ | ||
189 | struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, | ||
190 | int packet_type, | ||
191 | struct gspca_frame *frame, | ||
192 | const __u8 *data, | ||
193 | int len) | ||
194 | { | ||
195 | int i, j; | ||
196 | |||
197 | PDEBUG(D_PACK, "add t:%d l:%d", packet_type, len); | ||
198 | |||
199 | /* when start of a new frame, if the current frame buffer | ||
200 | * is not queued, discard the whole frame */ | ||
201 | if (packet_type == FIRST_PACKET) { | ||
202 | if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS) | ||
203 | != V4L2_BUF_FLAG_QUEUED) { | ||
204 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
205 | return frame; | ||
206 | } | ||
207 | frame->data_end = frame->data; | ||
208 | jiffies_to_timeval(get_jiffies_64(), | ||
209 | &frame->v4l2_buf.timestamp); | ||
210 | frame->v4l2_buf.sequence = ++gspca_dev->sequence; | ||
211 | } else if (gspca_dev->last_packet_type == DISCARD_PACKET) { | ||
212 | return frame; | ||
213 | } | ||
214 | |||
215 | /* append the packet to the frame buffer */ | ||
216 | if (len > 0) { | ||
217 | if (frame->data_end - frame->data + len | ||
218 | > frame->v4l2_buf.length) { | ||
219 | PDEBUG(D_ERR|D_PACK, "frame overflow %zd > %d", | ||
220 | frame->data_end - frame->data + len, | ||
221 | frame->v4l2_buf.length); | ||
222 | packet_type = DISCARD_PACKET; | ||
223 | } else { | ||
224 | memcpy(frame->data_end, data, len); | ||
225 | frame->data_end += len; | ||
226 | } | ||
227 | } | ||
228 | gspca_dev->last_packet_type = packet_type; | ||
229 | |||
230 | /* if last packet, wake the application and advance in the queue */ | ||
231 | if (packet_type == LAST_PACKET) { | ||
232 | frame->v4l2_buf.bytesused = frame->data_end - frame->data; | ||
233 | frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED; | ||
234 | frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE; | ||
235 | atomic_inc(&gspca_dev->nevent); | ||
236 | wake_up_interruptible(&gspca_dev->wq); /* event = new frame */ | ||
237 | i = (gspca_dev->fr_i + 1) % gspca_dev->nframes; | ||
238 | gspca_dev->fr_i = i; | ||
239 | PDEBUG(D_FRAM, "frame complete len:%d q:%d i:%d o:%d", | ||
240 | frame->v4l2_buf.bytesused, | ||
241 | gspca_dev->fr_q, | ||
242 | i, | ||
243 | gspca_dev->fr_o); | ||
244 | j = gspca_dev->fr_queue[i]; | ||
245 | frame = &gspca_dev->frame[j]; | ||
246 | } | ||
247 | return frame; | ||
248 | } | ||
249 | EXPORT_SYMBOL(gspca_frame_add); | ||
250 | |||
251 | static int gspca_is_compressed(__u32 format) | ||
252 | { | ||
253 | switch (format) { | ||
254 | case V4L2_PIX_FMT_MJPEG: | ||
255 | case V4L2_PIX_FMT_JPEG: | ||
256 | case V4L2_PIX_FMT_SPCA561: | ||
257 | case V4L2_PIX_FMT_PAC207: | ||
258 | return 1; | ||
259 | } | ||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | static void *rvmalloc(unsigned long size) | ||
264 | { | ||
265 | void *mem; | ||
266 | unsigned long adr; | ||
267 | |||
268 | /* size = PAGE_ALIGN(size); (already done) */ | ||
269 | mem = vmalloc_32(size); | ||
270 | if (mem != NULL) { | ||
271 | adr = (unsigned long) mem; | ||
272 | while ((long) size > 0) { | ||
273 | SetPageReserved(vmalloc_to_page((void *) adr)); | ||
274 | adr += PAGE_SIZE; | ||
275 | size -= PAGE_SIZE; | ||
276 | } | ||
277 | } | ||
278 | return mem; | ||
279 | } | ||
280 | |||
281 | static void rvfree(void *mem, long size) | ||
282 | { | ||
283 | unsigned long adr; | ||
284 | |||
285 | adr = (unsigned long) mem; | ||
286 | while (size > 0) { | ||
287 | ClearPageReserved(vmalloc_to_page((void *) adr)); | ||
288 | adr += PAGE_SIZE; | ||
289 | size -= PAGE_SIZE; | ||
290 | } | ||
291 | vfree(mem); | ||
292 | } | ||
293 | |||
294 | static int frame_alloc(struct gspca_dev *gspca_dev, | ||
295 | unsigned int count) | ||
296 | { | ||
297 | struct gspca_frame *frame; | ||
298 | unsigned int frsz; | ||
299 | int i; | ||
300 | |||
301 | i = gspca_dev->curr_mode; | ||
302 | frsz = gspca_dev->cam.cam_mode[i].sizeimage; | ||
303 | PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz); | ||
304 | frsz = PAGE_ALIGN(frsz); | ||
305 | gspca_dev->frsz = frsz; | ||
306 | if (count > GSPCA_MAX_FRAMES) | ||
307 | count = GSPCA_MAX_FRAMES; | ||
308 | gspca_dev->frbuf = rvmalloc(frsz * count); | ||
309 | if (!gspca_dev->frbuf) { | ||
310 | err("frame alloc failed"); | ||
311 | return -ENOMEM; | ||
312 | } | ||
313 | gspca_dev->nframes = count; | ||
314 | for (i = 0; i < count; i++) { | ||
315 | frame = &gspca_dev->frame[i]; | ||
316 | frame->v4l2_buf.index = i; | ||
317 | frame->v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
318 | frame->v4l2_buf.flags = 0; | ||
319 | frame->v4l2_buf.field = V4L2_FIELD_NONE; | ||
320 | frame->v4l2_buf.length = frsz; | ||
321 | frame->v4l2_buf.memory = gspca_dev->memory; | ||
322 | frame->v4l2_buf.sequence = 0; | ||
323 | frame->data = frame->data_end = | ||
324 | gspca_dev->frbuf + i * frsz; | ||
325 | frame->v4l2_buf.m.offset = i * frsz; | ||
326 | } | ||
327 | gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; | ||
328 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
329 | gspca_dev->sequence = 0; | ||
330 | atomic_set(&gspca_dev->nevent, 0); | ||
331 | return 0; | ||
332 | } | ||
333 | |||
334 | static void frame_free(struct gspca_dev *gspca_dev) | ||
335 | { | ||
336 | int i; | ||
337 | |||
338 | PDEBUG(D_STREAM, "frame free"); | ||
339 | if (gspca_dev->frbuf != NULL) { | ||
340 | rvfree(gspca_dev->frbuf, | ||
341 | gspca_dev->nframes * gspca_dev->frsz); | ||
342 | gspca_dev->frbuf = NULL; | ||
343 | for (i = 0; i < gspca_dev->nframes; i++) | ||
344 | gspca_dev->frame[i].data = NULL; | ||
345 | } | ||
346 | gspca_dev->nframes = 0; | ||
347 | } | ||
348 | |||
349 | static void destroy_urbs(struct gspca_dev *gspca_dev) | ||
350 | { | ||
351 | struct urb *urb; | ||
352 | unsigned int i; | ||
353 | |||
354 | PDEBUG(D_STREAM, "kill transfer"); | ||
355 | for (i = 0; i < MAX_NURBS; ++i) { | ||
356 | urb = gspca_dev->urb[i]; | ||
357 | if (urb == NULL) | ||
358 | break; | ||
359 | |||
360 | gspca_dev->urb[i] = NULL; | ||
361 | usb_kill_urb(urb); | ||
362 | if (urb->transfer_buffer != NULL) | ||
363 | usb_buffer_free(gspca_dev->dev, | ||
364 | urb->transfer_buffer_length, | ||
365 | urb->transfer_buffer, | ||
366 | urb->transfer_dma); | ||
367 | usb_free_urb(urb); | ||
368 | } | ||
369 | } | ||
370 | |||
371 | /* | ||
372 | * search an input isochronous endpoint in an alternate setting | ||
373 | */ | ||
374 | static struct usb_host_endpoint *alt_isoc(struct usb_host_interface *alt, | ||
375 | __u8 epaddr) | ||
376 | { | ||
377 | struct usb_host_endpoint *ep; | ||
378 | int i, attr; | ||
379 | |||
380 | epaddr |= USB_DIR_IN; | ||
381 | for (i = 0; i < alt->desc.bNumEndpoints; i++) { | ||
382 | ep = &alt->endpoint[i]; | ||
383 | if (ep->desc.bEndpointAddress == epaddr) { | ||
384 | attr = ep->desc.bmAttributes | ||
385 | & USB_ENDPOINT_XFERTYPE_MASK; | ||
386 | if (attr == USB_ENDPOINT_XFER_ISOC) | ||
387 | return ep; | ||
388 | break; | ||
389 | } | ||
390 | } | ||
391 | return NULL; | ||
392 | } | ||
393 | |||
394 | /* | ||
395 | * search an input isochronous endpoint | ||
396 | * | ||
397 | * The endpoint is defined by the subdriver. | ||
398 | * Use only the first isoc (some Zoran - 0x0572:0x0001 - have two such ep). | ||
399 | * This routine may be called many times when the bandwidth is too small | ||
400 | * (the bandwidth is checked on urb submit). | ||
401 | */ | ||
402 | struct usb_host_endpoint *get_isoc_ep(struct gspca_dev *gspca_dev) | ||
403 | { | ||
404 | struct usb_interface *intf; | ||
405 | struct usb_host_endpoint *ep; | ||
406 | int i, ret; | ||
407 | |||
408 | intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); | ||
409 | ep = NULL; | ||
410 | i = gspca_dev->alt; /* previous alt setting */ | ||
411 | while (--i > 0) { /* alt 0 is unusable */ | ||
412 | ep = alt_isoc(&intf->altsetting[i], gspca_dev->cam.epaddr); | ||
413 | if (ep) | ||
414 | break; | ||
415 | } | ||
416 | if (ep == NULL) { | ||
417 | err("no ISOC endpoint found"); | ||
418 | return NULL; | ||
419 | } | ||
420 | PDEBUG(D_STREAM, "use ISOC alt %d ep 0x%02x", | ||
421 | i, ep->desc.bEndpointAddress); | ||
422 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); | ||
423 | if (ret < 0) { | ||
424 | err("set interface err %d", ret); | ||
425 | return NULL; | ||
426 | } | ||
427 | gspca_dev->alt = i; /* memorize the current alt setting */ | ||
428 | return ep; | ||
429 | } | ||
430 | |||
431 | /* | ||
432 | * create the isochronous URBs | ||
433 | */ | ||
434 | static int create_urbs(struct gspca_dev *gspca_dev, | ||
435 | struct usb_host_endpoint *ep) | ||
436 | { | ||
437 | struct urb *urb; | ||
438 | int n, nurbs, i, psize, npkt, bsize; | ||
439 | |||
440 | /* calculate the packet size and the number of packets */ | ||
441 | psize = le16_to_cpu(ep->desc.wMaxPacketSize); | ||
442 | |||
443 | /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ | ||
444 | psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); | ||
445 | npkt = ISO_MAX_SIZE / psize; | ||
446 | if (npkt > ISO_MAX_PKT) | ||
447 | npkt = ISO_MAX_PKT; | ||
448 | bsize = psize * npkt; | ||
449 | PDEBUG(D_STREAM, | ||
450 | "isoc %d pkts size %d (bsize:%d)", npkt, psize, bsize); | ||
451 | nurbs = DEF_NURBS; | ||
452 | gspca_dev->nurbs = nurbs; | ||
453 | for (n = 0; n < nurbs; n++) { | ||
454 | urb = usb_alloc_urb(npkt, GFP_KERNEL); | ||
455 | if (!urb) { | ||
456 | err("usb_alloc_urb failed"); | ||
457 | return -ENOMEM; | ||
458 | } | ||
459 | urb->transfer_buffer = usb_buffer_alloc(gspca_dev->dev, | ||
460 | bsize, | ||
461 | GFP_KERNEL, | ||
462 | &urb->transfer_dma); | ||
463 | |||
464 | if (urb->transfer_buffer == NULL) { | ||
465 | usb_free_urb(urb); | ||
466 | destroy_urbs(gspca_dev); | ||
467 | err("usb_buffer_urb failed"); | ||
468 | return -ENOMEM; | ||
469 | } | ||
470 | gspca_dev->urb[n] = urb; | ||
471 | urb->dev = gspca_dev->dev; | ||
472 | urb->context = gspca_dev; | ||
473 | urb->pipe = usb_rcvisocpipe(gspca_dev->dev, | ||
474 | ep->desc.bEndpointAddress); | ||
475 | urb->transfer_flags = URB_ISO_ASAP | ||
476 | | URB_NO_TRANSFER_DMA_MAP; | ||
477 | urb->interval = ep->desc.bInterval; | ||
478 | urb->complete = isoc_irq; | ||
479 | urb->number_of_packets = npkt; | ||
480 | urb->transfer_buffer_length = bsize; | ||
481 | for (i = 0; i < npkt; i++) { | ||
482 | urb->iso_frame_desc[i].length = psize; | ||
483 | urb->iso_frame_desc[i].offset = psize * i; | ||
484 | } | ||
485 | } | ||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | /* | ||
490 | * start the USB transfer | ||
491 | */ | ||
492 | static int gspca_init_transfer(struct gspca_dev *gspca_dev) | ||
493 | { | ||
494 | struct usb_host_endpoint *ep; | ||
495 | int n, ret; | ||
496 | |||
497 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | ||
498 | return -ERESTARTSYS; | ||
499 | |||
500 | /* set the higher alternate setting and | ||
501 | * loop until urb submit succeeds */ | ||
502 | gspca_dev->alt = gspca_dev->nbalt; | ||
503 | for (;;) { | ||
504 | PDEBUG(D_STREAM, "init transfer alt %d", gspca_dev->alt); | ||
505 | ep = get_isoc_ep(gspca_dev); | ||
506 | if (ep == NULL) { | ||
507 | ret = -EIO; | ||
508 | goto out; | ||
509 | } | ||
510 | ret = create_urbs(gspca_dev, ep); | ||
511 | if (ret < 0) | ||
512 | goto out; | ||
513 | |||
514 | /* start the cam */ | ||
515 | gspca_dev->sd_desc->start(gspca_dev); | ||
516 | gspca_dev->streaming = 1; | ||
517 | atomic_set(&gspca_dev->nevent, 0); | ||
518 | |||
519 | /* submit the URBs */ | ||
520 | for (n = 0; n < gspca_dev->nurbs; n++) { | ||
521 | ret = usb_submit_urb(gspca_dev->urb[n], GFP_KERNEL); | ||
522 | if (ret < 0) { | ||
523 | PDEBUG(D_ERR|D_STREAM, | ||
524 | "usb_submit_urb [%d] err %d", n, ret); | ||
525 | gspca_dev->streaming = 0; | ||
526 | destroy_urbs(gspca_dev); | ||
527 | if (ret == -ENOSPC) | ||
528 | break; /* try the previous alt */ | ||
529 | goto out; | ||
530 | } | ||
531 | } | ||
532 | if (ret >= 0) | ||
533 | break; | ||
534 | } | ||
535 | out: | ||
536 | mutex_unlock(&gspca_dev->usb_lock); | ||
537 | return ret; | ||
538 | } | ||
539 | |||
540 | static int gspca_set_alt0(struct gspca_dev *gspca_dev) | ||
541 | { | ||
542 | int ret; | ||
543 | |||
544 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0); | ||
545 | if (ret < 0) | ||
546 | PDEBUG(D_ERR|D_STREAM, "set interface 0 err %d", ret); | ||
547 | return ret; | ||
548 | } | ||
549 | |||
550 | /* Note both the queue and the usb lock should be hold when calling this */ | ||
551 | static void gspca_stream_off(struct gspca_dev *gspca_dev) | ||
552 | { | ||
553 | gspca_dev->streaming = 0; | ||
554 | atomic_set(&gspca_dev->nevent, 0); | ||
555 | if (gspca_dev->present) { | ||
556 | gspca_dev->sd_desc->stopN(gspca_dev); | ||
557 | destroy_urbs(gspca_dev); | ||
558 | gspca_set_alt0(gspca_dev); | ||
559 | gspca_dev->sd_desc->stop0(gspca_dev); | ||
560 | PDEBUG(D_STREAM, "stream off OK"); | ||
561 | } | ||
562 | } | ||
563 | |||
564 | static void gspca_set_default_mode(struct gspca_dev *gspca_dev) | ||
565 | { | ||
566 | int i; | ||
567 | |||
568 | i = gspca_dev->cam.nmodes - 1; /* take the highest mode */ | ||
569 | gspca_dev->curr_mode = i; | ||
570 | gspca_dev->width = gspca_dev->cam.cam_mode[i].width; | ||
571 | gspca_dev->height = gspca_dev->cam.cam_mode[i].height; | ||
572 | gspca_dev->pixfmt = gspca_dev->cam.cam_mode[i].pixelformat; | ||
573 | } | ||
574 | |||
575 | static int wxh_to_mode(struct gspca_dev *gspca_dev, | ||
576 | int width, int height) | ||
577 | { | ||
578 | int i; | ||
579 | |||
580 | for (i = gspca_dev->cam.nmodes; --i > 0; ) { | ||
581 | if (width >= gspca_dev->cam.cam_mode[i].width | ||
582 | && height >= gspca_dev->cam.cam_mode[i].height) | ||
583 | break; | ||
584 | } | ||
585 | return i; | ||
586 | } | ||
587 | |||
588 | /* | ||
589 | * search a mode with the right pixel format | ||
590 | */ | ||
591 | static int gspca_get_mode(struct gspca_dev *gspca_dev, | ||
592 | int mode, | ||
593 | int pixfmt) | ||
594 | { | ||
595 | int modeU, modeD; | ||
596 | |||
597 | modeU = modeD = mode; | ||
598 | while ((modeU < gspca_dev->cam.nmodes) || modeD >= 0) { | ||
599 | if (--modeD >= 0) { | ||
600 | if (gspca_dev->cam.cam_mode[modeD].pixelformat | ||
601 | == pixfmt) | ||
602 | return modeD; | ||
603 | } | ||
604 | if (++modeU < gspca_dev->cam.nmodes) { | ||
605 | if (gspca_dev->cam.cam_mode[modeU].pixelformat | ||
606 | == pixfmt) | ||
607 | return modeU; | ||
608 | } | ||
609 | } | ||
610 | return -EINVAL; | ||
611 | } | ||
612 | |||
613 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | ||
614 | struct v4l2_fmtdesc *fmtdesc) | ||
615 | { | ||
616 | struct gspca_dev *gspca_dev = priv; | ||
617 | int i, j, index; | ||
618 | __u32 fmt_tb[8]; | ||
619 | |||
620 | /* give an index to each format */ | ||
621 | index = 0; | ||
622 | j = 0; | ||
623 | for (i = gspca_dev->cam.nmodes; --i >= 0; ) { | ||
624 | fmt_tb[index] = gspca_dev->cam.cam_mode[i].pixelformat; | ||
625 | j = 0; | ||
626 | for (;;) { | ||
627 | if (fmt_tb[j] == fmt_tb[index]) | ||
628 | break; | ||
629 | j++; | ||
630 | } | ||
631 | if (j == index) { | ||
632 | if (fmtdesc->index == index) | ||
633 | break; /* new format */ | ||
634 | index++; | ||
635 | if (index >= sizeof fmt_tb / sizeof fmt_tb[0]) | ||
636 | return -EINVAL; | ||
637 | } | ||
638 | } | ||
639 | if (i < 0) | ||
640 | return -EINVAL; /* no more format */ | ||
641 | |||
642 | fmtdesc->pixelformat = fmt_tb[index]; | ||
643 | if (gspca_is_compressed(fmt_tb[index])) | ||
644 | fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED; | ||
645 | fmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
646 | fmtdesc->description[0] = fmtdesc->pixelformat & 0xff; | ||
647 | fmtdesc->description[1] = (fmtdesc->pixelformat >> 8) & 0xff; | ||
648 | fmtdesc->description[2] = (fmtdesc->pixelformat >> 16) & 0xff; | ||
649 | fmtdesc->description[3] = fmtdesc->pixelformat >> 24; | ||
650 | fmtdesc->description[4] = '\0'; | ||
651 | return 0; | ||
652 | } | ||
653 | |||
654 | static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | ||
655 | struct v4l2_format *fmt) | ||
656 | { | ||
657 | struct gspca_dev *gspca_dev = priv; | ||
658 | int mode; | ||
659 | |||
660 | if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
661 | return -EINVAL; | ||
662 | mode = gspca_dev->curr_mode; | ||
663 | memcpy(&fmt->fmt.pix, &gspca_dev->cam.cam_mode[mode], | ||
664 | sizeof fmt->fmt.pix); | ||
665 | return 0; | ||
666 | } | ||
667 | |||
668 | static int try_fmt_vid_cap(struct gspca_dev *gspca_dev, | ||
669 | struct v4l2_format *fmt) | ||
670 | { | ||
671 | int w, h, mode, mode2; | ||
672 | |||
673 | if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
674 | return -EINVAL; | ||
675 | w = fmt->fmt.pix.width; | ||
676 | h = fmt->fmt.pix.height; | ||
677 | |||
678 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
679 | if (gspca_debug & D_CONF) | ||
680 | PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h); | ||
681 | #endif | ||
682 | /* search the closest mode for width and height */ | ||
683 | mode = wxh_to_mode(gspca_dev, w, h); | ||
684 | |||
685 | /* OK if right palette */ | ||
686 | if (gspca_dev->cam.cam_mode[mode].pixelformat | ||
687 | != fmt->fmt.pix.pixelformat) { | ||
688 | |||
689 | /* else, search the closest mode with the same pixel format */ | ||
690 | mode2 = gspca_get_mode(gspca_dev, mode, | ||
691 | fmt->fmt.pix.pixelformat); | ||
692 | if (mode2 >= 0) | ||
693 | mode = mode2; | ||
694 | /* else | ||
695 | ; * no chance, return this mode */ | ||
696 | } | ||
697 | memcpy(&fmt->fmt.pix, &gspca_dev->cam.cam_mode[mode], | ||
698 | sizeof fmt->fmt.pix); | ||
699 | return mode; /* used when s_fmt */ | ||
700 | } | ||
701 | |||
702 | static int vidioc_try_fmt_vid_cap(struct file *file, | ||
703 | void *priv, | ||
704 | struct v4l2_format *fmt) | ||
705 | { | ||
706 | struct gspca_dev *gspca_dev = priv; | ||
707 | int ret; | ||
708 | |||
709 | ret = try_fmt_vid_cap(gspca_dev, fmt); | ||
710 | if (ret < 0) | ||
711 | return ret; | ||
712 | return 0; | ||
713 | } | ||
714 | |||
715 | static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | ||
716 | struct v4l2_format *fmt) | ||
717 | { | ||
718 | struct gspca_dev *gspca_dev = priv; | ||
719 | int ret; | ||
720 | |||
721 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) | ||
722 | return -ERESTARTSYS; | ||
723 | |||
724 | ret = try_fmt_vid_cap(gspca_dev, fmt); | ||
725 | if (ret < 0) | ||
726 | goto out; | ||
727 | |||
728 | if (gspca_dev->nframes != 0 | ||
729 | && fmt->fmt.pix.sizeimage > gspca_dev->frsz) { | ||
730 | ret = -EINVAL; | ||
731 | goto out; | ||
732 | } | ||
733 | |||
734 | if (ret == gspca_dev->curr_mode) { | ||
735 | ret = 0; | ||
736 | goto out; /* same mode */ | ||
737 | } | ||
738 | |||
739 | if (gspca_dev->streaming) { | ||
740 | ret = -EBUSY; | ||
741 | goto out; | ||
742 | } | ||
743 | gspca_dev->width = fmt->fmt.pix.width; | ||
744 | gspca_dev->height = fmt->fmt.pix.height; | ||
745 | gspca_dev->pixfmt = fmt->fmt.pix.pixelformat; | ||
746 | gspca_dev->curr_mode = ret; | ||
747 | |||
748 | ret = 0; | ||
749 | out: | ||
750 | mutex_unlock(&gspca_dev->queue_lock); | ||
751 | return ret; | ||
752 | } | ||
753 | |||
754 | static int dev_open(struct inode *inode, struct file *file) | ||
755 | { | ||
756 | struct gspca_dev *gspca_dev; | ||
757 | int ret; | ||
758 | |||
759 | PDEBUG(D_STREAM, "%s open", current->comm); | ||
760 | gspca_dev = (struct gspca_dev *) video_devdata(file); | ||
761 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) | ||
762 | return -ERESTARTSYS; | ||
763 | if (!gspca_dev->present) { | ||
764 | ret = -ENODEV; | ||
765 | goto out; | ||
766 | } | ||
767 | |||
768 | /* if not done yet, initialize the sensor */ | ||
769 | if (gspca_dev->users == 0) { | ||
770 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) { | ||
771 | ret = -ERESTARTSYS; | ||
772 | goto out; | ||
773 | } | ||
774 | ret = gspca_dev->sd_desc->open(gspca_dev); | ||
775 | mutex_unlock(&gspca_dev->usb_lock); | ||
776 | if (ret != 0) { | ||
777 | PDEBUG(D_ERR|D_CONF, "init device failed %d", ret); | ||
778 | goto out; | ||
779 | } | ||
780 | } else if (gspca_dev->users > 4) { /* (arbitrary value) */ | ||
781 | ret = -EBUSY; | ||
782 | goto out; | ||
783 | } | ||
784 | gspca_dev->users++; | ||
785 | file->private_data = gspca_dev; | ||
786 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
787 | /* activate the v4l2 debug */ | ||
788 | if (gspca_debug & D_V4L2) | ||
789 | gspca_dev->vdev.debug |= 3; | ||
790 | else | ||
791 | gspca_dev->vdev.debug &= ~3; | ||
792 | #endif | ||
793 | out: | ||
794 | mutex_unlock(&gspca_dev->queue_lock); | ||
795 | if (ret != 0) | ||
796 | PDEBUG(D_ERR|D_STREAM, "open failed err %d", ret); | ||
797 | else | ||
798 | PDEBUG(D_STREAM, "open done"); | ||
799 | return ret; | ||
800 | } | ||
801 | |||
802 | static int dev_close(struct inode *inode, struct file *file) | ||
803 | { | ||
804 | struct gspca_dev *gspca_dev = file->private_data; | ||
805 | |||
806 | PDEBUG(D_STREAM, "%s close", current->comm); | ||
807 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) | ||
808 | return -ERESTARTSYS; | ||
809 | gspca_dev->users--; | ||
810 | |||
811 | /* if the file did the capture, free the streaming resources */ | ||
812 | if (gspca_dev->capt_file == file) { | ||
813 | mutex_lock(&gspca_dev->usb_lock); | ||
814 | if (gspca_dev->streaming) | ||
815 | gspca_stream_off(gspca_dev); | ||
816 | gspca_dev->sd_desc->close(gspca_dev); | ||
817 | mutex_unlock(&gspca_dev->usb_lock); | ||
818 | frame_free(gspca_dev); | ||
819 | gspca_dev->capt_file = NULL; | ||
820 | gspca_dev->memory = GSPCA_MEMORY_NO; | ||
821 | } | ||
822 | file->private_data = NULL; | ||
823 | mutex_unlock(&gspca_dev->queue_lock); | ||
824 | PDEBUG(D_STREAM, "close done"); | ||
825 | return 0; | ||
826 | } | ||
827 | |||
828 | static int vidioc_querycap(struct file *file, void *priv, | ||
829 | struct v4l2_capability *cap) | ||
830 | { | ||
831 | struct gspca_dev *gspca_dev = priv; | ||
832 | |||
833 | memset(cap, 0, sizeof *cap); | ||
834 | strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver); | ||
835 | strncpy(cap->card, gspca_dev->cam.dev_name, sizeof cap->card); | ||
836 | strncpy(cap->bus_info, gspca_dev->dev->bus->bus_name, | ||
837 | sizeof cap->bus_info); | ||
838 | cap->version = DRIVER_VERSION_NUMBER; | ||
839 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | ||
840 | | V4L2_CAP_STREAMING | ||
841 | | V4L2_CAP_READWRITE; | ||
842 | return 0; | ||
843 | } | ||
844 | |||
845 | /* the use of V4L2_CTRL_FLAG_NEXT_CTRL asks for the controls to be sorted */ | ||
846 | static int vidioc_queryctrl(struct file *file, void *priv, | ||
847 | struct v4l2_queryctrl *q_ctrl) | ||
848 | { | ||
849 | struct gspca_dev *gspca_dev = priv; | ||
850 | int i; | ||
851 | u32 id; | ||
852 | |||
853 | id = q_ctrl->id; | ||
854 | if (id & V4L2_CTRL_FLAG_NEXT_CTRL) { | ||
855 | id &= V4L2_CTRL_ID_MASK; | ||
856 | id++; | ||
857 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { | ||
858 | if (id >= gspca_dev->sd_desc->ctrls[i].qctrl.id) { | ||
859 | memcpy(q_ctrl, | ||
860 | &gspca_dev->sd_desc->ctrls[i].qctrl, | ||
861 | sizeof *q_ctrl); | ||
862 | return 0; | ||
863 | } | ||
864 | } | ||
865 | return -EINVAL; | ||
866 | } | ||
867 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { | ||
868 | if (id == gspca_dev->sd_desc->ctrls[i].qctrl.id) { | ||
869 | memcpy(q_ctrl, | ||
870 | &gspca_dev->sd_desc->ctrls[i].qctrl, | ||
871 | sizeof *q_ctrl); | ||
872 | return 0; | ||
873 | } | ||
874 | } | ||
875 | if (id >= V4L2_CID_BASE | ||
876 | && id <= V4L2_CID_LASTP1) { | ||
877 | q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED; | ||
878 | return 0; | ||
879 | } | ||
880 | return -EINVAL; | ||
881 | } | ||
882 | |||
883 | static int vidioc_s_ctrl(struct file *file, void *priv, | ||
884 | struct v4l2_control *ctrl) | ||
885 | { | ||
886 | struct gspca_dev *gspca_dev = priv; | ||
887 | const struct ctrl *ctrls; | ||
888 | int i, ret; | ||
889 | |||
890 | for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; | ||
891 | i < gspca_dev->sd_desc->nctrls; | ||
892 | i++, ctrls++) { | ||
893 | if (ctrl->id != ctrls->qctrl.id) | ||
894 | continue; | ||
895 | if (ctrl->value < ctrls->qctrl.minimum | ||
896 | && ctrl->value > ctrls->qctrl.maximum) | ||
897 | return -ERANGE; | ||
898 | PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); | ||
899 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | ||
900 | return -ERESTARTSYS; | ||
901 | ret = ctrls->set(gspca_dev, ctrl->value); | ||
902 | mutex_unlock(&gspca_dev->usb_lock); | ||
903 | return ret; | ||
904 | } | ||
905 | return -EINVAL; | ||
906 | } | ||
907 | |||
908 | static int vidioc_g_ctrl(struct file *file, void *priv, | ||
909 | struct v4l2_control *ctrl) | ||
910 | { | ||
911 | struct gspca_dev *gspca_dev = priv; | ||
912 | |||
913 | const struct ctrl *ctrls; | ||
914 | int i, ret; | ||
915 | |||
916 | for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; | ||
917 | i < gspca_dev->sd_desc->nctrls; | ||
918 | i++, ctrls++) { | ||
919 | if (ctrl->id != ctrls->qctrl.id) | ||
920 | continue; | ||
921 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | ||
922 | return -ERESTARTSYS; | ||
923 | ret = ctrls->get(gspca_dev, &ctrl->value); | ||
924 | mutex_unlock(&gspca_dev->usb_lock); | ||
925 | return ret; | ||
926 | } | ||
927 | return -EINVAL; | ||
928 | } | ||
929 | |||
930 | static int vidioc_querymenu(struct file *file, void *priv, | ||
931 | struct v4l2_querymenu *qmenu) | ||
932 | { | ||
933 | struct gspca_dev *gspca_dev = priv; | ||
934 | |||
935 | if (!gspca_dev->sd_desc->querymenu) | ||
936 | return -EINVAL; | ||
937 | return gspca_dev->sd_desc->querymenu(gspca_dev, qmenu); | ||
938 | } | ||
939 | |||
940 | static int vidioc_enum_input(struct file *file, void *priv, | ||
941 | struct v4l2_input *input) | ||
942 | { | ||
943 | struct gspca_dev *gspca_dev = priv; | ||
944 | |||
945 | if (input->index != 0) | ||
946 | return -EINVAL; | ||
947 | memset(input, 0, sizeof *input); | ||
948 | input->type = V4L2_INPUT_TYPE_CAMERA; | ||
949 | strncpy(input->name, gspca_dev->sd_desc->name, | ||
950 | sizeof input->name); | ||
951 | return 0; | ||
952 | } | ||
953 | |||
954 | static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) | ||
955 | { | ||
956 | *i = 0; | ||
957 | return 0; | ||
958 | } | ||
959 | |||
960 | static int vidioc_s_input(struct file *file, void *priv, unsigned int i) | ||
961 | { | ||
962 | if (i > 0) | ||
963 | return -EINVAL; | ||
964 | return (0); | ||
965 | } | ||
966 | |||
967 | static int vidioc_reqbufs(struct file *file, void *priv, | ||
968 | struct v4l2_requestbuffers *rb) | ||
969 | { | ||
970 | struct gspca_dev *gspca_dev = priv; | ||
971 | int i, ret = 0; | ||
972 | |||
973 | if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
974 | return -EINVAL; | ||
975 | switch (rb->memory) { | ||
976 | case GSPCA_MEMORY_READ: /* (internal call) */ | ||
977 | case V4L2_MEMORY_MMAP: | ||
978 | case V4L2_MEMORY_USERPTR: | ||
979 | break; | ||
980 | default: | ||
981 | return -EINVAL; | ||
982 | } | ||
983 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) | ||
984 | return -ERESTARTSYS; | ||
985 | |||
986 | if (gspca_dev->memory != GSPCA_MEMORY_NO | ||
987 | && gspca_dev->memory != rb->memory) { | ||
988 | ret = -EBUSY; | ||
989 | goto out; | ||
990 | } | ||
991 | |||
992 | /* only one file may do the capture */ | ||
993 | if (gspca_dev->capt_file != NULL | ||
994 | && gspca_dev->capt_file != file) { | ||
995 | ret = -EBUSY; | ||
996 | goto out; | ||
997 | } | ||
998 | |||
999 | /* if allocated, the buffers must not be mapped */ | ||
1000 | for (i = 0; i < gspca_dev->nframes; i++) { | ||
1001 | if (gspca_dev->frame[i].vma_use_count) { | ||
1002 | ret = -EBUSY; | ||
1003 | goto out; | ||
1004 | } | ||
1005 | } | ||
1006 | |||
1007 | /* stop streaming */ | ||
1008 | if (gspca_dev->streaming) { | ||
1009 | mutex_lock(&gspca_dev->usb_lock); | ||
1010 | gspca_stream_off(gspca_dev); | ||
1011 | mutex_unlock(&gspca_dev->usb_lock); | ||
1012 | } | ||
1013 | |||
1014 | /* free the previous allocated buffers, if any */ | ||
1015 | if (gspca_dev->nframes != 0) { | ||
1016 | frame_free(gspca_dev); | ||
1017 | gspca_dev->capt_file = NULL; | ||
1018 | } | ||
1019 | if (rb->count == 0) /* unrequest */ | ||
1020 | goto out; | ||
1021 | gspca_dev->memory = rb->memory; | ||
1022 | ret = frame_alloc(gspca_dev, rb->count); | ||
1023 | if (ret == 0) { | ||
1024 | rb->count = gspca_dev->nframes; | ||
1025 | gspca_dev->capt_file = file; | ||
1026 | } | ||
1027 | out: | ||
1028 | mutex_unlock(&gspca_dev->queue_lock); | ||
1029 | PDEBUG(D_STREAM, "reqbufs st:%d c:%d", ret, rb->count); | ||
1030 | return ret; | ||
1031 | } | ||
1032 | |||
1033 | static int vidioc_querybuf(struct file *file, void *priv, | ||
1034 | struct v4l2_buffer *v4l2_buf) | ||
1035 | { | ||
1036 | struct gspca_dev *gspca_dev = priv; | ||
1037 | struct gspca_frame *frame; | ||
1038 | |||
1039 | if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE | ||
1040 | || v4l2_buf->index < 0 | ||
1041 | || v4l2_buf->index >= gspca_dev->nframes) | ||
1042 | return -EINVAL; | ||
1043 | |||
1044 | frame = &gspca_dev->frame[v4l2_buf->index]; | ||
1045 | memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf); | ||
1046 | return 0; | ||
1047 | } | ||
1048 | |||
1049 | static int vidioc_streamon(struct file *file, void *priv, | ||
1050 | enum v4l2_buf_type buf_type) | ||
1051 | { | ||
1052 | struct gspca_dev *gspca_dev = priv; | ||
1053 | int ret; | ||
1054 | |||
1055 | if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1056 | return -EINVAL; | ||
1057 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) | ||
1058 | return -ERESTARTSYS; | ||
1059 | if (!gspca_dev->present) { | ||
1060 | ret = -ENODEV; | ||
1061 | goto out; | ||
1062 | } | ||
1063 | if (gspca_dev->nframes == 0) { | ||
1064 | ret = -EINVAL; | ||
1065 | goto out; | ||
1066 | } | ||
1067 | if (!gspca_dev->streaming) { | ||
1068 | ret = gspca_init_transfer(gspca_dev); | ||
1069 | if (ret < 0) | ||
1070 | goto out; | ||
1071 | } | ||
1072 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1073 | if (gspca_debug & D_STREAM) { | ||
1074 | PDEBUG_MODE("stream on OK", | ||
1075 | gspca_dev->pixfmt, | ||
1076 | gspca_dev->width, | ||
1077 | gspca_dev->height); | ||
1078 | } | ||
1079 | #endif | ||
1080 | ret = 0; | ||
1081 | out: | ||
1082 | mutex_unlock(&gspca_dev->queue_lock); | ||
1083 | return ret; | ||
1084 | } | ||
1085 | |||
1086 | static int vidioc_streamoff(struct file *file, void *priv, | ||
1087 | enum v4l2_buf_type buf_type) | ||
1088 | { | ||
1089 | struct gspca_dev *gspca_dev = priv; | ||
1090 | int i, ret; | ||
1091 | |||
1092 | if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1093 | return -EINVAL; | ||
1094 | if (!gspca_dev->streaming) | ||
1095 | return 0; | ||
1096 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) | ||
1097 | return -ERESTARTSYS; | ||
1098 | |||
1099 | /* stop streaming */ | ||
1100 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) { | ||
1101 | ret = -ERESTARTSYS; | ||
1102 | goto out; | ||
1103 | } | ||
1104 | gspca_stream_off(gspca_dev); | ||
1105 | mutex_unlock(&gspca_dev->usb_lock); | ||
1106 | |||
1107 | /* empty the application queues */ | ||
1108 | for (i = 0; i < gspca_dev->nframes; i++) | ||
1109 | gspca_dev->frame[i].v4l2_buf.flags &= ~BUF_ALL_FLAGS; | ||
1110 | gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; | ||
1111 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
1112 | gspca_dev->sequence = 0; | ||
1113 | atomic_set(&gspca_dev->nevent, 0); | ||
1114 | ret = 0; | ||
1115 | out: | ||
1116 | mutex_unlock(&gspca_dev->queue_lock); | ||
1117 | return ret; | ||
1118 | } | ||
1119 | |||
1120 | static int vidioc_g_jpegcomp(struct file *file, void *priv, | ||
1121 | struct v4l2_jpegcompression *jpegcomp) | ||
1122 | { | ||
1123 | struct gspca_dev *gspca_dev = priv; | ||
1124 | int ret; | ||
1125 | |||
1126 | if (!gspca_dev->sd_desc->get_jcomp) | ||
1127 | return -EINVAL; | ||
1128 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | ||
1129 | return -ERESTARTSYS; | ||
1130 | ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp); | ||
1131 | mutex_unlock(&gspca_dev->usb_lock); | ||
1132 | return ret; | ||
1133 | } | ||
1134 | |||
1135 | static int vidioc_s_jpegcomp(struct file *file, void *priv, | ||
1136 | struct v4l2_jpegcompression *jpegcomp) | ||
1137 | { | ||
1138 | struct gspca_dev *gspca_dev = priv; | ||
1139 | int ret; | ||
1140 | |||
1141 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) | ||
1142 | return -ERESTARTSYS; | ||
1143 | if (!gspca_dev->sd_desc->set_jcomp) | ||
1144 | return -EINVAL; | ||
1145 | ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp); | ||
1146 | mutex_unlock(&gspca_dev->usb_lock); | ||
1147 | return ret; | ||
1148 | } | ||
1149 | |||
1150 | static int vidioc_g_parm(struct file *filp, void *priv, | ||
1151 | struct v4l2_streamparm *parm) | ||
1152 | { | ||
1153 | struct gspca_dev *gspca_dev = priv; | ||
1154 | |||
1155 | memset(parm, 0, sizeof *parm); | ||
1156 | parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1157 | parm->parm.capture.readbuffers = gspca_dev->nbufread; | ||
1158 | return 0; | ||
1159 | } | ||
1160 | |||
1161 | static int vidioc_s_parm(struct file *filp, void *priv, | ||
1162 | struct v4l2_streamparm *parm) | ||
1163 | { | ||
1164 | struct gspca_dev *gspca_dev = priv; | ||
1165 | int n; | ||
1166 | |||
1167 | n = parm->parm.capture.readbuffers; | ||
1168 | if (n == 0 || n > GSPCA_MAX_FRAMES) | ||
1169 | parm->parm.capture.readbuffers = gspca_dev->nbufread; | ||
1170 | else | ||
1171 | gspca_dev->nbufread = n; | ||
1172 | return 0; | ||
1173 | } | ||
1174 | |||
1175 | static int vidioc_s_std(struct file *filp, void *priv, | ||
1176 | v4l2_std_id *parm) | ||
1177 | { | ||
1178 | return 0; | ||
1179 | } | ||
1180 | |||
1181 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1182 | static int vidiocgmbuf(struct file *file, void *priv, | ||
1183 | struct video_mbuf *mbuf) | ||
1184 | { | ||
1185 | struct gspca_dev *gspca_dev = file->private_data; | ||
1186 | int i; | ||
1187 | |||
1188 | PDEBUG(D_STREAM, "cgmbuf"); | ||
1189 | if (gspca_dev->nframes == 0) { | ||
1190 | int ret; | ||
1191 | |||
1192 | { | ||
1193 | struct v4l2_format fmt; | ||
1194 | |||
1195 | memset(&fmt, 0, sizeof fmt); | ||
1196 | fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1197 | i = gspca_dev->cam.nmodes - 1; /* highest mode */ | ||
1198 | fmt.fmt.pix.width = gspca_dev->cam.cam_mode[i].width; | ||
1199 | fmt.fmt.pix.height = gspca_dev->cam.cam_mode[i].height; | ||
1200 | fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24; | ||
1201 | ret = vidioc_s_fmt_vid_cap(file, priv, &fmt); | ||
1202 | if (ret != 0) | ||
1203 | return ret; | ||
1204 | } | ||
1205 | { | ||
1206 | struct v4l2_requestbuffers rb; | ||
1207 | |||
1208 | memset(&rb, 0, sizeof rb); | ||
1209 | rb.count = 4; | ||
1210 | rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1211 | rb.memory = V4L2_MEMORY_MMAP; | ||
1212 | ret = vidioc_reqbufs(file, priv, &rb); | ||
1213 | if (ret != 0) | ||
1214 | return ret; | ||
1215 | } | ||
1216 | } | ||
1217 | mbuf->frames = gspca_dev->nframes; | ||
1218 | mbuf->size = gspca_dev->frsz * gspca_dev->nframes; | ||
1219 | for (i = 0; i < mbuf->frames; i++) | ||
1220 | mbuf->offsets[i] = gspca_dev->frame[i].v4l2_buf.m.offset; | ||
1221 | return 0; | ||
1222 | } | ||
1223 | #endif | ||
1224 | |||
1225 | static int dev_mmap(struct file *file, struct vm_area_struct *vma) | ||
1226 | { | ||
1227 | struct gspca_dev *gspca_dev = file->private_data; | ||
1228 | struct gspca_frame *frame; | ||
1229 | struct page *page; | ||
1230 | unsigned long addr, start, size; | ||
1231 | int i, ret; | ||
1232 | |||
1233 | start = vma->vm_start; | ||
1234 | size = vma->vm_end - vma->vm_start; | ||
1235 | PDEBUG(D_STREAM, "mmap start:%08x size:%d", (int) start, (int) size); | ||
1236 | |||
1237 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) | ||
1238 | return -ERESTARTSYS; | ||
1239 | if (!gspca_dev->present) { | ||
1240 | ret = -ENODEV; | ||
1241 | goto out; | ||
1242 | } | ||
1243 | if (gspca_dev->capt_file != file) { | ||
1244 | ret = -EINVAL; | ||
1245 | goto out; | ||
1246 | } | ||
1247 | |||
1248 | frame = NULL; | ||
1249 | for (i = 0; i < gspca_dev->nframes; ++i) { | ||
1250 | if (gspca_dev->frame[i].v4l2_buf.memory != V4L2_MEMORY_MMAP) { | ||
1251 | PDEBUG(D_STREAM, "mmap bad memory type"); | ||
1252 | break; | ||
1253 | } | ||
1254 | if ((gspca_dev->frame[i].v4l2_buf.m.offset >> PAGE_SHIFT) | ||
1255 | == vma->vm_pgoff) { | ||
1256 | frame = &gspca_dev->frame[i]; | ||
1257 | break; | ||
1258 | } | ||
1259 | } | ||
1260 | if (frame == NULL) { | ||
1261 | PDEBUG(D_STREAM, "mmap no frame buffer found"); | ||
1262 | ret = -EINVAL; | ||
1263 | goto out; | ||
1264 | } | ||
1265 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1266 | /* v4l1 maps all the buffers */ | ||
1267 | if (i != 0 | ||
1268 | || size != frame->v4l2_buf.length * gspca_dev->nframes) | ||
1269 | #endif | ||
1270 | if (size != frame->v4l2_buf.length) { | ||
1271 | PDEBUG(D_STREAM, "mmap bad size"); | ||
1272 | ret = -EINVAL; | ||
1273 | goto out; | ||
1274 | } | ||
1275 | |||
1276 | /* | ||
1277 | * - VM_IO marks the area as being a mmaped region for I/O to a | ||
1278 | * device. It also prevents the region from being core dumped. | ||
1279 | */ | ||
1280 | vma->vm_flags |= VM_IO; | ||
1281 | |||
1282 | addr = (unsigned long) frame->data; | ||
1283 | while (size > 0) { | ||
1284 | page = vmalloc_to_page((void *) addr); | ||
1285 | ret = vm_insert_page(vma, start, page); | ||
1286 | if (ret < 0) | ||
1287 | goto out; | ||
1288 | start += PAGE_SIZE; | ||
1289 | addr += PAGE_SIZE; | ||
1290 | size -= PAGE_SIZE; | ||
1291 | } | ||
1292 | |||
1293 | vma->vm_ops = &gspca_vm_ops; | ||
1294 | vma->vm_private_data = frame; | ||
1295 | gspca_vm_open(vma); | ||
1296 | ret = 0; | ||
1297 | out: | ||
1298 | mutex_unlock(&gspca_dev->queue_lock); | ||
1299 | return ret; | ||
1300 | } | ||
1301 | |||
1302 | /* | ||
1303 | * wait for a video frame | ||
1304 | * | ||
1305 | * If a frame is ready, its index is returned. | ||
1306 | */ | ||
1307 | static int frame_wait(struct gspca_dev *gspca_dev, | ||
1308 | int nonblock_ing) | ||
1309 | { | ||
1310 | struct gspca_frame *frame; | ||
1311 | int i, j, ret; | ||
1312 | |||
1313 | /* check if a frame is ready */ | ||
1314 | i = gspca_dev->fr_o; | ||
1315 | j = gspca_dev->fr_queue[i]; | ||
1316 | frame = &gspca_dev->frame[j]; | ||
1317 | if (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE) { | ||
1318 | atomic_dec(&gspca_dev->nevent); | ||
1319 | goto ok; | ||
1320 | } | ||
1321 | if (nonblock_ing) /* no frame yet */ | ||
1322 | return -EAGAIN; | ||
1323 | |||
1324 | /* wait till a frame is ready */ | ||
1325 | for (;;) { | ||
1326 | ret = wait_event_interruptible_timeout(gspca_dev->wq, | ||
1327 | atomic_read(&gspca_dev->nevent) > 0, | ||
1328 | msecs_to_jiffies(3000)); | ||
1329 | if (ret <= 0) { | ||
1330 | if (ret < 0) | ||
1331 | return ret; /* interrupt */ | ||
1332 | return -EIO; /* timeout */ | ||
1333 | } | ||
1334 | atomic_dec(&gspca_dev->nevent); | ||
1335 | if (!gspca_dev->streaming || !gspca_dev->present) | ||
1336 | return -EIO; | ||
1337 | i = gspca_dev->fr_o; | ||
1338 | j = gspca_dev->fr_queue[i]; | ||
1339 | frame = &gspca_dev->frame[j]; | ||
1340 | if (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE) | ||
1341 | break; | ||
1342 | } | ||
1343 | ok: | ||
1344 | gspca_dev->fr_o = (i + 1) % gspca_dev->nframes; | ||
1345 | PDEBUG(D_FRAM, "frame wait q:%d i:%d o:%d", | ||
1346 | gspca_dev->fr_q, | ||
1347 | gspca_dev->fr_i, | ||
1348 | gspca_dev->fr_o); | ||
1349 | |||
1350 | if (gspca_dev->sd_desc->dq_callback) { | ||
1351 | mutex_lock(&gspca_dev->usb_lock); | ||
1352 | gspca_dev->sd_desc->dq_callback(gspca_dev); | ||
1353 | mutex_unlock(&gspca_dev->usb_lock); | ||
1354 | } | ||
1355 | return j; | ||
1356 | } | ||
1357 | |||
1358 | /* | ||
1359 | * dequeue a video buffer | ||
1360 | * | ||
1361 | * If nonblock_ing is false, block until a buffer is available. | ||
1362 | */ | ||
1363 | static int vidioc_dqbuf(struct file *file, void *priv, | ||
1364 | struct v4l2_buffer *v4l2_buf) | ||
1365 | { | ||
1366 | struct gspca_dev *gspca_dev = priv; | ||
1367 | struct gspca_frame *frame; | ||
1368 | int i, ret; | ||
1369 | |||
1370 | PDEBUG(D_FRAM, "dqbuf"); | ||
1371 | if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1372 | return -EINVAL; | ||
1373 | if (v4l2_buf->memory != gspca_dev->memory) | ||
1374 | return -EINVAL; | ||
1375 | |||
1376 | /* if not streaming, be sure the application will not loop forever */ | ||
1377 | if (!(file->f_flags & O_NONBLOCK) | ||
1378 | && !gspca_dev->streaming && gspca_dev->users == 1) | ||
1379 | return -EINVAL; | ||
1380 | |||
1381 | /* only the capturing file may dequeue */ | ||
1382 | if (gspca_dev->capt_file != file) | ||
1383 | return -EINVAL; | ||
1384 | |||
1385 | /* only one dequeue / read at a time */ | ||
1386 | if (mutex_lock_interruptible(&gspca_dev->read_lock)) | ||
1387 | return -ERESTARTSYS; | ||
1388 | |||
1389 | ret = frame_wait(gspca_dev, file->f_flags & O_NONBLOCK); | ||
1390 | if (ret < 0) | ||
1391 | goto out; | ||
1392 | i = ret; /* frame index */ | ||
1393 | frame = &gspca_dev->frame[i]; | ||
1394 | if (gspca_dev->memory == V4L2_MEMORY_USERPTR) { | ||
1395 | if (copy_to_user((__u8 *) frame->v4l2_buf.m.userptr, | ||
1396 | frame->data, | ||
1397 | frame->v4l2_buf.bytesused)) { | ||
1398 | PDEBUG(D_ERR|D_STREAM, | ||
1399 | "dqbuf cp to user failed"); | ||
1400 | ret = -EFAULT; | ||
1401 | goto out; | ||
1402 | } | ||
1403 | } | ||
1404 | frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; | ||
1405 | memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf); | ||
1406 | PDEBUG(D_FRAM, "dqbuf %d", i); | ||
1407 | ret = 0; | ||
1408 | out: | ||
1409 | mutex_unlock(&gspca_dev->read_lock); | ||
1410 | return ret; | ||
1411 | } | ||
1412 | |||
1413 | /* | ||
1414 | * queue a video buffer | ||
1415 | * | ||
1416 | * Attempting to queue a buffer that has already been | ||
1417 | * queued will return -EINVAL. | ||
1418 | */ | ||
1419 | static int vidioc_qbuf(struct file *file, void *priv, | ||
1420 | struct v4l2_buffer *v4l2_buf) | ||
1421 | { | ||
1422 | struct gspca_dev *gspca_dev = priv; | ||
1423 | struct gspca_frame *frame; | ||
1424 | int i, index, ret; | ||
1425 | |||
1426 | PDEBUG(D_FRAM, "qbuf %d", v4l2_buf->index); | ||
1427 | if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1428 | return -EINVAL; | ||
1429 | |||
1430 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) | ||
1431 | return -ERESTARTSYS; | ||
1432 | |||
1433 | index = v4l2_buf->index; | ||
1434 | if ((unsigned) index >= gspca_dev->nframes) { | ||
1435 | PDEBUG(D_FRAM, | ||
1436 | "qbuf idx %d >= %d", index, gspca_dev->nframes); | ||
1437 | ret = -EINVAL; | ||
1438 | goto out; | ||
1439 | } | ||
1440 | if (v4l2_buf->memory != gspca_dev->memory) { | ||
1441 | PDEBUG(D_FRAM, "qbuf bad memory type"); | ||
1442 | ret = -EINVAL; | ||
1443 | goto out; | ||
1444 | } | ||
1445 | |||
1446 | frame = &gspca_dev->frame[index]; | ||
1447 | if (frame->v4l2_buf.flags & BUF_ALL_FLAGS) { | ||
1448 | PDEBUG(D_FRAM, "qbuf bad state"); | ||
1449 | ret = -EINVAL; | ||
1450 | goto out; | ||
1451 | } | ||
1452 | |||
1453 | frame->v4l2_buf.flags |= V4L2_BUF_FLAG_QUEUED; | ||
1454 | /* frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; */ | ||
1455 | |||
1456 | if (frame->v4l2_buf.memory == V4L2_MEMORY_USERPTR) { | ||
1457 | frame->v4l2_buf.m.userptr = v4l2_buf->m.userptr; | ||
1458 | frame->v4l2_buf.length = v4l2_buf->length; | ||
1459 | } | ||
1460 | |||
1461 | /* put the buffer in the 'queued' queue */ | ||
1462 | i = gspca_dev->fr_q; | ||
1463 | gspca_dev->fr_queue[i] = index; | ||
1464 | gspca_dev->fr_q = (i + 1) % gspca_dev->nframes; | ||
1465 | PDEBUG(D_FRAM, "qbuf q:%d i:%d o:%d", | ||
1466 | gspca_dev->fr_q, | ||
1467 | gspca_dev->fr_i, | ||
1468 | gspca_dev->fr_o); | ||
1469 | |||
1470 | v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED; | ||
1471 | v4l2_buf->flags &= ~V4L2_BUF_FLAG_DONE; | ||
1472 | ret = 0; | ||
1473 | out: | ||
1474 | mutex_unlock(&gspca_dev->queue_lock); | ||
1475 | return ret; | ||
1476 | } | ||
1477 | |||
1478 | /* | ||
1479 | * allocate the resources for read() | ||
1480 | */ | ||
1481 | static int read_alloc(struct gspca_dev *gspca_dev, | ||
1482 | struct file *file) | ||
1483 | { | ||
1484 | struct v4l2_buffer v4l2_buf; | ||
1485 | int i, ret; | ||
1486 | |||
1487 | PDEBUG(D_STREAM, "read alloc"); | ||
1488 | if (gspca_dev->nframes == 0) { | ||
1489 | struct v4l2_requestbuffers rb; | ||
1490 | |||
1491 | memset(&rb, 0, sizeof rb); | ||
1492 | rb.count = gspca_dev->nbufread; | ||
1493 | rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1494 | rb.memory = GSPCA_MEMORY_READ; | ||
1495 | ret = vidioc_reqbufs(file, gspca_dev, &rb); | ||
1496 | if (ret != 0) { | ||
1497 | PDEBUG(D_STREAM, "read reqbuf err %d", ret); | ||
1498 | return ret; | ||
1499 | } | ||
1500 | memset(&v4l2_buf, 0, sizeof v4l2_buf); | ||
1501 | v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1502 | v4l2_buf.memory = GSPCA_MEMORY_READ; | ||
1503 | for (i = 0; i < gspca_dev->nbufread; i++) { | ||
1504 | v4l2_buf.index = i; | ||
1505 | ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf); | ||
1506 | if (ret != 0) { | ||
1507 | PDEBUG(D_STREAM, "read qbuf err: %d", ret); | ||
1508 | return ret; | ||
1509 | } | ||
1510 | } | ||
1511 | gspca_dev->memory = GSPCA_MEMORY_READ; | ||
1512 | } | ||
1513 | |||
1514 | /* start streaming */ | ||
1515 | ret = vidioc_streamon(file, gspca_dev, V4L2_BUF_TYPE_VIDEO_CAPTURE); | ||
1516 | if (ret != 0) | ||
1517 | PDEBUG(D_STREAM, "read streamon err %d", ret); | ||
1518 | return ret; | ||
1519 | } | ||
1520 | |||
1521 | static unsigned int dev_poll(struct file *file, poll_table *wait) | ||
1522 | { | ||
1523 | struct gspca_dev *gspca_dev = file->private_data; | ||
1524 | int i, ret; | ||
1525 | |||
1526 | PDEBUG(D_FRAM, "poll"); | ||
1527 | |||
1528 | poll_wait(file, &gspca_dev->wq, wait); | ||
1529 | if (!gspca_dev->present) | ||
1530 | return POLLERR; | ||
1531 | |||
1532 | /* if reqbufs is not done, the user would use read() */ | ||
1533 | if (gspca_dev->nframes == 0) { | ||
1534 | if (gspca_dev->memory != GSPCA_MEMORY_NO) | ||
1535 | return POLLERR; /* not the 1st time */ | ||
1536 | ret = read_alloc(gspca_dev, file); | ||
1537 | if (ret != 0) | ||
1538 | return POLLERR; | ||
1539 | } | ||
1540 | |||
1541 | if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0) | ||
1542 | return POLLERR; | ||
1543 | if (!gspca_dev->present) { | ||
1544 | ret = POLLERR; | ||
1545 | goto out; | ||
1546 | } | ||
1547 | |||
1548 | /* check the next incoming buffer */ | ||
1549 | i = gspca_dev->fr_o; | ||
1550 | i = gspca_dev->fr_queue[i]; | ||
1551 | if (gspca_dev->frame[i].v4l2_buf.flags & V4L2_BUF_FLAG_DONE) | ||
1552 | ret = POLLIN | POLLRDNORM; /* something to read */ | ||
1553 | else | ||
1554 | ret = 0; | ||
1555 | out: | ||
1556 | mutex_unlock(&gspca_dev->queue_lock); | ||
1557 | return ret; | ||
1558 | } | ||
1559 | |||
1560 | static ssize_t dev_read(struct file *file, char __user *data, | ||
1561 | size_t count, loff_t *ppos) | ||
1562 | { | ||
1563 | struct gspca_dev *gspca_dev = file->private_data; | ||
1564 | struct gspca_frame *frame; | ||
1565 | struct v4l2_buffer v4l2_buf; | ||
1566 | struct timeval timestamp; | ||
1567 | int n, ret, ret2; | ||
1568 | |||
1569 | PDEBUG(D_FRAM, "read (%zd)", count); | ||
1570 | if (!gspca_dev->present) | ||
1571 | return -ENODEV; | ||
1572 | switch (gspca_dev->memory) { | ||
1573 | case GSPCA_MEMORY_NO: /* first time */ | ||
1574 | ret = read_alloc(gspca_dev, file); | ||
1575 | if (ret != 0) | ||
1576 | return ret; | ||
1577 | break; | ||
1578 | case GSPCA_MEMORY_READ: | ||
1579 | if (gspca_dev->capt_file == file) | ||
1580 | break; | ||
1581 | /* fall thru */ | ||
1582 | default: | ||
1583 | return -EINVAL; | ||
1584 | } | ||
1585 | |||
1586 | /* get a frame */ | ||
1587 | jiffies_to_timeval(get_jiffies_64(), ×tamp); | ||
1588 | timestamp.tv_sec--; | ||
1589 | n = 2; | ||
1590 | for (;;) { | ||
1591 | memset(&v4l2_buf, 0, sizeof v4l2_buf); | ||
1592 | v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1593 | v4l2_buf.memory = GSPCA_MEMORY_READ; | ||
1594 | ret = vidioc_dqbuf(file, gspca_dev, &v4l2_buf); | ||
1595 | if (ret != 0) { | ||
1596 | PDEBUG(D_STREAM, "read dqbuf err %d", ret); | ||
1597 | return ret; | ||
1598 | } | ||
1599 | |||
1600 | /* if the process slept for more than 1 second, | ||
1601 | * get anewer frame */ | ||
1602 | frame = &gspca_dev->frame[v4l2_buf.index]; | ||
1603 | if (--n < 0) | ||
1604 | break; /* avoid infinite loop */ | ||
1605 | if (frame->v4l2_buf.timestamp.tv_sec >= timestamp.tv_sec) | ||
1606 | break; | ||
1607 | ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf); | ||
1608 | if (ret != 0) { | ||
1609 | PDEBUG(D_STREAM, "read qbuf err %d", ret); | ||
1610 | return ret; | ||
1611 | } | ||
1612 | } | ||
1613 | |||
1614 | /* copy the frame */ | ||
1615 | if (count > frame->v4l2_buf.bytesused) | ||
1616 | count = frame->v4l2_buf.bytesused; | ||
1617 | ret = copy_to_user(data, frame->data, count); | ||
1618 | if (ret != 0) { | ||
1619 | PDEBUG(D_ERR|D_STREAM, | ||
1620 | "read cp to user lack %d / %zd", ret, count); | ||
1621 | ret = -EFAULT; | ||
1622 | goto out; | ||
1623 | } | ||
1624 | ret = count; | ||
1625 | out: | ||
1626 | /* in each case, requeue the buffer */ | ||
1627 | ret2 = vidioc_qbuf(file, gspca_dev, &v4l2_buf); | ||
1628 | if (ret2 != 0) | ||
1629 | return ret2; | ||
1630 | return ret; | ||
1631 | } | ||
1632 | |||
1633 | static void dev_release(struct video_device *vfd) | ||
1634 | { | ||
1635 | /* nothing */ | ||
1636 | } | ||
1637 | |||
1638 | static struct file_operations dev_fops = { | ||
1639 | .owner = THIS_MODULE, | ||
1640 | .open = dev_open, | ||
1641 | .release = dev_close, | ||
1642 | .read = dev_read, | ||
1643 | .mmap = dev_mmap, | ||
1644 | .ioctl = video_ioctl2, | ||
1645 | #ifdef CONFIG_COMPAT | ||
1646 | .compat_ioctl = v4l_compat_ioctl32, | ||
1647 | #endif | ||
1648 | .llseek = no_llseek, | ||
1649 | .poll = dev_poll, | ||
1650 | }; | ||
1651 | |||
1652 | static struct video_device gspca_template = { | ||
1653 | .name = "gspca main driver", | ||
1654 | .type = VID_TYPE_CAPTURE, | ||
1655 | .fops = &dev_fops, | ||
1656 | .release = dev_release, /* mandatory */ | ||
1657 | .minor = -1, | ||
1658 | .vidioc_querycap = vidioc_querycap, | ||
1659 | .vidioc_dqbuf = vidioc_dqbuf, | ||
1660 | .vidioc_qbuf = vidioc_qbuf, | ||
1661 | .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, | ||
1662 | .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, | ||
1663 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, | ||
1664 | .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, | ||
1665 | .vidioc_streamon = vidioc_streamon, | ||
1666 | .vidioc_queryctrl = vidioc_queryctrl, | ||
1667 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
1668 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
1669 | .vidioc_querymenu = vidioc_querymenu, | ||
1670 | .vidioc_enum_input = vidioc_enum_input, | ||
1671 | .vidioc_g_input = vidioc_g_input, | ||
1672 | .vidioc_s_input = vidioc_s_input, | ||
1673 | .vidioc_reqbufs = vidioc_reqbufs, | ||
1674 | .vidioc_querybuf = vidioc_querybuf, | ||
1675 | .vidioc_streamoff = vidioc_streamoff, | ||
1676 | .vidioc_g_jpegcomp = vidioc_g_jpegcomp, | ||
1677 | .vidioc_s_jpegcomp = vidioc_s_jpegcomp, | ||
1678 | .vidioc_g_parm = vidioc_g_parm, | ||
1679 | .vidioc_s_parm = vidioc_s_parm, | ||
1680 | .vidioc_s_std = vidioc_s_std, | ||
1681 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1682 | .vidiocgmbuf = vidiocgmbuf, | ||
1683 | #endif | ||
1684 | }; | ||
1685 | |||
1686 | /* | ||
1687 | * probe and create a new gspca device | ||
1688 | * | ||
1689 | * This function must be called by the sub-driver when it is | ||
1690 | * called for probing a new device. | ||
1691 | */ | ||
1692 | int gspca_dev_probe(struct usb_interface *intf, | ||
1693 | const struct usb_device_id *id, | ||
1694 | const struct sd_desc *sd_desc, | ||
1695 | int dev_size, | ||
1696 | struct module *module) | ||
1697 | { | ||
1698 | struct usb_interface_descriptor *interface; | ||
1699 | struct gspca_dev *gspca_dev; | ||
1700 | struct usb_device *dev = interface_to_usbdev(intf); | ||
1701 | int ret; | ||
1702 | |||
1703 | PDEBUG(D_PROBE, "probing %04x:%04x", id->idVendor, id->idProduct); | ||
1704 | |||
1705 | /* we don't handle multi-config cameras */ | ||
1706 | if (dev->descriptor.bNumConfigurations != 1) | ||
1707 | return -ENODEV; | ||
1708 | interface = &intf->cur_altsetting->desc; | ||
1709 | if (interface->bInterfaceNumber > 0) | ||
1710 | return -ENODEV; | ||
1711 | |||
1712 | /* create the device */ | ||
1713 | if (dev_size < sizeof *gspca_dev) | ||
1714 | dev_size = sizeof *gspca_dev; | ||
1715 | gspca_dev = kzalloc(dev_size, GFP_KERNEL); | ||
1716 | if (gspca_dev == NULL) { | ||
1717 | err("couldn't kzalloc gspca struct"); | ||
1718 | return -EIO; | ||
1719 | } | ||
1720 | gspca_dev->dev = dev; | ||
1721 | gspca_dev->iface = interface->bInterfaceNumber; | ||
1722 | gspca_dev->nbalt = intf->num_altsetting; | ||
1723 | gspca_dev->sd_desc = sd_desc; | ||
1724 | /* gspca_dev->users = 0; (done by kzalloc) */ | ||
1725 | gspca_dev->nbufread = 2; | ||
1726 | |||
1727 | /* configure the subdriver */ | ||
1728 | ret = gspca_dev->sd_desc->config(gspca_dev, id); | ||
1729 | if (ret < 0) | ||
1730 | goto out; | ||
1731 | ret = gspca_set_alt0(gspca_dev); | ||
1732 | if (ret < 0) | ||
1733 | goto out; | ||
1734 | gspca_set_default_mode(gspca_dev); | ||
1735 | |||
1736 | mutex_init(&gspca_dev->usb_lock); | ||
1737 | mutex_init(&gspca_dev->read_lock); | ||
1738 | mutex_init(&gspca_dev->queue_lock); | ||
1739 | init_waitqueue_head(&gspca_dev->wq); | ||
1740 | |||
1741 | /* init video stuff */ | ||
1742 | memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template); | ||
1743 | gspca_dev->vdev.dev = &dev->dev; | ||
1744 | memcpy(&gspca_dev->fops, &dev_fops, sizeof gspca_dev->fops); | ||
1745 | gspca_dev->vdev.fops = &gspca_dev->fops; | ||
1746 | gspca_dev->fops.owner = module; /* module protection */ | ||
1747 | ret = video_register_device(&gspca_dev->vdev, | ||
1748 | VFL_TYPE_GRABBER, | ||
1749 | video_nr); | ||
1750 | if (ret < 0) { | ||
1751 | err("video_register_device err %d", ret); | ||
1752 | goto out; | ||
1753 | } | ||
1754 | |||
1755 | gspca_dev->present = 1; | ||
1756 | usb_set_intfdata(intf, gspca_dev); | ||
1757 | PDEBUG(D_PROBE, "probe ok"); | ||
1758 | return 0; | ||
1759 | out: | ||
1760 | kfree(gspca_dev); | ||
1761 | return ret; | ||
1762 | } | ||
1763 | EXPORT_SYMBOL(gspca_dev_probe); | ||
1764 | |||
1765 | /* | ||
1766 | * USB disconnection | ||
1767 | * | ||
1768 | * This function must be called by the sub-driver | ||
1769 | * when the device disconnects, after the specific resources are freed. | ||
1770 | */ | ||
1771 | void gspca_disconnect(struct usb_interface *intf) | ||
1772 | { | ||
1773 | struct gspca_dev *gspca_dev = usb_get_intfdata(intf); | ||
1774 | |||
1775 | if (!gspca_dev) | ||
1776 | return; | ||
1777 | gspca_dev->present = 0; | ||
1778 | mutex_lock(&gspca_dev->queue_lock); | ||
1779 | mutex_lock(&gspca_dev->usb_lock); | ||
1780 | gspca_dev->streaming = 0; | ||
1781 | destroy_urbs(gspca_dev); | ||
1782 | mutex_unlock(&gspca_dev->usb_lock); | ||
1783 | mutex_unlock(&gspca_dev->queue_lock); | ||
1784 | while (gspca_dev->users != 0) { /* wait until fully closed */ | ||
1785 | atomic_inc(&gspca_dev->nevent); | ||
1786 | wake_up_interruptible(&gspca_dev->wq); /* wake processes */ | ||
1787 | schedule(); | ||
1788 | } | ||
1789 | /* We don't want people trying to open up the device */ | ||
1790 | video_unregister_device(&gspca_dev->vdev); | ||
1791 | /* Free the memory */ | ||
1792 | kfree(gspca_dev); | ||
1793 | PDEBUG(D_PROBE, "disconnect complete"); | ||
1794 | } | ||
1795 | EXPORT_SYMBOL(gspca_disconnect); | ||
1796 | |||
1797 | /* -- cam driver utility functions -- */ | ||
1798 | |||
1799 | /* auto gain and exposure algorithm based on the knee algorithm described here: | ||
1800 | http://ytse.tricolour.net/docs/LowLightOptimization.html | ||
1801 | |||
1802 | Returns 0 if no changes were made, 1 if the gain and or exposure settings | ||
1803 | where changed. */ | ||
1804 | int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum, | ||
1805 | int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee) | ||
1806 | { | ||
1807 | int i, steps, gain, orig_gain, exposure, orig_exposure, autogain; | ||
1808 | const struct ctrl *gain_ctrl = NULL; | ||
1809 | const struct ctrl *exposure_ctrl = NULL; | ||
1810 | const struct ctrl *autogain_ctrl = NULL; | ||
1811 | int retval = 0; | ||
1812 | |||
1813 | for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { | ||
1814 | if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_GAIN) | ||
1815 | gain_ctrl = &gspca_dev->sd_desc->ctrls[i]; | ||
1816 | if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_EXPOSURE) | ||
1817 | exposure_ctrl = &gspca_dev->sd_desc->ctrls[i]; | ||
1818 | if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_AUTOGAIN) | ||
1819 | autogain_ctrl = &gspca_dev->sd_desc->ctrls[i]; | ||
1820 | } | ||
1821 | if (!gain_ctrl || !exposure_ctrl || !autogain_ctrl) { | ||
1822 | PDEBUG(D_ERR, "Error: gspca_auto_gain_n_exposure called " | ||
1823 | "on cam without (auto)gain/exposure"); | ||
1824 | return 0; | ||
1825 | } | ||
1826 | |||
1827 | if (gain_ctrl->get(gspca_dev, &gain) || | ||
1828 | exposure_ctrl->get(gspca_dev, &exposure) || | ||
1829 | autogain_ctrl->get(gspca_dev, &autogain) || !autogain) | ||
1830 | return 0; | ||
1831 | |||
1832 | orig_gain = gain; | ||
1833 | orig_exposure = exposure; | ||
1834 | |||
1835 | /* If we are of a multiple of deadzone, do multiple steps to reach the | ||
1836 | desired lumination fast (with the risc of a slight overshoot) */ | ||
1837 | steps = abs(desired_avg_lum - avg_lum) / deadzone; | ||
1838 | |||
1839 | PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d\n", | ||
1840 | avg_lum, desired_avg_lum, steps); | ||
1841 | |||
1842 | for (i = 0; i < steps; i++) { | ||
1843 | if (avg_lum > desired_avg_lum) { | ||
1844 | if (gain > gain_knee) | ||
1845 | gain--; | ||
1846 | else if (exposure > exposure_knee) | ||
1847 | exposure--; | ||
1848 | else if (gain > gain_ctrl->qctrl.default_value) | ||
1849 | gain--; | ||
1850 | else if (exposure > exposure_ctrl->qctrl.minimum) | ||
1851 | exposure--; | ||
1852 | else if (gain > gain_ctrl->qctrl.minimum) | ||
1853 | gain--; | ||
1854 | else | ||
1855 | break; | ||
1856 | } else { | ||
1857 | if (gain < gain_ctrl->qctrl.default_value) | ||
1858 | gain++; | ||
1859 | else if (exposure < exposure_knee) | ||
1860 | exposure++; | ||
1861 | else if (gain < gain_knee) | ||
1862 | gain++; | ||
1863 | else if (exposure < exposure_ctrl->qctrl.maximum) | ||
1864 | exposure++; | ||
1865 | else if (gain < gain_ctrl->qctrl.maximum) | ||
1866 | gain++; | ||
1867 | else | ||
1868 | break; | ||
1869 | } | ||
1870 | } | ||
1871 | |||
1872 | if (gain != orig_gain) { | ||
1873 | gain_ctrl->set(gspca_dev, gain); | ||
1874 | retval = 1; | ||
1875 | } | ||
1876 | if (exposure != orig_exposure) { | ||
1877 | exposure_ctrl->set(gspca_dev, exposure); | ||
1878 | retval = 1; | ||
1879 | } | ||
1880 | |||
1881 | return retval; | ||
1882 | } | ||
1883 | EXPORT_SYMBOL(gspca_auto_gain_n_exposure); | ||
1884 | |||
1885 | /* -- module insert / remove -- */ | ||
1886 | static int __init gspca_init(void) | ||
1887 | { | ||
1888 | info("main v%s registered", version); | ||
1889 | return 0; | ||
1890 | } | ||
1891 | static void __exit gspca_exit(void) | ||
1892 | { | ||
1893 | info("main deregistered"); | ||
1894 | } | ||
1895 | |||
1896 | module_init(gspca_init); | ||
1897 | module_exit(gspca_exit); | ||
1898 | |||
1899 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1900 | module_param_named(debug, gspca_debug, int, 0644); | ||
1901 | MODULE_PARM_DESC(debug, | ||
1902 | "Debug (bit) 0x01:error 0x02:probe 0x04:config" | ||
1903 | " 0x08:stream 0x10:frame 0x20:packet 0x40:USBin 0x80:USBout" | ||
1904 | " 0x0100: v4l2"); | ||
1905 | #endif | ||
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h new file mode 100644 index 000000000000..3fd2c4eee204 --- /dev/null +++ b/drivers/media/video/gspca/gspca.h | |||
@@ -0,0 +1,176 @@ | |||
1 | #ifndef GSPCAV2_H | ||
2 | #define GSPCAV2_H | ||
3 | |||
4 | #include <linux/module.h> | ||
5 | #include <linux/version.h> | ||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/usb.h> | ||
8 | #include <linux/videodev2.h> | ||
9 | #include <media/v4l2-common.h> | ||
10 | #include <linux/mutex.h> | ||
11 | |||
12 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
13 | /* GSPCA our debug messages */ | ||
14 | extern int gspca_debug; | ||
15 | #define PDEBUG(level, fmt, args...) \ | ||
16 | do {\ | ||
17 | if (gspca_debug & (level)) \ | ||
18 | printk(KERN_INFO MODULE_NAME ": " fmt "\n", ## args); \ | ||
19 | } while (0) | ||
20 | #define D_ERR 0x01 | ||
21 | #define D_PROBE 0x02 | ||
22 | #define D_CONF 0x04 | ||
23 | #define D_STREAM 0x08 | ||
24 | #define D_FRAM 0x10 | ||
25 | #define D_PACK 0x20 | ||
26 | #define D_USBI 0x40 | ||
27 | #define D_USBO 0x80 | ||
28 | #define D_V4L2 0x0100 | ||
29 | #else | ||
30 | #define PDEBUG(level, fmt, args...) | ||
31 | #endif | ||
32 | #undef err | ||
33 | #define err(fmt, args...) \ | ||
34 | do {\ | ||
35 | printk(KERN_ERR MODULE_NAME ": " fmt "\n", ## args); \ | ||
36 | } while (0) | ||
37 | #undef info | ||
38 | #define info(fmt, args...) \ | ||
39 | do {\ | ||
40 | printk(KERN_INFO MODULE_NAME ": " fmt "\n", ## args); \ | ||
41 | } while (0) | ||
42 | #undef warn | ||
43 | #define warn(fmt, args...) \ | ||
44 | do {\ | ||
45 | printk(KERN_WARNING MODULE_NAME ": " fmt "\n", ## args); \ | ||
46 | } while (0) | ||
47 | |||
48 | #define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */ | ||
49 | /* ISOC transfers */ | ||
50 | #define MAX_NURBS 16 /* max number of URBs */ | ||
51 | #define ISO_MAX_PKT 32 /* max number of packets in an ISOC transfer */ | ||
52 | #define ISO_MAX_SIZE 0x8000 /* max size of one URB buffer (32 Kb) */ | ||
53 | |||
54 | /* device information - set at probe time */ | ||
55 | struct cam { | ||
56 | char *dev_name; | ||
57 | struct v4l2_pix_format *cam_mode; /* size nmodes */ | ||
58 | char nmodes; | ||
59 | __u8 epaddr; | ||
60 | }; | ||
61 | |||
62 | struct gspca_dev; | ||
63 | struct gspca_frame; | ||
64 | |||
65 | /* subdriver operations */ | ||
66 | typedef int (*cam_op) (struct gspca_dev *); | ||
67 | typedef void (*cam_v_op) (struct gspca_dev *); | ||
68 | typedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *); | ||
69 | typedef int (*cam_jpg_op) (struct gspca_dev *, | ||
70 | struct v4l2_jpegcompression *); | ||
71 | typedef int (*cam_qmnu_op) (struct gspca_dev *, | ||
72 | struct v4l2_querymenu *); | ||
73 | typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev, | ||
74 | struct gspca_frame *frame, | ||
75 | __u8 *data, | ||
76 | int len); | ||
77 | |||
78 | struct ctrl { | ||
79 | struct v4l2_queryctrl qctrl; | ||
80 | int (*set)(struct gspca_dev *, __s32); | ||
81 | int (*get)(struct gspca_dev *, __s32 *); | ||
82 | }; | ||
83 | |||
84 | /* subdriver description */ | ||
85 | struct sd_desc { | ||
86 | /* information */ | ||
87 | const char *name; /* sub-driver name */ | ||
88 | /* controls */ | ||
89 | const struct ctrl *ctrls; | ||
90 | int nctrls; | ||
91 | /* operations */ | ||
92 | cam_cf_op config; /* called on probe */ | ||
93 | cam_op open; /* called on open */ | ||
94 | cam_v_op start; /* called on stream on */ | ||
95 | cam_v_op stopN; /* called on stream off - main alt */ | ||
96 | cam_v_op stop0; /* called on stream off - alt 0 */ | ||
97 | cam_v_op close; /* called on close */ | ||
98 | cam_pkt_op pkt_scan; | ||
99 | /* optional operations */ | ||
100 | cam_v_op dq_callback; /* called when a frame has been dequeued */ | ||
101 | cam_jpg_op get_jcomp; | ||
102 | cam_jpg_op set_jcomp; | ||
103 | cam_qmnu_op querymenu; | ||
104 | }; | ||
105 | |||
106 | /* packet types when moving from iso buf to frame buf */ | ||
107 | #define DISCARD_PACKET 0 | ||
108 | #define FIRST_PACKET 1 | ||
109 | #define INTER_PACKET 2 | ||
110 | #define LAST_PACKET 3 | ||
111 | |||
112 | struct gspca_frame { | ||
113 | __u8 *data; /* frame buffer */ | ||
114 | __u8 *data_end; /* end of frame while filling */ | ||
115 | int vma_use_count; | ||
116 | struct v4l2_buffer v4l2_buf; | ||
117 | }; | ||
118 | |||
119 | struct gspca_dev { | ||
120 | struct video_device vdev; /* !! must be the first item */ | ||
121 | struct file_operations fops; | ||
122 | struct usb_device *dev; | ||
123 | struct file *capt_file; /* file doing video capture */ | ||
124 | |||
125 | struct cam cam; /* device information */ | ||
126 | const struct sd_desc *sd_desc; /* subdriver description */ | ||
127 | |||
128 | __u8 usb_buf[8]; /* buffer for USB exchanges */ | ||
129 | struct urb *urb[MAX_NURBS]; | ||
130 | |||
131 | __u8 *frbuf; /* buffer for nframes */ | ||
132 | struct gspca_frame frame[GSPCA_MAX_FRAMES]; | ||
133 | __u32 frsz; /* frame size */ | ||
134 | char nframes; /* number of frames */ | ||
135 | char fr_i; /* frame being filled */ | ||
136 | char fr_q; /* next frame to queue */ | ||
137 | char fr_o; /* next frame to dequeue */ | ||
138 | signed char fr_queue[GSPCA_MAX_FRAMES]; /* frame queue */ | ||
139 | char last_packet_type; | ||
140 | |||
141 | __u8 iface; /* USB interface number */ | ||
142 | __u8 alt; /* USB alternate setting */ | ||
143 | __u8 curr_mode; /* current camera mode */ | ||
144 | __u32 pixfmt; /* current mode parameters */ | ||
145 | __u16 width; | ||
146 | __u16 height; | ||
147 | |||
148 | atomic_t nevent; /* number of frames done */ | ||
149 | wait_queue_head_t wq; /* wait queue */ | ||
150 | struct mutex usb_lock; /* usb exchange protection */ | ||
151 | struct mutex read_lock; /* read protection */ | ||
152 | struct mutex queue_lock; /* ISOC queue protection */ | ||
153 | __u32 sequence; /* frame sequence number */ | ||
154 | char streaming; | ||
155 | char users; /* number of opens */ | ||
156 | char present; /* device connected */ | ||
157 | char nbufread; /* number of buffers for read() */ | ||
158 | char nurbs; /* number of allocated URBs */ | ||
159 | char memory; /* memory type (V4L2_MEMORY_xxx) */ | ||
160 | __u8 nbalt; /* number of USB alternate settings */ | ||
161 | }; | ||
162 | |||
163 | int gspca_dev_probe(struct usb_interface *intf, | ||
164 | const struct usb_device_id *id, | ||
165 | const struct sd_desc *sd_desc, | ||
166 | int dev_size, | ||
167 | struct module *module); | ||
168 | void gspca_disconnect(struct usb_interface *intf); | ||
169 | struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, | ||
170 | int packet_type, | ||
171 | struct gspca_frame *frame, | ||
172 | const __u8 *data, | ||
173 | int len); | ||
174 | int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum, | ||
175 | int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee); | ||
176 | #endif /* GSPCAV2_H */ | ||
diff --git a/drivers/media/video/gspca/jpeg.h b/drivers/media/video/gspca/jpeg.h new file mode 100644 index 000000000000..d823b47bd4e6 --- /dev/null +++ b/drivers/media/video/gspca/jpeg.h | |||
@@ -0,0 +1,301 @@ | |||
1 | #ifndef JPEG_H | ||
2 | #define JPEG_H 1 | ||
3 | /* | ||
4 | * Insert a JPEG header at start of frame | ||
5 | * | ||
6 | * This module is used by the gspca subdrivers. | ||
7 | * A special case is done for Conexant webcams. | ||
8 | * | ||
9 | * Copyright (C) Jean-Francois Moine (http://moinejf.free.fr) | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | /* start of jpeg frame + quantization table */ | ||
28 | static const unsigned char quant[][0x88] = { | ||
29 | /* index 0 - Q40*/ | ||
30 | { | ||
31 | 0xff, 0xd8, /* jpeg */ | ||
32 | 0xff, 0xdb, 0x00, 0x84, /* DQT */ | ||
33 | 0, /* quantization table part 1 */ | ||
34 | 20, 14, 15, 18, 15, 13, 20, 18, 16, 18, 23, 21, 20, 24, 30, 50, | ||
35 | 33, 30, 28, 28, 30, 61, 44, 46, 36, 50, 73, 64, 76, 75, 71, 64, | ||
36 | 70, 69, 80, 90, 115, 98, 80, 85, 109, 86, 69, 70, 100, 136, 101, | ||
37 | 109, | ||
38 | 119, 123, 129, 130, 129, 78, 96, 141, 151, 140, 125, 150, 115, | ||
39 | 126, 129, 124, | ||
40 | 1, /* quantization table part 2 */ | ||
41 | 21, 23, 23, 30, 26, 30, 59, 33, 33, 59, 124, 83, 70, 83, 124, 124, | ||
42 | 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, | ||
43 | 124, 124, 124, | ||
44 | 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, | ||
45 | 124, 124, 124, | ||
46 | 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, | ||
47 | 124, 124, 124}, | ||
48 | /* index 1 - Q50 */ | ||
49 | { | ||
50 | 0xff, 0xd8, | ||
51 | 0xff, 0xdb, 0x00, 0x84, /* DQT */ | ||
52 | 0, | ||
53 | 16, 11, 12, 14, 12, 10, 16, 14, 13, 14, 18, 17, 16, 19, 24, 40, | ||
54 | 26, 24, 22, 22, 24, 49, 35, 37, 29, 40, 58, 51, 61, 60, 57, 51, | ||
55 | 56, 55, 64, 72, 92, 78, 64, 68, 87, 69, 55, 56, 80, 109, 81, 87, | ||
56 | 95, 98, 103, 104, 103, 62, 77, 113, 121, 112, 100, 120, 92, 101, | ||
57 | 103, 99, | ||
58 | 1, | ||
59 | 17, 18, 18, 24, 21, 24, 47, 26, 26, 47, 99, 66, 56, 66, 99, 99, | ||
60 | 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, | ||
61 | 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, | ||
62 | 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}, | ||
63 | /* index 2 Q60 */ | ||
64 | { | ||
65 | 0xff, 0xd8, | ||
66 | 0xff, 0xdb, 0x00, 0x84, /* DQT */ | ||
67 | 0, | ||
68 | 13, 9, 10, 11, 10, 8, 13, 11, 10, 11, 14, 14, 13, 15, 19, 32, | ||
69 | 21, 19, 18, 18, 19, 39, 28, 30, 23, 32, 46, 41, 49, 48, 46, 41, | ||
70 | 45, 44, 51, 58, 74, 62, 51, 54, 70, 55, 44, 45, 64, 87, 65, 70, | ||
71 | 76, 78, 82, 83, 82, 50, 62, 90, 97, 90, 80, 96, 74, 81, 82, 79, | ||
72 | 1, | ||
73 | 14, 14, 14, 19, 17, 19, 38, 21, 21, 38, 79, 53, 45, 53, 79, 79, | ||
74 | 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, | ||
75 | 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, | ||
76 | 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79}, | ||
77 | /* index 3 - Q70 */ | ||
78 | { | ||
79 | 0xff, 0xd8, | ||
80 | 0xff, 0xdb, 0x00, 0x84, /* DQT */ | ||
81 | 0, | ||
82 | 10, 7, 7, 8, 7, 6, 10, 8, 8, 8, 11, 10, 10, 11, 14, 24, | ||
83 | 16, 14, 13, 13, 14, 29, 21, 22, 17, 24, 35, 31, 37, 36, 34, 31, | ||
84 | 34, 33, 38, 43, 55, 47, 38, 41, 52, 41, 33, 34, 48, 65, 49, 52, | ||
85 | 57, 59, 62, 62, 62, 37, 46, 68, 73, 67, 60, 72, 55, 61, 62, 59, | ||
86 | 1, | ||
87 | 10, 11, 11, 14, 13, 14, 28, 16, 16, 28, 59, 40, 34, 40, 59, 59, | ||
88 | 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, | ||
89 | 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, | ||
90 | 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59}, | ||
91 | /* index 4 - Q80 */ | ||
92 | { | ||
93 | 0xff, 0xd8, | ||
94 | 0xff, 0xdb, 0x00, 0x84, /* DQT */ | ||
95 | 0, | ||
96 | 6, 4, 5, 6, 5, 4, 6, 6, 5, 6, 7, 7, 6, 8, 10, 16, | ||
97 | 10, 10, 9, 9, 10, 20, 14, 15, 12, 16, 23, 20, 24, 24, 23, 20, | ||
98 | 22, 22, 26, 29, 37, 31, 26, 27, 35, 28, 22, 22, 32, 44, 32, 35, | ||
99 | 38, 39, 41, 42, 41, 25, 31, 45, 48, 45, 40, 48, 37, 40, 41, 40, | ||
100 | 1, | ||
101 | 7, 7, 7, 10, 8, 10, 19, 10, 10, 19, 40, 26, 22, 26, 40, 40, | ||
102 | 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, | ||
103 | 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, | ||
104 | 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}, | ||
105 | /* index 5 - Q85 */ | ||
106 | { | ||
107 | 0xff, 0xd8, | ||
108 | 0xff, 0xdb, 0x00, 0x84, /* DQT */ | ||
109 | 0, | ||
110 | 5, 3, 4, 4, 4, 3, 5, 4, 4, 4, 5, 5, 5, 6, 7, 12, | ||
111 | 8, 7, 7, 7, 7, 15, 11, 11, 9, 12, 17, 15, 18, 18, 17, 15, | ||
112 | 17, 17, 19, 22, 28, 23, 19, 20, 26, 21, 17, 17, 24, 33, 24, 26, | ||
113 | 29, 29, 31, 31, 31, 19, 23, 34, 36, 34, 30, 36, 28, 30, 31, 30, | ||
114 | 1, | ||
115 | 5, 5, 5, 7, 6, 7, 14, 8, 8, 14, 30, 20, 17, 20, 30, 30, | ||
116 | 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, | ||
117 | 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, | ||
118 | 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, | ||
119 | /* index 6 - 86 */ | ||
120 | { | ||
121 | 0xff, 0xd8, | ||
122 | 0xff, 0xdb, 0x00, 0x84, /* DQT */ | ||
123 | 0, | ||
124 | 0x04, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x04, | ||
125 | 0x04, 0x04, 0x05, 0x05, 0x04, 0x05, 0x07, 0x0B, | ||
126 | 0x07, 0x07, 0x06, 0x06, 0x07, 0x0E, 0x0A, 0x0A, | ||
127 | 0x08, 0x0B, 0x10, 0x0E, 0x11, 0x11, 0x10, 0x0E, | ||
128 | 0x10, 0x0F, 0x12, 0x14, 0x1A, 0x16, 0x12, 0x13, | ||
129 | 0x18, 0x13, 0x0F, 0x10, 0x16, 0x1F, 0x17, 0x18, | ||
130 | 0x1B, 0x1B, 0x1D, 0x1D, 0x1D, 0x11, 0x16, 0x20, | ||
131 | 0x22, 0x1F, 0x1C, 0x22, 0x1A, 0x1C, 0x1D, 0x1C, | ||
132 | 1, | ||
133 | 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x0D, 0x07, | ||
134 | 0x07, 0x0D, 0x1C, 0x12, 0x10, 0x12, 0x1C, 0x1C, | ||
135 | 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, | ||
136 | 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, | ||
137 | 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, | ||
138 | 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, | ||
139 | 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, | ||
140 | 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, | ||
141 | }, | ||
142 | /* index 7 - 88 */ | ||
143 | { | ||
144 | 0xff, 0xd8, | ||
145 | 0xff, 0xdb, 0x00, 0x84, /* DQT */ | ||
146 | 0, | ||
147 | 0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x04, 0x03, | ||
148 | 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x06, 0x0A, | ||
149 | 0x06, 0x06, 0x05, 0x05, 0x06, 0x0C, 0x08, 0x09, | ||
150 | 0x07, 0x0A, 0x0E, 0x0C, 0x0F, 0x0E, 0x0E, 0x0C, | ||
151 | 0x0D, 0x0D, 0x0F, 0x11, 0x16, 0x13, 0x0F, 0x10, | ||
152 | 0x15, 0x11, 0x0D, 0x0D, 0x13, 0x1A, 0x13, 0x15, | ||
153 | 0x17, 0x18, 0x19, 0x19, 0x19, 0x0F, 0x12, 0x1B, | ||
154 | 0x1D, 0x1B, 0x18, 0x1D, 0x16, 0x18, 0x19, 0x18, | ||
155 | 1, | ||
156 | 0x04, 0x04, 0x04, 0x06, 0x05, 0x06, 0x0B, 0x06, | ||
157 | 0x06, 0x0B, 0x18, 0x10, 0x0D, 0x10, 0x18, 0x18, | ||
158 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
159 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
160 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
161 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
162 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
163 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
164 | }, | ||
165 | /* index 8 - ?? */ | ||
166 | { | ||
167 | 0xff, 0xd8, | ||
168 | 0xff, 0xdb, 0x00, 0x84, /* DQT */ | ||
169 | 0, | ||
170 | 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, | ||
171 | 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x05, | ||
172 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x06, 0x04, 0x05, | ||
173 | 0x04, 0x05, 0x07, 0x06, 0x08, 0x08, 0x07, 0x06, | ||
174 | 0x07, 0x07, 0x08, 0x09, 0x0C, 0x0A, 0x08, 0x09, | ||
175 | 0x0B, 0x09, 0x07, 0x07, 0x0A, 0x0E, 0x0A, 0x0B, | ||
176 | 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x08, 0x0A, 0x0E, | ||
177 | 0x0F, 0x0E, 0x0D, 0x0F, 0x0C, 0x0D, 0x0D, 0x0C, | ||
178 | 1, | ||
179 | 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x06, 0x03, | ||
180 | 0x03, 0x06, 0x0C, 0x08, 0x07, 0x08, 0x0C, 0x0C, | ||
181 | 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, | ||
182 | 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, | ||
183 | 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, | ||
184 | 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, | ||
185 | 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, | ||
186 | 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C | ||
187 | } | ||
188 | }; | ||
189 | |||
190 | /* huffman table + start of SOF0 */ | ||
191 | static unsigned char huffman[] = { | ||
192 | 0xff, 0xc4, 0x01, 0xa2, | ||
193 | 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, | ||
194 | 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
195 | 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, | ||
196 | 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x01, 0x00, 0x03, | ||
197 | 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, | ||
198 | 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | ||
199 | 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, | ||
200 | 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, | ||
201 | 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, | ||
202 | 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04, | ||
203 | 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, | ||
204 | 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, | ||
205 | 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, | ||
206 | 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, | ||
207 | 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, | ||
208 | 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, | ||
209 | 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, | ||
210 | 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, | ||
211 | 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, | ||
212 | 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, | ||
213 | 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, | ||
214 | 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, | ||
215 | 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, | ||
216 | 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, | ||
217 | 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, | ||
218 | 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, | ||
219 | 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, | ||
220 | 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, | ||
221 | 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, | ||
222 | 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0x11, 0x00, 0x02, | ||
223 | 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, | ||
224 | 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, | ||
225 | 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, | ||
226 | 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, | ||
227 | 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, | ||
228 | 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, | ||
229 | 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, | ||
230 | 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, | ||
231 | 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, | ||
232 | 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, | ||
233 | 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, | ||
234 | 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, | ||
235 | 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, | ||
236 | 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, | ||
237 | 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, | ||
238 | 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, | ||
239 | 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, | ||
240 | 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, | ||
241 | 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, | ||
242 | 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, | ||
243 | 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, | ||
244 | 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, | ||
245 | #ifdef CONEX_CAM | ||
246 | /* the Conexant frames start with SOF0 */ | ||
247 | #else | ||
248 | 0xff, 0xc0, 0x00, 0x11, /* SOF0 (start of frame 0 */ | ||
249 | 0x08, /* data precision */ | ||
250 | #endif | ||
251 | }; | ||
252 | |||
253 | #ifndef CONEX_CAM | ||
254 | /* variable part: | ||
255 | * 0x01, 0xe0, height | ||
256 | * 0x02, 0x80, width | ||
257 | * 0x03, component number | ||
258 | * 0x01, | ||
259 | * 0x21, samples Y | ||
260 | */ | ||
261 | |||
262 | /* end of header */ | ||
263 | static unsigned char eoh[] = { | ||
264 | 0x00, /* quant Y */ | ||
265 | 0x02, 0x11, 0x01, /* samples CbCr - quant CbCr */ | ||
266 | 0x03, 0x11, 0x01, | ||
267 | |||
268 | 0xff, 0xda, 0x00, 0x0c, /* SOS (start of scan) */ | ||
269 | 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00 | ||
270 | }; | ||
271 | #endif | ||
272 | |||
273 | /* -- output the JPEG header -- */ | ||
274 | static void jpeg_put_header(struct gspca_dev *gspca_dev, | ||
275 | struct gspca_frame *frame, | ||
276 | int qindex, | ||
277 | int samplesY) | ||
278 | { | ||
279 | #ifndef CONEX_CAM | ||
280 | unsigned char tmpbuf[8]; | ||
281 | #endif | ||
282 | |||
283 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | ||
284 | (unsigned char *) quant[qindex], sizeof quant[0]); | ||
285 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
286 | (unsigned char *) huffman, sizeof huffman); | ||
287 | #ifndef CONEX_CAM | ||
288 | tmpbuf[0] = gspca_dev->height >> 8; | ||
289 | tmpbuf[1] = gspca_dev->height & 0xff; | ||
290 | tmpbuf[2] = gspca_dev->width >> 8; | ||
291 | tmpbuf[3] = gspca_dev->width & 0xff; | ||
292 | tmpbuf[4] = 0x03; /* component number */ | ||
293 | tmpbuf[5] = 0x01; /* first component */ | ||
294 | tmpbuf[6] = samplesY; | ||
295 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
296 | tmpbuf, 7); | ||
297 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
298 | eoh, sizeof eoh); | ||
299 | #endif | ||
300 | } | ||
301 | #endif | ||
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c new file mode 100644 index 000000000000..88c2b02f380a --- /dev/null +++ b/drivers/media/video/gspca/mars.c | |||
@@ -0,0 +1,464 @@ | |||
1 | /* | ||
2 | * Mars-Semi MR97311A library | ||
3 | * Copyright (C) 2005 <bradlch@hotmail.com> | ||
4 | * | ||
5 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #define MODULE_NAME "mars" | ||
23 | |||
24 | #include "gspca.h" | ||
25 | #include "jpeg.h" | ||
26 | |||
27 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) | ||
28 | static const char version[] = "2.1.7"; | ||
29 | |||
30 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
31 | MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver"); | ||
32 | MODULE_LICENSE("GPL"); | ||
33 | |||
34 | /* specific webcam descriptor */ | ||
35 | struct sd { | ||
36 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
37 | |||
38 | char qindex; | ||
39 | }; | ||
40 | |||
41 | /* V4L2 controls supported by the driver */ | ||
42 | static struct ctrl sd_ctrls[] = { | ||
43 | }; | ||
44 | |||
45 | static struct v4l2_pix_format vga_mode[] = { | ||
46 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
47 | .bytesperline = 320, | ||
48 | .sizeimage = 320 * 240 * 3 / 8 + 589, | ||
49 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
50 | .priv = 2}, | ||
51 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
52 | .bytesperline = 640, | ||
53 | .sizeimage = 640 * 480 * 3 / 8 + 590, | ||
54 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
55 | .priv = 1}, | ||
56 | }; | ||
57 | |||
58 | /* MI Register table //elvis */ | ||
59 | enum { | ||
60 | REG_HW_MI_0, | ||
61 | REG_HW_MI_1, | ||
62 | REG_HW_MI_2, | ||
63 | REG_HW_MI_3, | ||
64 | REG_HW_MI_4, | ||
65 | REG_HW_MI_5, | ||
66 | REG_HW_MI_6, | ||
67 | REG_HW_MI_7, | ||
68 | REG_HW_MI_9 = 0x09, | ||
69 | REG_HW_MI_B = 0x0B, | ||
70 | REG_HW_MI_C, | ||
71 | REG_HW_MI_D, | ||
72 | REG_HW_MI_1E = 0x1E, | ||
73 | REG_HW_MI_20 = 0x20, | ||
74 | REG_HW_MI_2B = 0x2B, | ||
75 | REG_HW_MI_2C, | ||
76 | REG_HW_MI_2D, | ||
77 | REG_HW_MI_2E, | ||
78 | REG_HW_MI_35 = 0x35, | ||
79 | REG_HW_MI_5F = 0x5f, | ||
80 | REG_HW_MI_60, | ||
81 | REG_HW_MI_61, | ||
82 | REG_HW_MI_62, | ||
83 | REG_HW_MI_63, | ||
84 | REG_HW_MI_64, | ||
85 | REG_HW_MI_F1 = 0xf1, | ||
86 | ATTR_TOTAL_MI_REG = 0xf2 | ||
87 | }; | ||
88 | |||
89 | /* the bytes to write are in gspca_dev->usb_buf */ | ||
90 | static int reg_w(struct gspca_dev *gspca_dev, | ||
91 | __u16 index, int len) | ||
92 | { | ||
93 | int rc; | ||
94 | |||
95 | rc = usb_control_msg(gspca_dev->dev, | ||
96 | usb_sndbulkpipe(gspca_dev->dev, 4), | ||
97 | 0x12, | ||
98 | 0xc8, /* ?? */ | ||
99 | 0, /* value */ | ||
100 | index, gspca_dev->usb_buf, len, 500); | ||
101 | if (rc < 0) | ||
102 | PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc); | ||
103 | return rc; | ||
104 | } | ||
105 | |||
106 | static int reg_w_buf(struct gspca_dev *gspca_dev, | ||
107 | __u16 index, __u8 *buf, int len) | ||
108 | { | ||
109 | int rc; | ||
110 | |||
111 | rc = usb_control_msg(gspca_dev->dev, | ||
112 | usb_sndbulkpipe(gspca_dev->dev, 4), | ||
113 | 0x12, | ||
114 | 0xc8, /* ?? */ | ||
115 | 0, /* value */ | ||
116 | index, buf, len, 500); | ||
117 | if (rc < 0) | ||
118 | PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc); | ||
119 | return rc; | ||
120 | } | ||
121 | |||
122 | static void bulk_w(struct gspca_dev *gspca_dev, | ||
123 | __u16 *pch, | ||
124 | __u16 Address) | ||
125 | { | ||
126 | gspca_dev->usb_buf[0] = 0x1f; | ||
127 | gspca_dev->usb_buf[1] = 0; /* control byte */ | ||
128 | gspca_dev->usb_buf[2] = Address; | ||
129 | gspca_dev->usb_buf[3] = *pch >> 8; /* high byte */ | ||
130 | gspca_dev->usb_buf[4] = *pch; /* low byte */ | ||
131 | |||
132 | reg_w(gspca_dev, Address, 5); | ||
133 | } | ||
134 | |||
135 | /* this function is called at probe time */ | ||
136 | static int sd_config(struct gspca_dev *gspca_dev, | ||
137 | const struct usb_device_id *id) | ||
138 | { | ||
139 | struct sd *sd = (struct sd *) gspca_dev; | ||
140 | struct cam *cam; | ||
141 | |||
142 | cam = &gspca_dev->cam; | ||
143 | cam->dev_name = (char *) id->driver_info; | ||
144 | cam->epaddr = 0x01; | ||
145 | cam->cam_mode = vga_mode; | ||
146 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | ||
147 | sd->qindex = 1; /* set the quantization table */ | ||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | /* this function is called at open time */ | ||
152 | static int sd_open(struct gspca_dev *gspca_dev) | ||
153 | { | ||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | static void sd_start(struct gspca_dev *gspca_dev) | ||
158 | { | ||
159 | int err_code; | ||
160 | __u8 *data; | ||
161 | __u16 *MI_buf; | ||
162 | int h_size, v_size; | ||
163 | int intpipe; | ||
164 | |||
165 | PDEBUG(D_STREAM, "camera start, iface %d, alt 8", gspca_dev->iface); | ||
166 | if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 8) < 0) { | ||
167 | PDEBUG(D_ERR|D_STREAM, "Set packet size: set interface error"); | ||
168 | return; | ||
169 | } | ||
170 | |||
171 | data = gspca_dev->usb_buf; | ||
172 | data[0] = 0x01; /* address */ | ||
173 | data[1] = 0x01; | ||
174 | |||
175 | err_code = reg_w(gspca_dev, data[0], 2); | ||
176 | if (err_code < 0) | ||
177 | return; | ||
178 | |||
179 | /* | ||
180 | Initialize the MR97113 chip register | ||
181 | */ | ||
182 | data = kmalloc(16, GFP_KERNEL); | ||
183 | data[0] = 0x00; /* address */ | ||
184 | data[1] = 0x0c | 0x01; /* reg 0 */ | ||
185 | data[2] = 0x01; /* reg 1 */ | ||
186 | h_size = gspca_dev->width; | ||
187 | v_size = gspca_dev->height; | ||
188 | data[3] = h_size / 8; /* h_size , reg 2 */ | ||
189 | data[4] = v_size / 8; /* v_size , reg 3 */ | ||
190 | data[5] = 0x30; /* reg 4, MI, PAS5101 : | ||
191 | * 0x30 for 24mhz , 0x28 for 12mhz */ | ||
192 | data[6] = 4; /* reg 5, H start */ | ||
193 | data[7] = 0xc0; /* reg 6, gamma 1.5 */ | ||
194 | data[8] = 3; /* reg 7, V start */ | ||
195 | /* if (h_size == 320 ) */ | ||
196 | /* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */ | ||
197 | /* else */ | ||
198 | data[9] = 0x52; /* reg 8, 24MHz, no scale down */ | ||
199 | data[10] = 0x5d; /* reg 9, I2C device address | ||
200 | * [for PAS5101 (0x40)] [for MI (0x5d)] */ | ||
201 | |||
202 | err_code = reg_w_buf(gspca_dev, data[0], data, 11); | ||
203 | kfree(data); | ||
204 | if (err_code < 0) | ||
205 | return; | ||
206 | |||
207 | data = gspca_dev->usb_buf; | ||
208 | data[0] = 0x23; /* address */ | ||
209 | data[1] = 0x09; /* reg 35, append frame header */ | ||
210 | |||
211 | err_code = reg_w(gspca_dev, data[0], 2); | ||
212 | if (err_code < 0) | ||
213 | return; | ||
214 | |||
215 | data[0] = 0x3c; /* address */ | ||
216 | /* if (gspca_dev->width == 1280) */ | ||
217 | /* data[1] = 200; * reg 60, pc-cam frame size | ||
218 | * (unit: 4KB) 800KB */ | ||
219 | /* else */ | ||
220 | data[1] = 50; /* 50 reg 60, pc-cam frame size | ||
221 | * (unit: 4KB) 200KB */ | ||
222 | err_code = reg_w(gspca_dev, data[0], 2); | ||
223 | if (err_code < 0) | ||
224 | return; | ||
225 | |||
226 | if (0) { /* fixed dark-gain */ | ||
227 | data[1] = 0; /* reg 94, Y Gain (1.75) */ | ||
228 | data[2] = 0; /* reg 95, UV Gain (1.75) */ | ||
229 | data[3] = 0x3f; /* reg 96, Y Gain/UV Gain/disable | ||
230 | * auto dark-gain */ | ||
231 | data[4] = 0; /* reg 97, set fixed dark level */ | ||
232 | data[5] = 0; /* reg 98, don't care */ | ||
233 | } else { /* auto dark-gain */ | ||
234 | data[1] = 0; /* reg 94, Y Gain (auto) */ | ||
235 | data[2] = 0; /* reg 95, UV Gain (1.75) */ | ||
236 | data[3] = 0x78; /* reg 96, Y Gain/UV Gain/disable | ||
237 | * auto dark-gain */ | ||
238 | switch (gspca_dev->width) { | ||
239 | /* case 1280: */ | ||
240 | /* data[4] = 154; | ||
241 | * reg 97, %3 shadow point (unit: 256 pixel) */ | ||
242 | /* data[5] = 51; | ||
243 | * reg 98, %1 highlight point | ||
244 | * (uint: 256 pixel) */ | ||
245 | /* break; */ | ||
246 | default: | ||
247 | /* case 640: */ | ||
248 | data[4] = 36; /* reg 97, %3 shadow point | ||
249 | * (unit: 256 pixel) */ | ||
250 | data[5] = 12; /* reg 98, %1 highlight point | ||
251 | * (uint: 256 pixel) */ | ||
252 | break; | ||
253 | case 320: | ||
254 | data[4] = 9; /* reg 97, %3 shadow point | ||
255 | * (unit: 256 pixel) */ | ||
256 | data[5] = 3; /* reg 98, %1 highlight point | ||
257 | * (uint: 256 pixel) */ | ||
258 | break; | ||
259 | } | ||
260 | } | ||
261 | /* auto dark-gain */ | ||
262 | data[0] = 0x5e; /* address */ | ||
263 | |||
264 | err_code = reg_w(gspca_dev, data[0], 6); | ||
265 | if (err_code < 0) | ||
266 | return; | ||
267 | |||
268 | data[0] = 0x67; | ||
269 | data[1] = 0x13; /* reg 103, first pixel B, disable sharpness */ | ||
270 | err_code = reg_w(gspca_dev, data[0], 2); | ||
271 | if (err_code < 0) | ||
272 | return; | ||
273 | |||
274 | /* | ||
275 | * initialize the value of MI sensor... | ||
276 | */ | ||
277 | MI_buf = kzalloc(ATTR_TOTAL_MI_REG * sizeof *MI_buf, GFP_KERNEL); | ||
278 | MI_buf[REG_HW_MI_1] = 0x000a; | ||
279 | MI_buf[REG_HW_MI_2] = 0x000c; | ||
280 | MI_buf[REG_HW_MI_3] = 0x0405; | ||
281 | MI_buf[REG_HW_MI_4] = 0x0507; | ||
282 | /* mi_Attr_Reg_[REG_HW_MI_5] = 0x01ff;//13 */ | ||
283 | MI_buf[REG_HW_MI_5] = 0x0013; /* 13 */ | ||
284 | MI_buf[REG_HW_MI_6] = 0x001f; /* vertical blanking */ | ||
285 | /* mi_Attr_Reg_[REG_HW_MI_6] = 0x0400; // vertical blanking */ | ||
286 | MI_buf[REG_HW_MI_7] = 0x0002; | ||
287 | /* mi_Attr_Reg_[REG_HW_MI_9] = 0x015f; */ | ||
288 | /* mi_Attr_Reg_[REG_HW_MI_9] = 0x030f; */ | ||
289 | MI_buf[REG_HW_MI_9] = 0x0374; | ||
290 | MI_buf[REG_HW_MI_B] = 0x0000; | ||
291 | MI_buf[REG_HW_MI_C] = 0x0000; | ||
292 | MI_buf[REG_HW_MI_D] = 0x0000; | ||
293 | MI_buf[REG_HW_MI_1E] = 0x8000; | ||
294 | /* mi_Attr_Reg_[REG_HW_MI_20] = 0x1104; */ | ||
295 | MI_buf[REG_HW_MI_20] = 0x1104; /* 0x111c; */ | ||
296 | MI_buf[REG_HW_MI_2B] = 0x0008; | ||
297 | /* mi_Attr_Reg_[REG_HW_MI_2C] = 0x000f; */ | ||
298 | MI_buf[REG_HW_MI_2C] = 0x001f; /* lita suggest */ | ||
299 | MI_buf[REG_HW_MI_2D] = 0x0008; | ||
300 | MI_buf[REG_HW_MI_2E] = 0x0008; | ||
301 | MI_buf[REG_HW_MI_35] = 0x0051; | ||
302 | MI_buf[REG_HW_MI_5F] = 0x0904; /* fail to write */ | ||
303 | MI_buf[REG_HW_MI_60] = 0x0000; | ||
304 | MI_buf[REG_HW_MI_61] = 0x0000; | ||
305 | MI_buf[REG_HW_MI_62] = 0x0498; | ||
306 | MI_buf[REG_HW_MI_63] = 0x0000; | ||
307 | MI_buf[REG_HW_MI_64] = 0x0000; | ||
308 | MI_buf[REG_HW_MI_F1] = 0x0001; | ||
309 | /* changing while setting up the different value of dx/dy */ | ||
310 | |||
311 | if (gspca_dev->width != 1280) { | ||
312 | MI_buf[0x01] = 0x010a; | ||
313 | MI_buf[0x02] = 0x014c; | ||
314 | MI_buf[0x03] = 0x01e5; | ||
315 | MI_buf[0x04] = 0x0287; | ||
316 | } | ||
317 | MI_buf[0x20] = 0x1104; | ||
318 | |||
319 | bulk_w(gspca_dev, MI_buf + 1, 1); | ||
320 | bulk_w(gspca_dev, MI_buf + 2, 2); | ||
321 | bulk_w(gspca_dev, MI_buf + 3, 3); | ||
322 | bulk_w(gspca_dev, MI_buf + 4, 4); | ||
323 | bulk_w(gspca_dev, MI_buf + 5, 5); | ||
324 | bulk_w(gspca_dev, MI_buf + 6, 6); | ||
325 | bulk_w(gspca_dev, MI_buf + 7, 7); | ||
326 | bulk_w(gspca_dev, MI_buf + 9, 9); | ||
327 | bulk_w(gspca_dev, MI_buf + 0x0b, 0x0b); | ||
328 | bulk_w(gspca_dev, MI_buf + 0x0c, 0x0c); | ||
329 | bulk_w(gspca_dev, MI_buf + 0x0d, 0x0d); | ||
330 | bulk_w(gspca_dev, MI_buf + 0x1e, 0x1e); | ||
331 | bulk_w(gspca_dev, MI_buf + 0x20, 0x20); | ||
332 | bulk_w(gspca_dev, MI_buf + 0x2b, 0x2b); | ||
333 | bulk_w(gspca_dev, MI_buf + 0x2c, 0x2c); | ||
334 | bulk_w(gspca_dev, MI_buf + 0x2d, 0x2d); | ||
335 | bulk_w(gspca_dev, MI_buf + 0x2e, 0x2e); | ||
336 | bulk_w(gspca_dev, MI_buf + 0x35, 0x35); | ||
337 | bulk_w(gspca_dev, MI_buf + 0x5f, 0x5f); | ||
338 | bulk_w(gspca_dev, MI_buf + 0x60, 0x60); | ||
339 | bulk_w(gspca_dev, MI_buf + 0x61, 0x61); | ||
340 | bulk_w(gspca_dev, MI_buf + 0x62, 0x62); | ||
341 | bulk_w(gspca_dev, MI_buf + 0x63, 0x63); | ||
342 | bulk_w(gspca_dev, MI_buf + 0x64, 0x64); | ||
343 | bulk_w(gspca_dev, MI_buf + 0xf1, 0xf1); | ||
344 | kfree(MI_buf); | ||
345 | |||
346 | intpipe = usb_sndintpipe(gspca_dev->dev, 0); | ||
347 | err_code = usb_clear_halt(gspca_dev->dev, intpipe); | ||
348 | |||
349 | data[0] = 0x00; | ||
350 | data[1] = 0x4d; /* ISOC transfering enable... */ | ||
351 | reg_w(gspca_dev, data[0], 2); | ||
352 | } | ||
353 | |||
354 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
355 | { | ||
356 | int result; | ||
357 | |||
358 | gspca_dev->usb_buf[0] = 1; | ||
359 | gspca_dev->usb_buf[1] = 0; | ||
360 | result = reg_w(gspca_dev, gspca_dev->usb_buf[0], 2); | ||
361 | if (result < 0) | ||
362 | PDEBUG(D_ERR, "Camera Stop failed"); | ||
363 | } | ||
364 | |||
365 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
366 | { | ||
367 | } | ||
368 | |||
369 | static void sd_close(struct gspca_dev *gspca_dev) | ||
370 | { | ||
371 | } | ||
372 | |||
373 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
374 | struct gspca_frame *frame, /* target */ | ||
375 | __u8 *data, /* isoc packet */ | ||
376 | int len) /* iso packet length */ | ||
377 | { | ||
378 | struct sd *sd = (struct sd *) gspca_dev; | ||
379 | int p; | ||
380 | |||
381 | if (len < 6) { | ||
382 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
383 | return; | ||
384 | } | ||
385 | for (p = 0; p < len - 6; p++) { | ||
386 | if (data[0 + p] == 0xff | ||
387 | && data[1 + p] == 0xff | ||
388 | && data[2 + p] == 0x00 | ||
389 | && data[3 + p] == 0xff | ||
390 | && data[4 + p] == 0x96) { | ||
391 | if (data[5 + p] == 0x64 | ||
392 | || data[5 + p] == 0x65 | ||
393 | || data[5 + p] == 0x66 | ||
394 | || data[5 + p] == 0x67) { | ||
395 | PDEBUG(D_PACK, "sof offset: %d leng: %d", | ||
396 | p, len); | ||
397 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, | ||
398 | frame, data, 0); | ||
399 | |||
400 | /* put the JPEG header */ | ||
401 | jpeg_put_header(gspca_dev, frame, | ||
402 | sd->qindex, 0x21); | ||
403 | data += 16; | ||
404 | len -= 16; | ||
405 | break; | ||
406 | } | ||
407 | } | ||
408 | } | ||
409 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
410 | } | ||
411 | |||
412 | /* sub-driver description */ | ||
413 | static const struct sd_desc sd_desc = { | ||
414 | .name = MODULE_NAME, | ||
415 | .ctrls = sd_ctrls, | ||
416 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
417 | .config = sd_config, | ||
418 | .open = sd_open, | ||
419 | .start = sd_start, | ||
420 | .stopN = sd_stopN, | ||
421 | .stop0 = sd_stop0, | ||
422 | .close = sd_close, | ||
423 | .pkt_scan = sd_pkt_scan, | ||
424 | }; | ||
425 | |||
426 | /* -- module initialisation -- */ | ||
427 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
428 | static const __devinitdata struct usb_device_id device_table[] = { | ||
429 | {USB_DEVICE(0x093a, 0x050f), DVNM("Mars-Semi Pc-Camera")}, | ||
430 | {} | ||
431 | }; | ||
432 | MODULE_DEVICE_TABLE(usb, device_table); | ||
433 | |||
434 | /* -- device connect -- */ | ||
435 | static int sd_probe(struct usb_interface *intf, | ||
436 | const struct usb_device_id *id) | ||
437 | { | ||
438 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
439 | THIS_MODULE); | ||
440 | } | ||
441 | |||
442 | static struct usb_driver sd_driver = { | ||
443 | .name = MODULE_NAME, | ||
444 | .id_table = device_table, | ||
445 | .probe = sd_probe, | ||
446 | .disconnect = gspca_disconnect, | ||
447 | }; | ||
448 | |||
449 | /* -- module insert / remove -- */ | ||
450 | static int __init sd_mod_init(void) | ||
451 | { | ||
452 | if (usb_register(&sd_driver) < 0) | ||
453 | return -1; | ||
454 | PDEBUG(D_PROBE, "v%s registered", version); | ||
455 | return 0; | ||
456 | } | ||
457 | static void __exit sd_mod_exit(void) | ||
458 | { | ||
459 | usb_deregister(&sd_driver); | ||
460 | PDEBUG(D_PROBE, "deregistered"); | ||
461 | } | ||
462 | |||
463 | module_init(sd_mod_init); | ||
464 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c new file mode 100644 index 000000000000..08d99c3b78e2 --- /dev/null +++ b/drivers/media/video/gspca/ov519.c | |||
@@ -0,0 +1,2186 @@ | |||
1 | /** | ||
2 | * OV519 driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr) | ||
5 | * | ||
6 | * (This module is adapted from the ov51x-jpeg package) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | * | ||
22 | */ | ||
23 | #define MODULE_NAME "ov519" | ||
24 | |||
25 | #include "gspca.h" | ||
26 | |||
27 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) | ||
28 | static const char version[] = "2.1.7"; | ||
29 | |||
30 | MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); | ||
31 | MODULE_DESCRIPTION("OV519 USB Camera Driver"); | ||
32 | MODULE_LICENSE("GPL"); | ||
33 | |||
34 | /* global parameters */ | ||
35 | static int frame_rate; | ||
36 | |||
37 | /* Number of times to retry a failed I2C transaction. Increase this if you | ||
38 | * are getting "Failed to read sensor ID..." */ | ||
39 | static int i2c_detect_tries = 10; | ||
40 | |||
41 | /* ov519 device descriptor */ | ||
42 | struct sd { | ||
43 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
44 | |||
45 | /* Determined by sensor type */ | ||
46 | short maxwidth; | ||
47 | short maxheight; | ||
48 | |||
49 | unsigned char primary_i2c_slave; /* I2C write id of sensor */ | ||
50 | |||
51 | unsigned char brightness; | ||
52 | unsigned char contrast; | ||
53 | unsigned char colors; | ||
54 | |||
55 | char compress; /* Should the next frame be compressed? */ | ||
56 | char compress_inited; /* Are compression params uploaded? */ | ||
57 | char stopped; /* Streaming is temporarily paused */ | ||
58 | |||
59 | char frame_rate; /* current Framerate (OV519 only) */ | ||
60 | char clockdiv; /* clockdiv override for OV519 only */ | ||
61 | |||
62 | char sensor; /* Type of image sensor chip (SEN_*) */ | ||
63 | #define SEN_UNKNOWN 0 | ||
64 | #define SEN_OV6620 1 | ||
65 | #define SEN_OV6630 2 | ||
66 | #define SEN_OV7610 3 | ||
67 | #define SEN_OV7620 4 | ||
68 | #define SEN_OV7630 5 | ||
69 | #define SEN_OV7640 6 | ||
70 | #define SEN_OV7670 7 | ||
71 | #define SEN_OV76BE 8 | ||
72 | #define SEN_OV8610 9 | ||
73 | |||
74 | }; | ||
75 | |||
76 | /* V4L2 controls supported by the driver */ | ||
77 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
78 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
79 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
80 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
81 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
82 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
83 | |||
84 | static struct ctrl sd_ctrls[] = { | ||
85 | #define SD_BRIGHTNESS 0 | ||
86 | { | ||
87 | { | ||
88 | .id = V4L2_CID_BRIGHTNESS, | ||
89 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
90 | .name = "Brightness", | ||
91 | .minimum = 0, | ||
92 | .maximum = 255, | ||
93 | .step = 1, | ||
94 | .default_value = 127, | ||
95 | }, | ||
96 | .set = sd_setbrightness, | ||
97 | .get = sd_getbrightness, | ||
98 | }, | ||
99 | #define SD_CONTRAST 1 | ||
100 | { | ||
101 | { | ||
102 | .id = V4L2_CID_CONTRAST, | ||
103 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
104 | .name = "Contrast", | ||
105 | .minimum = 0, | ||
106 | .maximum = 255, | ||
107 | .step = 1, | ||
108 | .default_value = 127, | ||
109 | }, | ||
110 | .set = sd_setcontrast, | ||
111 | .get = sd_getcontrast, | ||
112 | }, | ||
113 | #define SD_COLOR 2 | ||
114 | { | ||
115 | { | ||
116 | .id = V4L2_CID_SATURATION, | ||
117 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
118 | .name = "Saturation", | ||
119 | .minimum = 0, | ||
120 | .maximum = 255, | ||
121 | .step = 1, | ||
122 | .default_value = 127, | ||
123 | }, | ||
124 | .set = sd_setcolors, | ||
125 | .get = sd_getcolors, | ||
126 | }, | ||
127 | }; | ||
128 | |||
129 | static struct v4l2_pix_format vga_mode[] = { | ||
130 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
131 | .bytesperline = 320, | ||
132 | .sizeimage = 320 * 240 * 3 / 8 + 589, | ||
133 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
134 | .priv = 1}, | ||
135 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
136 | .bytesperline = 640, | ||
137 | .sizeimage = 640 * 480 * 3 / 8 + 590, | ||
138 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
139 | .priv = 0}, | ||
140 | }; | ||
141 | static struct v4l2_pix_format sif_mode[] = { | ||
142 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
143 | .bytesperline = 176, | ||
144 | .sizeimage = 176 * 144 * 3 / 8 + 589, | ||
145 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
146 | .priv = 1}, | ||
147 | {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
148 | .bytesperline = 352, | ||
149 | .sizeimage = 352 * 288 * 3 / 8 + 589, | ||
150 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
151 | .priv = 0}, | ||
152 | }; | ||
153 | |||
154 | /* OV519 Camera interface register numbers */ | ||
155 | #define OV519_CAM_H_SIZE 0x10 | ||
156 | #define OV519_CAM_V_SIZE 0x11 | ||
157 | #define OV519_CAM_X_OFFSETL 0x12 | ||
158 | #define OV519_CAM_X_OFFSETH 0x13 | ||
159 | #define OV519_CAM_Y_OFFSETL 0x14 | ||
160 | #define OV519_CAM_Y_OFFSETH 0x15 | ||
161 | #define OV519_CAM_DIVIDER 0x16 | ||
162 | #define OV519_CAM_DFR 0x20 | ||
163 | #define OV519_CAM_FORMAT 0x25 | ||
164 | |||
165 | /* OV519 System Controller register numbers */ | ||
166 | #define OV519_SYS_RESET1 0x51 | ||
167 | #define OV519_SYS_EN_CLK1 0x54 | ||
168 | |||
169 | #define OV519_GPIO_DATA_OUT0 0x71 | ||
170 | #define OV519_GPIO_IO_CTRL0 0x72 | ||
171 | |||
172 | #define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */ | ||
173 | |||
174 | /* I2C registers */ | ||
175 | #define R51x_I2C_W_SID 0x41 | ||
176 | #define R51x_I2C_SADDR_3 0x42 | ||
177 | #define R51x_I2C_SADDR_2 0x43 | ||
178 | #define R51x_I2C_R_SID 0x44 | ||
179 | #define R51x_I2C_DATA 0x45 | ||
180 | #define R518_I2C_CTL 0x47 /* OV518(+) only */ | ||
181 | |||
182 | /* I2C ADDRESSES */ | ||
183 | #define OV7xx0_SID 0x42 | ||
184 | #define OV8xx0_SID 0xa0 | ||
185 | #define OV6xx0_SID 0xc0 | ||
186 | |||
187 | /* OV7610 registers */ | ||
188 | #define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */ | ||
189 | #define OV7610_REG_SAT 0x03 /* saturation */ | ||
190 | #define OV8610_REG_HUE 0x04 /* 04 reserved */ | ||
191 | #define OV7610_REG_CNT 0x05 /* Y contrast */ | ||
192 | #define OV7610_REG_BRT 0x06 /* Y brightness */ | ||
193 | #define OV7610_REG_COM_C 0x14 /* misc common regs */ | ||
194 | #define OV7610_REG_ID_HIGH 0x1c /* manufacturer ID MSB */ | ||
195 | #define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */ | ||
196 | #define OV7610_REG_COM_I 0x29 /* misc settings */ | ||
197 | |||
198 | /* OV7670 registers */ | ||
199 | #define OV7670_REG_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */ | ||
200 | #define OV7670_REG_BLUE 0x01 /* blue gain */ | ||
201 | #define OV7670_REG_RED 0x02 /* red gain */ | ||
202 | #define OV7670_REG_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */ | ||
203 | #define OV7670_REG_COM1 0x04 /* Control 1 */ | ||
204 | #define OV7670_REG_AECHH 0x07 /* AEC MS 5 bits */ | ||
205 | #define OV7670_REG_COM3 0x0c /* Control 3 */ | ||
206 | #define OV7670_REG_COM4 0x0d /* Control 4 */ | ||
207 | #define OV7670_REG_COM5 0x0e /* All "reserved" */ | ||
208 | #define OV7670_REG_COM6 0x0f /* Control 6 */ | ||
209 | #define OV7670_REG_AECH 0x10 /* More bits of AEC value */ | ||
210 | #define OV7670_REG_CLKRC 0x11 /* Clock control */ | ||
211 | #define OV7670_REG_COM7 0x12 /* Control 7 */ | ||
212 | #define OV7670_COM7_FMT_VGA 0x00 | ||
213 | #define OV7670_COM7_YUV 0x00 /* YUV */ | ||
214 | #define OV7670_COM7_FMT_QVGA 0x10 /* QVGA format */ | ||
215 | #define OV7670_COM7_FMT_MASK 0x38 | ||
216 | #define OV7670_COM7_RESET 0x80 /* Register reset */ | ||
217 | #define OV7670_REG_COM8 0x13 /* Control 8 */ | ||
218 | #define OV7670_COM8_AEC 0x01 /* Auto exposure enable */ | ||
219 | #define OV7670_COM8_AWB 0x02 /* White balance enable */ | ||
220 | #define OV7670_COM8_AGC 0x04 /* Auto gain enable */ | ||
221 | #define OV7670_COM8_BFILT 0x20 /* Band filter enable */ | ||
222 | #define OV7670_COM8_AECSTEP 0x40 /* Unlimited AEC step size */ | ||
223 | #define OV7670_COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */ | ||
224 | #define OV7670_REG_COM9 0x14 /* Control 9 - gain ceiling */ | ||
225 | #define OV7670_REG_COM10 0x15 /* Control 10 */ | ||
226 | #define OV7670_REG_HSTART 0x17 /* Horiz start high bits */ | ||
227 | #define OV7670_REG_HSTOP 0x18 /* Horiz stop high bits */ | ||
228 | #define OV7670_REG_VSTART 0x19 /* Vert start high bits */ | ||
229 | #define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */ | ||
230 | #define OV7670_REG_MVFP 0x1e /* Mirror / vflip */ | ||
231 | #define OV7670_MVFP_MIRROR 0x20 /* Mirror image */ | ||
232 | #define OV7670_REG_AEW 0x24 /* AGC upper limit */ | ||
233 | #define OV7670_REG_AEB 0x25 /* AGC lower limit */ | ||
234 | #define OV7670_REG_VPT 0x26 /* AGC/AEC fast mode op region */ | ||
235 | #define OV7670_REG_HREF 0x32 /* HREF pieces */ | ||
236 | #define OV7670_REG_TSLB 0x3a /* lots of stuff */ | ||
237 | #define OV7670_REG_COM11 0x3b /* Control 11 */ | ||
238 | #define OV7670_COM11_EXP 0x02 | ||
239 | #define OV7670_COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */ | ||
240 | #define OV7670_REG_COM12 0x3c /* Control 12 */ | ||
241 | #define OV7670_REG_COM13 0x3d /* Control 13 */ | ||
242 | #define OV7670_COM13_GAMMA 0x80 /* Gamma enable */ | ||
243 | #define OV7670_COM13_UVSAT 0x40 /* UV saturation auto adjustment */ | ||
244 | #define OV7670_REG_COM14 0x3e /* Control 14 */ | ||
245 | #define OV7670_REG_EDGE 0x3f /* Edge enhancement factor */ | ||
246 | #define OV7670_REG_COM15 0x40 /* Control 15 */ | ||
247 | #define OV7670_COM15_R00FF 0xc0 /* 00 to FF */ | ||
248 | #define OV7670_REG_COM16 0x41 /* Control 16 */ | ||
249 | #define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */ | ||
250 | #define OV7670_REG_BRIGHT 0x55 /* Brightness */ | ||
251 | #define OV7670_REG_CONTRAS 0x56 /* Contrast control */ | ||
252 | #define OV7670_REG_GFIX 0x69 /* Fix gain control */ | ||
253 | #define OV7670_REG_RGB444 0x8c /* RGB 444 control */ | ||
254 | #define OV7670_REG_HAECC1 0x9f /* Hist AEC/AGC control 1 */ | ||
255 | #define OV7670_REG_HAECC2 0xa0 /* Hist AEC/AGC control 2 */ | ||
256 | #define OV7670_REG_BD50MAX 0xa5 /* 50hz banding step limit */ | ||
257 | #define OV7670_REG_HAECC3 0xa6 /* Hist AEC/AGC control 3 */ | ||
258 | #define OV7670_REG_HAECC4 0xa7 /* Hist AEC/AGC control 4 */ | ||
259 | #define OV7670_REG_HAECC5 0xa8 /* Hist AEC/AGC control 5 */ | ||
260 | #define OV7670_REG_HAECC6 0xa9 /* Hist AEC/AGC control 6 */ | ||
261 | #define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */ | ||
262 | #define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */ | ||
263 | |||
264 | struct ovsensor_window { | ||
265 | short x; | ||
266 | short y; | ||
267 | short width; | ||
268 | short height; | ||
269 | /* int format; */ | ||
270 | short quarter; /* Scale width and height down 2x */ | ||
271 | short clockdiv; /* Clock divisor setting */ | ||
272 | }; | ||
273 | |||
274 | static unsigned char ov7670_abs_to_sm(unsigned char v) | ||
275 | { | ||
276 | if (v > 127) | ||
277 | return v & 0x7f; | ||
278 | return (128 - v) | 0x80; | ||
279 | } | ||
280 | |||
281 | /* Write a OV519 register */ | ||
282 | static int reg_w(struct sd *sd, __u16 index, __u8 value) | ||
283 | { | ||
284 | int ret; | ||
285 | |||
286 | sd->gspca_dev.usb_buf[0] = value; | ||
287 | ret = usb_control_msg(sd->gspca_dev.dev, | ||
288 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), | ||
289 | 1, /* REQ_IO (ov518/519) */ | ||
290 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
291 | 0, index, | ||
292 | sd->gspca_dev.usb_buf, 1, 500); | ||
293 | if (ret < 0) | ||
294 | PDEBUG(D_ERR, "Write reg [%02x] %02x failed", index, value); | ||
295 | return ret; | ||
296 | } | ||
297 | |||
298 | /* Read from a OV519 register */ | ||
299 | /* returns: negative is error, pos or zero is data */ | ||
300 | static int reg_r(struct sd *sd, __u16 index) | ||
301 | { | ||
302 | int ret; | ||
303 | |||
304 | ret = usb_control_msg(sd->gspca_dev.dev, | ||
305 | usb_rcvctrlpipe(sd->gspca_dev.dev, 0), | ||
306 | 1, /* REQ_IO */ | ||
307 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
308 | 0, index, sd->gspca_dev.usb_buf, 1, 500); | ||
309 | |||
310 | if (ret >= 0) | ||
311 | ret = sd->gspca_dev.usb_buf[0]; | ||
312 | else | ||
313 | PDEBUG(D_ERR, "Read reg [0x%02x] failed", index); | ||
314 | return ret; | ||
315 | } | ||
316 | |||
317 | /* Read 8 values from a OV519 register */ | ||
318 | static int reg_r8(struct sd *sd, | ||
319 | __u16 index) | ||
320 | { | ||
321 | int ret; | ||
322 | |||
323 | ret = usb_control_msg(sd->gspca_dev.dev, | ||
324 | usb_rcvctrlpipe(sd->gspca_dev.dev, 0), | ||
325 | 1, /* REQ_IO */ | ||
326 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
327 | 0, index, sd->gspca_dev.usb_buf, 8, 500); | ||
328 | |||
329 | if (ret >= 0) | ||
330 | ret = sd->gspca_dev.usb_buf[0]; | ||
331 | else | ||
332 | PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index); | ||
333 | return ret; | ||
334 | } | ||
335 | |||
336 | /* | ||
337 | * Writes bits at positions specified by mask to an OV51x reg. Bits that are in | ||
338 | * the same position as 1's in "mask" are cleared and set to "value". Bits | ||
339 | * that are in the same position as 0's in "mask" are preserved, regardless | ||
340 | * of their respective state in "value". | ||
341 | */ | ||
342 | static int reg_w_mask(struct sd *sd, | ||
343 | __u16 index, | ||
344 | __u8 value, | ||
345 | __u8 mask) | ||
346 | { | ||
347 | int ret; | ||
348 | __u8 oldval; | ||
349 | |||
350 | if (mask != 0xff) { | ||
351 | value &= mask; /* Enforce mask on value */ | ||
352 | ret = reg_r(sd, index); | ||
353 | if (ret < 0) | ||
354 | return ret; | ||
355 | |||
356 | oldval = ret & ~mask; /* Clear the masked bits */ | ||
357 | value |= oldval; /* Set the desired bits */ | ||
358 | } | ||
359 | return reg_w(sd, index, value); | ||
360 | } | ||
361 | |||
362 | /* | ||
363 | * The OV518 I2C I/O procedure is different, hence, this function. | ||
364 | * This is normally only called from i2c_w(). Note that this function | ||
365 | * always succeeds regardless of whether the sensor is present and working. | ||
366 | */ | ||
367 | static int i2c_w(struct sd *sd, | ||
368 | __u8 reg, | ||
369 | __u8 value) | ||
370 | { | ||
371 | int rc; | ||
372 | |||
373 | PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg); | ||
374 | |||
375 | /* Select camera register */ | ||
376 | rc = reg_w(sd, R51x_I2C_SADDR_3, reg); | ||
377 | if (rc < 0) | ||
378 | return rc; | ||
379 | |||
380 | /* Write "value" to I2C data port of OV511 */ | ||
381 | rc = reg_w(sd, R51x_I2C_DATA, value); | ||
382 | if (rc < 0) | ||
383 | return rc; | ||
384 | |||
385 | /* Initiate 3-byte write cycle */ | ||
386 | rc = reg_w(sd, R518_I2C_CTL, 0x01); | ||
387 | |||
388 | /* wait for write complete */ | ||
389 | msleep(4); | ||
390 | if (rc < 0) | ||
391 | return rc; | ||
392 | return reg_r8(sd, R518_I2C_CTL); | ||
393 | } | ||
394 | |||
395 | /* | ||
396 | * returns: negative is error, pos or zero is data | ||
397 | * | ||
398 | * The OV518 I2C I/O procedure is different, hence, this function. | ||
399 | * This is normally only called from i2c_r(). Note that this function | ||
400 | * always succeeds regardless of whether the sensor is present and working. | ||
401 | */ | ||
402 | static int i2c_r(struct sd *sd, __u8 reg) | ||
403 | { | ||
404 | int rc, value; | ||
405 | |||
406 | /* Select camera register */ | ||
407 | rc = reg_w(sd, R51x_I2C_SADDR_2, reg); | ||
408 | if (rc < 0) | ||
409 | return rc; | ||
410 | |||
411 | /* Initiate 2-byte write cycle */ | ||
412 | rc = reg_w(sd, R518_I2C_CTL, 0x03); | ||
413 | if (rc < 0) | ||
414 | return rc; | ||
415 | |||
416 | /* Initiate 2-byte read cycle */ | ||
417 | rc = reg_w(sd, R518_I2C_CTL, 0x05); | ||
418 | if (rc < 0) | ||
419 | return rc; | ||
420 | value = reg_r(sd, R51x_I2C_DATA); | ||
421 | PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value); | ||
422 | return value; | ||
423 | } | ||
424 | |||
425 | /* Writes bits at positions specified by mask to an I2C reg. Bits that are in | ||
426 | * the same position as 1's in "mask" are cleared and set to "value". Bits | ||
427 | * that are in the same position as 0's in "mask" are preserved, regardless | ||
428 | * of their respective state in "value". | ||
429 | */ | ||
430 | static int i2c_w_mask(struct sd *sd, | ||
431 | __u8 reg, | ||
432 | __u8 value, | ||
433 | __u8 mask) | ||
434 | { | ||
435 | int rc; | ||
436 | __u8 oldval; | ||
437 | |||
438 | value &= mask; /* Enforce mask on value */ | ||
439 | rc = i2c_r(sd, reg); | ||
440 | if (rc < 0) | ||
441 | return rc; | ||
442 | oldval = rc & ~mask; /* Clear the masked bits */ | ||
443 | value |= oldval; /* Set the desired bits */ | ||
444 | return i2c_w(sd, reg, value); | ||
445 | } | ||
446 | |||
447 | /* Temporarily stops OV511 from functioning. Must do this before changing | ||
448 | * registers while the camera is streaming */ | ||
449 | static inline int ov51x_stop(struct sd *sd) | ||
450 | { | ||
451 | PDEBUG(D_STREAM, "stopping"); | ||
452 | sd->stopped = 1; | ||
453 | return reg_w(sd, OV519_SYS_RESET1, 0x0f); | ||
454 | } | ||
455 | |||
456 | /* Restarts OV511 after ov511_stop() is called. Has no effect if it is not | ||
457 | * actually stopped (for performance). */ | ||
458 | static inline int ov51x_restart(struct sd *sd) | ||
459 | { | ||
460 | PDEBUG(D_STREAM, "restarting"); | ||
461 | if (!sd->stopped) | ||
462 | return 0; | ||
463 | sd->stopped = 0; | ||
464 | |||
465 | /* Reinitialize the stream */ | ||
466 | return reg_w(sd, OV519_SYS_RESET1, 0x00); | ||
467 | } | ||
468 | |||
469 | /* This does an initial reset of an OmniVision sensor and ensures that I2C | ||
470 | * is synchronized. Returns <0 on failure. | ||
471 | */ | ||
472 | static int init_ov_sensor(struct sd *sd) | ||
473 | { | ||
474 | int i, success; | ||
475 | |||
476 | /* Reset the sensor */ | ||
477 | if (i2c_w(sd, 0x12, 0x80) < 0) | ||
478 | return -EIO; | ||
479 | |||
480 | /* Wait for it to initialize */ | ||
481 | msleep(150); | ||
482 | |||
483 | for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) { | ||
484 | if (i2c_r(sd, OV7610_REG_ID_HIGH) == 0x7f && | ||
485 | i2c_r(sd, OV7610_REG_ID_LOW) == 0xa2) { | ||
486 | success = 1; | ||
487 | continue; | ||
488 | } | ||
489 | |||
490 | /* Reset the sensor */ | ||
491 | if (i2c_w(sd, 0x12, 0x80) < 0) | ||
492 | return -EIO; | ||
493 | /* Wait for it to initialize */ | ||
494 | msleep(150); | ||
495 | /* Dummy read to sync I2C */ | ||
496 | if (i2c_r(sd, 0x00) < 0) | ||
497 | return -EIO; | ||
498 | } | ||
499 | if (!success) | ||
500 | return -EIO; | ||
501 | PDEBUG(D_PROBE, "I2C synced in %d attempt(s)", i); | ||
502 | return 0; | ||
503 | } | ||
504 | |||
505 | /* Switch on standard JPEG compression. Returns 0 for success. */ | ||
506 | static int ov519_init_compression(struct sd *sd) | ||
507 | { | ||
508 | if (!sd->compress_inited) { | ||
509 | if (reg_w_mask(sd, OV519_SYS_EN_CLK1, 1 << 2, 1 << 2) < 0) { | ||
510 | PDEBUG(D_ERR, "Error switching to compressed mode"); | ||
511 | return -EIO; | ||
512 | } | ||
513 | sd->compress_inited = 1; | ||
514 | } | ||
515 | return 0; | ||
516 | } | ||
517 | |||
518 | /* Set the read and write slave IDs. The "slave" argument is the write slave, | ||
519 | * and the read slave will be set to (slave + 1). | ||
520 | * This should not be called from outside the i2c I/O functions. | ||
521 | * Sets I2C read and write slave IDs. Returns <0 for error | ||
522 | */ | ||
523 | static int ov51x_set_slave_ids(struct sd *sd, | ||
524 | __u8 slave) | ||
525 | { | ||
526 | int rc; | ||
527 | |||
528 | rc = reg_w(sd, R51x_I2C_W_SID, slave); | ||
529 | if (rc < 0) | ||
530 | return rc; | ||
531 | return reg_w(sd, R51x_I2C_R_SID, slave + 1); | ||
532 | } | ||
533 | |||
534 | struct ov_regvals { | ||
535 | __u8 reg; | ||
536 | __u8 val; | ||
537 | }; | ||
538 | struct ov_i2c_regvals { | ||
539 | __u8 reg; | ||
540 | __u8 val; | ||
541 | }; | ||
542 | |||
543 | static int write_regvals(struct sd *sd, | ||
544 | const struct ov_regvals *regvals, | ||
545 | int n) | ||
546 | { | ||
547 | int rc; | ||
548 | |||
549 | while (--n >= 0) { | ||
550 | rc = reg_w(sd, regvals->reg, regvals->val); | ||
551 | if (rc < 0) | ||
552 | return rc; | ||
553 | regvals++; | ||
554 | } | ||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | static int write_i2c_regvals(struct sd *sd, | ||
559 | const struct ov_i2c_regvals *regvals, | ||
560 | int n) | ||
561 | { | ||
562 | int rc; | ||
563 | |||
564 | while (--n >= 0) { | ||
565 | rc = i2c_w(sd, regvals->reg, regvals->val); | ||
566 | if (rc < 0) | ||
567 | return rc; | ||
568 | regvals++; | ||
569 | } | ||
570 | return 0; | ||
571 | } | ||
572 | |||
573 | /**************************************************************************** | ||
574 | * | ||
575 | * OV511 and sensor configuration | ||
576 | * | ||
577 | ***************************************************************************/ | ||
578 | |||
579 | /* This initializes the OV8110, OV8610 sensor. The OV8110 uses | ||
580 | * the same register settings as the OV8610, since they are very similar. | ||
581 | */ | ||
582 | static int ov8xx0_configure(struct sd *sd) | ||
583 | { | ||
584 | int rc; | ||
585 | static const struct ov_i2c_regvals norm_8610[] = { | ||
586 | { 0x12, 0x80 }, | ||
587 | { 0x00, 0x00 }, | ||
588 | { 0x01, 0x80 }, | ||
589 | { 0x02, 0x80 }, | ||
590 | { 0x03, 0xc0 }, | ||
591 | { 0x04, 0x30 }, | ||
592 | { 0x05, 0x30 }, /* was 0x10, new from windrv 090403 */ | ||
593 | { 0x06, 0x70 }, /* was 0x80, new from windrv 090403 */ | ||
594 | { 0x0a, 0x86 }, | ||
595 | { 0x0b, 0xb0 }, | ||
596 | { 0x0c, 0x20 }, | ||
597 | { 0x0d, 0x20 }, | ||
598 | { 0x11, 0x01 }, | ||
599 | { 0x12, 0x25 }, | ||
600 | { 0x13, 0x01 }, | ||
601 | { 0x14, 0x04 }, | ||
602 | { 0x15, 0x01 }, /* Lin and Win think different about UV order */ | ||
603 | { 0x16, 0x03 }, | ||
604 | { 0x17, 0x38 }, /* was 0x2f, new from windrv 090403 */ | ||
605 | { 0x18, 0xea }, /* was 0xcf, new from windrv 090403 */ | ||
606 | { 0x19, 0x02 }, /* was 0x06, new from windrv 090403 */ | ||
607 | { 0x1a, 0xf5 }, | ||
608 | { 0x1b, 0x00 }, | ||
609 | { 0x20, 0xd0 }, /* was 0x90, new from windrv 090403 */ | ||
610 | { 0x23, 0xc0 }, /* was 0x00, new from windrv 090403 */ | ||
611 | { 0x24, 0x30 }, /* was 0x1d, new from windrv 090403 */ | ||
612 | { 0x25, 0x50 }, /* was 0x57, new from windrv 090403 */ | ||
613 | { 0x26, 0xa2 }, | ||
614 | { 0x27, 0xea }, | ||
615 | { 0x28, 0x00 }, | ||
616 | { 0x29, 0x00 }, | ||
617 | { 0x2a, 0x80 }, | ||
618 | { 0x2b, 0xc8 }, /* was 0xcc, new from windrv 090403 */ | ||
619 | { 0x2c, 0xac }, | ||
620 | { 0x2d, 0x45 }, /* was 0xd5, new from windrv 090403 */ | ||
621 | { 0x2e, 0x80 }, | ||
622 | { 0x2f, 0x14 }, /* was 0x01, new from windrv 090403 */ | ||
623 | { 0x4c, 0x00 }, | ||
624 | { 0x4d, 0x30 }, /* was 0x10, new from windrv 090403 */ | ||
625 | { 0x60, 0x02 }, /* was 0x01, new from windrv 090403 */ | ||
626 | { 0x61, 0x00 }, /* was 0x09, new from windrv 090403 */ | ||
627 | { 0x62, 0x5f }, /* was 0xd7, new from windrv 090403 */ | ||
628 | { 0x63, 0xff }, | ||
629 | { 0x64, 0x53 }, /* new windrv 090403 says 0x57, | ||
630 | * maybe thats wrong */ | ||
631 | { 0x65, 0x00 }, | ||
632 | { 0x66, 0x55 }, | ||
633 | { 0x67, 0xb0 }, | ||
634 | { 0x68, 0xc0 }, /* was 0xaf, new from windrv 090403 */ | ||
635 | { 0x69, 0x02 }, | ||
636 | { 0x6a, 0x22 }, | ||
637 | { 0x6b, 0x00 }, | ||
638 | { 0x6c, 0x99 }, /* was 0x80, old windrv says 0x00, but | ||
639 | deleting bit7 colors the first images red */ | ||
640 | { 0x6d, 0x11 }, /* was 0x00, new from windrv 090403 */ | ||
641 | { 0x6e, 0x11 }, /* was 0x00, new from windrv 090403 */ | ||
642 | { 0x6f, 0x01 }, | ||
643 | { 0x70, 0x8b }, | ||
644 | { 0x71, 0x00 }, | ||
645 | { 0x72, 0x14 }, | ||
646 | { 0x73, 0x54 }, | ||
647 | { 0x74, 0x00 },/* 0x60? - was 0x00, new from windrv 090403 */ | ||
648 | { 0x75, 0x0e }, | ||
649 | { 0x76, 0x02 }, /* was 0x02, new from windrv 090403 */ | ||
650 | { 0x77, 0xff }, | ||
651 | { 0x78, 0x80 }, | ||
652 | { 0x79, 0x80 }, | ||
653 | { 0x7a, 0x80 }, | ||
654 | { 0x7b, 0x10 }, /* was 0x13, new from windrv 090403 */ | ||
655 | { 0x7c, 0x00 }, | ||
656 | { 0x7d, 0x08 }, /* was 0x09, new from windrv 090403 */ | ||
657 | { 0x7e, 0x08 }, /* was 0xc0, new from windrv 090403 */ | ||
658 | { 0x7f, 0xfb }, | ||
659 | { 0x80, 0x28 }, | ||
660 | { 0x81, 0x00 }, | ||
661 | { 0x82, 0x23 }, | ||
662 | { 0x83, 0x0b }, | ||
663 | { 0x84, 0x00 }, | ||
664 | { 0x85, 0x62 }, /* was 0x61, new from windrv 090403 */ | ||
665 | { 0x86, 0xc9 }, | ||
666 | { 0x87, 0x00 }, | ||
667 | { 0x88, 0x00 }, | ||
668 | { 0x89, 0x01 }, | ||
669 | { 0x12, 0x20 }, | ||
670 | { 0x12, 0x25 }, /* was 0x24, new from windrv 090403 */ | ||
671 | }; | ||
672 | |||
673 | PDEBUG(D_PROBE, "starting ov8xx0 configuration"); | ||
674 | |||
675 | if (init_ov_sensor(sd) < 0) | ||
676 | PDEBUG(D_ERR|D_PROBE, "Failed to read sensor ID"); | ||
677 | else | ||
678 | PDEBUG(D_PROBE, "OV86x0 initialized"); | ||
679 | |||
680 | /* Detect sensor (sub)type */ | ||
681 | rc = i2c_r(sd, OV7610_REG_COM_I); | ||
682 | if (rc < 0) { | ||
683 | PDEBUG(D_ERR, "Error detecting sensor type"); | ||
684 | return -1; | ||
685 | } | ||
686 | if ((rc & 3) == 1) { | ||
687 | PDEBUG(D_PROBE, "Sensor is an OV8610"); | ||
688 | sd->sensor = SEN_OV8610; | ||
689 | } else { | ||
690 | PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3); | ||
691 | return -1; | ||
692 | } | ||
693 | PDEBUG(D_PROBE, "Writing 8610 registers"); | ||
694 | if (write_i2c_regvals(sd, | ||
695 | norm_8610, | ||
696 | sizeof norm_8610 / sizeof norm_8610[0])) | ||
697 | return -1; | ||
698 | |||
699 | /* Set sensor-specific vars */ | ||
700 | sd->maxwidth = 640; | ||
701 | sd->maxheight = 480; | ||
702 | return 0; | ||
703 | } | ||
704 | |||
705 | /* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses | ||
706 | * the same register settings as the OV7610, since they are very similar. | ||
707 | */ | ||
708 | static int ov7xx0_configure(struct sd *sd) | ||
709 | { | ||
710 | int rc, high, low; | ||
711 | |||
712 | /* Lawrence Glaister <lg@jfm.bc.ca> reports: | ||
713 | * | ||
714 | * Register 0x0f in the 7610 has the following effects: | ||
715 | * | ||
716 | * 0x85 (AEC method 1): Best overall, good contrast range | ||
717 | * 0x45 (AEC method 2): Very overexposed | ||
718 | * 0xa5 (spec sheet default): Ok, but the black level is | ||
719 | * shifted resulting in loss of contrast | ||
720 | * 0x05 (old driver setting): very overexposed, too much | ||
721 | * contrast | ||
722 | */ | ||
723 | static const struct ov_i2c_regvals norm_7610[] = { | ||
724 | { 0x10, 0xff }, | ||
725 | { 0x16, 0x06 }, | ||
726 | { 0x28, 0x24 }, | ||
727 | { 0x2b, 0xac }, | ||
728 | { 0x12, 0x00 }, | ||
729 | { 0x38, 0x81 }, | ||
730 | { 0x28, 0x24 }, /* 0c */ | ||
731 | { 0x0f, 0x85 }, /* lg's setting */ | ||
732 | { 0x15, 0x01 }, | ||
733 | { 0x20, 0x1c }, | ||
734 | { 0x23, 0x2a }, | ||
735 | { 0x24, 0x10 }, | ||
736 | { 0x25, 0x8a }, | ||
737 | { 0x26, 0xa2 }, | ||
738 | { 0x27, 0xc2 }, | ||
739 | { 0x2a, 0x04 }, | ||
740 | { 0x2c, 0xfe }, | ||
741 | { 0x2d, 0x93 }, | ||
742 | { 0x30, 0x71 }, | ||
743 | { 0x31, 0x60 }, | ||
744 | { 0x32, 0x26 }, | ||
745 | { 0x33, 0x20 }, | ||
746 | { 0x34, 0x48 }, | ||
747 | { 0x12, 0x24 }, | ||
748 | { 0x11, 0x01 }, | ||
749 | { 0x0c, 0x24 }, | ||
750 | { 0x0d, 0x24 }, | ||
751 | }; | ||
752 | |||
753 | static const struct ov_i2c_regvals norm_7620[] = { | ||
754 | { 0x00, 0x00 }, /* gain */ | ||
755 | { 0x01, 0x80 }, /* blue gain */ | ||
756 | { 0x02, 0x80 }, /* red gain */ | ||
757 | { 0x03, 0xc0 }, /* OV7670_REG_VREF */ | ||
758 | { 0x06, 0x60 }, | ||
759 | { 0x07, 0x00 }, | ||
760 | { 0x0c, 0x24 }, | ||
761 | { 0x0c, 0x24 }, | ||
762 | { 0x0d, 0x24 }, | ||
763 | { 0x11, 0x01 }, | ||
764 | { 0x12, 0x24 }, | ||
765 | { 0x13, 0x01 }, | ||
766 | { 0x14, 0x84 }, | ||
767 | { 0x15, 0x01 }, | ||
768 | { 0x16, 0x03 }, | ||
769 | { 0x17, 0x2f }, | ||
770 | { 0x18, 0xcf }, | ||
771 | { 0x19, 0x06 }, | ||
772 | { 0x1a, 0xf5 }, | ||
773 | { 0x1b, 0x00 }, | ||
774 | { 0x20, 0x18 }, | ||
775 | { 0x21, 0x80 }, | ||
776 | { 0x22, 0x80 }, | ||
777 | { 0x23, 0x00 }, | ||
778 | { 0x26, 0xa2 }, | ||
779 | { 0x27, 0xea }, | ||
780 | { 0x28, 0x20 }, | ||
781 | { 0x29, 0x00 }, | ||
782 | { 0x2a, 0x10 }, | ||
783 | { 0x2b, 0x00 }, | ||
784 | { 0x2c, 0x88 }, | ||
785 | { 0x2d, 0x91 }, | ||
786 | { 0x2e, 0x80 }, | ||
787 | { 0x2f, 0x44 }, | ||
788 | { 0x60, 0x27 }, | ||
789 | { 0x61, 0x02 }, | ||
790 | { 0x62, 0x5f }, | ||
791 | { 0x63, 0xd5 }, | ||
792 | { 0x64, 0x57 }, | ||
793 | { 0x65, 0x83 }, | ||
794 | { 0x66, 0x55 }, | ||
795 | { 0x67, 0x92 }, | ||
796 | { 0x68, 0xcf }, | ||
797 | { 0x69, 0x76 }, | ||
798 | { 0x6a, 0x22 }, | ||
799 | { 0x6b, 0x00 }, | ||
800 | { 0x6c, 0x02 }, | ||
801 | { 0x6d, 0x44 }, | ||
802 | { 0x6e, 0x80 }, | ||
803 | { 0x6f, 0x1d }, | ||
804 | { 0x70, 0x8b }, | ||
805 | { 0x71, 0x00 }, | ||
806 | { 0x72, 0x14 }, | ||
807 | { 0x73, 0x54 }, | ||
808 | { 0x74, 0x00 }, | ||
809 | { 0x75, 0x8e }, | ||
810 | { 0x76, 0x00 }, | ||
811 | { 0x77, 0xff }, | ||
812 | { 0x78, 0x80 }, | ||
813 | { 0x79, 0x80 }, | ||
814 | { 0x7a, 0x80 }, | ||
815 | { 0x7b, 0xe2 }, | ||
816 | { 0x7c, 0x00 }, | ||
817 | }; | ||
818 | |||
819 | /* 7640 and 7648. The defaults should be OK for most registers. */ | ||
820 | static const struct ov_i2c_regvals norm_7640[] = { | ||
821 | { 0x12, 0x80 }, | ||
822 | { 0x12, 0x14 }, | ||
823 | }; | ||
824 | |||
825 | /* 7670. Defaults taken from OmniVision provided data, | ||
826 | * as provided by Jonathan Corbet of OLPC */ | ||
827 | static const struct ov_i2c_regvals norm_7670[] = { | ||
828 | { OV7670_REG_COM7, OV7670_COM7_RESET }, | ||
829 | { OV7670_REG_TSLB, 0x04 }, /* OV */ | ||
830 | { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */ | ||
831 | { OV7670_REG_CLKRC, 0x1 }, | ||
832 | /* | ||
833 | * Set the hardware window. These values from OV don't entirely | ||
834 | * make sense - hstop is less than hstart. But they work... | ||
835 | */ | ||
836 | { OV7670_REG_HSTART, 0x13 }, { OV7670_REG_HSTOP, 0x01 }, | ||
837 | { OV7670_REG_HREF, 0xb6 }, { OV7670_REG_VSTART, 0x02 }, | ||
838 | { OV7670_REG_VSTOP, 0x7a }, { OV7670_REG_VREF, 0x0a }, | ||
839 | |||
840 | { OV7670_REG_COM3, 0 }, { OV7670_REG_COM14, 0 }, | ||
841 | /* Mystery scaling numbers */ | ||
842 | { 0x70, 0x3a }, { 0x71, 0x35 }, | ||
843 | { 0x72, 0x11 }, { 0x73, 0xf0 }, | ||
844 | { 0xa2, 0x02 }, | ||
845 | /* jfm */ | ||
846 | /* { OV7670_REG_COM10, 0x0 }, */ | ||
847 | |||
848 | /* Gamma curve values */ | ||
849 | { 0x7a, 0x20 }, | ||
850 | /* jfm:win 7b=1c */ | ||
851 | { 0x7b, 0x10 }, | ||
852 | /* jfm:win 7c=28 */ | ||
853 | { 0x7c, 0x1e }, | ||
854 | /* jfm:win 7d=3c */ | ||
855 | { 0x7d, 0x35 }, | ||
856 | { 0x7e, 0x5a }, { 0x7f, 0x69 }, | ||
857 | { 0x80, 0x76 }, { 0x81, 0x80 }, | ||
858 | { 0x82, 0x88 }, { 0x83, 0x8f }, | ||
859 | { 0x84, 0x96 }, { 0x85, 0xa3 }, | ||
860 | { 0x86, 0xaf }, { 0x87, 0xc4 }, | ||
861 | { 0x88, 0xd7 }, { 0x89, 0xe8 }, | ||
862 | |||
863 | /* AGC and AEC parameters. Note we start by disabling those features, | ||
864 | then turn them only after tweaking the values. */ | ||
865 | { OV7670_REG_COM8, OV7670_COM8_FASTAEC | ||
866 | | OV7670_COM8_AECSTEP | ||
867 | | OV7670_COM8_BFILT }, | ||
868 | { OV7670_REG_GAIN, 0 }, { OV7670_REG_AECH, 0 }, | ||
869 | { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */ | ||
870 | /* jfm:win 14=38 */ | ||
871 | { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */ | ||
872 | { OV7670_REG_BD50MAX, 0x05 }, { OV7670_REG_BD60MAX, 0x07 }, | ||
873 | { OV7670_REG_AEW, 0x95 }, { OV7670_REG_AEB, 0x33 }, | ||
874 | { OV7670_REG_VPT, 0xe3 }, { OV7670_REG_HAECC1, 0x78 }, | ||
875 | { OV7670_REG_HAECC2, 0x68 }, | ||
876 | /* jfm:win a1=0b */ | ||
877 | { 0xa1, 0x03 }, /* magic */ | ||
878 | { OV7670_REG_HAECC3, 0xd8 }, { OV7670_REG_HAECC4, 0xd8 }, | ||
879 | { OV7670_REG_HAECC5, 0xf0 }, { OV7670_REG_HAECC6, 0x90 }, | ||
880 | { OV7670_REG_HAECC7, 0x94 }, | ||
881 | { OV7670_REG_COM8, OV7670_COM8_FASTAEC | ||
882 | | OV7670_COM8_AECSTEP | ||
883 | | OV7670_COM8_BFILT | ||
884 | | OV7670_COM8_AGC | ||
885 | | OV7670_COM8_AEC }, | ||
886 | |||
887 | /* Almost all of these are magic "reserved" values. */ | ||
888 | { OV7670_REG_COM5, 0x61 }, { OV7670_REG_COM6, 0x4b }, | ||
889 | { 0x16, 0x02 }, | ||
890 | /* jfm */ | ||
891 | /* { OV7670_REG_MVFP, 0x07|OV7670_MVFP_MIRROR }, */ | ||
892 | { OV7670_REG_MVFP, 0x07 }, | ||
893 | { 0x21, 0x02 }, { 0x22, 0x91 }, | ||
894 | { 0x29, 0x07 }, { 0x33, 0x0b }, | ||
895 | { 0x35, 0x0b }, { 0x37, 0x1d }, | ||
896 | { 0x38, 0x71 }, { 0x39, 0x2a }, | ||
897 | { OV7670_REG_COM12, 0x78 }, { 0x4d, 0x40 }, | ||
898 | { 0x4e, 0x20 }, { OV7670_REG_GFIX, 0 }, | ||
899 | { 0x6b, 0x4a }, { 0x74, 0x10 }, | ||
900 | { 0x8d, 0x4f }, { 0x8e, 0 }, | ||
901 | { 0x8f, 0 }, { 0x90, 0 }, | ||
902 | { 0x91, 0 }, { 0x96, 0 }, | ||
903 | { 0x9a, 0 }, { 0xb0, 0x84 }, | ||
904 | { 0xb1, 0x0c }, { 0xb2, 0x0e }, | ||
905 | { 0xb3, 0x82 }, { 0xb8, 0x0a }, | ||
906 | |||
907 | /* More reserved magic, some of which tweaks white balance */ | ||
908 | { 0x43, 0x0a }, { 0x44, 0xf0 }, | ||
909 | { 0x45, 0x34 }, { 0x46, 0x58 }, | ||
910 | { 0x47, 0x28 }, { 0x48, 0x3a }, | ||
911 | { 0x59, 0x88 }, { 0x5a, 0x88 }, | ||
912 | { 0x5b, 0x44 }, { 0x5c, 0x67 }, | ||
913 | { 0x5d, 0x49 }, { 0x5e, 0x0e }, | ||
914 | { 0x6c, 0x0a }, { 0x6d, 0x55 }, | ||
915 | { 0x6e, 0x11 }, { 0x6f, 0x9f }, | ||
916 | /* "9e for advance AWB" */ | ||
917 | { 0x6a, 0x40 }, { OV7670_REG_BLUE, 0x40 }, | ||
918 | { OV7670_REG_RED, 0x60 }, | ||
919 | { OV7670_REG_COM8, OV7670_COM8_FASTAEC | ||
920 | | OV7670_COM8_AECSTEP | ||
921 | | OV7670_COM8_BFILT | ||
922 | | OV7670_COM8_AGC | ||
923 | | OV7670_COM8_AEC | ||
924 | | OV7670_COM8_AWB }, | ||
925 | |||
926 | /* Matrix coefficients */ | ||
927 | { 0x4f, 0x80 }, { 0x50, 0x80 }, | ||
928 | { 0x51, 0 }, { 0x52, 0x22 }, | ||
929 | { 0x53, 0x5e }, { 0x54, 0x80 }, | ||
930 | { 0x58, 0x9e }, | ||
931 | |||
932 | { OV7670_REG_COM16, OV7670_COM16_AWBGAIN }, | ||
933 | { OV7670_REG_EDGE, 0 }, | ||
934 | { 0x75, 0x05 }, { 0x76, 0xe1 }, | ||
935 | { 0x4c, 0 }, { 0x77, 0x01 }, | ||
936 | { OV7670_REG_COM13, 0xc3 }, { 0x4b, 0x09 }, | ||
937 | { 0xc9, 0x60 }, { OV7670_REG_COM16, 0x38 }, | ||
938 | { 0x56, 0x40 }, | ||
939 | |||
940 | { 0x34, 0x11 }, | ||
941 | { OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO }, | ||
942 | { 0xa4, 0x88 }, { 0x96, 0 }, | ||
943 | { 0x97, 0x30 }, { 0x98, 0x20 }, | ||
944 | { 0x99, 0x30 }, { 0x9a, 0x84 }, | ||
945 | { 0x9b, 0x29 }, { 0x9c, 0x03 }, | ||
946 | { 0x9d, 0x4c }, { 0x9e, 0x3f }, | ||
947 | { 0x78, 0x04 }, | ||
948 | |||
949 | /* Extra-weird stuff. Some sort of multiplexor register */ | ||
950 | { 0x79, 0x01 }, { 0xc8, 0xf0 }, | ||
951 | { 0x79, 0x0f }, { 0xc8, 0x00 }, | ||
952 | { 0x79, 0x10 }, { 0xc8, 0x7e }, | ||
953 | { 0x79, 0x0a }, { 0xc8, 0x80 }, | ||
954 | { 0x79, 0x0b }, { 0xc8, 0x01 }, | ||
955 | { 0x79, 0x0c }, { 0xc8, 0x0f }, | ||
956 | { 0x79, 0x0d }, { 0xc8, 0x20 }, | ||
957 | { 0x79, 0x09 }, { 0xc8, 0x80 }, | ||
958 | { 0x79, 0x02 }, { 0xc8, 0xc0 }, | ||
959 | { 0x79, 0x03 }, { 0xc8, 0x40 }, | ||
960 | { 0x79, 0x05 }, { 0xc8, 0x30 }, | ||
961 | { 0x79, 0x26 }, | ||
962 | |||
963 | /* Format YUV422 */ | ||
964 | { OV7670_REG_COM7, OV7670_COM7_YUV }, /* Selects YUV mode */ | ||
965 | { OV7670_REG_RGB444, 0 }, /* No RGB444 please */ | ||
966 | { OV7670_REG_COM1, 0 }, | ||
967 | { OV7670_REG_COM15, OV7670_COM15_R00FF }, | ||
968 | { OV7670_REG_COM9, 0x18 }, | ||
969 | /* 4x gain ceiling; 0x8 is reserved bit */ | ||
970 | { 0x4f, 0x80 }, /* "matrix coefficient 1" */ | ||
971 | { 0x50, 0x80 }, /* "matrix coefficient 2" */ | ||
972 | { 0x52, 0x22 }, /* "matrix coefficient 4" */ | ||
973 | { 0x53, 0x5e }, /* "matrix coefficient 5" */ | ||
974 | { 0x54, 0x80 }, /* "matrix coefficient 6" */ | ||
975 | { OV7670_REG_COM13, OV7670_COM13_GAMMA|OV7670_COM13_UVSAT }, | ||
976 | }; | ||
977 | |||
978 | PDEBUG(D_PROBE, "starting OV7xx0 configuration"); | ||
979 | |||
980 | /* jfm:already done? */ | ||
981 | if (init_ov_sensor(sd) < 0) | ||
982 | PDEBUG(D_ERR, "Failed to read sensor ID"); | ||
983 | else | ||
984 | PDEBUG(D_PROBE, "OV7xx0 initialized"); | ||
985 | |||
986 | /* Detect sensor (sub)type */ | ||
987 | rc = i2c_r(sd, OV7610_REG_COM_I); | ||
988 | |||
989 | /* add OV7670 here | ||
990 | * it appears to be wrongly detected as a 7610 by default */ | ||
991 | if (rc < 0) { | ||
992 | PDEBUG(D_ERR, "Error detecting sensor type"); | ||
993 | return -1; | ||
994 | } | ||
995 | if ((rc & 3) == 3) { | ||
996 | /* quick hack to make OV7670s work */ | ||
997 | high = i2c_r(sd, 0x0a); | ||
998 | low = i2c_r(sd, 0x0b); | ||
999 | /* info("%x, %x", high, low); */ | ||
1000 | if (high == 0x76 && low == 0x73) { | ||
1001 | PDEBUG(D_PROBE, "Sensor is an OV7670"); | ||
1002 | sd->sensor = SEN_OV7670; | ||
1003 | } else { | ||
1004 | PDEBUG(D_PROBE, "Sensor is an OV7610"); | ||
1005 | sd->sensor = SEN_OV7610; | ||
1006 | } | ||
1007 | } else if ((rc & 3) == 1) { | ||
1008 | /* I don't know what's different about the 76BE yet. */ | ||
1009 | if (i2c_r(sd, 0x15) & 1) | ||
1010 | PDEBUG(D_PROBE, "Sensor is an OV7620AE"); | ||
1011 | else | ||
1012 | PDEBUG(D_PROBE, "Sensor is an OV76BE"); | ||
1013 | |||
1014 | /* OV511+ will return all zero isoc data unless we | ||
1015 | * configure the sensor as a 7620. Someone needs to | ||
1016 | * find the exact reg. setting that causes this. */ | ||
1017 | sd->sensor = SEN_OV76BE; | ||
1018 | } else if ((rc & 3) == 0) { | ||
1019 | /* try to read product id registers */ | ||
1020 | high = i2c_r(sd, 0x0a); | ||
1021 | if (high < 0) { | ||
1022 | PDEBUG(D_ERR, "Error detecting camera chip PID"); | ||
1023 | return high; | ||
1024 | } | ||
1025 | low = i2c_r(sd, 0x0b); | ||
1026 | if (low < 0) { | ||
1027 | PDEBUG(D_ERR, "Error detecting camera chip VER"); | ||
1028 | return low; | ||
1029 | } | ||
1030 | if (high == 0x76) { | ||
1031 | if (low == 0x30) { | ||
1032 | PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635"); | ||
1033 | sd->sensor = SEN_OV7630; | ||
1034 | } else if (low == 0x40) { | ||
1035 | PDEBUG(D_PROBE, "Sensor is an OV7645"); | ||
1036 | sd->sensor = SEN_OV7640; /* FIXME */ | ||
1037 | } else if (low == 0x45) { | ||
1038 | PDEBUG(D_PROBE, "Sensor is an OV7645B"); | ||
1039 | sd->sensor = SEN_OV7640; /* FIXME */ | ||
1040 | } else if (low == 0x48) { | ||
1041 | PDEBUG(D_PROBE, "Sensor is an OV7648"); | ||
1042 | sd->sensor = SEN_OV7640; /* FIXME */ | ||
1043 | } else { | ||
1044 | PDEBUG(D_PROBE, "Unknown sensor: 0x76%X", low); | ||
1045 | return -1; | ||
1046 | } | ||
1047 | } else { | ||
1048 | PDEBUG(D_PROBE, "Sensor is an OV7620"); | ||
1049 | sd->sensor = SEN_OV7620; | ||
1050 | } | ||
1051 | } else { | ||
1052 | PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3); | ||
1053 | return -1; | ||
1054 | } | ||
1055 | |||
1056 | if (sd->sensor == SEN_OV7620) { | ||
1057 | PDEBUG(D_PROBE, "Writing 7620 registers"); | ||
1058 | if (write_i2c_regvals(sd, norm_7620, | ||
1059 | sizeof norm_7620 / sizeof norm_7620[0])) | ||
1060 | return -1; | ||
1061 | } else if (sd->sensor == SEN_OV7630) { | ||
1062 | PDEBUG(D_ERR, "7630 is not supported by this driver version"); | ||
1063 | return -1; | ||
1064 | } else if (sd->sensor == SEN_OV7640) { | ||
1065 | PDEBUG(D_PROBE, "Writing 7640 registers"); | ||
1066 | if (write_i2c_regvals(sd, norm_7640, | ||
1067 | sizeof norm_7640 / sizeof norm_7640[0])) | ||
1068 | return -1; | ||
1069 | } else if (sd->sensor == SEN_OV7670) { | ||
1070 | PDEBUG(D_PROBE, "Writing 7670 registers"); | ||
1071 | if (write_i2c_regvals(sd, norm_7670, | ||
1072 | sizeof norm_7670 / sizeof norm_7670[0])) | ||
1073 | return -1; | ||
1074 | } else { | ||
1075 | PDEBUG(D_PROBE, "Writing 7610 registers"); | ||
1076 | if (write_i2c_regvals(sd, norm_7610, | ||
1077 | sizeof norm_7610 / sizeof norm_7610[0])) | ||
1078 | return -1; | ||
1079 | } | ||
1080 | |||
1081 | /* Set sensor-specific vars */ | ||
1082 | sd->maxwidth = 640; | ||
1083 | sd->maxheight = 480; | ||
1084 | return 0; | ||
1085 | } | ||
1086 | |||
1087 | /* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */ | ||
1088 | static int ov6xx0_configure(struct sd *sd) | ||
1089 | { | ||
1090 | int rc; | ||
1091 | static const struct ov_i2c_regvals norm_6x20[] = { | ||
1092 | { 0x12, 0x80 }, /* reset */ | ||
1093 | { 0x11, 0x01 }, | ||
1094 | { 0x03, 0x60 }, | ||
1095 | { 0x05, 0x7f }, /* For when autoadjust is off */ | ||
1096 | { 0x07, 0xa8 }, | ||
1097 | /* The ratio of 0x0c and 0x0d controls the white point */ | ||
1098 | { 0x0c, 0x24 }, | ||
1099 | { 0x0d, 0x24 }, | ||
1100 | { 0x0f, 0x15 }, /* COMS */ | ||
1101 | { 0x10, 0x75 }, /* AEC Exposure time */ | ||
1102 | { 0x12, 0x24 }, /* Enable AGC */ | ||
1103 | { 0x14, 0x04 }, | ||
1104 | /* 0x16: 0x06 helps frame stability with moving objects */ | ||
1105 | { 0x16, 0x06 }, | ||
1106 | /* { 0x20, 0x30 }, * Aperture correction enable */ | ||
1107 | { 0x26, 0xb2 }, /* BLC enable */ | ||
1108 | /* 0x28: 0x05 Selects RGB format if RGB on */ | ||
1109 | { 0x28, 0x05 }, | ||
1110 | { 0x2a, 0x04 }, /* Disable framerate adjust */ | ||
1111 | /* { 0x2b, 0xac }, * Framerate; Set 2a[7] first */ | ||
1112 | { 0x2d, 0x99 }, | ||
1113 | { 0x33, 0xa0 }, /* Color Processing Parameter */ | ||
1114 | { 0x34, 0xd2 }, /* Max A/D range */ | ||
1115 | { 0x38, 0x8b }, | ||
1116 | { 0x39, 0x40 }, | ||
1117 | |||
1118 | { 0x3c, 0x39 }, /* Enable AEC mode changing */ | ||
1119 | { 0x3c, 0x3c }, /* Change AEC mode */ | ||
1120 | { 0x3c, 0x24 }, /* Disable AEC mode changing */ | ||
1121 | |||
1122 | { 0x3d, 0x80 }, | ||
1123 | /* These next two registers (0x4a, 0x4b) are undocumented. | ||
1124 | * They control the color balance */ | ||
1125 | { 0x4a, 0x80 }, | ||
1126 | { 0x4b, 0x80 }, | ||
1127 | { 0x4d, 0xd2 }, /* This reduces noise a bit */ | ||
1128 | { 0x4e, 0xc1 }, | ||
1129 | { 0x4f, 0x04 }, | ||
1130 | /* Do 50-53 have any effect? */ | ||
1131 | /* Toggle 0x12[2] off and on here? */ | ||
1132 | }; | ||
1133 | |||
1134 | static const struct ov_i2c_regvals norm_6x30[] = { | ||
1135 | { 0x12, 0x80 }, /* Reset */ | ||
1136 | { 0x00, 0x1f }, /* Gain */ | ||
1137 | { 0x01, 0x99 }, /* Blue gain */ | ||
1138 | { 0x02, 0x7c }, /* Red gain */ | ||
1139 | { 0x03, 0xc0 }, /* Saturation */ | ||
1140 | { 0x05, 0x0a }, /* Contrast */ | ||
1141 | { 0x06, 0x95 }, /* Brightness */ | ||
1142 | { 0x07, 0x2d }, /* Sharpness */ | ||
1143 | { 0x0c, 0x20 }, | ||
1144 | { 0x0d, 0x20 }, | ||
1145 | { 0x0e, 0x20 }, | ||
1146 | { 0x0f, 0x05 }, | ||
1147 | { 0x10, 0x9a }, | ||
1148 | { 0x11, 0x00 }, /* Pixel clock = fastest */ | ||
1149 | { 0x12, 0x24 }, /* Enable AGC and AWB */ | ||
1150 | { 0x13, 0x21 }, | ||
1151 | { 0x14, 0x80 }, | ||
1152 | { 0x15, 0x01 }, | ||
1153 | { 0x16, 0x03 }, | ||
1154 | { 0x17, 0x38 }, | ||
1155 | { 0x18, 0xea }, | ||
1156 | { 0x19, 0x04 }, | ||
1157 | { 0x1a, 0x93 }, | ||
1158 | { 0x1b, 0x00 }, | ||
1159 | { 0x1e, 0xc4 }, | ||
1160 | { 0x1f, 0x04 }, | ||
1161 | { 0x20, 0x20 }, | ||
1162 | { 0x21, 0x10 }, | ||
1163 | { 0x22, 0x88 }, | ||
1164 | { 0x23, 0xc0 }, /* Crystal circuit power level */ | ||
1165 | { 0x25, 0x9a }, /* Increase AEC black ratio */ | ||
1166 | { 0x26, 0xb2 }, /* BLC enable */ | ||
1167 | { 0x27, 0xa2 }, | ||
1168 | { 0x28, 0x00 }, | ||
1169 | { 0x29, 0x00 }, | ||
1170 | { 0x2a, 0x84 }, /* 60 Hz power */ | ||
1171 | { 0x2b, 0xa8 }, /* 60 Hz power */ | ||
1172 | { 0x2c, 0xa0 }, | ||
1173 | { 0x2d, 0x95 }, /* Enable auto-brightness */ | ||
1174 | { 0x2e, 0x88 }, | ||
1175 | { 0x33, 0x26 }, | ||
1176 | { 0x34, 0x03 }, | ||
1177 | { 0x36, 0x8f }, | ||
1178 | { 0x37, 0x80 }, | ||
1179 | { 0x38, 0x83 }, | ||
1180 | { 0x39, 0x80 }, | ||
1181 | { 0x3a, 0x0f }, | ||
1182 | { 0x3b, 0x3c }, | ||
1183 | { 0x3c, 0x1a }, | ||
1184 | { 0x3d, 0x80 }, | ||
1185 | { 0x3e, 0x80 }, | ||
1186 | { 0x3f, 0x0e }, | ||
1187 | { 0x40, 0x00 }, /* White bal */ | ||
1188 | { 0x41, 0x00 }, /* White bal */ | ||
1189 | { 0x42, 0x80 }, | ||
1190 | { 0x43, 0x3f }, /* White bal */ | ||
1191 | { 0x44, 0x80 }, | ||
1192 | { 0x45, 0x20 }, | ||
1193 | { 0x46, 0x20 }, | ||
1194 | { 0x47, 0x80 }, | ||
1195 | { 0x48, 0x7f }, | ||
1196 | { 0x49, 0x00 }, | ||
1197 | { 0x4a, 0x00 }, | ||
1198 | { 0x4b, 0x80 }, | ||
1199 | { 0x4c, 0xd0 }, | ||
1200 | { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */ | ||
1201 | { 0x4e, 0x40 }, | ||
1202 | { 0x4f, 0x07 }, /* UV avg., col. killer: max */ | ||
1203 | { 0x50, 0xff }, | ||
1204 | { 0x54, 0x23 }, /* Max AGC gain: 18dB */ | ||
1205 | { 0x55, 0xff }, | ||
1206 | { 0x56, 0x12 }, | ||
1207 | { 0x57, 0x81 }, | ||
1208 | { 0x58, 0x75 }, | ||
1209 | { 0x59, 0x01 }, /* AGC dark current comp.: +1 */ | ||
1210 | { 0x5a, 0x2c }, | ||
1211 | { 0x5b, 0x0f }, /* AWB chrominance levels */ | ||
1212 | { 0x5c, 0x10 }, | ||
1213 | { 0x3d, 0x80 }, | ||
1214 | { 0x27, 0xa6 }, | ||
1215 | { 0x12, 0x20 }, /* Toggle AWB */ | ||
1216 | { 0x12, 0x24 }, | ||
1217 | }; | ||
1218 | |||
1219 | PDEBUG(D_PROBE, "starting sensor configuration"); | ||
1220 | |||
1221 | if (init_ov_sensor(sd) < 0) { | ||
1222 | PDEBUG(D_ERR, "Failed to read sensor ID."); | ||
1223 | return -1; | ||
1224 | } | ||
1225 | PDEBUG(D_PROBE, "OV6xx0 sensor detected"); | ||
1226 | |||
1227 | /* Detect sensor (sub)type */ | ||
1228 | rc = i2c_r(sd, OV7610_REG_COM_I); | ||
1229 | if (rc < 0) { | ||
1230 | PDEBUG(D_ERR, "Error detecting sensor type"); | ||
1231 | return -1; | ||
1232 | } | ||
1233 | |||
1234 | /* Ugh. The first two bits are the version bits, but | ||
1235 | * the entire register value must be used. I guess OVT | ||
1236 | * underestimated how many variants they would make. */ | ||
1237 | if (rc == 0x00) { | ||
1238 | sd->sensor = SEN_OV6630; | ||
1239 | PDEBUG(D_ERR, | ||
1240 | "WARNING: Sensor is an OV66308. Your camera may have"); | ||
1241 | PDEBUG(D_ERR, "been misdetected in previous driver versions."); | ||
1242 | } else if (rc == 0x01) { | ||
1243 | sd->sensor = SEN_OV6620; | ||
1244 | PDEBUG(D_PROBE, "Sensor is an OV6620"); | ||
1245 | } else if (rc == 0x02) { | ||
1246 | sd->sensor = SEN_OV6630; | ||
1247 | PDEBUG(D_PROBE, "Sensor is an OV66308AE"); | ||
1248 | } else if (rc == 0x03) { | ||
1249 | sd->sensor = SEN_OV6630; | ||
1250 | PDEBUG(D_PROBE, "Sensor is an OV66308AF"); | ||
1251 | } else if (rc == 0x90) { | ||
1252 | sd->sensor = SEN_OV6630; | ||
1253 | PDEBUG(D_ERR, | ||
1254 | "WARNING: Sensor is an OV66307. Your camera may have"); | ||
1255 | PDEBUG(D_ERR, "been misdetected in previous driver versions."); | ||
1256 | } else { | ||
1257 | PDEBUG(D_ERR, "FATAL: Unknown sensor version: 0x%02x", rc); | ||
1258 | return -1; | ||
1259 | } | ||
1260 | |||
1261 | /* Set sensor-specific vars */ | ||
1262 | sd->maxwidth = 352; | ||
1263 | sd->maxheight = 288; | ||
1264 | |||
1265 | if (sd->sensor == SEN_OV6620) { | ||
1266 | PDEBUG(D_PROBE, "Writing 6x20 registers"); | ||
1267 | if (write_i2c_regvals(sd, norm_6x20, | ||
1268 | sizeof norm_6x20 / sizeof norm_6x20[0])) | ||
1269 | return -1; | ||
1270 | } else { | ||
1271 | PDEBUG(D_PROBE, "Writing 6x30 registers"); | ||
1272 | if (write_i2c_regvals(sd, norm_6x30, | ||
1273 | sizeof norm_6x30 / sizeof norm_6x30[0])) | ||
1274 | return -1; | ||
1275 | } | ||
1276 | return 0; | ||
1277 | } | ||
1278 | |||
1279 | /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ | ||
1280 | static void ov51x_led_control(struct sd *sd, int on) | ||
1281 | { | ||
1282 | PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off"); | ||
1283 | |||
1284 | /* if (sd->bridge == BRG_OV511PLUS) */ | ||
1285 | /* reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0); */ | ||
1286 | /* else if (sd->bridge == BRG_OV519) */ | ||
1287 | reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ | ||
1288 | /* else if (sd->bclass == BCL_OV518) */ | ||
1289 | /* reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02); */ | ||
1290 | } | ||
1291 | |||
1292 | /* this function is called at probe time */ | ||
1293 | static int sd_config(struct gspca_dev *gspca_dev, | ||
1294 | const struct usb_device_id *id) | ||
1295 | { | ||
1296 | struct sd *sd = (struct sd *) gspca_dev; | ||
1297 | struct cam *cam; | ||
1298 | |||
1299 | /* (from ov519_configure) */ | ||
1300 | static const struct ov_regvals init_519[] = { | ||
1301 | { 0x5a, 0x6d }, /* EnableSystem */ | ||
1302 | /* jfm trace usbsnoop3-1.txt */ | ||
1303 | /* jfm 53 = fb */ | ||
1304 | { 0x53, 0x9b }, | ||
1305 | { 0x54, 0xff }, /* set bit2 to enable jpeg */ | ||
1306 | { 0x5d, 0x03 }, | ||
1307 | { 0x49, 0x01 }, | ||
1308 | { 0x48, 0x00 }, | ||
1309 | /* Set LED pin to output mode. Bit 4 must be cleared or sensor | ||
1310 | * detection will fail. This deserves further investigation. */ | ||
1311 | { OV519_GPIO_IO_CTRL0, 0xee }, | ||
1312 | { 0x51, 0x0f }, /* SetUsbInit */ | ||
1313 | { 0x51, 0x00 }, | ||
1314 | { 0x22, 0x00 }, | ||
1315 | /* windows reads 0x55 at this point*/ | ||
1316 | }; | ||
1317 | |||
1318 | if (write_regvals(sd, init_519, ARRAY_SIZE(init_519))) | ||
1319 | goto error; | ||
1320 | /* jfm: not seen in windows trace */ | ||
1321 | if (ov519_init_compression(sd)) | ||
1322 | goto error; | ||
1323 | ov51x_led_control(sd, 0); /* turn LED off */ | ||
1324 | |||
1325 | /* Test for 76xx */ | ||
1326 | sd->primary_i2c_slave = OV7xx0_SID; | ||
1327 | if (ov51x_set_slave_ids(sd, OV7xx0_SID) < 0) | ||
1328 | goto error; | ||
1329 | |||
1330 | /* The OV519 must be more aggressive about sensor detection since | ||
1331 | * I2C write will never fail if the sensor is not present. We have | ||
1332 | * to try to initialize the sensor to detect its presence */ | ||
1333 | if (init_ov_sensor(sd) < 0) { | ||
1334 | /* Test for 6xx0 */ | ||
1335 | sd->primary_i2c_slave = OV6xx0_SID; | ||
1336 | if (ov51x_set_slave_ids(sd, OV6xx0_SID) < 0) | ||
1337 | goto error; | ||
1338 | |||
1339 | if (init_ov_sensor(sd) < 0) { | ||
1340 | /* Test for 8xx0 */ | ||
1341 | sd->primary_i2c_slave = OV8xx0_SID; | ||
1342 | if (ov51x_set_slave_ids(sd, OV8xx0_SID) < 0) | ||
1343 | goto error; | ||
1344 | |||
1345 | if (init_ov_sensor(sd) < 0) { | ||
1346 | PDEBUG(D_ERR, | ||
1347 | "Can't determine sensor slave IDs"); | ||
1348 | goto error; | ||
1349 | } else { | ||
1350 | if (ov8xx0_configure(sd) < 0) { | ||
1351 | PDEBUG(D_ERR, | ||
1352 | "Failed to configure OV8xx0 sensor"); | ||
1353 | goto error; | ||
1354 | } | ||
1355 | } | ||
1356 | } else { | ||
1357 | if (ov6xx0_configure(sd) < 0) { | ||
1358 | PDEBUG(D_ERR, "Failed to configure OV6xx0"); | ||
1359 | goto error; | ||
1360 | } | ||
1361 | } | ||
1362 | } else { | ||
1363 | if (ov7xx0_configure(sd) < 0) { | ||
1364 | PDEBUG(D_ERR, "Failed to configure OV7xx0"); | ||
1365 | goto error; | ||
1366 | } | ||
1367 | } | ||
1368 | |||
1369 | cam = &gspca_dev->cam; | ||
1370 | cam->epaddr = OV511_ENDPOINT_ADDRESS; | ||
1371 | if (sd->maxwidth == 640) { | ||
1372 | cam->cam_mode = vga_mode; | ||
1373 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | ||
1374 | } else { | ||
1375 | cam->cam_mode = sif_mode; | ||
1376 | cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; | ||
1377 | } | ||
1378 | cam->dev_name = (char *) id->driver_info; | ||
1379 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
1380 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | ||
1381 | sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; | ||
1382 | return 0; | ||
1383 | error: | ||
1384 | PDEBUG(D_ERR, "OV519 Config failed"); | ||
1385 | return -EBUSY; | ||
1386 | } | ||
1387 | |||
1388 | /* this function is called at open time */ | ||
1389 | static int sd_open(struct gspca_dev *gspca_dev) | ||
1390 | { | ||
1391 | return 0; | ||
1392 | } | ||
1393 | |||
1394 | /* Sets up the OV519 with the given image parameters | ||
1395 | * | ||
1396 | * OV519 needs a completely different approach, until we can figure out what | ||
1397 | * the individual registers do. | ||
1398 | * | ||
1399 | * Do not put any sensor-specific code in here (including I2C I/O functions) | ||
1400 | */ | ||
1401 | static int ov519_mode_init_regs(struct sd *sd, | ||
1402 | int width, int height) | ||
1403 | { | ||
1404 | static const struct ov_regvals mode_init_519_ov7670[] = { | ||
1405 | { 0x5d, 0x03 }, /* Turn off suspend mode */ | ||
1406 | { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */ | ||
1407 | { 0x54, 0x0f }, /* bit2 (jpeg enable) */ | ||
1408 | { 0xa2, 0x20 }, /* a2-a5 are undocumented */ | ||
1409 | { 0xa3, 0x18 }, | ||
1410 | { 0xa4, 0x04 }, | ||
1411 | { 0xa5, 0x28 }, | ||
1412 | { 0x37, 0x00 }, /* SetUsbInit */ | ||
1413 | { 0x55, 0x02 }, /* 4.096 Mhz audio clock */ | ||
1414 | /* Enable both fields, YUV Input, disable defect comp (why?) */ | ||
1415 | { 0x20, 0x0c }, | ||
1416 | { 0x21, 0x38 }, | ||
1417 | { 0x22, 0x1d }, | ||
1418 | { 0x17, 0x50 }, /* undocumented */ | ||
1419 | { 0x37, 0x00 }, /* undocumented */ | ||
1420 | { 0x40, 0xff }, /* I2C timeout counter */ | ||
1421 | { 0x46, 0x00 }, /* I2C clock prescaler */ | ||
1422 | { 0x59, 0x04 }, /* new from windrv 090403 */ | ||
1423 | { 0xff, 0x00 }, /* undocumented */ | ||
1424 | /* windows reads 0x55 at this point, why? */ | ||
1425 | }; | ||
1426 | |||
1427 | static const struct ov_regvals mode_init_519[] = { | ||
1428 | { 0x5d, 0x03 }, /* Turn off suspend mode */ | ||
1429 | { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */ | ||
1430 | { 0x54, 0x0f }, /* bit2 (jpeg enable) */ | ||
1431 | { 0xa2, 0x20 }, /* a2-a5 are undocumented */ | ||
1432 | { 0xa3, 0x18 }, | ||
1433 | { 0xa4, 0x04 }, | ||
1434 | { 0xa5, 0x28 }, | ||
1435 | { 0x37, 0x00 }, /* SetUsbInit */ | ||
1436 | { 0x55, 0x02 }, /* 4.096 Mhz audio clock */ | ||
1437 | /* Enable both fields, YUV Input, disable defect comp (why?) */ | ||
1438 | { 0x22, 0x1d }, | ||
1439 | { 0x17, 0x50 }, /* undocumented */ | ||
1440 | { 0x37, 0x00 }, /* undocumented */ | ||
1441 | { 0x40, 0xff }, /* I2C timeout counter */ | ||
1442 | { 0x46, 0x00 }, /* I2C clock prescaler */ | ||
1443 | { 0x59, 0x04 }, /* new from windrv 090403 */ | ||
1444 | { 0xff, 0x00 }, /* undocumented */ | ||
1445 | /* windows reads 0x55 at this point, why? */ | ||
1446 | }; | ||
1447 | |||
1448 | /* int hi_res; */ | ||
1449 | |||
1450 | PDEBUG(D_CONF, "mode init %dx%d", width, height); | ||
1451 | |||
1452 | /* if (width >= 800 && height >= 600) | ||
1453 | hi_res = 1; | ||
1454 | else | ||
1455 | hi_res = 0; */ | ||
1456 | |||
1457 | /* if (ov51x_stop(sd) < 0) | ||
1458 | return -EIO; */ | ||
1459 | |||
1460 | /******** Set the mode ********/ | ||
1461 | if (sd->sensor != SEN_OV7670) { | ||
1462 | if (write_regvals(sd, mode_init_519, | ||
1463 | ARRAY_SIZE(mode_init_519))) | ||
1464 | return -EIO; | ||
1465 | } else { | ||
1466 | if (write_regvals(sd, mode_init_519_ov7670, | ||
1467 | ARRAY_SIZE(mode_init_519_ov7670))) | ||
1468 | return -EIO; | ||
1469 | } | ||
1470 | |||
1471 | if (sd->sensor == SEN_OV7640) { | ||
1472 | /* Select 8-bit input mode */ | ||
1473 | reg_w_mask(sd, OV519_CAM_DFR, 0x10, 0x10); | ||
1474 | } | ||
1475 | |||
1476 | reg_w(sd, OV519_CAM_H_SIZE, width >> 4); | ||
1477 | reg_w(sd, OV519_CAM_V_SIZE, height >> 3); | ||
1478 | reg_w(sd, OV519_CAM_X_OFFSETL, 0x00); | ||
1479 | reg_w(sd, OV519_CAM_X_OFFSETH, 0x00); | ||
1480 | reg_w(sd, OV519_CAM_Y_OFFSETL, 0x00); | ||
1481 | reg_w(sd, OV519_CAM_Y_OFFSETH, 0x00); | ||
1482 | reg_w(sd, OV519_CAM_DIVIDER, 0x00); | ||
1483 | reg_w(sd, OV519_CAM_FORMAT, 0x03); /* YUV422 */ | ||
1484 | reg_w(sd, 0x26, 0x00); /* Undocumented */ | ||
1485 | |||
1486 | /******** Set the framerate ********/ | ||
1487 | if (frame_rate > 0) | ||
1488 | sd->frame_rate = frame_rate; | ||
1489 | |||
1490 | /* FIXME: These are only valid at the max resolution. */ | ||
1491 | sd->clockdiv = 0; | ||
1492 | if (sd->sensor == SEN_OV7640) { | ||
1493 | switch (sd->frame_rate) { | ||
1494 | /*jfm: default was 30 fps */ | ||
1495 | case 30: | ||
1496 | reg_w(sd, 0xa4, 0x0c); | ||
1497 | reg_w(sd, 0x23, 0xff); | ||
1498 | break; | ||
1499 | case 25: | ||
1500 | reg_w(sd, 0xa4, 0x0c); | ||
1501 | reg_w(sd, 0x23, 0x1f); | ||
1502 | break; | ||
1503 | case 20: | ||
1504 | reg_w(sd, 0xa4, 0x0c); | ||
1505 | reg_w(sd, 0x23, 0x1b); | ||
1506 | break; | ||
1507 | default: | ||
1508 | /* case 15: */ | ||
1509 | reg_w(sd, 0xa4, 0x04); | ||
1510 | reg_w(sd, 0x23, 0xff); | ||
1511 | sd->clockdiv = 1; | ||
1512 | break; | ||
1513 | case 10: | ||
1514 | reg_w(sd, 0xa4, 0x04); | ||
1515 | reg_w(sd, 0x23, 0x1f); | ||
1516 | sd->clockdiv = 1; | ||
1517 | break; | ||
1518 | case 5: | ||
1519 | reg_w(sd, 0xa4, 0x04); | ||
1520 | reg_w(sd, 0x23, 0x1b); | ||
1521 | sd->clockdiv = 1; | ||
1522 | break; | ||
1523 | } | ||
1524 | } else if (sd->sensor == SEN_OV8610) { | ||
1525 | switch (sd->frame_rate) { | ||
1526 | default: /* 15 fps */ | ||
1527 | /* case 15: */ | ||
1528 | reg_w(sd, 0xa4, 0x06); | ||
1529 | reg_w(sd, 0x23, 0xff); | ||
1530 | break; | ||
1531 | case 10: | ||
1532 | reg_w(sd, 0xa4, 0x06); | ||
1533 | reg_w(sd, 0x23, 0x1f); | ||
1534 | break; | ||
1535 | case 5: | ||
1536 | reg_w(sd, 0xa4, 0x06); | ||
1537 | reg_w(sd, 0x23, 0x1b); | ||
1538 | break; | ||
1539 | } | ||
1540 | sd->clockdiv = 0; | ||
1541 | } else if (sd->sensor == SEN_OV7670) { /* guesses, based on 7640 */ | ||
1542 | PDEBUG(D_STREAM, "Setting framerate to %d fps", | ||
1543 | (sd->frame_rate == 0) ? 15 : sd->frame_rate); | ||
1544 | switch (sd->frame_rate) { | ||
1545 | case 30: | ||
1546 | reg_w(sd, 0xa4, 0x10); | ||
1547 | reg_w(sd, 0x23, 0xff); | ||
1548 | break; | ||
1549 | case 20: | ||
1550 | reg_w(sd, 0xa4, 0x10); | ||
1551 | reg_w(sd, 0x23, 0x1b); | ||
1552 | break; | ||
1553 | default: /* 15 fps */ | ||
1554 | /* case 15: */ | ||
1555 | reg_w(sd, 0xa4, 0x10); | ||
1556 | reg_w(sd, 0x23, 0xff); | ||
1557 | sd->clockdiv = 1; | ||
1558 | break; | ||
1559 | } | ||
1560 | } | ||
1561 | |||
1562 | /* if (ov51x_restart(sd) < 0) | ||
1563 | return -EIO; */ | ||
1564 | |||
1565 | /* Reset it just for good measure */ | ||
1566 | /* if (ov51x_reset(sd, OV511_RESET_NOREGS) < 0) | ||
1567 | return -EIO; */ | ||
1568 | return 0; | ||
1569 | } | ||
1570 | |||
1571 | static int mode_init_ov_sensor_regs(struct sd *sd, | ||
1572 | struct ovsensor_window *win) | ||
1573 | { | ||
1574 | int qvga = win->quarter; | ||
1575 | |||
1576 | /******** Mode (VGA/QVGA) and sensor specific regs ********/ | ||
1577 | switch (sd->sensor) { | ||
1578 | case SEN_OV8610: | ||
1579 | /* For OV8610 qvga means qsvga */ | ||
1580 | i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5); | ||
1581 | break; | ||
1582 | case SEN_OV7610: | ||
1583 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | ||
1584 | break; | ||
1585 | case SEN_OV7620: | ||
1586 | /* i2c_w(sd, 0x2b, 0x00); */ | ||
1587 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | ||
1588 | i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); | ||
1589 | i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); | ||
1590 | i2c_w(sd, 0x25, qvga ? 0x30 : 0x60); | ||
1591 | i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); | ||
1592 | i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); | ||
1593 | i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); | ||
1594 | break; | ||
1595 | case SEN_OV76BE: | ||
1596 | /* i2c_w(sd, 0x2b, 0x00); */ | ||
1597 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | ||
1598 | break; | ||
1599 | case SEN_OV7640: | ||
1600 | /* i2c_w(sd, 0x2b, 0x00); */ | ||
1601 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | ||
1602 | i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); | ||
1603 | /* i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); */ | ||
1604 | /* i2c_w(sd, 0x25, qvga ? 0x30 : 0x60); */ | ||
1605 | /* i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); */ | ||
1606 | /* i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); */ | ||
1607 | /* i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); */ | ||
1608 | break; | ||
1609 | case SEN_OV7670: | ||
1610 | /* set COM7_FMT_VGA or COM7_FMT_QVGA | ||
1611 | * do we need to set anything else? | ||
1612 | * HSTART etc are set in set_ov_sensor_window itself */ | ||
1613 | i2c_w_mask(sd, OV7670_REG_COM7, | ||
1614 | qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA, | ||
1615 | OV7670_COM7_FMT_MASK); | ||
1616 | break; | ||
1617 | case SEN_OV6620: | ||
1618 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | ||
1619 | break; | ||
1620 | case SEN_OV6630: | ||
1621 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | ||
1622 | break; | ||
1623 | default: | ||
1624 | return -EINVAL; | ||
1625 | } | ||
1626 | |||
1627 | /******** Palette-specific regs ********/ | ||
1628 | /* Need to do work here for the OV7670 */ | ||
1629 | |||
1630 | if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { | ||
1631 | /* not valid on the OV6620/OV7620/6630? */ | ||
1632 | i2c_w_mask(sd, 0x0e, 0x00, 0x40); | ||
1633 | } | ||
1634 | |||
1635 | /* The OV518 needs special treatment. Although both the OV518 | ||
1636 | * and the OV6630 support a 16-bit video bus, only the 8 bit Y | ||
1637 | * bus is actually used. The UV bus is tied to ground. | ||
1638 | * Therefore, the OV6630 needs to be in 8-bit multiplexed | ||
1639 | * output mode */ | ||
1640 | |||
1641 | /* OV7640 is 8-bit only */ | ||
1642 | |||
1643 | if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640) | ||
1644 | i2c_w_mask(sd, 0x13, 0x00, 0x20); | ||
1645 | /* } */ | ||
1646 | |||
1647 | /******** Clock programming ********/ | ||
1648 | /* The OV6620 needs special handling. This prevents the | ||
1649 | * severe banding that normally occurs */ | ||
1650 | if (sd->sensor == SEN_OV6620) { | ||
1651 | |||
1652 | /* Clock down */ | ||
1653 | i2c_w(sd, 0x2a, 0x04); | ||
1654 | i2c_w(sd, 0x11, win->clockdiv); | ||
1655 | i2c_w(sd, 0x2a, 0x84); | ||
1656 | /* This next setting is critical. It seems to improve | ||
1657 | * the gain or the contrast. The "reserved" bits seem | ||
1658 | * to have some effect in this case. */ | ||
1659 | i2c_w(sd, 0x2d, 0x85); | ||
1660 | } else if (win->clockdiv >= 0) { | ||
1661 | i2c_w(sd, 0x11, win->clockdiv); | ||
1662 | } | ||
1663 | |||
1664 | /******** Special Features ********/ | ||
1665 | /* no evidence this is possible with OV7670, either */ | ||
1666 | /* Test Pattern */ | ||
1667 | if (sd->sensor != SEN_OV7640 && sd->sensor != SEN_OV7670) | ||
1668 | i2c_w_mask(sd, 0x12, 0x00, 0x02); | ||
1669 | |||
1670 | /* Enable auto white balance */ | ||
1671 | if (sd->sensor == SEN_OV7670) | ||
1672 | i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB, | ||
1673 | OV7670_COM8_AWB); | ||
1674 | else | ||
1675 | i2c_w_mask(sd, 0x12, 0x04, 0x04); | ||
1676 | |||
1677 | /* This will go away as soon as ov51x_mode_init_sensor_regs() */ | ||
1678 | /* is fully tested. */ | ||
1679 | /* 7620/6620/6630? don't have register 0x35, so play it safe */ | ||
1680 | if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { | ||
1681 | if (win->width == 640 /*&& win->height == 480*/) | ||
1682 | i2c_w(sd, 0x35, 0x9e); | ||
1683 | else | ||
1684 | i2c_w(sd, 0x35, 0x1e); | ||
1685 | } | ||
1686 | return 0; | ||
1687 | } | ||
1688 | |||
1689 | static int set_ov_sensor_window(struct sd *sd, | ||
1690 | struct ovsensor_window *win) | ||
1691 | { | ||
1692 | int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; | ||
1693 | int ret, hstart, hstop, vstop, vstart; | ||
1694 | __u8 v; | ||
1695 | |||
1696 | /* The different sensor ICs handle setting up of window differently. | ||
1697 | * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */ | ||
1698 | switch (sd->sensor) { | ||
1699 | case SEN_OV8610: | ||
1700 | hwsbase = 0x1e; | ||
1701 | hwebase = 0x1e; | ||
1702 | vwsbase = 0x02; | ||
1703 | vwebase = 0x02; | ||
1704 | break; | ||
1705 | case SEN_OV7610: | ||
1706 | case SEN_OV76BE: | ||
1707 | hwsbase = 0x38; | ||
1708 | hwebase = 0x3a; | ||
1709 | vwsbase = vwebase = 0x05; | ||
1710 | break; | ||
1711 | case SEN_OV6620: | ||
1712 | case SEN_OV6630: | ||
1713 | hwsbase = 0x38; | ||
1714 | hwebase = 0x3a; | ||
1715 | vwsbase = 0x05; | ||
1716 | vwebase = 0x06; | ||
1717 | break; | ||
1718 | case SEN_OV7620: | ||
1719 | hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */ | ||
1720 | hwebase = 0x2f; | ||
1721 | vwsbase = vwebase = 0x05; | ||
1722 | break; | ||
1723 | case SEN_OV7640: | ||
1724 | hwsbase = 0x1a; | ||
1725 | hwebase = 0x1a; | ||
1726 | vwsbase = vwebase = 0x03; | ||
1727 | break; | ||
1728 | case SEN_OV7670: | ||
1729 | /*handling of OV7670 hardware sensor start and stop values | ||
1730 | * is very odd, compared to the other OV sensors */ | ||
1731 | vwsbase = vwebase = hwebase = hwsbase = 0x00; | ||
1732 | break; | ||
1733 | default: | ||
1734 | return -EINVAL; | ||
1735 | } | ||
1736 | |||
1737 | switch (sd->sensor) { | ||
1738 | case SEN_OV6620: | ||
1739 | case SEN_OV6630: | ||
1740 | if (win->quarter) { /* QCIF */ | ||
1741 | hwscale = 0; | ||
1742 | vwscale = 0; | ||
1743 | } else { /* CIF */ | ||
1744 | hwscale = 1; | ||
1745 | vwscale = 1; /* The datasheet says 0; | ||
1746 | * it's wrong */ | ||
1747 | } | ||
1748 | break; | ||
1749 | case SEN_OV8610: | ||
1750 | if (win->quarter) { /* QSVGA */ | ||
1751 | hwscale = 1; | ||
1752 | vwscale = 1; | ||
1753 | } else { /* SVGA */ | ||
1754 | hwscale = 2; | ||
1755 | vwscale = 2; | ||
1756 | } | ||
1757 | break; | ||
1758 | default: /* SEN_OV7xx0 */ | ||
1759 | if (win->quarter) { /* QVGA */ | ||
1760 | hwscale = 1; | ||
1761 | vwscale = 0; | ||
1762 | } else { /* VGA */ | ||
1763 | hwscale = 2; | ||
1764 | vwscale = 1; | ||
1765 | } | ||
1766 | } | ||
1767 | |||
1768 | ret = mode_init_ov_sensor_regs(sd, win); | ||
1769 | if (ret < 0) | ||
1770 | return ret; | ||
1771 | |||
1772 | if (sd->sensor == SEN_OV8610) { | ||
1773 | i2c_w_mask(sd, 0x2d, 0x05, 0x40); | ||
1774 | /* old 0x95, new 0x05 from windrv 090403 */ | ||
1775 | /* bits 5-7: reserved */ | ||
1776 | i2c_w_mask(sd, 0x28, 0x20, 0x20); | ||
1777 | /* bit 5: progressive mode on */ | ||
1778 | } | ||
1779 | |||
1780 | /* The below is wrong for OV7670s because their window registers | ||
1781 | * only store the high bits in 0x17 to 0x1a */ | ||
1782 | |||
1783 | /* SRH Use sd->max values instead of requested win values */ | ||
1784 | /* SCS Since we're sticking with only the max hardware widths | ||
1785 | * for a given mode */ | ||
1786 | /* I can hard code this for OV7670s */ | ||
1787 | /* Yes, these numbers do look odd, but they're tested and work! */ | ||
1788 | if (sd->sensor == SEN_OV7670) { | ||
1789 | if (win->quarter) { /* QVGA from ov7670.c by | ||
1790 | * Jonathan Corbet */ | ||
1791 | hstart = 164; | ||
1792 | hstop = 20; | ||
1793 | vstart = 14; | ||
1794 | vstop = 494; | ||
1795 | } else { /* VGA */ | ||
1796 | hstart = 158; | ||
1797 | hstop = 14; | ||
1798 | vstart = 10; | ||
1799 | vstop = 490; | ||
1800 | } | ||
1801 | /* OV7670 hardware window registers are split across | ||
1802 | * multiple locations */ | ||
1803 | i2c_w(sd, OV7670_REG_HSTART, (hstart >> 3) & 0xff); | ||
1804 | i2c_w(sd, OV7670_REG_HSTOP, (hstop >> 3) & 0xff); | ||
1805 | v = i2c_r(sd, OV7670_REG_HREF); | ||
1806 | v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07); | ||
1807 | msleep(10); /* need to sleep between read and write to | ||
1808 | * same reg! */ | ||
1809 | i2c_w(sd, OV7670_REG_HREF, v); | ||
1810 | |||
1811 | i2c_w(sd, OV7670_REG_VSTART, (vstart >> 2) & 0xff); | ||
1812 | i2c_w(sd, OV7670_REG_VSTOP, (vstop >> 2) & 0xff); | ||
1813 | v = i2c_r(sd, OV7670_REG_VREF); | ||
1814 | v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03); | ||
1815 | msleep(10); /* need to sleep between read and write to | ||
1816 | * same reg! */ | ||
1817 | i2c_w(sd, OV7670_REG_VREF, v); | ||
1818 | |||
1819 | } else { | ||
1820 | i2c_w(sd, 0x17, hwsbase + (win->x >> hwscale)); | ||
1821 | i2c_w(sd, 0x18, hwebase + ((win->x + win->width) >> hwscale)); | ||
1822 | i2c_w(sd, 0x19, vwsbase + (win->y >> vwscale)); | ||
1823 | i2c_w(sd, 0x1a, vwebase + ((win->y + win->height) >> vwscale)); | ||
1824 | } | ||
1825 | return 0; | ||
1826 | } | ||
1827 | |||
1828 | static int ov_sensor_mode_setup(struct sd *sd, | ||
1829 | int width, int height) | ||
1830 | { | ||
1831 | struct ovsensor_window win; | ||
1832 | |||
1833 | /* win.format = mode; */ | ||
1834 | |||
1835 | /* Unless subcapture is enabled, | ||
1836 | * center the image window and downsample | ||
1837 | * if possible to increase the field of view */ | ||
1838 | /* NOTE: OV518(+) and OV519 does downsampling on its own */ | ||
1839 | win.width = width; | ||
1840 | win.height = height; | ||
1841 | if (width == sd->maxwidth) | ||
1842 | win.quarter = 0; | ||
1843 | else | ||
1844 | win.quarter = 1; | ||
1845 | |||
1846 | /* Center it */ | ||
1847 | win.x = (win.width - width) / 2; | ||
1848 | win.y = (win.height - height) / 2; | ||
1849 | |||
1850 | /* Clock is determined by OV519 frame rate code */ | ||
1851 | win.clockdiv = sd->clockdiv; | ||
1852 | |||
1853 | PDEBUG(D_CONF, "Setting clock divider to %d", win.clockdiv); | ||
1854 | return set_ov_sensor_window(sd, &win); | ||
1855 | } | ||
1856 | |||
1857 | /* -- start the camera -- */ | ||
1858 | static void sd_start(struct gspca_dev *gspca_dev) | ||
1859 | { | ||
1860 | struct sd *sd = (struct sd *) gspca_dev; | ||
1861 | int ret; | ||
1862 | |||
1863 | |||
1864 | ret = ov519_mode_init_regs(sd, gspca_dev->width, gspca_dev->height); | ||
1865 | if (ret < 0) | ||
1866 | goto out; | ||
1867 | ret = ov_sensor_mode_setup(sd, gspca_dev->width, gspca_dev->height); | ||
1868 | if (ret < 0) | ||
1869 | goto out; | ||
1870 | |||
1871 | ret = ov51x_restart((struct sd *) gspca_dev); | ||
1872 | if (ret < 0) | ||
1873 | goto out; | ||
1874 | PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt); | ||
1875 | ov51x_led_control(sd, 1); | ||
1876 | return; | ||
1877 | out: | ||
1878 | PDEBUG(D_ERR, "camera start error:%d", ret); | ||
1879 | } | ||
1880 | |||
1881 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
1882 | { | ||
1883 | ov51x_stop((struct sd *) gspca_dev); | ||
1884 | ov51x_led_control((struct sd *) gspca_dev, 0); | ||
1885 | } | ||
1886 | |||
1887 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
1888 | { | ||
1889 | } | ||
1890 | |||
1891 | static void sd_close(struct gspca_dev *gspca_dev) | ||
1892 | { | ||
1893 | } | ||
1894 | |||
1895 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
1896 | struct gspca_frame *frame, /* target */ | ||
1897 | __u8 *data, /* isoc packet */ | ||
1898 | int len) /* iso packet length */ | ||
1899 | { | ||
1900 | /* Header of ov519 is 16 bytes: | ||
1901 | * Byte Value Description | ||
1902 | * 0 0xff magic | ||
1903 | * 1 0xff magic | ||
1904 | * 2 0xff magic | ||
1905 | * 3 0xXX 0x50 = SOF, 0x51 = EOF | ||
1906 | * 9 0xXX 0x01 initial frame without data, | ||
1907 | * 0x00 standard frame with image | ||
1908 | * 14 Lo in EOF: length of image data / 8 | ||
1909 | * 15 Hi | ||
1910 | */ | ||
1911 | |||
1912 | if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) { | ||
1913 | switch (data[3]) { | ||
1914 | case 0x50: /* start of frame */ | ||
1915 | #define HDRSZ 16 | ||
1916 | data += HDRSZ; | ||
1917 | len -= HDRSZ; | ||
1918 | #undef HDRSZ | ||
1919 | if (data[0] == 0xff || data[1] == 0xd8) | ||
1920 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | ||
1921 | data, len); | ||
1922 | else | ||
1923 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
1924 | return; | ||
1925 | case 0x51: /* end of frame */ | ||
1926 | if (data[9] != 0) | ||
1927 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
1928 | gspca_frame_add(gspca_dev, LAST_PACKET, frame, | ||
1929 | data, 0); | ||
1930 | return; | ||
1931 | } | ||
1932 | } | ||
1933 | |||
1934 | /* intermediate packet */ | ||
1935 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
1936 | data, len); | ||
1937 | } | ||
1938 | |||
1939 | /* -- management routines -- */ | ||
1940 | |||
1941 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
1942 | { | ||
1943 | struct sd *sd = (struct sd *) gspca_dev; | ||
1944 | int val; | ||
1945 | /* int was_streaming; */ | ||
1946 | |||
1947 | val = sd->brightness; | ||
1948 | PDEBUG(D_CONF, "brightness:%d", val); | ||
1949 | /* was_streaming = gspca_dev->streaming; | ||
1950 | * if (was_streaming) | ||
1951 | * ov51x_stop(sd); */ | ||
1952 | switch (sd->sensor) { | ||
1953 | case SEN_OV8610: | ||
1954 | case SEN_OV7610: | ||
1955 | case SEN_OV76BE: | ||
1956 | case SEN_OV6620: | ||
1957 | case SEN_OV6630: | ||
1958 | case SEN_OV7640: | ||
1959 | i2c_w(sd, OV7610_REG_BRT, val); | ||
1960 | break; | ||
1961 | case SEN_OV7620: | ||
1962 | /* 7620 doesn't like manual changes when in auto mode */ | ||
1963 | /*fixme | ||
1964 | * if (!sd->auto_brt) */ | ||
1965 | i2c_w(sd, OV7610_REG_BRT, val); | ||
1966 | break; | ||
1967 | case SEN_OV7670: | ||
1968 | /*jfm - from windblows | ||
1969 | * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */ | ||
1970 | i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val)); | ||
1971 | break; | ||
1972 | } | ||
1973 | /* if (was_streaming) | ||
1974 | * ov51x_restart(sd); */ | ||
1975 | } | ||
1976 | |||
1977 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
1978 | { | ||
1979 | struct sd *sd = (struct sd *) gspca_dev; | ||
1980 | int val; | ||
1981 | /* int was_streaming; */ | ||
1982 | |||
1983 | val = sd->contrast; | ||
1984 | PDEBUG(D_CONF, "contrast:%d", val); | ||
1985 | /* was_streaming = gspca_dev->streaming; | ||
1986 | if (was_streaming) | ||
1987 | ov51x_stop(sd); */ | ||
1988 | switch (sd->sensor) { | ||
1989 | case SEN_OV7610: | ||
1990 | case SEN_OV6620: | ||
1991 | i2c_w(sd, OV7610_REG_CNT, val); | ||
1992 | break; | ||
1993 | case SEN_OV6630: | ||
1994 | i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f); | ||
1995 | case SEN_OV8610: { | ||
1996 | static const __u8 ctab[] = { | ||
1997 | 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f | ||
1998 | }; | ||
1999 | |||
2000 | /* Use Y gamma control instead. Bit 0 enables it. */ | ||
2001 | i2c_w(sd, 0x64, ctab[val >> 5]); | ||
2002 | break; | ||
2003 | } | ||
2004 | case SEN_OV7620: { | ||
2005 | static const __u8 ctab[] = { | ||
2006 | 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57, | ||
2007 | 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff | ||
2008 | }; | ||
2009 | |||
2010 | /* Use Y gamma control instead. Bit 0 enables it. */ | ||
2011 | i2c_w(sd, 0x64, ctab[val >> 4]); | ||
2012 | break; | ||
2013 | } | ||
2014 | case SEN_OV7640: | ||
2015 | /* Use gain control instead. */ | ||
2016 | i2c_w(sd, OV7610_REG_GAIN, val >> 2); | ||
2017 | break; | ||
2018 | case SEN_OV7670: | ||
2019 | /* check that this isn't just the same as ov7610 */ | ||
2020 | i2c_w(sd, OV7670_REG_CONTRAS, val >> 1); | ||
2021 | break; | ||
2022 | } | ||
2023 | /* if (was_streaming) | ||
2024 | ov51x_restart(sd); */ | ||
2025 | } | ||
2026 | |||
2027 | static void setcolors(struct gspca_dev *gspca_dev) | ||
2028 | { | ||
2029 | struct sd *sd = (struct sd *) gspca_dev; | ||
2030 | int val; | ||
2031 | /* int was_streaming; */ | ||
2032 | |||
2033 | val = sd->colors; | ||
2034 | PDEBUG(D_CONF, "saturation:%d", val); | ||
2035 | /* was_streaming = gspca_dev->streaming; | ||
2036 | if (was_streaming) | ||
2037 | ov51x_stop(sd); */ | ||
2038 | switch (sd->sensor) { | ||
2039 | case SEN_OV8610: | ||
2040 | case SEN_OV7610: | ||
2041 | case SEN_OV76BE: | ||
2042 | case SEN_OV6620: | ||
2043 | case SEN_OV6630: | ||
2044 | i2c_w(sd, OV7610_REG_SAT, val); | ||
2045 | break; | ||
2046 | case SEN_OV7620: | ||
2047 | /* Use UV gamma control instead. Bits 0 & 7 are reserved. */ | ||
2048 | /* rc = ov_i2c_write(sd->dev, 0x62, (val >> 9) & 0x7e); | ||
2049 | if (rc < 0) | ||
2050 | goto out; */ | ||
2051 | i2c_w(sd, OV7610_REG_SAT, val); | ||
2052 | break; | ||
2053 | case SEN_OV7640: | ||
2054 | i2c_w(sd, OV7610_REG_SAT, val & 0xf0); | ||
2055 | break; | ||
2056 | case SEN_OV7670: | ||
2057 | /* supported later once I work out how to do it | ||
2058 | * transparently fail now! */ | ||
2059 | /* set REG_COM13 values for UV sat auto mode */ | ||
2060 | break; | ||
2061 | } | ||
2062 | /* if (was_streaming) | ||
2063 | ov51x_restart(sd); */ | ||
2064 | } | ||
2065 | |||
2066 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
2067 | { | ||
2068 | struct sd *sd = (struct sd *) gspca_dev; | ||
2069 | |||
2070 | sd->brightness = val; | ||
2071 | setbrightness(gspca_dev); | ||
2072 | return 0; | ||
2073 | } | ||
2074 | |||
2075 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
2076 | { | ||
2077 | struct sd *sd = (struct sd *) gspca_dev; | ||
2078 | |||
2079 | *val = sd->brightness; | ||
2080 | return 0; | ||
2081 | } | ||
2082 | |||
2083 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
2084 | { | ||
2085 | struct sd *sd = (struct sd *) gspca_dev; | ||
2086 | |||
2087 | sd->contrast = val; | ||
2088 | setcontrast(gspca_dev); | ||
2089 | return 0; | ||
2090 | } | ||
2091 | |||
2092 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
2093 | { | ||
2094 | struct sd *sd = (struct sd *) gspca_dev; | ||
2095 | |||
2096 | *val = sd->contrast; | ||
2097 | return 0; | ||
2098 | } | ||
2099 | |||
2100 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
2101 | { | ||
2102 | struct sd *sd = (struct sd *) gspca_dev; | ||
2103 | |||
2104 | sd->colors = val; | ||
2105 | setcolors(gspca_dev); | ||
2106 | return 0; | ||
2107 | } | ||
2108 | |||
2109 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
2110 | { | ||
2111 | struct sd *sd = (struct sd *) gspca_dev; | ||
2112 | |||
2113 | *val = sd->colors; | ||
2114 | return 0; | ||
2115 | } | ||
2116 | |||
2117 | /* sub-driver description */ | ||
2118 | static const struct sd_desc sd_desc = { | ||
2119 | .name = MODULE_NAME, | ||
2120 | .ctrls = sd_ctrls, | ||
2121 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
2122 | .config = sd_config, | ||
2123 | .open = sd_open, | ||
2124 | .start = sd_start, | ||
2125 | .stopN = sd_stopN, | ||
2126 | .stop0 = sd_stop0, | ||
2127 | .close = sd_close, | ||
2128 | .pkt_scan = sd_pkt_scan, | ||
2129 | }; | ||
2130 | |||
2131 | /* -- module initialisation -- */ | ||
2132 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
2133 | static const __devinitdata struct usb_device_id device_table[] = { | ||
2134 | {USB_DEVICE(0x041e, 0x4052), DVNM("Creative Live! VISTA IM")}, | ||
2135 | {USB_DEVICE(0x041e, 0x405f), DVNM("Creative Live! VISTA VF0330")}, | ||
2136 | {USB_DEVICE(0x041e, 0x4060), DVNM("Creative Live! VISTA VF0350")}, | ||
2137 | {USB_DEVICE(0x041e, 0x4061), DVNM("Creative Live! VISTA VF0400")}, | ||
2138 | {USB_DEVICE(0x041e, 0x4064), DVNM("Creative Live! VISTA VF0420")}, | ||
2139 | {USB_DEVICE(0x041e, 0x4068), DVNM("Creative Live! VISTA VF0470")}, | ||
2140 | {USB_DEVICE(0x045e, 0x028c), DVNM("Microsoft xbox cam")}, | ||
2141 | {USB_DEVICE(0x054c, 0x0154), DVNM("Sonny toy4")}, | ||
2142 | {USB_DEVICE(0x054c, 0x0155), DVNM("Sonny toy5")}, | ||
2143 | {USB_DEVICE(0x05a9, 0x0519), DVNM("OmniVision")}, | ||
2144 | {USB_DEVICE(0x05a9, 0x0530), DVNM("OmniVision")}, | ||
2145 | {USB_DEVICE(0x05a9, 0x4519), DVNM("OmniVision")}, | ||
2146 | {USB_DEVICE(0x05a9, 0x8519), DVNM("OmniVision")}, | ||
2147 | {} | ||
2148 | }; | ||
2149 | #undef DVNAME | ||
2150 | MODULE_DEVICE_TABLE(usb, device_table); | ||
2151 | |||
2152 | /* -- device connect -- */ | ||
2153 | static int sd_probe(struct usb_interface *intf, | ||
2154 | const struct usb_device_id *id) | ||
2155 | { | ||
2156 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
2157 | THIS_MODULE); | ||
2158 | } | ||
2159 | |||
2160 | static struct usb_driver sd_driver = { | ||
2161 | .name = MODULE_NAME, | ||
2162 | .id_table = device_table, | ||
2163 | .probe = sd_probe, | ||
2164 | .disconnect = gspca_disconnect, | ||
2165 | }; | ||
2166 | |||
2167 | /* -- module insert / remove -- */ | ||
2168 | static int __init sd_mod_init(void) | ||
2169 | { | ||
2170 | if (usb_register(&sd_driver) < 0) | ||
2171 | return -1; | ||
2172 | PDEBUG(D_PROBE, "v%s registered", version); | ||
2173 | return 0; | ||
2174 | } | ||
2175 | static void __exit sd_mod_exit(void) | ||
2176 | { | ||
2177 | usb_deregister(&sd_driver); | ||
2178 | PDEBUG(D_PROBE, "deregistered"); | ||
2179 | } | ||
2180 | |||
2181 | module_init(sd_mod_init); | ||
2182 | module_exit(sd_mod_exit); | ||
2183 | |||
2184 | module_param(frame_rate, int, 0644); | ||
2185 | MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)"); | ||
2186 | |||
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c new file mode 100644 index 000000000000..fa7abc411090 --- /dev/null +++ b/drivers/media/video/gspca/pac207.c | |||
@@ -0,0 +1,622 @@ | |||
1 | /* | ||
2 | * Pixart PAC207BCA library | ||
3 | * | ||
4 | * Copyright (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> | ||
5 | * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li | ||
6 | * Copyleft (C) 2005 Michel Xhaard mxhaard@magic.fr | ||
7 | * | ||
8 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #define MODULE_NAME "pac207" | ||
27 | |||
28 | #include "gspca.h" | ||
29 | |||
30 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) | ||
31 | static const char version[] = "2.1.7"; | ||
32 | |||
33 | MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>"); | ||
34 | MODULE_DESCRIPTION("Pixart PAC207"); | ||
35 | MODULE_LICENSE("GPL"); | ||
36 | |||
37 | #define PAC207_CTRL_TIMEOUT 100 /* ms */ | ||
38 | |||
39 | #define PAC207_BRIGHTNESS_MIN 0 | ||
40 | #define PAC207_BRIGHTNESS_MAX 255 | ||
41 | #define PAC207_BRIGHTNESS_DEFAULT 4 /* power on default: 4 */ | ||
42 | |||
43 | /* An exposure value of 4 also works (3 does not) but then we need to lower | ||
44 | the compression balance setting when in 352x288 mode, otherwise the usb | ||
45 | bandwidth is not enough and packets get dropped resulting in corrupt | ||
46 | frames. The problem with this is that when the compression balance gets | ||
47 | lowered below 0x80, the pac207 starts using a different compression | ||
48 | algorithm for some lines, these lines get prefixed with a 0x2dd2 prefix | ||
49 | and currently we do not know how to decompress these lines, so for now | ||
50 | we use a minimum exposure value of 5 */ | ||
51 | #define PAC207_EXPOSURE_MIN 5 | ||
52 | #define PAC207_EXPOSURE_MAX 26 | ||
53 | #define PAC207_EXPOSURE_DEFAULT 5 /* power on default: 3 ?? */ | ||
54 | #define PAC207_EXPOSURE_KNEE 11 /* 4 = 30 fps, 11 = 8, 15 = 6 */ | ||
55 | |||
56 | #define PAC207_GAIN_MIN 0 | ||
57 | #define PAC207_GAIN_MAX 31 | ||
58 | #define PAC207_GAIN_DEFAULT 9 /* power on default: 9 */ | ||
59 | #define PAC207_GAIN_KNEE 20 | ||
60 | |||
61 | #define PAC207_AUTOGAIN_DEADZONE 30 | ||
62 | /* We calculating the autogain at the end of the transfer of a frame, at this | ||
63 | moment a frame with the old settings is being transmitted, and a frame is | ||
64 | being captured with the old settings. So if we adjust the autogain we must | ||
65 | ignore atleast the 2 next frames for the new settings to come into effect | ||
66 | before doing any other adjustments */ | ||
67 | #define PAC207_AUTOGAIN_IGNORE_FRAMES 3 | ||
68 | |||
69 | /* specific webcam descriptor */ | ||
70 | struct sd { | ||
71 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
72 | |||
73 | u8 mode; | ||
74 | |||
75 | u8 brightness; | ||
76 | u8 exposure; | ||
77 | u8 autogain; | ||
78 | u8 gain; | ||
79 | |||
80 | u8 sof_read; | ||
81 | u8 header_read; | ||
82 | u8 autogain_ignore_frames; | ||
83 | |||
84 | atomic_t avg_lum; | ||
85 | }; | ||
86 | |||
87 | /* V4L2 controls supported by the driver */ | ||
88 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
89 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
90 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); | ||
91 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
92 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
93 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
94 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); | ||
95 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); | ||
96 | |||
97 | static struct ctrl sd_ctrls[] = { | ||
98 | #define SD_BRIGHTNESS 0 | ||
99 | { | ||
100 | { | ||
101 | .id = V4L2_CID_BRIGHTNESS, | ||
102 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
103 | .name = "Brightness", | ||
104 | .minimum = PAC207_BRIGHTNESS_MIN, | ||
105 | .maximum = PAC207_BRIGHTNESS_MAX, | ||
106 | .step = 1, | ||
107 | .default_value = PAC207_BRIGHTNESS_DEFAULT, | ||
108 | .flags = 0, | ||
109 | }, | ||
110 | .set = sd_setbrightness, | ||
111 | .get = sd_getbrightness, | ||
112 | }, | ||
113 | #define SD_EXPOSURE 1 | ||
114 | { | ||
115 | { | ||
116 | .id = V4L2_CID_EXPOSURE, | ||
117 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
118 | .name = "exposure", | ||
119 | .minimum = PAC207_EXPOSURE_MIN, | ||
120 | .maximum = PAC207_EXPOSURE_MAX, | ||
121 | .step = 1, | ||
122 | .default_value = PAC207_EXPOSURE_DEFAULT, | ||
123 | .flags = 0, | ||
124 | }, | ||
125 | .set = sd_setexposure, | ||
126 | .get = sd_getexposure, | ||
127 | }, | ||
128 | #define SD_AUTOGAIN 2 | ||
129 | { | ||
130 | { | ||
131 | .id = V4L2_CID_AUTOGAIN, | ||
132 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
133 | .name = "Auto Gain", | ||
134 | .minimum = 0, | ||
135 | .maximum = 1, | ||
136 | .step = 1, | ||
137 | .default_value = 1, | ||
138 | .flags = 0, | ||
139 | }, | ||
140 | .set = sd_setautogain, | ||
141 | .get = sd_getautogain, | ||
142 | }, | ||
143 | #define SD_GAIN 3 | ||
144 | { | ||
145 | { | ||
146 | .id = V4L2_CID_GAIN, | ||
147 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
148 | .name = "gain", | ||
149 | .minimum = PAC207_GAIN_MIN, | ||
150 | .maximum = PAC207_GAIN_MAX, | ||
151 | .step = 1, | ||
152 | .default_value = PAC207_GAIN_DEFAULT, | ||
153 | .flags = 0, | ||
154 | }, | ||
155 | .set = sd_setgain, | ||
156 | .get = sd_getgain, | ||
157 | }, | ||
158 | }; | ||
159 | |||
160 | static struct v4l2_pix_format sif_mode[] = { | ||
161 | {176, 144, V4L2_PIX_FMT_PAC207, V4L2_FIELD_NONE, | ||
162 | .bytesperline = 176, | ||
163 | .sizeimage = (176 + 2) * 144, | ||
164 | /* uncompressed, add 2 bytes / line for line header */ | ||
165 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
166 | .priv = 1}, | ||
167 | {352, 288, V4L2_PIX_FMT_PAC207, V4L2_FIELD_NONE, | ||
168 | .bytesperline = 352, | ||
169 | /* compressed, but only when needed (not compressed | ||
170 | when the framerate is low) */ | ||
171 | .sizeimage = (352 + 2) * 288, | ||
172 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
173 | .priv = 0}, | ||
174 | }; | ||
175 | |||
176 | static const __u8 pac207_sensor_init[][8] = { | ||
177 | {0x10, 0x12, 0x0d, 0x12, 0x0c, 0x01, 0x29, 0xf0}, | ||
178 | {0x00, 0x64, 0x64, 0x64, 0x04, 0x10, 0xf0, 0x30}, | ||
179 | {0x00, 0x00, 0x00, 0x70, 0xa0, 0xf8, 0x00, 0x00}, | ||
180 | {0x00, 0x00, 0x32, 0x00, 0x96, 0x00, 0xa2, 0x02}, | ||
181 | {0x32, 0x00, 0x96, 0x00, 0xA2, 0x02, 0xaf, 0x00}, | ||
182 | }; | ||
183 | |||
184 | /* 48 reg_72 Rate Control end BalSize_4a =0x36 */ | ||
185 | static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 }; | ||
186 | |||
187 | static const unsigned char pac207_sof_marker[5] = | ||
188 | { 0xff, 0xff, 0x00, 0xff, 0x96 }; | ||
189 | |||
190 | static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index, | ||
191 | const u8 *buffer, u16 length) | ||
192 | { | ||
193 | struct usb_device *udev = gspca_dev->dev; | ||
194 | int err; | ||
195 | |||
196 | memcpy(gspca_dev->usb_buf, buffer, length); | ||
197 | |||
198 | err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01, | ||
199 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
200 | 0x00, index, | ||
201 | gspca_dev->usb_buf, length, PAC207_CTRL_TIMEOUT); | ||
202 | if (err < 0) | ||
203 | PDEBUG(D_ERR, | ||
204 | "Failed to write registers to index 0x%04X, error %d)", | ||
205 | index, err); | ||
206 | |||
207 | return err; | ||
208 | } | ||
209 | |||
210 | |||
211 | int pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value) | ||
212 | { | ||
213 | struct usb_device *udev = gspca_dev->dev; | ||
214 | int err; | ||
215 | |||
216 | err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, | ||
217 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
218 | value, index, NULL, 0, PAC207_CTRL_TIMEOUT); | ||
219 | if (err) | ||
220 | PDEBUG(D_ERR, "Failed to write a register (index 0x%04X," | ||
221 | " value 0x%02X, error %d)", index, value, err); | ||
222 | |||
223 | return err; | ||
224 | } | ||
225 | |||
226 | |||
227 | int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index) | ||
228 | { | ||
229 | struct usb_device *udev = gspca_dev->dev; | ||
230 | int res; | ||
231 | |||
232 | res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, | ||
233 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
234 | 0x00, index, | ||
235 | gspca_dev->usb_buf, 1, PAC207_CTRL_TIMEOUT); | ||
236 | if (res < 0) { | ||
237 | PDEBUG(D_ERR, | ||
238 | "Failed to read a register (index 0x%04X, error %d)", | ||
239 | index, res); | ||
240 | return res; | ||
241 | } | ||
242 | |||
243 | return gspca_dev->usb_buf[0]; | ||
244 | } | ||
245 | |||
246 | /* this function is called at probe time */ | ||
247 | static int sd_config(struct gspca_dev *gspca_dev, | ||
248 | const struct usb_device_id *id) | ||
249 | { | ||
250 | struct sd *sd = (struct sd *) gspca_dev; | ||
251 | struct cam *cam; | ||
252 | u8 idreg[2]; | ||
253 | |||
254 | idreg[0] = pac207_read_reg(gspca_dev, 0x0000); | ||
255 | idreg[1] = pac207_read_reg(gspca_dev, 0x0001); | ||
256 | idreg[0] = ((idreg[0] & 0x0F) << 4) | ((idreg[1] & 0xf0) >> 4); | ||
257 | idreg[1] = idreg[1] & 0x0f; | ||
258 | PDEBUG(D_PROBE, "Pixart Sensor ID 0x%02X Chips ID 0x%02X", | ||
259 | idreg[0], idreg[1]); | ||
260 | |||
261 | if (idreg[0] != 0x27) { | ||
262 | PDEBUG(D_PROBE, "Error invalid sensor ID!"); | ||
263 | return -ENODEV; | ||
264 | } | ||
265 | |||
266 | pac207_write_reg(gspca_dev, 0x41, 0x00); | ||
267 | /* Bit_0=Image Format, | ||
268 | * Bit_1=LED, | ||
269 | * Bit_2=Compression test mode enable */ | ||
270 | pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */ | ||
271 | pac207_write_reg(gspca_dev, 0x11, 0x30); /* Analog Bias */ | ||
272 | |||
273 | PDEBUG(D_PROBE, | ||
274 | "Pixart PAC207BCA Image Processor and Control Chip detected" | ||
275 | " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); | ||
276 | |||
277 | cam = &gspca_dev->cam; | ||
278 | cam->dev_name = (char *) id->driver_info; | ||
279 | cam->epaddr = 0x05; | ||
280 | cam->cam_mode = sif_mode; | ||
281 | cam->nmodes = ARRAY_SIZE(sif_mode); | ||
282 | sd->brightness = PAC207_BRIGHTNESS_DEFAULT; | ||
283 | sd->exposure = PAC207_EXPOSURE_DEFAULT; | ||
284 | sd->gain = PAC207_GAIN_DEFAULT; | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | /* this function is called at open time */ | ||
290 | static int sd_open(struct gspca_dev *gspca_dev) | ||
291 | { | ||
292 | struct sd *sd = (struct sd *) gspca_dev; | ||
293 | |||
294 | sd->autogain = 1; | ||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | /* -- start the camera -- */ | ||
299 | static void sd_start(struct gspca_dev *gspca_dev) | ||
300 | { | ||
301 | struct sd *sd = (struct sd *) gspca_dev; | ||
302 | __u8 mode; | ||
303 | |||
304 | pac207_write_reg(gspca_dev, 0x0f, 0x10); /* Power control (Bit 6-0) */ | ||
305 | pac207_write_regs(gspca_dev, 0x0002, pac207_sensor_init[0], 8); | ||
306 | pac207_write_regs(gspca_dev, 0x000a, pac207_sensor_init[1], 8); | ||
307 | pac207_write_regs(gspca_dev, 0x0012, pac207_sensor_init[2], 8); | ||
308 | pac207_write_regs(gspca_dev, 0x0040, pac207_sensor_init[3], 8); | ||
309 | pac207_write_regs(gspca_dev, 0x0042, pac207_sensor_init[4], 8); | ||
310 | pac207_write_regs(gspca_dev, 0x0048, PacReg72, 4); | ||
311 | |||
312 | /* Compression Balance */ | ||
313 | if (gspca_dev->width == 176) | ||
314 | pac207_write_reg(gspca_dev, 0x4a, 0xff); | ||
315 | else | ||
316 | pac207_write_reg(gspca_dev, 0x4a, 0x88); | ||
317 | pac207_write_reg(gspca_dev, 0x4b, 0x00); /* Sram test value */ | ||
318 | pac207_write_reg(gspca_dev, 0x08, sd->brightness); | ||
319 | |||
320 | /* PGA global gain (Bit 4-0) */ | ||
321 | pac207_write_reg(gspca_dev, 0x0e, sd->gain); | ||
322 | pac207_write_reg(gspca_dev, 0x02, sd->exposure); /* PXCK = 12MHz /n */ | ||
323 | |||
324 | mode = 0x02; /* Image Format (Bit 0), LED (1), Compr. test mode (2) */ | ||
325 | if (gspca_dev->width == 176) { /* 176x144 */ | ||
326 | mode |= 0x01; | ||
327 | PDEBUG(D_STREAM, "pac207_start mode 176x144"); | ||
328 | } else { /* 352x288 */ | ||
329 | PDEBUG(D_STREAM, "pac207_start mode 352x288"); | ||
330 | } | ||
331 | pac207_write_reg(gspca_dev, 0x41, mode); | ||
332 | |||
333 | pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */ | ||
334 | pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */ | ||
335 | msleep(10); | ||
336 | pac207_write_reg(gspca_dev, 0x40, 0x01); /* Start ISO pipe */ | ||
337 | |||
338 | sd->sof_read = 0; | ||
339 | sd->autogain_ignore_frames = 0; | ||
340 | atomic_set(&sd->avg_lum, -1); | ||
341 | } | ||
342 | |||
343 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
344 | { | ||
345 | pac207_write_reg(gspca_dev, 0x40, 0x00); /* Stop ISO pipe */ | ||
346 | pac207_write_reg(gspca_dev, 0x41, 0x00); /* Turn of LED */ | ||
347 | pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */ | ||
348 | } | ||
349 | |||
350 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
351 | { | ||
352 | } | ||
353 | |||
354 | /* this function is called at close time */ | ||
355 | static void sd_close(struct gspca_dev *gspca_dev) | ||
356 | { | ||
357 | } | ||
358 | |||
359 | static void pac207_do_auto_gain(struct gspca_dev *gspca_dev) | ||
360 | { | ||
361 | struct sd *sd = (struct sd *) gspca_dev; | ||
362 | int avg_lum = atomic_read(&sd->avg_lum); | ||
363 | |||
364 | if (avg_lum == -1) | ||
365 | return; | ||
366 | |||
367 | if (sd->autogain_ignore_frames > 0) | ||
368 | sd->autogain_ignore_frames--; | ||
369 | else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, | ||
370 | 100 + sd->brightness / 2, PAC207_AUTOGAIN_DEADZONE, | ||
371 | PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE)) | ||
372 | sd->autogain_ignore_frames = PAC207_AUTOGAIN_IGNORE_FRAMES; | ||
373 | } | ||
374 | |||
375 | static unsigned char *pac207_find_sof(struct gspca_dev *gspca_dev, | ||
376 | unsigned char *m, int len) | ||
377 | { | ||
378 | struct sd *sd = (struct sd *) gspca_dev; | ||
379 | int i; | ||
380 | |||
381 | /* Search for the SOF marker (fixed part) in the header */ | ||
382 | for (i = 0; i < len; i++) { | ||
383 | if (m[i] == pac207_sof_marker[sd->sof_read]) { | ||
384 | sd->sof_read++; | ||
385 | if (sd->sof_read == sizeof(pac207_sof_marker)) { | ||
386 | PDEBUG(D_STREAM, | ||
387 | "SOF found, bytes to analyze: %u." | ||
388 | " Frame starts at byte #%u", | ||
389 | len, i + 1); | ||
390 | sd->sof_read = 0; | ||
391 | return m + i + 1; | ||
392 | } | ||
393 | } else { | ||
394 | sd->sof_read = 0; | ||
395 | } | ||
396 | } | ||
397 | |||
398 | return NULL; | ||
399 | } | ||
400 | |||
401 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
402 | struct gspca_frame *frame, | ||
403 | __u8 *data, | ||
404 | int len) | ||
405 | { | ||
406 | struct sd *sd = (struct sd *) gspca_dev; | ||
407 | unsigned char *sof; | ||
408 | |||
409 | sof = pac207_find_sof(gspca_dev, data, len); | ||
410 | if (sof) { | ||
411 | int n; | ||
412 | |||
413 | /* finish decoding current frame */ | ||
414 | n = sof - data; | ||
415 | if (n > sizeof pac207_sof_marker) | ||
416 | n -= sizeof pac207_sof_marker; | ||
417 | else | ||
418 | n = 0; | ||
419 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | ||
420 | data, n); | ||
421 | sd->header_read = 0; | ||
422 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0); | ||
423 | len -= sof - data; | ||
424 | data = sof; | ||
425 | } | ||
426 | if (sd->header_read < 11) { | ||
427 | int needed; | ||
428 | |||
429 | /* get average lumination from frame header (byte 5) */ | ||
430 | if (sd->header_read < 5) { | ||
431 | needed = 5 - sd->header_read; | ||
432 | if (len >= needed) | ||
433 | atomic_set(&sd->avg_lum, data[needed - 1]); | ||
434 | } | ||
435 | /* skip the rest of the header */ | ||
436 | needed = 11 - sd->header_read; | ||
437 | if (len <= needed) { | ||
438 | sd->header_read += len; | ||
439 | return; | ||
440 | } | ||
441 | data += needed; | ||
442 | len -= needed; | ||
443 | sd->header_read = 11; | ||
444 | } | ||
445 | |||
446 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
447 | } | ||
448 | |||
449 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
450 | { | ||
451 | struct sd *sd = (struct sd *) gspca_dev; | ||
452 | |||
453 | pac207_write_reg(gspca_dev, 0x08, sd->brightness); | ||
454 | pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */ | ||
455 | pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */ | ||
456 | } | ||
457 | |||
458 | static void setexposure(struct gspca_dev *gspca_dev) | ||
459 | { | ||
460 | struct sd *sd = (struct sd *) gspca_dev; | ||
461 | |||
462 | pac207_write_reg(gspca_dev, 0x02, sd->exposure); | ||
463 | pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */ | ||
464 | pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */ | ||
465 | } | ||
466 | |||
467 | static void setgain(struct gspca_dev *gspca_dev) | ||
468 | { | ||
469 | struct sd *sd = (struct sd *) gspca_dev; | ||
470 | |||
471 | pac207_write_reg(gspca_dev, 0x0e, sd->gain); | ||
472 | pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */ | ||
473 | pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */ | ||
474 | } | ||
475 | |||
476 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
477 | { | ||
478 | struct sd *sd = (struct sd *) gspca_dev; | ||
479 | |||
480 | sd->brightness = val; | ||
481 | if (gspca_dev->streaming) | ||
482 | setbrightness(gspca_dev); | ||
483 | return 0; | ||
484 | } | ||
485 | |||
486 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
487 | { | ||
488 | struct sd *sd = (struct sd *) gspca_dev; | ||
489 | |||
490 | *val = sd->brightness; | ||
491 | return 0; | ||
492 | } | ||
493 | |||
494 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val) | ||
495 | { | ||
496 | struct sd *sd = (struct sd *) gspca_dev; | ||
497 | |||
498 | sd->exposure = val; | ||
499 | if (gspca_dev->streaming) | ||
500 | setexposure(gspca_dev); | ||
501 | return 0; | ||
502 | } | ||
503 | |||
504 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) | ||
505 | { | ||
506 | struct sd *sd = (struct sd *) gspca_dev; | ||
507 | |||
508 | *val = sd->exposure; | ||
509 | return 0; | ||
510 | } | ||
511 | |||
512 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) | ||
513 | { | ||
514 | struct sd *sd = (struct sd *) gspca_dev; | ||
515 | |||
516 | sd->gain = val; | ||
517 | if (gspca_dev->streaming) | ||
518 | setgain(gspca_dev); | ||
519 | return 0; | ||
520 | } | ||
521 | |||
522 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) | ||
523 | { | ||
524 | struct sd *sd = (struct sd *) gspca_dev; | ||
525 | |||
526 | *val = sd->gain; | ||
527 | return 0; | ||
528 | } | ||
529 | |||
530 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
531 | { | ||
532 | struct sd *sd = (struct sd *) gspca_dev; | ||
533 | |||
534 | sd->autogain = val; | ||
535 | /* when switching to autogain set defaults to make sure | ||
536 | we are on a valid point of the autogain gain / | ||
537 | exposure knee graph, and give this change time to | ||
538 | take effect before doing autogain. */ | ||
539 | if (sd->autogain) { | ||
540 | sd->exposure = PAC207_EXPOSURE_DEFAULT; | ||
541 | sd->gain = PAC207_GAIN_DEFAULT; | ||
542 | if (gspca_dev->streaming) { | ||
543 | sd->autogain_ignore_frames = | ||
544 | PAC207_AUTOGAIN_IGNORE_FRAMES; | ||
545 | setexposure(gspca_dev); | ||
546 | setgain(gspca_dev); | ||
547 | } | ||
548 | } | ||
549 | |||
550 | return 0; | ||
551 | } | ||
552 | |||
553 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | ||
554 | { | ||
555 | struct sd *sd = (struct sd *) gspca_dev; | ||
556 | |||
557 | *val = sd->autogain; | ||
558 | return 0; | ||
559 | } | ||
560 | |||
561 | /* sub-driver description */ | ||
562 | static const struct sd_desc sd_desc = { | ||
563 | .name = MODULE_NAME, | ||
564 | .ctrls = sd_ctrls, | ||
565 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
566 | .config = sd_config, | ||
567 | .open = sd_open, | ||
568 | .start = sd_start, | ||
569 | .stopN = sd_stopN, | ||
570 | .stop0 = sd_stop0, | ||
571 | .close = sd_close, | ||
572 | .dq_callback = pac207_do_auto_gain, | ||
573 | .pkt_scan = sd_pkt_scan, | ||
574 | }; | ||
575 | |||
576 | /* -- module initialisation -- */ | ||
577 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
578 | static const __devinitdata struct usb_device_id device_table[] = { | ||
579 | {USB_DEVICE(0x041e, 0x4028), DVNM("Creative Webcam Vista Plus")}, | ||
580 | {USB_DEVICE(0x093a, 0x2460), DVNM("Q-Tec Webcam 100")}, | ||
581 | {USB_DEVICE(0x093a, 0x2463), DVNM("Philips spc200nc pac207")}, | ||
582 | {USB_DEVICE(0x093a, 0x2464), DVNM("Labtec Webcam 1200")}, | ||
583 | {USB_DEVICE(0x093a, 0x2468), DVNM("PAC207")}, | ||
584 | {USB_DEVICE(0x093a, 0x2470), DVNM("Genius GF112")}, | ||
585 | {USB_DEVICE(0x093a, 0x2471), DVNM("Genius VideoCam GE111")}, | ||
586 | {USB_DEVICE(0x093a, 0x2472), DVNM("Genius VideoCam GE110")}, | ||
587 | {USB_DEVICE(0x2001, 0xf115), DVNM("D-Link DSB-C120")}, | ||
588 | {} | ||
589 | }; | ||
590 | MODULE_DEVICE_TABLE(usb, device_table); | ||
591 | |||
592 | /* -- device connect -- */ | ||
593 | static int sd_probe(struct usb_interface *intf, | ||
594 | const struct usb_device_id *id) | ||
595 | { | ||
596 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
597 | THIS_MODULE); | ||
598 | } | ||
599 | |||
600 | static struct usb_driver sd_driver = { | ||
601 | .name = MODULE_NAME, | ||
602 | .id_table = device_table, | ||
603 | .probe = sd_probe, | ||
604 | .disconnect = gspca_disconnect, | ||
605 | }; | ||
606 | |||
607 | /* -- module insert / remove -- */ | ||
608 | static int __init sd_mod_init(void) | ||
609 | { | ||
610 | if (usb_register(&sd_driver) < 0) | ||
611 | return -1; | ||
612 | PDEBUG(D_PROBE, "v%s registered", version); | ||
613 | return 0; | ||
614 | } | ||
615 | static void __exit sd_mod_exit(void) | ||
616 | { | ||
617 | usb_deregister(&sd_driver); | ||
618 | PDEBUG(D_PROBE, "deregistered"); | ||
619 | } | ||
620 | |||
621 | module_init(sd_mod_init); | ||
622 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c new file mode 100644 index 000000000000..5c052e31be4a --- /dev/null +++ b/drivers/media/video/gspca/pac7311.c | |||
@@ -0,0 +1,760 @@ | |||
1 | /* | ||
2 | * Pixart PAC7311 library | ||
3 | * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li | ||
4 | * | ||
5 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #define MODULE_NAME "pac7311" | ||
23 | |||
24 | #include "gspca.h" | ||
25 | |||
26 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) | ||
27 | static const char version[] = "2.1.7"; | ||
28 | |||
29 | MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); | ||
30 | MODULE_DESCRIPTION("Pixart PAC7311"); | ||
31 | MODULE_LICENSE("GPL"); | ||
32 | |||
33 | /* specific webcam descriptor */ | ||
34 | struct sd { | ||
35 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
36 | |||
37 | int avg_lum; | ||
38 | |||
39 | unsigned char brightness; | ||
40 | unsigned char contrast; | ||
41 | unsigned char colors; | ||
42 | unsigned char autogain; | ||
43 | |||
44 | char ffseq; | ||
45 | signed char ag_cnt; | ||
46 | #define AG_CNT_START 13 | ||
47 | }; | ||
48 | |||
49 | /* V4L2 controls supported by the driver */ | ||
50 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
51 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
52 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
53 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
54 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
55 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
56 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
57 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
58 | |||
59 | static struct ctrl sd_ctrls[] = { | ||
60 | { | ||
61 | { | ||
62 | .id = V4L2_CID_BRIGHTNESS, | ||
63 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
64 | .name = "Brightness", | ||
65 | .minimum = 0, | ||
66 | #define BRIGHTNESS_MAX 0x20 | ||
67 | .maximum = BRIGHTNESS_MAX, | ||
68 | .step = 1, | ||
69 | #define BRIGHTNESS_DEF 0x10 | ||
70 | .default_value = BRIGHTNESS_DEF, | ||
71 | }, | ||
72 | .set = sd_setbrightness, | ||
73 | .get = sd_getbrightness, | ||
74 | }, | ||
75 | { | ||
76 | { | ||
77 | .id = V4L2_CID_CONTRAST, | ||
78 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
79 | .name = "Contrast", | ||
80 | .minimum = 0, | ||
81 | .maximum = 255, | ||
82 | .step = 1, | ||
83 | #define CONTRAST_DEF 127 | ||
84 | .default_value = CONTRAST_DEF, | ||
85 | }, | ||
86 | .set = sd_setcontrast, | ||
87 | .get = sd_getcontrast, | ||
88 | }, | ||
89 | { | ||
90 | { | ||
91 | .id = V4L2_CID_SATURATION, | ||
92 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
93 | .name = "Color", | ||
94 | .minimum = 0, | ||
95 | .maximum = 255, | ||
96 | .step = 1, | ||
97 | #define COLOR_DEF 127 | ||
98 | .default_value = COLOR_DEF, | ||
99 | }, | ||
100 | .set = sd_setcolors, | ||
101 | .get = sd_getcolors, | ||
102 | }, | ||
103 | { | ||
104 | { | ||
105 | .id = V4L2_CID_AUTOGAIN, | ||
106 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
107 | .name = "Auto Gain", | ||
108 | .minimum = 0, | ||
109 | .maximum = 1, | ||
110 | .step = 1, | ||
111 | #define AUTOGAIN_DEF 1 | ||
112 | .default_value = AUTOGAIN_DEF, | ||
113 | }, | ||
114 | .set = sd_setautogain, | ||
115 | .get = sd_getautogain, | ||
116 | }, | ||
117 | }; | ||
118 | |||
119 | static struct v4l2_pix_format vga_mode[] = { | ||
120 | {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
121 | .bytesperline = 160, | ||
122 | .sizeimage = 160 * 120 * 3 / 8 + 590, | ||
123 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
124 | .priv = 2}, | ||
125 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
126 | .bytesperline = 320, | ||
127 | .sizeimage = 320 * 240 * 3 / 8 + 590, | ||
128 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
129 | .priv = 1}, | ||
130 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
131 | .bytesperline = 640, | ||
132 | .sizeimage = 640 * 480 * 3 / 8 + 590, | ||
133 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
134 | .priv = 0}, | ||
135 | }; | ||
136 | |||
137 | #define PAC7311_JPEG_HEADER_SIZE (sizeof pac7311_jpeg_header) /* (594) */ | ||
138 | |||
139 | static const __u8 pac7311_jpeg_header[] = { | ||
140 | 0xff, 0xd8, | ||
141 | 0xff, 0xe0, 0x00, 0x03, 0x20, | ||
142 | 0xff, 0xc0, 0x00, 0x11, 0x08, | ||
143 | 0x01, 0xe0, /* 12: height */ | ||
144 | 0x02, 0x80, /* 14: width */ | ||
145 | 0x03, /* 16 */ | ||
146 | 0x01, 0x21, 0x00, | ||
147 | 0x02, 0x11, 0x01, | ||
148 | 0x03, 0x11, 0x01, | ||
149 | 0xff, 0xdb, 0x00, 0x84, | ||
150 | 0x00, 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d, | ||
151 | 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a, 0x18, 0x16, | ||
152 | 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d, 0x28, 0x3a, 0x33, 0x3d, | ||
153 | 0x3c, 0x39, 0x33, 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, | ||
154 | 0x44, 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57, 0x5f, | ||
155 | 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, 0x79, 0x70, 0x64, | ||
156 | 0x78, 0x5c, 0x65, 0x67, 0x63, 0x01, 0x11, 0x12, 0x12, 0x18, | ||
157 | 0x15, 0x18, 0x2f, 0x1a, 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, | ||
158 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
159 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
160 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
161 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
162 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
163 | 0xff, 0xc4, 0x01, 0xa2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, | ||
164 | 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
165 | 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, | ||
166 | 0x09, 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, | ||
167 | 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, | ||
168 | 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, | ||
169 | 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, | ||
170 | 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, | ||
171 | 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, | ||
172 | 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, | ||
173 | 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, | ||
174 | 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, | ||
175 | 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, | ||
176 | 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, | ||
177 | 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, | ||
178 | 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, | ||
179 | 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, | ||
180 | 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, | ||
181 | 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, | ||
182 | 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, | ||
183 | 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, | ||
184 | 0xf9, 0xfa, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, | ||
185 | 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
186 | 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, | ||
187 | 0x0b, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, | ||
188 | 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, | ||
189 | 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, | ||
190 | 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, | ||
191 | 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, | ||
192 | 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, | ||
193 | 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, | ||
194 | 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, | ||
195 | 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, | ||
196 | 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, | ||
197 | 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, | ||
198 | 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, | ||
199 | 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, | ||
200 | 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, | ||
201 | 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, | ||
202 | 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, | ||
203 | 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, | ||
204 | 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, | ||
205 | 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, | ||
206 | 0x11, 0x00, 0x3f, 0x00 | ||
207 | }; | ||
208 | |||
209 | static void reg_w_buf(struct gspca_dev *gspca_dev, | ||
210 | __u16 index, | ||
211 | const char *buffer, __u16 len) | ||
212 | { | ||
213 | memcpy(gspca_dev->usb_buf, buffer, len); | ||
214 | usb_control_msg(gspca_dev->dev, | ||
215 | usb_sndctrlpipe(gspca_dev->dev, 0), | ||
216 | 1, /* request */ | ||
217 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
218 | 0, /* value */ | ||
219 | index, gspca_dev->usb_buf, len, | ||
220 | 500); | ||
221 | } | ||
222 | |||
223 | static __u8 reg_r(struct gspca_dev *gspca_dev, | ||
224 | __u16 index) | ||
225 | { | ||
226 | usb_control_msg(gspca_dev->dev, | ||
227 | usb_rcvctrlpipe(gspca_dev->dev, 0), | ||
228 | 0, /* request */ | ||
229 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
230 | 0, /* value */ | ||
231 | index, gspca_dev->usb_buf, 1, | ||
232 | 500); | ||
233 | return gspca_dev->usb_buf[0]; | ||
234 | } | ||
235 | |||
236 | static void reg_w(struct gspca_dev *gspca_dev, | ||
237 | __u16 index, | ||
238 | __u8 value) | ||
239 | { | ||
240 | gspca_dev->usb_buf[0] = value; | ||
241 | usb_control_msg(gspca_dev->dev, | ||
242 | usb_sndctrlpipe(gspca_dev->dev, 0), | ||
243 | 0, /* request */ | ||
244 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
245 | value, index, gspca_dev->usb_buf, 1, | ||
246 | 500); | ||
247 | } | ||
248 | |||
249 | /* this function is called at probe time */ | ||
250 | static int sd_config(struct gspca_dev *gspca_dev, | ||
251 | const struct usb_device_id *id) | ||
252 | { | ||
253 | struct sd *sd = (struct sd *) gspca_dev; | ||
254 | struct cam *cam; | ||
255 | |||
256 | PDEBUG(D_CONF, "Find Sensor PAC7311"); | ||
257 | reg_w(gspca_dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */ | ||
258 | reg_w(gspca_dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */ | ||
259 | reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ | ||
260 | reg_w(gspca_dev, 0xff, 0x04); | ||
261 | reg_w(gspca_dev, 0x27, 0x80); | ||
262 | reg_w(gspca_dev, 0x28, 0xca); | ||
263 | reg_w(gspca_dev, 0x29, 0x53); | ||
264 | reg_w(gspca_dev, 0x2a, 0x0e); | ||
265 | reg_w(gspca_dev, 0xff, 0x01); | ||
266 | reg_w(gspca_dev, 0x3e, 0x20); | ||
267 | |||
268 | cam = &gspca_dev->cam; | ||
269 | cam->dev_name = (char *) id->driver_info; | ||
270 | cam->epaddr = 0x05; | ||
271 | cam->cam_mode = vga_mode; | ||
272 | cam->nmodes = ARRAY_SIZE(vga_mode); | ||
273 | |||
274 | sd->brightness = BRIGHTNESS_DEF; | ||
275 | sd->contrast = CONTRAST_DEF; | ||
276 | sd->colors = COLOR_DEF; | ||
277 | sd->autogain = AUTOGAIN_DEF; | ||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
282 | { | ||
283 | struct sd *sd = (struct sd *) gspca_dev; | ||
284 | int brightness; | ||
285 | |||
286 | /*jfm: inverted?*/ | ||
287 | brightness = BRIGHTNESS_MAX - sd->brightness; | ||
288 | reg_w(gspca_dev, 0xff, 0x04); | ||
289 | /* reg_w(gspca_dev, 0x0e, 0x00); */ | ||
290 | reg_w(gspca_dev, 0x0f, brightness); | ||
291 | /* load registers to sensor (Bit 0, auto clear) */ | ||
292 | reg_w(gspca_dev, 0x11, 0x01); | ||
293 | PDEBUG(D_CONF|D_STREAM, "brightness: %i", brightness); | ||
294 | } | ||
295 | |||
296 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
297 | { | ||
298 | struct sd *sd = (struct sd *) gspca_dev; | ||
299 | |||
300 | reg_w(gspca_dev, 0xff, 0x01); | ||
301 | reg_w(gspca_dev, 0x80, sd->contrast); | ||
302 | /* load registers to sensor (Bit 0, auto clear) */ | ||
303 | reg_w(gspca_dev, 0x11, 0x01); | ||
304 | PDEBUG(D_CONF|D_STREAM, "contrast: %i", sd->contrast); | ||
305 | } | ||
306 | |||
307 | static void setcolors(struct gspca_dev *gspca_dev) | ||
308 | { | ||
309 | struct sd *sd = (struct sd *) gspca_dev; | ||
310 | |||
311 | reg_w(gspca_dev, 0xff, 0x01); | ||
312 | reg_w(gspca_dev, 0x10, sd->colors); | ||
313 | /* load registers to sensor (Bit 0, auto clear) */ | ||
314 | reg_w(gspca_dev, 0x11, 0x01); | ||
315 | PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); | ||
316 | } | ||
317 | |||
318 | /* this function is called at open time */ | ||
319 | static int sd_open(struct gspca_dev *gspca_dev) | ||
320 | { | ||
321 | reg_w(gspca_dev, 0x78, 0x00); /* Turn on LED */ | ||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | static void sd_start(struct gspca_dev *gspca_dev) | ||
326 | { | ||
327 | struct sd *sd = (struct sd *) gspca_dev; | ||
328 | |||
329 | reg_w(gspca_dev, 0xff, 0x01); | ||
330 | reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8); | ||
331 | reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8); | ||
332 | reg_w_buf(gspca_dev, 0x0012, "\x00\x07\x00\x0a\x10\x00\xa0\x10", 8); | ||
333 | reg_w_buf(gspca_dev, 0x001a, "\x02\x00\x00\x00\x00\x0b\x01\x00", 8); | ||
334 | reg_w_buf(gspca_dev, 0x0022, "\x00\x00\x00\x00\x00\x00\x00\x00", 8); | ||
335 | reg_w_buf(gspca_dev, 0x002a, "\x00\x00\x00", 3); | ||
336 | reg_w_buf(gspca_dev, 0x003e, "\x00\x00\x78\x52\x4a\x52\x78\x6e", 8); | ||
337 | reg_w_buf(gspca_dev, 0x0046, "\x48\x46\x48\x6e\x5f\x49\x42\x49", 8); | ||
338 | reg_w_buf(gspca_dev, 0x004e, "\x5f\x5f\x49\x42\x49\x5f\x6e\x48", 8); | ||
339 | reg_w_buf(gspca_dev, 0x0056, "\x46\x48\x6e\x78\x52\x4a\x52\x78", 8); | ||
340 | reg_w_buf(gspca_dev, 0x005e, "\x00\x00\x09\x1b\x34\x49\x5c\x9b", 8); | ||
341 | reg_w_buf(gspca_dev, 0x0066, "\xd0\xff", 2); | ||
342 | reg_w_buf(gspca_dev, 0x0078, "\x44\x00\xf2\x01\x01\x80", 6); | ||
343 | reg_w_buf(gspca_dev, 0x007f, "\x2a\x1c\x00\xc8\x02\x58\x03\x84", 8); | ||
344 | reg_w_buf(gspca_dev, 0x0087, "\x12\x00\x1a\x04\x08\x0c\x10\x14", 8); | ||
345 | reg_w_buf(gspca_dev, 0x008f, "\x18\x20", 2); | ||
346 | reg_w_buf(gspca_dev, 0x0096, "\x01\x08\x04", 3); | ||
347 | reg_w_buf(gspca_dev, 0x00a0, "\x44\x44\x44\x04", 4); | ||
348 | reg_w_buf(gspca_dev, 0x00f0, "\x01\x00\x00\x00\x22\x00\x20\x00", 8); | ||
349 | reg_w_buf(gspca_dev, 0x00f8, "\x3f\x00\x0a\x01\x00", 5); | ||
350 | |||
351 | reg_w(gspca_dev, 0xff, 0x04); | ||
352 | reg_w(gspca_dev, 0x02, 0x04); | ||
353 | reg_w(gspca_dev, 0x03, 0x54); | ||
354 | reg_w(gspca_dev, 0x04, 0x07); | ||
355 | reg_w(gspca_dev, 0x05, 0x2b); | ||
356 | reg_w(gspca_dev, 0x06, 0x09); | ||
357 | reg_w(gspca_dev, 0x07, 0x0f); | ||
358 | reg_w(gspca_dev, 0x08, 0x09); | ||
359 | reg_w(gspca_dev, 0x09, 0x00); | ||
360 | reg_w(gspca_dev, 0x0c, 0x07); | ||
361 | reg_w(gspca_dev, 0x0d, 0x00); | ||
362 | reg_w(gspca_dev, 0x0e, 0x00); | ||
363 | reg_w(gspca_dev, 0x0f, 0x62); | ||
364 | reg_w(gspca_dev, 0x10, 0x08); | ||
365 | reg_w(gspca_dev, 0x12, 0x07); | ||
366 | reg_w(gspca_dev, 0x13, 0x00); | ||
367 | reg_w(gspca_dev, 0x14, 0x00); | ||
368 | reg_w(gspca_dev, 0x15, 0x00); | ||
369 | reg_w(gspca_dev, 0x16, 0x00); | ||
370 | reg_w(gspca_dev, 0x17, 0x00); | ||
371 | reg_w(gspca_dev, 0x18, 0x00); | ||
372 | reg_w(gspca_dev, 0x19, 0x00); | ||
373 | reg_w(gspca_dev, 0x1a, 0x00); | ||
374 | reg_w(gspca_dev, 0x1b, 0x03); | ||
375 | reg_w(gspca_dev, 0x1c, 0xa0); | ||
376 | reg_w(gspca_dev, 0x1d, 0x01); | ||
377 | reg_w(gspca_dev, 0x1e, 0xf4); | ||
378 | reg_w(gspca_dev, 0x21, 0x00); | ||
379 | reg_w(gspca_dev, 0x22, 0x08); | ||
380 | reg_w(gspca_dev, 0x24, 0x03); | ||
381 | reg_w(gspca_dev, 0x26, 0x00); | ||
382 | reg_w(gspca_dev, 0x27, 0x01); | ||
383 | reg_w(gspca_dev, 0x28, 0xca); | ||
384 | reg_w(gspca_dev, 0x29, 0x10); | ||
385 | reg_w(gspca_dev, 0x2a, 0x06); | ||
386 | reg_w(gspca_dev, 0x2b, 0x78); | ||
387 | reg_w(gspca_dev, 0x2c, 0x00); | ||
388 | reg_w(gspca_dev, 0x2d, 0x00); | ||
389 | reg_w(gspca_dev, 0x2e, 0x00); | ||
390 | reg_w(gspca_dev, 0x2f, 0x00); | ||
391 | reg_w(gspca_dev, 0x30, 0x23); | ||
392 | reg_w(gspca_dev, 0x31, 0x28); | ||
393 | reg_w(gspca_dev, 0x32, 0x04); | ||
394 | reg_w(gspca_dev, 0x33, 0x11); | ||
395 | reg_w(gspca_dev, 0x34, 0x00); | ||
396 | reg_w(gspca_dev, 0x35, 0x00); | ||
397 | reg_w(gspca_dev, 0x11, 0x01); | ||
398 | setcontrast(gspca_dev); | ||
399 | setbrightness(gspca_dev); | ||
400 | setcolors(gspca_dev); | ||
401 | |||
402 | /* set correct resolution */ | ||
403 | switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { | ||
404 | case 2: /* 160x120 */ | ||
405 | reg_w(gspca_dev, 0xff, 0x04); | ||
406 | reg_w(gspca_dev, 0x02, 0x03); | ||
407 | reg_w(gspca_dev, 0xff, 0x01); | ||
408 | reg_w(gspca_dev, 0x08, 0x09); | ||
409 | reg_w(gspca_dev, 0x17, 0x20); | ||
410 | reg_w(gspca_dev, 0x1b, 0x00); | ||
411 | /* reg_w(gspca_dev, 0x80, 0x69); */ | ||
412 | reg_w(gspca_dev, 0x87, 0x10); | ||
413 | break; | ||
414 | case 1: /* 320x240 */ | ||
415 | reg_w(gspca_dev, 0xff, 0x04); | ||
416 | reg_w(gspca_dev, 0x02, 0x03); | ||
417 | reg_w(gspca_dev, 0xff, 0x01); | ||
418 | reg_w(gspca_dev, 0x08, 0x09); | ||
419 | reg_w(gspca_dev, 0x17, 0x30); | ||
420 | /* reg_w(gspca_dev, 0x80, 0x3f); */ | ||
421 | reg_w(gspca_dev, 0x87, 0x11); | ||
422 | break; | ||
423 | case 0: /* 640x480 */ | ||
424 | reg_w(gspca_dev, 0xff, 0x04); | ||
425 | reg_w(gspca_dev, 0x02, 0x03); | ||
426 | reg_w(gspca_dev, 0xff, 0x01); | ||
427 | reg_w(gspca_dev, 0x08, 0x08); | ||
428 | reg_w(gspca_dev, 0x17, 0x00); | ||
429 | /* reg_w(gspca_dev, 0x80, 0x1c); */ | ||
430 | reg_w(gspca_dev, 0x87, 0x12); | ||
431 | break; | ||
432 | } | ||
433 | |||
434 | /* start stream */ | ||
435 | reg_w(gspca_dev, 0xff, 0x01); | ||
436 | reg_w(gspca_dev, 0x78, 0x04); | ||
437 | reg_w(gspca_dev, 0x78, 0x05); | ||
438 | |||
439 | if (sd->autogain) { | ||
440 | sd->ag_cnt = AG_CNT_START; | ||
441 | sd->avg_lum = 0; | ||
442 | } else { | ||
443 | sd->ag_cnt = -1; | ||
444 | } | ||
445 | } | ||
446 | |||
447 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
448 | { | ||
449 | reg_w(gspca_dev, 0xff, 0x04); | ||
450 | reg_w(gspca_dev, 0x27, 0x80); | ||
451 | reg_w(gspca_dev, 0x28, 0xca); | ||
452 | reg_w(gspca_dev, 0x29, 0x53); | ||
453 | reg_w(gspca_dev, 0x2a, 0x0e); | ||
454 | reg_w(gspca_dev, 0xff, 0x01); | ||
455 | reg_w(gspca_dev, 0x3e, 0x20); | ||
456 | reg_w(gspca_dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */ | ||
457 | reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ | ||
458 | reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ | ||
459 | } | ||
460 | |||
461 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
462 | { | ||
463 | } | ||
464 | |||
465 | /* this function is called at close time */ | ||
466 | static void sd_close(struct gspca_dev *gspca_dev) | ||
467 | { | ||
468 | reg_w(gspca_dev, 0xff, 0x04); | ||
469 | reg_w(gspca_dev, 0x27, 0x80); | ||
470 | reg_w(gspca_dev, 0x28, 0xca); | ||
471 | reg_w(gspca_dev, 0x29, 0x53); | ||
472 | reg_w(gspca_dev, 0x2a, 0x0e); | ||
473 | reg_w(gspca_dev, 0xff, 0x01); | ||
474 | reg_w(gspca_dev, 0x3e, 0x20); | ||
475 | reg_w(gspca_dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */ | ||
476 | reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ | ||
477 | reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ | ||
478 | } | ||
479 | |||
480 | static void setautogain(struct gspca_dev *gspca_dev, int luma) | ||
481 | { | ||
482 | int luma_mean = 128; | ||
483 | int luma_delta = 20; | ||
484 | __u8 spring = 5; | ||
485 | int Gbright; | ||
486 | |||
487 | Gbright = reg_r(gspca_dev, 0x02); | ||
488 | PDEBUG(D_FRAM, "luma mean %d", luma); | ||
489 | if (luma < luma_mean - luma_delta || | ||
490 | luma > luma_mean + luma_delta) { | ||
491 | Gbright += (luma_mean - luma) >> spring; | ||
492 | if (Gbright > 0x1a) | ||
493 | Gbright = 0x1a; | ||
494 | else if (Gbright < 4) | ||
495 | Gbright = 4; | ||
496 | PDEBUG(D_FRAM, "gbright %d", Gbright); | ||
497 | reg_w(gspca_dev, 0xff, 0x04); | ||
498 | reg_w(gspca_dev, 0x0f, Gbright); | ||
499 | /* load registers to sensor (Bit 0, auto clear) */ | ||
500 | reg_w(gspca_dev, 0x11, 0x01); | ||
501 | } | ||
502 | } | ||
503 | |||
504 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
505 | struct gspca_frame *frame, /* target */ | ||
506 | __u8 *data, /* isoc packet */ | ||
507 | int len) /* iso packet length */ | ||
508 | { | ||
509 | struct sd *sd = (struct sd *) gspca_dev; | ||
510 | unsigned char tmpbuf[4]; | ||
511 | int i, p, ffseq; | ||
512 | |||
513 | /* if (len < 5) { */ | ||
514 | if (len < 6) { | ||
515 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
516 | return; | ||
517 | } | ||
518 | |||
519 | ffseq = sd->ffseq; | ||
520 | |||
521 | for (p = 0; p < len - 6; p++) { | ||
522 | if ((data[0 + p] == 0xff) | ||
523 | && (data[1 + p] == 0xff) | ||
524 | && (data[2 + p] == 0x00) | ||
525 | && (data[3 + p] == 0xff) | ||
526 | && (data[4 + p] == 0x96)) { | ||
527 | |||
528 | /* start of frame */ | ||
529 | if (sd->ag_cnt >= 0 && p > 28) { | ||
530 | sd->avg_lum += data[p - 23]; | ||
531 | if (--sd->ag_cnt < 0) { | ||
532 | sd->ag_cnt = AG_CNT_START; | ||
533 | setautogain(gspca_dev, | ||
534 | sd->avg_lum / AG_CNT_START); | ||
535 | sd->avg_lum = 0; | ||
536 | } | ||
537 | } | ||
538 | |||
539 | /* copy the end of data to the current frame */ | ||
540 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | ||
541 | data, p); | ||
542 | |||
543 | /* put the JPEG header in the new frame */ | ||
544 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | ||
545 | (unsigned char *) pac7311_jpeg_header, | ||
546 | 12); | ||
547 | tmpbuf[0] = gspca_dev->height >> 8; | ||
548 | tmpbuf[1] = gspca_dev->height & 0xff; | ||
549 | tmpbuf[2] = gspca_dev->width >> 8; | ||
550 | tmpbuf[3] = gspca_dev->width & 0xff; | ||
551 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
552 | tmpbuf, 4); | ||
553 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
554 | (unsigned char *) &pac7311_jpeg_header[16], | ||
555 | PAC7311_JPEG_HEADER_SIZE - 16); | ||
556 | |||
557 | data += p + 7; | ||
558 | len -= p + 7; | ||
559 | ffseq = 0; | ||
560 | break; | ||
561 | } | ||
562 | } | ||
563 | |||
564 | /* remove the 'ff ff ff xx' sequences */ | ||
565 | switch (ffseq) { | ||
566 | case 3: | ||
567 | data += 1; | ||
568 | len -= 1; | ||
569 | break; | ||
570 | case 2: | ||
571 | if (data[0] == 0xff) { | ||
572 | data += 2; | ||
573 | len -= 2; | ||
574 | frame->data_end -= 2; | ||
575 | } | ||
576 | break; | ||
577 | case 1: | ||
578 | if (data[0] == 0xff | ||
579 | && data[1] == 0xff) { | ||
580 | data += 3; | ||
581 | len -= 3; | ||
582 | frame->data_end -= 1; | ||
583 | } | ||
584 | break; | ||
585 | } | ||
586 | for (i = 0; i < len - 4; i++) { | ||
587 | if (data[i] == 0xff | ||
588 | && data[i + 1] == 0xff | ||
589 | && data[i + 2] == 0xff) { | ||
590 | memmove(&data[i], &data[i + 4], len - i - 4); | ||
591 | len -= 4; | ||
592 | } | ||
593 | } | ||
594 | ffseq = 0; | ||
595 | if (data[len - 4] == 0xff) { | ||
596 | if (data[len - 3] == 0xff | ||
597 | && data[len - 2] == 0xff) { | ||
598 | len -= 4; | ||
599 | } | ||
600 | } else if (data[len - 3] == 0xff) { | ||
601 | if (data[len - 2] == 0xff | ||
602 | && data[len - 1] == 0xff) | ||
603 | ffseq = 3; | ||
604 | } else if (data[len - 2] == 0xff) { | ||
605 | if (data[len - 1] == 0xff) | ||
606 | ffseq = 2; | ||
607 | } else if (data[len - 1] == 0xff) | ||
608 | ffseq = 1; | ||
609 | sd->ffseq = ffseq; | ||
610 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
611 | } | ||
612 | |||
613 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
614 | { | ||
615 | /* sd->brightness = reg_r(gspca_dev, 0x08); | ||
616 | return sd->brightness; */ | ||
617 | /* PDEBUG(D_CONF, "Called pac7311_getbrightness: Not implemented yet"); */ | ||
618 | } | ||
619 | |||
620 | |||
621 | |||
622 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
623 | { | ||
624 | struct sd *sd = (struct sd *) gspca_dev; | ||
625 | |||
626 | sd->brightness = val; | ||
627 | if (gspca_dev->streaming) | ||
628 | setbrightness(gspca_dev); | ||
629 | return 0; | ||
630 | } | ||
631 | |||
632 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
633 | { | ||
634 | struct sd *sd = (struct sd *) gspca_dev; | ||
635 | |||
636 | getbrightness(gspca_dev); | ||
637 | *val = sd->brightness; | ||
638 | return 0; | ||
639 | } | ||
640 | |||
641 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
642 | { | ||
643 | struct sd *sd = (struct sd *) gspca_dev; | ||
644 | |||
645 | sd->contrast = val; | ||
646 | if (gspca_dev->streaming) | ||
647 | setcontrast(gspca_dev); | ||
648 | return 0; | ||
649 | } | ||
650 | |||
651 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
652 | { | ||
653 | struct sd *sd = (struct sd *) gspca_dev; | ||
654 | |||
655 | /* getcontrast(gspca_dev); */ | ||
656 | *val = sd->contrast; | ||
657 | return 0; | ||
658 | } | ||
659 | |||
660 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
661 | { | ||
662 | struct sd *sd = (struct sd *) gspca_dev; | ||
663 | |||
664 | sd->colors = val; | ||
665 | if (gspca_dev->streaming) | ||
666 | setcolors(gspca_dev); | ||
667 | return 0; | ||
668 | } | ||
669 | |||
670 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
671 | { | ||
672 | struct sd *sd = (struct sd *) gspca_dev; | ||
673 | |||
674 | /* getcolors(gspca_dev); */ | ||
675 | *val = sd->colors; | ||
676 | return 0; | ||
677 | } | ||
678 | |||
679 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
680 | { | ||
681 | struct sd *sd = (struct sd *) gspca_dev; | ||
682 | |||
683 | sd->autogain = val; | ||
684 | if (val) { | ||
685 | sd->ag_cnt = AG_CNT_START; | ||
686 | sd->avg_lum = 0; | ||
687 | } else { | ||
688 | sd->ag_cnt = -1; | ||
689 | } | ||
690 | return 0; | ||
691 | } | ||
692 | |||
693 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | ||
694 | { | ||
695 | struct sd *sd = (struct sd *) gspca_dev; | ||
696 | |||
697 | *val = sd->autogain; | ||
698 | return 0; | ||
699 | } | ||
700 | |||
701 | /* sub-driver description */ | ||
702 | static struct sd_desc sd_desc = { | ||
703 | .name = MODULE_NAME, | ||
704 | .ctrls = sd_ctrls, | ||
705 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
706 | .config = sd_config, | ||
707 | .open = sd_open, | ||
708 | .start = sd_start, | ||
709 | .stopN = sd_stopN, | ||
710 | .stop0 = sd_stop0, | ||
711 | .close = sd_close, | ||
712 | .pkt_scan = sd_pkt_scan, | ||
713 | }; | ||
714 | |||
715 | /* -- module initialisation -- */ | ||
716 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
717 | static __devinitdata struct usb_device_id device_table[] = { | ||
718 | {USB_DEVICE(0x093a, 0x2600), DVNM("Typhoon")}, | ||
719 | {USB_DEVICE(0x093a, 0x2601), DVNM("Philips SPC610NC")}, | ||
720 | {USB_DEVICE(0x093a, 0x2603), DVNM("PAC7312")}, | ||
721 | {USB_DEVICE(0x093a, 0x2608), DVNM("Trust WB-3300p")}, | ||
722 | {USB_DEVICE(0x093a, 0x260e), DVNM("Gigaware VGA PC Camera")}, | ||
723 | /* and also ', Trust WB-3350p, SIGMA cam 2350' */ | ||
724 | {USB_DEVICE(0x093a, 0x260f), DVNM("SnakeCam")}, | ||
725 | {USB_DEVICE(0x093a, 0x2621), DVNM("PAC731x")}, | ||
726 | {} | ||
727 | }; | ||
728 | MODULE_DEVICE_TABLE(usb, device_table); | ||
729 | |||
730 | /* -- device connect -- */ | ||
731 | static int sd_probe(struct usb_interface *intf, | ||
732 | const struct usb_device_id *id) | ||
733 | { | ||
734 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
735 | THIS_MODULE); | ||
736 | } | ||
737 | |||
738 | static struct usb_driver sd_driver = { | ||
739 | .name = MODULE_NAME, | ||
740 | .id_table = device_table, | ||
741 | .probe = sd_probe, | ||
742 | .disconnect = gspca_disconnect, | ||
743 | }; | ||
744 | |||
745 | /* -- module insert / remove -- */ | ||
746 | static int __init sd_mod_init(void) | ||
747 | { | ||
748 | if (usb_register(&sd_driver) < 0) | ||
749 | return -1; | ||
750 | PDEBUG(D_PROBE, "v%s registered", version); | ||
751 | return 0; | ||
752 | } | ||
753 | static void __exit sd_mod_exit(void) | ||
754 | { | ||
755 | usb_deregister(&sd_driver); | ||
756 | PDEBUG(D_PROBE, "deregistered"); | ||
757 | } | ||
758 | |||
759 | module_init(sd_mod_init); | ||
760 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c new file mode 100644 index 000000000000..dbeebe8625c5 --- /dev/null +++ b/drivers/media/video/gspca/sonixb.c | |||
@@ -0,0 +1,1477 @@ | |||
1 | /* | ||
2 | * sonix sn9c102 (bayer) library | ||
3 | * Copyright (C) 2003 2004 Michel Xhaard mxhaard@magic.fr | ||
4 | * Add Pas106 Stefano Mozzi (C) 2004 | ||
5 | * | ||
6 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #define MODULE_NAME "sonixb" | ||
24 | |||
25 | #include "gspca.h" | ||
26 | |||
27 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 8) | ||
28 | static const char version[] = "2.1.8"; | ||
29 | |||
30 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
31 | MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver"); | ||
32 | MODULE_LICENSE("GPL"); | ||
33 | |||
34 | /* specific webcam descriptor */ | ||
35 | struct sd { | ||
36 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
37 | |||
38 | struct sd_desc sd_desc; /* our nctrls differ dependend upon the | ||
39 | sensor, so we use a per cam copy */ | ||
40 | atomic_t avg_lum; | ||
41 | |||
42 | unsigned char gain; | ||
43 | unsigned char exposure; | ||
44 | unsigned char brightness; | ||
45 | unsigned char autogain; | ||
46 | unsigned char autogain_ignore_frames; | ||
47 | unsigned char freq; /* light freq filter setting */ | ||
48 | unsigned char saturation; | ||
49 | unsigned char hue; | ||
50 | unsigned char contrast; | ||
51 | |||
52 | unsigned char fr_h_sz; /* size of frame header */ | ||
53 | char sensor; /* Type of image sensor chip */ | ||
54 | #define SENSOR_HV7131R 0 | ||
55 | #define SENSOR_OV6650 1 | ||
56 | #define SENSOR_OV7630 2 | ||
57 | #define SENSOR_OV7630_3 3 | ||
58 | #define SENSOR_PAS106 4 | ||
59 | #define SENSOR_PAS202 5 | ||
60 | #define SENSOR_TAS5110 6 | ||
61 | #define SENSOR_TAS5130CXX 7 | ||
62 | char sensor_has_gain; | ||
63 | __u8 sensor_addr; | ||
64 | }; | ||
65 | |||
66 | #define COMP2 0x8f | ||
67 | #define COMP 0xc7 /* 0x87 //0x07 */ | ||
68 | #define COMP1 0xc9 /* 0x89 //0x09 */ | ||
69 | |||
70 | #define MCK_INIT 0x63 | ||
71 | #define MCK_INIT1 0x20 /*fixme: Bayer - 0x50 for JPEG ??*/ | ||
72 | |||
73 | #define SYS_CLK 0x04 | ||
74 | |||
75 | /* We calculate the autogain at the end of the transfer of a frame, at this | ||
76 | moment a frame with the old settings is being transmitted, and a frame is | ||
77 | being captured with the old settings. So if we adjust the autogain we must | ||
78 | ignore atleast the 2 next frames for the new settings to come into effect | ||
79 | before doing any other adjustments */ | ||
80 | #define AUTOGAIN_IGNORE_FRAMES 3 | ||
81 | #define AUTOGAIN_DEADZONE 1000 | ||
82 | #define DESIRED_AVG_LUM 7000 | ||
83 | |||
84 | /* V4L2 controls supported by the driver */ | ||
85 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
86 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
87 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); | ||
88 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); | ||
89 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); | ||
90 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
91 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
92 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
93 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | ||
94 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | ||
95 | static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val); | ||
96 | static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val); | ||
97 | static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val); | ||
98 | static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val); | ||
99 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
100 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
101 | |||
102 | static struct ctrl sd_ctrls[] = { | ||
103 | { | ||
104 | { | ||
105 | .id = V4L2_CID_BRIGHTNESS, | ||
106 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
107 | .name = "Brightness", | ||
108 | .minimum = 0, | ||
109 | .maximum = 255, | ||
110 | .step = 1, | ||
111 | #define BRIGHTNESS_DEF 127 | ||
112 | .default_value = BRIGHTNESS_DEF, | ||
113 | }, | ||
114 | .set = sd_setbrightness, | ||
115 | .get = sd_getbrightness, | ||
116 | }, | ||
117 | { | ||
118 | { | ||
119 | .id = V4L2_CID_GAIN, | ||
120 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
121 | .name = "Gain", | ||
122 | .minimum = 0, | ||
123 | .maximum = 255, | ||
124 | .step = 1, | ||
125 | #define GAIN_DEF 127 | ||
126 | #define GAIN_KNEE 200 | ||
127 | .default_value = GAIN_DEF, | ||
128 | }, | ||
129 | .set = sd_setgain, | ||
130 | .get = sd_getgain, | ||
131 | }, | ||
132 | { | ||
133 | { | ||
134 | .id = V4L2_CID_EXPOSURE, | ||
135 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
136 | .name = "Exposure", | ||
137 | #define EXPOSURE_DEF 16 /* 32 ms / 30 fps */ | ||
138 | #define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */ | ||
139 | .minimum = 0, | ||
140 | .maximum = 255, | ||
141 | .step = 1, | ||
142 | .default_value = EXPOSURE_DEF, | ||
143 | .flags = 0, | ||
144 | }, | ||
145 | .set = sd_setexposure, | ||
146 | .get = sd_getexposure, | ||
147 | }, | ||
148 | { | ||
149 | { | ||
150 | .id = V4L2_CID_AUTOGAIN, | ||
151 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
152 | .name = "Automatic Gain (and Exposure)", | ||
153 | .minimum = 0, | ||
154 | .maximum = 1, | ||
155 | .step = 1, | ||
156 | #define AUTOGAIN_DEF 1 | ||
157 | .default_value = AUTOGAIN_DEF, | ||
158 | .flags = 0, | ||
159 | }, | ||
160 | .set = sd_setautogain, | ||
161 | .get = sd_getautogain, | ||
162 | }, | ||
163 | { | ||
164 | { | ||
165 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | ||
166 | .type = V4L2_CTRL_TYPE_MENU, | ||
167 | .name = "Light frequency filter", | ||
168 | .minimum = 0, | ||
169 | .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ | ||
170 | .step = 1, | ||
171 | #define FREQ_DEF 1 | ||
172 | .default_value = FREQ_DEF, | ||
173 | }, | ||
174 | .set = sd_setfreq, | ||
175 | .get = sd_getfreq, | ||
176 | }, | ||
177 | { | ||
178 | { | ||
179 | .id = V4L2_CID_SATURATION, | ||
180 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
181 | .name = "Saturation", | ||
182 | .minimum = 0, | ||
183 | .maximum = 255, | ||
184 | .step = 1, | ||
185 | #define SATURATION_DEF 127 | ||
186 | .default_value = SATURATION_DEF, | ||
187 | }, | ||
188 | .set = sd_setsaturation, | ||
189 | .get = sd_getsaturation, | ||
190 | }, | ||
191 | { | ||
192 | { | ||
193 | .id = V4L2_CID_HUE, | ||
194 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
195 | .name = "Hue", | ||
196 | .minimum = 0, | ||
197 | .maximum = 255, | ||
198 | .step = 1, | ||
199 | #define HUE_DEF 127 | ||
200 | .default_value = HUE_DEF, | ||
201 | }, | ||
202 | .set = sd_sethue, | ||
203 | .get = sd_gethue, | ||
204 | }, | ||
205 | { | ||
206 | { | ||
207 | .id = V4L2_CID_CONTRAST, | ||
208 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
209 | .name = "Contrast", | ||
210 | .minimum = 0, | ||
211 | .maximum = 255, | ||
212 | .step = 1, | ||
213 | #define CONTRAST_DEF 127 | ||
214 | .default_value = CONTRAST_DEF, | ||
215 | }, | ||
216 | .set = sd_setcontrast, | ||
217 | .get = sd_getcontrast, | ||
218 | }, | ||
219 | }; | ||
220 | |||
221 | static struct v4l2_pix_format vga_mode[] = { | ||
222 | {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, | ||
223 | .bytesperline = 160, | ||
224 | .sizeimage = 160 * 120, | ||
225 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
226 | .priv = 2}, | ||
227 | {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, | ||
228 | .bytesperline = 320, | ||
229 | .sizeimage = 320 * 240, | ||
230 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
231 | .priv = 1}, | ||
232 | {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, | ||
233 | .bytesperline = 640, | ||
234 | .sizeimage = 640 * 480, | ||
235 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
236 | .priv = 0}, | ||
237 | }; | ||
238 | static struct v4l2_pix_format sif_mode[] = { | ||
239 | {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, | ||
240 | .bytesperline = 176, | ||
241 | .sizeimage = 176 * 144, | ||
242 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
243 | .priv = 1}, | ||
244 | {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, | ||
245 | .bytesperline = 352, | ||
246 | .sizeimage = 352 * 288, | ||
247 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
248 | .priv = 0}, | ||
249 | }; | ||
250 | |||
251 | static const __u8 probe_ov7630[] = {0x08, 0x44}; | ||
252 | |||
253 | static const __u8 initHv7131[] = { | ||
254 | 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, | ||
255 | 0x00, 0x00, | ||
256 | 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, /* shift from 0x02 0x01 0x00 */ | ||
257 | 0x28, 0x1e, 0x60, 0x8a, 0x20, | ||
258 | 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c | ||
259 | }; | ||
260 | static const __u8 hv7131_sensor_init[][8] = { | ||
261 | {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10}, | ||
262 | {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10}, | ||
263 | {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10}, | ||
264 | {0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16}, | ||
265 | {0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15}, | ||
266 | }; | ||
267 | static const __u8 initOv6650[] = { | ||
268 | 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, | ||
269 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
270 | 0x00, 0x02, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x0b, | ||
271 | 0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00 | ||
272 | }; | ||
273 | static const __u8 ov6650_sensor_init[][8] = | ||
274 | { | ||
275 | /* Bright, contrast, etc are set througth SCBB interface. | ||
276 | * AVCAP on win2 do not send any data on this controls. */ | ||
277 | /* Anyway, some registers appears to alter bright and constrat */ | ||
278 | |||
279 | /* Reset sensor */ | ||
280 | {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, | ||
281 | /* Set clock register 0x11 low nibble is clock divider */ | ||
282 | {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10}, | ||
283 | /* Next some unknown stuff */ | ||
284 | {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10}, | ||
285 | /* {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10}, | ||
286 | * THIS SET GREEN SCREEN | ||
287 | * (pixels could be innverted in decode kind of "brg", | ||
288 | * but blue wont be there. Avoid this data ... */ | ||
289 | {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */ | ||
290 | {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, | ||
291 | {0xa0, 0x60, 0x30, 0x3d, 0x0A, 0xd8, 0xa4, 0x10}, | ||
292 | /* Enable rgb brightness control */ | ||
293 | {0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10}, | ||
294 | /* HDG: Note windows uses the line below, which sets both register 0x60 | ||
295 | and 0x61 I believe these registers of the ov6650 are identical as | ||
296 | those of the ov7630, because if this is true the windows settings | ||
297 | add a bit additional red gain and a lot additional blue gain, which | ||
298 | matches my findings that the windows settings make blue much too | ||
299 | blue and red a little too red. | ||
300 | {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, */ | ||
301 | /* Some more unknown stuff */ | ||
302 | {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10}, | ||
303 | {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */ | ||
304 | }; | ||
305 | |||
306 | static const __u8 initOv7630[] = { | ||
307 | 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */ | ||
308 | 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */ | ||
309 | 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */ | ||
310 | 0x28, 0x1e, /* H & V sizes r15 .. r16 */ | ||
311 | 0x68, COMP1, MCK_INIT1, /* r17 .. r19 */ | ||
312 | 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */ | ||
313 | }; | ||
314 | static const __u8 initOv7630_3[] = { | ||
315 | 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */ | ||
316 | 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */ | ||
317 | 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */ | ||
318 | 0x28, 0x1e, /* H & V sizes r15 .. r16 */ | ||
319 | 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */ | ||
320 | 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00, /* r1a .. r20 */ | ||
321 | 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */ | ||
322 | 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */ | ||
323 | }; | ||
324 | static const __u8 ov7630_sensor_init_com[][8] = { | ||
325 | {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, | ||
326 | {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10}, | ||
327 | /* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */ | ||
328 | {0xd0, 0x21, 0x12, 0x1c, 0x00, 0x80, 0x34, 0x10}, /* jfm */ | ||
329 | {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10}, | ||
330 | {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10}, | ||
331 | {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10}, | ||
332 | {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10}, | ||
333 | {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10}, | ||
334 | {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10}, | ||
335 | {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10}, | ||
336 | {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10}, | ||
337 | /* {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10}, * jfm */ | ||
338 | {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10}, | ||
339 | {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10}, | ||
340 | {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10}, | ||
341 | {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10}, | ||
342 | {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10}, | ||
343 | {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10}, | ||
344 | }; | ||
345 | static const __u8 ov7630_sensor_init[][8] = { | ||
346 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 200ms */ | ||
347 | {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x10}, /* jfm */ | ||
348 | {0xa0, 0x21, 0x10, 0x57, 0xbd, 0x06, 0xf6, 0x16}, | ||
349 | {0xa0, 0x21, 0x76, 0x02, 0xbd, 0x06, 0xf6, 0x16}, | ||
350 | {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */ | ||
351 | }; | ||
352 | static const __u8 ov7630_sensor_init_3[][8] = { | ||
353 | {0xa0, 0x21, 0x2a, 0xa0, 0x00, 0x00, 0x00, 0x10}, | ||
354 | {0xa0, 0x21, 0x2a, 0x80, 0x00, 0x00, 0x00, 0x10}, | ||
355 | }; | ||
356 | |||
357 | static const __u8 initPas106[] = { | ||
358 | 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00, | ||
359 | 0x00, 0x00, | ||
360 | 0x00, 0x00, 0x00, 0x05, 0x01, 0x00, | ||
361 | 0x16, 0x12, 0x28, COMP1, MCK_INIT1, | ||
362 | 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c | ||
363 | }; | ||
364 | /* compression 0x86 mckinit1 0x2b */ | ||
365 | static const __u8 pas106_data[][2] = { | ||
366 | {0x02, 0x04}, /* Pixel Clock Divider 6 */ | ||
367 | {0x03, 0x13}, /* Frame Time MSB */ | ||
368 | /* {0x03, 0x12}, * Frame Time MSB */ | ||
369 | {0x04, 0x06}, /* Frame Time LSB */ | ||
370 | /* {0x04, 0x05}, * Frame Time LSB */ | ||
371 | {0x05, 0x65}, /* Shutter Time Line Offset */ | ||
372 | /* {0x05, 0x6d}, * Shutter Time Line Offset */ | ||
373 | /* {0x06, 0xb1}, * Shutter Time Pixel Offset */ | ||
374 | {0x06, 0xcd}, /* Shutter Time Pixel Offset */ | ||
375 | {0x07, 0xc1}, /* Black Level Subtract Sign */ | ||
376 | /* {0x07, 0x00}, * Black Level Subtract Sign */ | ||
377 | {0x08, 0x06}, /* Black Level Subtract Level */ | ||
378 | {0x08, 0x06}, /* Black Level Subtract Level */ | ||
379 | /* {0x08, 0x01}, * Black Level Subtract Level */ | ||
380 | {0x09, 0x05}, /* Color Gain B Pixel 5 a */ | ||
381 | {0x0a, 0x04}, /* Color Gain G1 Pixel 1 5 */ | ||
382 | {0x0b, 0x04}, /* Color Gain G2 Pixel 1 0 5 */ | ||
383 | {0x0c, 0x05}, /* Color Gain R Pixel 3 1 */ | ||
384 | {0x0d, 0x00}, /* Color GainH Pixel */ | ||
385 | {0x0e, 0x0e}, /* Global Gain */ | ||
386 | {0x0f, 0x00}, /* Contrast */ | ||
387 | {0x10, 0x06}, /* H&V synchro polarity */ | ||
388 | {0x11, 0x06}, /* ?default */ | ||
389 | {0x12, 0x06}, /* DAC scale */ | ||
390 | {0x14, 0x02}, /* ?default */ | ||
391 | {0x13, 0x01}, /* Validate Settings */ | ||
392 | }; | ||
393 | static const __u8 initPas202[] = { | ||
394 | 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, | ||
395 | 0x00, 0x00, | ||
396 | 0x00, 0x00, 0x00, 0x07, 0x03, 0x0a, /* 6 */ | ||
397 | 0x28, 0x1e, 0x28, 0x89, 0x30, | ||
398 | 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c | ||
399 | }; | ||
400 | static const __u8 pas202_sensor_init[][8] = { | ||
401 | {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10}, | ||
402 | {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10}, | ||
403 | {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10}, | ||
404 | {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x32, 0x10}, | ||
405 | {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10}, | ||
406 | {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10}, | ||
407 | {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10}, | ||
408 | {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10}, | ||
409 | {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10}, | ||
410 | {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10}, | ||
411 | {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x10}, | ||
412 | {0xb0, 0x40, 0x0e, 0x00, 0x3d, 0x00, 0x63, 0x10}, | ||
413 | |||
414 | {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16}, | ||
415 | {0xa0, 0x40, 0x10, 0x08, 0x3d, 0x00, 0x63, 0x15}, | ||
416 | {0xa0, 0x40, 0x02, 0x04, 0x3d, 0x00, 0x63, 0x16}, | ||
417 | {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16}, | ||
418 | {0xb0, 0x40, 0x0e, 0x00, 0x31, 0x00, 0x63, 0x16}, | ||
419 | {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16}, | ||
420 | {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15}, | ||
421 | {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16}, | ||
422 | }; | ||
423 | |||
424 | static const __u8 initTas5110[] = { | ||
425 | 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, | ||
426 | 0x00, 0x00, | ||
427 | 0x00, 0x01, 0x00, 0x46, 0x09, 0x0a, /* shift from 0x45 0x09 0x0a */ | ||
428 | 0x16, 0x12, 0x60, 0x86, 0x2b, | ||
429 | 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07 | ||
430 | }; | ||
431 | static const __u8 tas5110_sensor_init[][8] = { | ||
432 | {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10}, | ||
433 | {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10}, | ||
434 | {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17}, | ||
435 | }; | ||
436 | |||
437 | static const __u8 initTas5130[] = { | ||
438 | 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, | ||
439 | 0x00, 0x00, | ||
440 | 0x00, 0x01, 0x00, 0x69, 0x0c, 0x0a, | ||
441 | 0x28, 0x1e, 0x60, COMP, MCK_INIT, | ||
442 | 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c | ||
443 | }; | ||
444 | static const __u8 tas5130_sensor_init[][8] = { | ||
445 | /* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10}, | ||
446 | * shutter 0x47 short exposure? */ | ||
447 | {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10}, | ||
448 | /* shutter 0x01 long exposure */ | ||
449 | {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}, | ||
450 | }; | ||
451 | |||
452 | /* get one byte in gspca_dev->usb_buf */ | ||
453 | static void reg_r(struct gspca_dev *gspca_dev, | ||
454 | __u16 value) | ||
455 | { | ||
456 | usb_control_msg(gspca_dev->dev, | ||
457 | usb_rcvctrlpipe(gspca_dev->dev, 0), | ||
458 | 0, /* request */ | ||
459 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
460 | value, | ||
461 | 0, /* index */ | ||
462 | gspca_dev->usb_buf, 1, | ||
463 | 500); | ||
464 | } | ||
465 | |||
466 | static void reg_w(struct gspca_dev *gspca_dev, | ||
467 | __u16 value, | ||
468 | const __u8 *buffer, | ||
469 | int len) | ||
470 | { | ||
471 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
472 | if (len > sizeof gspca_dev->usb_buf) { | ||
473 | PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow"); | ||
474 | return; | ||
475 | } | ||
476 | #endif | ||
477 | memcpy(gspca_dev->usb_buf, buffer, len); | ||
478 | usb_control_msg(gspca_dev->dev, | ||
479 | usb_sndctrlpipe(gspca_dev->dev, 0), | ||
480 | 0x08, /* request */ | ||
481 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
482 | value, | ||
483 | 0, /* index */ | ||
484 | gspca_dev->usb_buf, len, | ||
485 | 500); | ||
486 | } | ||
487 | |||
488 | static void reg_w_big(struct gspca_dev *gspca_dev, | ||
489 | __u16 value, | ||
490 | const __u8 *buffer, | ||
491 | int len) | ||
492 | { | ||
493 | __u8 *tmpbuf; | ||
494 | |||
495 | tmpbuf = kmalloc(len, GFP_KERNEL); | ||
496 | memcpy(tmpbuf, buffer, len); | ||
497 | usb_control_msg(gspca_dev->dev, | ||
498 | usb_sndctrlpipe(gspca_dev->dev, 0), | ||
499 | 0x08, /* request */ | ||
500 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
501 | value, | ||
502 | 0, /* index */ | ||
503 | tmpbuf, len, | ||
504 | 500); | ||
505 | kfree(tmpbuf); | ||
506 | } | ||
507 | |||
508 | static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer) | ||
509 | { | ||
510 | int retry = 60; | ||
511 | |||
512 | /* is i2c ready */ | ||
513 | reg_w(gspca_dev, 0x08, buffer, 8); | ||
514 | while (retry--) { | ||
515 | msleep(10); | ||
516 | reg_r(gspca_dev, 0x08); | ||
517 | if (gspca_dev->usb_buf[0] & 0x04) { | ||
518 | if (gspca_dev->usb_buf[0] & 0x08) | ||
519 | return -1; | ||
520 | return 0; | ||
521 | } | ||
522 | } | ||
523 | return -1; | ||
524 | } | ||
525 | |||
526 | static void i2c_w_vector(struct gspca_dev *gspca_dev, | ||
527 | const __u8 buffer[][8], int len) | ||
528 | { | ||
529 | for (;;) { | ||
530 | reg_w(gspca_dev, 0x08, *buffer, 8); | ||
531 | len -= 8; | ||
532 | if (len <= 0) | ||
533 | break; | ||
534 | buffer++; | ||
535 | } | ||
536 | } | ||
537 | |||
538 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
539 | { | ||
540 | struct sd *sd = (struct sd *) gspca_dev; | ||
541 | __u8 value; | ||
542 | |||
543 | switch (sd->sensor) { | ||
544 | case SENSOR_OV6650: | ||
545 | case SENSOR_OV7630_3: | ||
546 | case SENSOR_OV7630: { | ||
547 | __u8 i2cOV[] = | ||
548 | {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}; | ||
549 | |||
550 | /* change reg 0x06 */ | ||
551 | i2cOV[1] = sd->sensor_addr; | ||
552 | i2cOV[3] = sd->brightness; | ||
553 | if (i2c_w(gspca_dev, i2cOV) < 0) | ||
554 | goto err; | ||
555 | break; | ||
556 | } | ||
557 | case SENSOR_PAS106: { | ||
558 | __u8 i2c1[] = | ||
559 | {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14}; | ||
560 | |||
561 | i2c1[3] = sd->brightness >> 3; | ||
562 | i2c1[2] = 0x0e; | ||
563 | if (i2c_w(gspca_dev, i2c1) < 0) | ||
564 | goto err; | ||
565 | i2c1[3] = 0x01; | ||
566 | i2c1[2] = 0x13; | ||
567 | if (i2c_w(gspca_dev, i2c1) < 0) | ||
568 | goto err; | ||
569 | break; | ||
570 | } | ||
571 | case SENSOR_PAS202: { | ||
572 | /* __u8 i2cpexpo1[] = | ||
573 | {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */ | ||
574 | __u8 i2cpexpo[] = | ||
575 | {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16}; | ||
576 | __u8 i2cp202[] = | ||
577 | {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15}; | ||
578 | static __u8 i2cpdoit[] = | ||
579 | {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16}; | ||
580 | |||
581 | /* change reg 0x10 */ | ||
582 | i2cpexpo[4] = 0xff - sd->brightness; | ||
583 | /* if(i2c_w(gspca_dev,i2cpexpo1) < 0) | ||
584 | goto err; */ | ||
585 | /* if(i2c_w(gspca_dev,i2cpdoit) < 0) | ||
586 | goto err; */ | ||
587 | if (i2c_w(gspca_dev, i2cpexpo) < 0) | ||
588 | goto err; | ||
589 | if (i2c_w(gspca_dev, i2cpdoit) < 0) | ||
590 | goto err; | ||
591 | i2cp202[3] = sd->brightness >> 3; | ||
592 | if (i2c_w(gspca_dev, i2cp202) < 0) | ||
593 | goto err; | ||
594 | if (i2c_w(gspca_dev, i2cpdoit) < 0) | ||
595 | goto err; | ||
596 | break; | ||
597 | } | ||
598 | case SENSOR_TAS5130CXX: { | ||
599 | __u8 i2c[] = | ||
600 | {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}; | ||
601 | |||
602 | value = 0xff - sd->brightness; | ||
603 | i2c[4] = value; | ||
604 | PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]); | ||
605 | if (i2c_w(gspca_dev, i2c) < 0) | ||
606 | goto err; | ||
607 | break; | ||
608 | } | ||
609 | case SENSOR_TAS5110: | ||
610 | /* FIXME figure out howto control brightness on TAS5110 */ | ||
611 | break; | ||
612 | } | ||
613 | return; | ||
614 | err: | ||
615 | PDEBUG(D_ERR, "i2c error brightness"); | ||
616 | } | ||
617 | |||
618 | static void setsensorgain(struct gspca_dev *gspca_dev) | ||
619 | { | ||
620 | struct sd *sd = (struct sd *) gspca_dev; | ||
621 | unsigned char gain = sd->gain; | ||
622 | |||
623 | switch (sd->sensor) { | ||
624 | |||
625 | case SENSOR_TAS5110: { | ||
626 | __u8 i2c[] = | ||
627 | {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}; | ||
628 | |||
629 | i2c[4] = 255 - gain; | ||
630 | if (i2c_w(gspca_dev, i2c) < 0) | ||
631 | goto err; | ||
632 | break; | ||
633 | } | ||
634 | |||
635 | case SENSOR_OV6650: | ||
636 | gain >>= 1; | ||
637 | /* fall thru */ | ||
638 | case SENSOR_OV7630_3: { | ||
639 | __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; | ||
640 | |||
641 | i2c[1] = sd->sensor_addr; | ||
642 | i2c[3] = gain >> 2; | ||
643 | if (i2c_w(gspca_dev, i2c) < 0) | ||
644 | goto err; | ||
645 | break; | ||
646 | } | ||
647 | } | ||
648 | return; | ||
649 | err: | ||
650 | PDEBUG(D_ERR, "i2c error gain"); | ||
651 | } | ||
652 | |||
653 | static void setgain(struct gspca_dev *gspca_dev) | ||
654 | { | ||
655 | struct sd *sd = (struct sd *) gspca_dev; | ||
656 | __u8 gain; | ||
657 | __u8 rgb_value; | ||
658 | |||
659 | gain = sd->gain >> 4; | ||
660 | |||
661 | /* red and blue gain */ | ||
662 | rgb_value = gain << 4 | gain; | ||
663 | reg_w(gspca_dev, 0x10, &rgb_value, 1); | ||
664 | /* green gain */ | ||
665 | rgb_value = gain; | ||
666 | reg_w(gspca_dev, 0x11, &rgb_value, 1); | ||
667 | |||
668 | if (sd->sensor_has_gain) | ||
669 | setsensorgain(gspca_dev); | ||
670 | } | ||
671 | |||
672 | static void setexposure(struct gspca_dev *gspca_dev) | ||
673 | { | ||
674 | struct sd *sd = (struct sd *) gspca_dev; | ||
675 | |||
676 | switch (sd->sensor) { | ||
677 | case SENSOR_TAS5110: { | ||
678 | __u8 reg; | ||
679 | |||
680 | /* register 19's high nibble contains the sn9c10x clock divider | ||
681 | The high nibble configures the no fps according to the | ||
682 | formula: 60 / high_nibble. With a maximum of 30 fps */ | ||
683 | reg = 120 * sd->exposure / 1000; | ||
684 | if (reg < 2) | ||
685 | reg = 2; | ||
686 | else if (reg > 15) | ||
687 | reg = 15; | ||
688 | reg = (reg << 4) | 0x0b; | ||
689 | reg_w(gspca_dev, 0x19, ®, 1); | ||
690 | break; | ||
691 | } | ||
692 | case SENSOR_OV6650: | ||
693 | case SENSOR_OV7630_3: { | ||
694 | /* The ov6650 / ov7630 have 2 registers which both influence | ||
695 | exposure, register 11, whose low nibble sets the nr off fps | ||
696 | according to: fps = 30 / (low_nibble + 1) | ||
697 | |||
698 | The fps configures the maximum exposure setting, but it is | ||
699 | possible to use less exposure then what the fps maximum | ||
700 | allows by setting register 10. register 10 configures the | ||
701 | actual exposure as quotient of the full exposure, with 0 | ||
702 | being no exposure at all (not very usefull) and reg10_max | ||
703 | being max exposure possible at that framerate. | ||
704 | |||
705 | The code maps our 0 - 510 ms exposure ctrl to these 2 | ||
706 | registers, trying to keep fps as high as possible. | ||
707 | */ | ||
708 | __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10}; | ||
709 | int reg10, reg11; | ||
710 | /* ov6645 datasheet says reg10_max is 9a, but that uses | ||
711 | tline * 2 * reg10 as formula for calculating texpo, the | ||
712 | ov6650 probably uses the same formula as the 7730 which uses | ||
713 | tline * 4 * reg10, which explains why the reg10max we've | ||
714 | found experimentally for the ov6650 is exactly half that of | ||
715 | the ov6645. The ov7630 datasheet says the max is 0x41. */ | ||
716 | const int reg10_max = (sd->sensor == SENSOR_OV6650) | ||
717 | ? 0x4d : 0x41; | ||
718 | |||
719 | reg11 = (60 * sd->exposure + 999) / 1000; | ||
720 | if (reg11 < 1) | ||
721 | reg11 = 1; | ||
722 | else if (reg11 > 16) | ||
723 | reg11 = 16; | ||
724 | |||
725 | /* frame exposure time in ms = 1000 * reg11 / 30 -> | ||
726 | reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */ | ||
727 | reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11); | ||
728 | |||
729 | /* Don't allow this to get below 10 when using autogain, the | ||
730 | steps become very large (relatively) when below 10 causing | ||
731 | the image to oscilate from much too dark, to much too bright | ||
732 | and back again. */ | ||
733 | if (sd->autogain && reg10 < 10) | ||
734 | reg10 = 10; | ||
735 | else if (reg10 > reg10_max) | ||
736 | reg10 = reg10_max; | ||
737 | |||
738 | /* Write reg 10 and reg11 low nibble */ | ||
739 | i2c[1] = sd->sensor_addr; | ||
740 | i2c[3] = reg10; | ||
741 | i2c[4] |= reg11 - 1; | ||
742 | if (sd->sensor == SENSOR_OV7630_3) { | ||
743 | __u8 reg76 = reg10 & 0x03; | ||
744 | __u8 i2c_reg76[] = {0xa0, 0x21, 0x76, 0x00, | ||
745 | 0x00, 0x00, 0x00, 0x10}; | ||
746 | reg10 >>= 2; | ||
747 | i2c_reg76[3] = reg76; | ||
748 | if (i2c_w(gspca_dev, i2c_reg76) < 0) | ||
749 | PDEBUG(D_ERR, "i2c error exposure"); | ||
750 | } | ||
751 | if (i2c_w(gspca_dev, i2c) < 0) | ||
752 | PDEBUG(D_ERR, "i2c error exposure"); | ||
753 | break; | ||
754 | } | ||
755 | } | ||
756 | } | ||
757 | |||
758 | static void setfreq(struct gspca_dev *gspca_dev) | ||
759 | { | ||
760 | struct sd *sd = (struct sd *) gspca_dev; | ||
761 | |||
762 | switch (sd->sensor) { | ||
763 | case SENSOR_OV6650: | ||
764 | case SENSOR_OV7630_3: { | ||
765 | /* Framerate adjust register for artificial light 50 hz flicker | ||
766 | compensation, identical to ov6630 0x2b register, see ov6630 | ||
767 | datasheet. | ||
768 | 0x4f -> (30 fps -> 25 fps), 0x00 -> no adjustment */ | ||
769 | __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}; | ||
770 | switch (sd->freq) { | ||
771 | default: | ||
772 | /* case 0: * no filter*/ | ||
773 | /* case 2: * 60 hz */ | ||
774 | i2c[3] = 0; | ||
775 | break; | ||
776 | case 1: /* 50 hz */ | ||
777 | i2c[3] = (sd->sensor == SENSOR_OV6650) | ||
778 | ? 0x4f : 0x8a; | ||
779 | break; | ||
780 | } | ||
781 | i2c[1] = sd->sensor_addr; | ||
782 | if (i2c_w(gspca_dev, i2c) < 0) | ||
783 | PDEBUG(D_ERR, "i2c error setfreq"); | ||
784 | break; | ||
785 | } | ||
786 | } | ||
787 | } | ||
788 | |||
789 | static void setsaturation(struct gspca_dev *gspca_dev) | ||
790 | { | ||
791 | struct sd *sd = (struct sd *) gspca_dev; | ||
792 | |||
793 | switch (sd->sensor) { | ||
794 | /* case SENSOR_OV6650: */ | ||
795 | case SENSOR_OV7630_3: | ||
796 | case SENSOR_OV7630: { | ||
797 | __u8 i2c[] = {0xa0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}; | ||
798 | i2c[1] = sd->sensor_addr; | ||
799 | i2c[3] = sd->saturation & 0xf0; | ||
800 | if (i2c_w(gspca_dev, i2c) < 0) | ||
801 | PDEBUG(D_ERR, "i2c error setsaturation"); | ||
802 | else | ||
803 | PDEBUG(D_CONF, "saturation set to: %d", | ||
804 | (int)sd->saturation); | ||
805 | break; | ||
806 | } | ||
807 | } | ||
808 | } | ||
809 | |||
810 | static void sethue(struct gspca_dev *gspca_dev) | ||
811 | { | ||
812 | struct sd *sd = (struct sd *) gspca_dev; | ||
813 | |||
814 | switch (sd->sensor) { | ||
815 | /* case SENSOR_OV6650: */ | ||
816 | case SENSOR_OV7630_3: | ||
817 | case SENSOR_OV7630: { | ||
818 | __u8 i2c[] = {0xa0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10}; | ||
819 | i2c[1] = sd->sensor_addr; | ||
820 | i2c[3] = 0x20 | (sd->hue >> 3); | ||
821 | if (i2c_w(gspca_dev, i2c) < 0) | ||
822 | PDEBUG(D_ERR, "i2c error setsaturation"); | ||
823 | else | ||
824 | PDEBUG(D_CONF, "hue set to: %d", (int)sd->hue); | ||
825 | break; | ||
826 | } | ||
827 | } | ||
828 | } | ||
829 | |||
830 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
831 | { | ||
832 | struct sd *sd = (struct sd *) gspca_dev; | ||
833 | |||
834 | switch (sd->sensor) { | ||
835 | /* case SENSOR_OV6650: */ | ||
836 | case SENSOR_OV7630_3: | ||
837 | case SENSOR_OV7630: { | ||
838 | __u8 i2c[] = {0xa0, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10}; | ||
839 | i2c[1] = sd->sensor_addr; | ||
840 | i2c[3] = 0x20 | (sd->contrast >> 3); | ||
841 | if (i2c_w(gspca_dev, i2c) < 0) | ||
842 | PDEBUG(D_ERR, "i2c error setcontrast"); | ||
843 | else | ||
844 | PDEBUG(D_CONF, "contrast set to: %d", | ||
845 | (int)sd->contrast); | ||
846 | break; | ||
847 | } | ||
848 | } | ||
849 | } | ||
850 | |||
851 | |||
852 | static void do_autogain(struct gspca_dev *gspca_dev) | ||
853 | { | ||
854 | struct sd *sd = (struct sd *) gspca_dev; | ||
855 | int avg_lum = atomic_read(&sd->avg_lum); | ||
856 | |||
857 | if (avg_lum == -1) | ||
858 | return; | ||
859 | |||
860 | if (sd->autogain_ignore_frames > 0) | ||
861 | sd->autogain_ignore_frames--; | ||
862 | else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, | ||
863 | sd->brightness * DESIRED_AVG_LUM / 127, | ||
864 | AUTOGAIN_DEADZONE, GAIN_KNEE, EXPOSURE_KNEE)) { | ||
865 | PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d\n", | ||
866 | (int)sd->gain, (int)sd->exposure); | ||
867 | sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; | ||
868 | } | ||
869 | } | ||
870 | |||
871 | /* this function is called at probe time */ | ||
872 | static int sd_config(struct gspca_dev *gspca_dev, | ||
873 | const struct usb_device_id *id) | ||
874 | { | ||
875 | struct sd *sd = (struct sd *) gspca_dev; | ||
876 | struct cam *cam; | ||
877 | __u16 product; | ||
878 | int sif = 0; | ||
879 | |||
880 | /* nctrls depends upon the sensor, so we use a per cam copy */ | ||
881 | memcpy(&sd->sd_desc, gspca_dev->sd_desc, sizeof(struct sd_desc)); | ||
882 | gspca_dev->sd_desc = &sd->sd_desc; | ||
883 | |||
884 | sd->fr_h_sz = 12; /* default size of the frame header */ | ||
885 | sd->sd_desc.nctrls = 2; /* default nb of ctrls */ | ||
886 | sd->autogain = AUTOGAIN_DEF; /* default is autogain active */ | ||
887 | |||
888 | product = id->idProduct; | ||
889 | /* switch (id->idVendor) { */ | ||
890 | /* case 0x0c45: * Sonix */ | ||
891 | switch (product) { | ||
892 | case 0x6001: /* SN9C102 */ | ||
893 | case 0x6005: /* SN9C101 */ | ||
894 | case 0x6007: /* SN9C101 */ | ||
895 | sd->sensor = SENSOR_TAS5110; | ||
896 | sd->sensor_has_gain = 1; | ||
897 | sd->sd_desc.nctrls = 4; | ||
898 | sd->sd_desc.dq_callback = do_autogain; | ||
899 | sif = 1; | ||
900 | break; | ||
901 | case 0x6009: /* SN9C101 */ | ||
902 | case 0x600d: /* SN9C101 */ | ||
903 | case 0x6029: /* SN9C101 */ | ||
904 | sd->sensor = SENSOR_PAS106; | ||
905 | sif = 1; | ||
906 | break; | ||
907 | case 0x6011: /* SN9C101 - SN9C101G */ | ||
908 | sd->sensor = SENSOR_OV6650; | ||
909 | sd->sensor_has_gain = 1; | ||
910 | sd->sensor_addr = 0x60; | ||
911 | sd->sd_desc.nctrls = 5; | ||
912 | sd->sd_desc.dq_callback = do_autogain; | ||
913 | sif = 1; | ||
914 | break; | ||
915 | case 0x6019: /* SN9C101 */ | ||
916 | case 0x602c: /* SN9C102 */ | ||
917 | case 0x602e: /* SN9C102 */ | ||
918 | sd->sensor = SENSOR_OV7630; | ||
919 | sd->sensor_addr = 0x21; | ||
920 | break; | ||
921 | case 0x60b0: /* SN9C103 */ | ||
922 | sd->sensor = SENSOR_OV7630_3; | ||
923 | sd->sensor_addr = 0x21; | ||
924 | sd->fr_h_sz = 18; /* size of frame header */ | ||
925 | sd->sensor_has_gain = 1; | ||
926 | sd->sd_desc.nctrls = 8; | ||
927 | sd->sd_desc.dq_callback = do_autogain; | ||
928 | sd->autogain = 0; | ||
929 | break; | ||
930 | case 0x6024: /* SN9C102 */ | ||
931 | case 0x6025: /* SN9C102 */ | ||
932 | sd->sensor = SENSOR_TAS5130CXX; | ||
933 | break; | ||
934 | case 0x6028: /* SN9C102 */ | ||
935 | sd->sensor = SENSOR_PAS202; | ||
936 | break; | ||
937 | case 0x602d: /* SN9C102 */ | ||
938 | sd->sensor = SENSOR_HV7131R; | ||
939 | break; | ||
940 | case 0x60af: /* SN9C103 */ | ||
941 | sd->sensor = SENSOR_PAS202; | ||
942 | sd->fr_h_sz = 18; /* size of frame header (?) */ | ||
943 | break; | ||
944 | } | ||
945 | /* break; */ | ||
946 | /* } */ | ||
947 | |||
948 | cam = &gspca_dev->cam; | ||
949 | cam->dev_name = (char *) id->driver_info; | ||
950 | cam->epaddr = 0x01; | ||
951 | if (!sif) { | ||
952 | cam->cam_mode = vga_mode; | ||
953 | cam->nmodes = ARRAY_SIZE(vga_mode); | ||
954 | if (sd->sensor == SENSOR_OV7630_3) { | ||
955 | /* We only have 320x240 & 640x480 */ | ||
956 | cam->cam_mode++; | ||
957 | cam->nmodes--; | ||
958 | } | ||
959 | } else { | ||
960 | cam->cam_mode = sif_mode; | ||
961 | cam->nmodes = ARRAY_SIZE(sif_mode); | ||
962 | } | ||
963 | sd->brightness = BRIGHTNESS_DEF; | ||
964 | sd->gain = GAIN_DEF; | ||
965 | sd->exposure = EXPOSURE_DEF; | ||
966 | sd->freq = FREQ_DEF; | ||
967 | sd->contrast = CONTRAST_DEF; | ||
968 | sd->saturation = SATURATION_DEF; | ||
969 | sd->hue = HUE_DEF; | ||
970 | if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */ | ||
971 | reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630); | ||
972 | return 0; | ||
973 | } | ||
974 | |||
975 | /* this function is called at open time */ | ||
976 | static int sd_open(struct gspca_dev *gspca_dev) | ||
977 | { | ||
978 | reg_r(gspca_dev, 0x00); | ||
979 | if (gspca_dev->usb_buf[0] != 0x10) | ||
980 | return -ENODEV; | ||
981 | return 0; | ||
982 | } | ||
983 | |||
984 | static void pas106_i2cinit(struct gspca_dev *gspca_dev) | ||
985 | { | ||
986 | int i; | ||
987 | const __u8 *data; | ||
988 | __u8 i2c1[] = { 0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 }; | ||
989 | |||
990 | i = ARRAY_SIZE(pas106_data); | ||
991 | data = pas106_data[0]; | ||
992 | while (--i >= 0) { | ||
993 | memcpy(&i2c1[2], data, 2); | ||
994 | /* copy 2 bytes from the template */ | ||
995 | if (i2c_w(gspca_dev, i2c1) < 0) | ||
996 | PDEBUG(D_ERR, "i2c error pas106"); | ||
997 | data += 2; | ||
998 | } | ||
999 | } | ||
1000 | |||
1001 | /* -- start the camera -- */ | ||
1002 | static void sd_start(struct gspca_dev *gspca_dev) | ||
1003 | { | ||
1004 | struct sd *sd = (struct sd *) gspca_dev; | ||
1005 | int mode, l; | ||
1006 | const __u8 *sn9c10x; | ||
1007 | __u8 reg01, reg17; | ||
1008 | __u8 reg17_19[3]; | ||
1009 | |||
1010 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | ||
1011 | switch (sd->sensor) { | ||
1012 | case SENSOR_HV7131R: | ||
1013 | sn9c10x = initHv7131; | ||
1014 | reg17_19[0] = 0x60; | ||
1015 | reg17_19[1] = (mode << 4) | 0x8a; | ||
1016 | reg17_19[2] = 0x20; | ||
1017 | break; | ||
1018 | case SENSOR_OV6650: | ||
1019 | sn9c10x = initOv6650; | ||
1020 | reg17_19[0] = 0x68; | ||
1021 | reg17_19[1] = (mode << 4) | 0x8b; | ||
1022 | reg17_19[2] = 0x20; | ||
1023 | break; | ||
1024 | case SENSOR_OV7630: | ||
1025 | sn9c10x = initOv7630; | ||
1026 | reg17_19[0] = 0x68; | ||
1027 | reg17_19[1] = (mode << 4) | COMP2; | ||
1028 | reg17_19[2] = MCK_INIT1; | ||
1029 | break; | ||
1030 | case SENSOR_OV7630_3: | ||
1031 | sn9c10x = initOv7630_3; | ||
1032 | reg17_19[0] = 0x68; | ||
1033 | reg17_19[1] = (mode << 4) | COMP2; | ||
1034 | reg17_19[2] = MCK_INIT1; | ||
1035 | break; | ||
1036 | case SENSOR_PAS106: | ||
1037 | sn9c10x = initPas106; | ||
1038 | reg17_19[0] = 0x24; /* 0x28 */ | ||
1039 | reg17_19[1] = (mode << 4) | COMP1; | ||
1040 | reg17_19[2] = MCK_INIT1; | ||
1041 | break; | ||
1042 | case SENSOR_PAS202: | ||
1043 | sn9c10x = initPas202; | ||
1044 | reg17_19[0] = mode ? 0x24 : 0x20; | ||
1045 | reg17_19[1] = (mode << 4) | 0x89; | ||
1046 | reg17_19[2] = 0x20; | ||
1047 | break; | ||
1048 | case SENSOR_TAS5110: | ||
1049 | sn9c10x = initTas5110; | ||
1050 | reg17_19[0] = 0x60; | ||
1051 | reg17_19[1] = (mode << 4) | 0x86; | ||
1052 | reg17_19[2] = 0x2b; /* 0xf3; */ | ||
1053 | break; | ||
1054 | default: | ||
1055 | /* case SENSOR_TAS5130CXX: */ | ||
1056 | sn9c10x = initTas5130; | ||
1057 | reg17_19[0] = 0x60; | ||
1058 | reg17_19[1] = (mode << 4) | COMP; | ||
1059 | reg17_19[2] = mode ? 0x23 : 0x43; | ||
1060 | break; | ||
1061 | } | ||
1062 | switch (sd->sensor) { | ||
1063 | case SENSOR_OV7630: | ||
1064 | reg01 = 0x06; | ||
1065 | reg17 = 0x29; | ||
1066 | l = sizeof initOv7630; | ||
1067 | break; | ||
1068 | case SENSOR_OV7630_3: | ||
1069 | reg01 = 0x44; | ||
1070 | reg17 = 0x68; | ||
1071 | l = sizeof initOv7630_3; | ||
1072 | break; | ||
1073 | default: | ||
1074 | reg01 = sn9c10x[0]; | ||
1075 | reg17 = sn9c10x[0x17 - 1]; | ||
1076 | l = 0x1f; | ||
1077 | break; | ||
1078 | } | ||
1079 | |||
1080 | /* reg 0x01 bit 2 video transfert on */ | ||
1081 | reg_w(gspca_dev, 0x01, ®01, 1); | ||
1082 | /* reg 0x17 SensorClk enable inv Clk 0x60 */ | ||
1083 | reg_w(gspca_dev, 0x17, ®17, 1); | ||
1084 | /*fixme: for ov7630 102 | ||
1085 | reg_w(gspca_dev, 0x01, {0x06, sn9c10x[1]}, 2); */ | ||
1086 | /* Set the registers from the template */ | ||
1087 | reg_w_big(gspca_dev, 0x01, sn9c10x, l); | ||
1088 | switch (sd->sensor) { | ||
1089 | case SENSOR_HV7131R: | ||
1090 | i2c_w_vector(gspca_dev, hv7131_sensor_init, | ||
1091 | sizeof hv7131_sensor_init); | ||
1092 | break; | ||
1093 | case SENSOR_OV6650: | ||
1094 | i2c_w_vector(gspca_dev, ov6650_sensor_init, | ||
1095 | sizeof ov6650_sensor_init); | ||
1096 | break; | ||
1097 | case SENSOR_OV7630: | ||
1098 | i2c_w_vector(gspca_dev, ov7630_sensor_init_com, | ||
1099 | sizeof ov7630_sensor_init_com); | ||
1100 | msleep(200); | ||
1101 | i2c_w_vector(gspca_dev, ov7630_sensor_init, | ||
1102 | sizeof ov7630_sensor_init); | ||
1103 | break; | ||
1104 | case SENSOR_OV7630_3: | ||
1105 | i2c_w_vector(gspca_dev, ov7630_sensor_init_com, | ||
1106 | sizeof ov7630_sensor_init_com); | ||
1107 | msleep(200); | ||
1108 | i2c_w(gspca_dev, ov7630_sensor_init_3[mode]); | ||
1109 | break; | ||
1110 | case SENSOR_PAS106: | ||
1111 | pas106_i2cinit(gspca_dev); | ||
1112 | break; | ||
1113 | case SENSOR_PAS202: | ||
1114 | i2c_w_vector(gspca_dev, pas202_sensor_init, | ||
1115 | sizeof pas202_sensor_init); | ||
1116 | break; | ||
1117 | case SENSOR_TAS5110: | ||
1118 | i2c_w_vector(gspca_dev, tas5110_sensor_init, | ||
1119 | sizeof tas5110_sensor_init); | ||
1120 | break; | ||
1121 | default: | ||
1122 | /* case SENSOR_TAS5130CXX: */ | ||
1123 | i2c_w_vector(gspca_dev, tas5130_sensor_init, | ||
1124 | sizeof tas5130_sensor_init); | ||
1125 | break; | ||
1126 | } | ||
1127 | /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */ | ||
1128 | reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2); | ||
1129 | /* compression register */ | ||
1130 | reg_w(gspca_dev, 0x18, ®17_19[1], 1); | ||
1131 | /* H_start */ | ||
1132 | reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1); | ||
1133 | /* V_START */ | ||
1134 | reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1); | ||
1135 | /* reset 0x17 SensorClk enable inv Clk 0x60 */ | ||
1136 | /*fixme: ov7630 [17]=68 8f (+20 if 102)*/ | ||
1137 | reg_w(gspca_dev, 0x17, ®17_19[0], 1); | ||
1138 | /*MCKSIZE ->3 */ /*fixme: not ov7630*/ | ||
1139 | reg_w(gspca_dev, 0x19, ®17_19[2], 1); | ||
1140 | /* AE_STRX AE_STRY AE_ENDX AE_ENDY */ | ||
1141 | reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4); | ||
1142 | /* Enable video transfert */ | ||
1143 | reg_w(gspca_dev, 0x01, &sn9c10x[0], 1); | ||
1144 | /* Compression */ | ||
1145 | reg_w(gspca_dev, 0x18, ®17_19[1], 2); | ||
1146 | msleep(20); | ||
1147 | |||
1148 | setgain(gspca_dev); | ||
1149 | setbrightness(gspca_dev); | ||
1150 | setexposure(gspca_dev); | ||
1151 | setfreq(gspca_dev); | ||
1152 | setsaturation(gspca_dev); | ||
1153 | sethue(gspca_dev); | ||
1154 | setcontrast(gspca_dev); | ||
1155 | |||
1156 | sd->autogain_ignore_frames = 0; | ||
1157 | atomic_set(&sd->avg_lum, -1); | ||
1158 | } | ||
1159 | |||
1160 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
1161 | { | ||
1162 | __u8 ByteSend; | ||
1163 | |||
1164 | ByteSend = 0x09; /* 0X00 */ | ||
1165 | reg_w(gspca_dev, 0x01, &ByteSend, 1); | ||
1166 | } | ||
1167 | |||
1168 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
1169 | { | ||
1170 | } | ||
1171 | |||
1172 | static void sd_close(struct gspca_dev *gspca_dev) | ||
1173 | { | ||
1174 | } | ||
1175 | |||
1176 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
1177 | struct gspca_frame *frame, /* target */ | ||
1178 | unsigned char *data, /* isoc packet */ | ||
1179 | int len) /* iso packet length */ | ||
1180 | { | ||
1181 | int i; | ||
1182 | struct sd *sd = (struct sd *) gspca_dev; | ||
1183 | |||
1184 | /* frames start with: | ||
1185 | * ff ff 00 c4 c4 96 synchro | ||
1186 | * 00 (unknown) | ||
1187 | * xx (frame sequence / size / compression) | ||
1188 | * (xx) (idem - extra byte for sn9c103) | ||
1189 | * ll mm brightness sum inside auto exposure | ||
1190 | * ll mm brightness sum outside auto exposure | ||
1191 | * (xx xx xx xx xx) audio values for snc103 | ||
1192 | */ | ||
1193 | if (len > 6 && len < 24) { | ||
1194 | for (i = 0; i < len - 6; i++) { | ||
1195 | if (data[0 + i] == 0xff | ||
1196 | && data[1 + i] == 0xff | ||
1197 | && data[2 + i] == 0x00 | ||
1198 | && data[3 + i] == 0xc4 | ||
1199 | && data[4 + i] == 0xc4 | ||
1200 | && data[5 + i] == 0x96) { /* start of frame */ | ||
1201 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, | ||
1202 | frame, data, 0); | ||
1203 | if (len - i < sd->fr_h_sz) { | ||
1204 | atomic_set(&sd->avg_lum, -1); | ||
1205 | PDEBUG(D_STREAM, "packet too short to" | ||
1206 | " get avg brightness"); | ||
1207 | } else if (sd->fr_h_sz == 12) { | ||
1208 | atomic_set(&sd->avg_lum, | ||
1209 | data[i + 8] + | ||
1210 | (data[i + 9] << 8)); | ||
1211 | } else { | ||
1212 | atomic_set(&sd->avg_lum, | ||
1213 | data[i + 9] + | ||
1214 | (data[i + 10] << 8)); | ||
1215 | } | ||
1216 | data += i + sd->fr_h_sz; | ||
1217 | len -= i + sd->fr_h_sz; | ||
1218 | gspca_frame_add(gspca_dev, FIRST_PACKET, | ||
1219 | frame, data, len); | ||
1220 | return; | ||
1221 | } | ||
1222 | } | ||
1223 | } | ||
1224 | gspca_frame_add(gspca_dev, INTER_PACKET, | ||
1225 | frame, data, len); | ||
1226 | } | ||
1227 | |||
1228 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
1229 | { | ||
1230 | struct sd *sd = (struct sd *) gspca_dev; | ||
1231 | |||
1232 | sd->brightness = val; | ||
1233 | if (gspca_dev->streaming) | ||
1234 | setbrightness(gspca_dev); | ||
1235 | return 0; | ||
1236 | } | ||
1237 | |||
1238 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
1239 | { | ||
1240 | struct sd *sd = (struct sd *) gspca_dev; | ||
1241 | |||
1242 | *val = sd->brightness; | ||
1243 | return 0; | ||
1244 | } | ||
1245 | |||
1246 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) | ||
1247 | { | ||
1248 | struct sd *sd = (struct sd *) gspca_dev; | ||
1249 | |||
1250 | sd->gain = val; | ||
1251 | if (gspca_dev->streaming) | ||
1252 | setgain(gspca_dev); | ||
1253 | return 0; | ||
1254 | } | ||
1255 | |||
1256 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) | ||
1257 | { | ||
1258 | struct sd *sd = (struct sd *) gspca_dev; | ||
1259 | |||
1260 | *val = sd->gain; | ||
1261 | return 0; | ||
1262 | } | ||
1263 | |||
1264 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val) | ||
1265 | { | ||
1266 | struct sd *sd = (struct sd *) gspca_dev; | ||
1267 | |||
1268 | sd->exposure = val; | ||
1269 | if (gspca_dev->streaming) | ||
1270 | setexposure(gspca_dev); | ||
1271 | return 0; | ||
1272 | } | ||
1273 | |||
1274 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) | ||
1275 | { | ||
1276 | struct sd *sd = (struct sd *) gspca_dev; | ||
1277 | |||
1278 | *val = sd->exposure; | ||
1279 | return 0; | ||
1280 | } | ||
1281 | |||
1282 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
1283 | { | ||
1284 | struct sd *sd = (struct sd *) gspca_dev; | ||
1285 | |||
1286 | sd->autogain = val; | ||
1287 | /* when switching to autogain set defaults to make sure | ||
1288 | we are on a valid point of the autogain gain / | ||
1289 | exposure knee graph, and give this change time to | ||
1290 | take effect before doing autogain. */ | ||
1291 | if (sd->autogain) { | ||
1292 | sd->exposure = EXPOSURE_DEF; | ||
1293 | sd->gain = GAIN_DEF; | ||
1294 | if (gspca_dev->streaming) { | ||
1295 | sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; | ||
1296 | setexposure(gspca_dev); | ||
1297 | setgain(gspca_dev); | ||
1298 | } | ||
1299 | } | ||
1300 | |||
1301 | return 0; | ||
1302 | } | ||
1303 | |||
1304 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | ||
1305 | { | ||
1306 | struct sd *sd = (struct sd *) gspca_dev; | ||
1307 | |||
1308 | *val = sd->autogain; | ||
1309 | return 0; | ||
1310 | } | ||
1311 | |||
1312 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | ||
1313 | { | ||
1314 | struct sd *sd = (struct sd *) gspca_dev; | ||
1315 | |||
1316 | sd->freq = val; | ||
1317 | if (gspca_dev->streaming) | ||
1318 | setfreq(gspca_dev); | ||
1319 | return 0; | ||
1320 | } | ||
1321 | |||
1322 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) | ||
1323 | { | ||
1324 | struct sd *sd = (struct sd *) gspca_dev; | ||
1325 | |||
1326 | *val = sd->freq; | ||
1327 | return 0; | ||
1328 | } | ||
1329 | |||
1330 | static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val) | ||
1331 | { | ||
1332 | struct sd *sd = (struct sd *) gspca_dev; | ||
1333 | |||
1334 | sd->saturation = val; | ||
1335 | if (gspca_dev->streaming) | ||
1336 | setsaturation(gspca_dev); | ||
1337 | return 0; | ||
1338 | } | ||
1339 | |||
1340 | static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val) | ||
1341 | { | ||
1342 | struct sd *sd = (struct sd *) gspca_dev; | ||
1343 | |||
1344 | *val = sd->saturation; | ||
1345 | return 0; | ||
1346 | } | ||
1347 | |||
1348 | static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val) | ||
1349 | { | ||
1350 | struct sd *sd = (struct sd *) gspca_dev; | ||
1351 | |||
1352 | sd->hue = val; | ||
1353 | if (gspca_dev->streaming) | ||
1354 | sethue(gspca_dev); | ||
1355 | return 0; | ||
1356 | } | ||
1357 | |||
1358 | static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val) | ||
1359 | { | ||
1360 | struct sd *sd = (struct sd *) gspca_dev; | ||
1361 | |||
1362 | *val = sd->hue; | ||
1363 | return 0; | ||
1364 | } | ||
1365 | |||
1366 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
1367 | { | ||
1368 | struct sd *sd = (struct sd *) gspca_dev; | ||
1369 | |||
1370 | sd->contrast = val; | ||
1371 | if (gspca_dev->streaming) | ||
1372 | setcontrast(gspca_dev); | ||
1373 | return 0; | ||
1374 | } | ||
1375 | |||
1376 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
1377 | { | ||
1378 | struct sd *sd = (struct sd *) gspca_dev; | ||
1379 | |||
1380 | *val = sd->contrast; | ||
1381 | return 0; | ||
1382 | } | ||
1383 | |||
1384 | static int sd_querymenu(struct gspca_dev *gspca_dev, | ||
1385 | struct v4l2_querymenu *menu) | ||
1386 | { | ||
1387 | switch (menu->id) { | ||
1388 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
1389 | switch (menu->index) { | ||
1390 | case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ | ||
1391 | strcpy((char *) menu->name, "NoFliker"); | ||
1392 | return 0; | ||
1393 | case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ | ||
1394 | strcpy((char *) menu->name, "50 Hz"); | ||
1395 | return 0; | ||
1396 | case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ | ||
1397 | strcpy((char *) menu->name, "60 Hz"); | ||
1398 | return 0; | ||
1399 | } | ||
1400 | break; | ||
1401 | } | ||
1402 | return -EINVAL; | ||
1403 | } | ||
1404 | |||
1405 | /* sub-driver description */ | ||
1406 | static const struct sd_desc sd_desc = { | ||
1407 | .name = MODULE_NAME, | ||
1408 | .ctrls = sd_ctrls, | ||
1409 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
1410 | .config = sd_config, | ||
1411 | .open = sd_open, | ||
1412 | .start = sd_start, | ||
1413 | .stopN = sd_stopN, | ||
1414 | .stop0 = sd_stop0, | ||
1415 | .close = sd_close, | ||
1416 | .pkt_scan = sd_pkt_scan, | ||
1417 | .querymenu = sd_querymenu, | ||
1418 | }; | ||
1419 | |||
1420 | /* -- module initialisation -- */ | ||
1421 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
1422 | static __devinitdata struct usb_device_id device_table[] = { | ||
1423 | #ifndef CONFIG_USB_SN9C102 | ||
1424 | {USB_DEVICE(0x0c45, 0x6001), DVNM("Genius VideoCAM NB")}, | ||
1425 | {USB_DEVICE(0x0c45, 0x6005), DVNM("Sweex Tas5110")}, | ||
1426 | {USB_DEVICE(0x0c45, 0x6007), DVNM("Sonix sn9c101 + Tas5110D")}, | ||
1427 | {USB_DEVICE(0x0c45, 0x6009), DVNM("spcaCam@120")}, | ||
1428 | {USB_DEVICE(0x0c45, 0x600d), DVNM("spcaCam@120")}, | ||
1429 | #endif | ||
1430 | {USB_DEVICE(0x0c45, 0x6011), DVNM("MAX Webcam Microdia")}, | ||
1431 | #ifndef CONFIG_USB_SN9C102 | ||
1432 | {USB_DEVICE(0x0c45, 0x6019), DVNM("Generic Sonix OV7630")}, | ||
1433 | {USB_DEVICE(0x0c45, 0x6024), DVNM("Generic Sonix Tas5130c")}, | ||
1434 | {USB_DEVICE(0x0c45, 0x6025), DVNM("Xcam Shanga")}, | ||
1435 | {USB_DEVICE(0x0c45, 0x6028), DVNM("Sonix Btc Pc380")}, | ||
1436 | {USB_DEVICE(0x0c45, 0x6029), DVNM("spcaCam@150")}, | ||
1437 | {USB_DEVICE(0x0c45, 0x602c), DVNM("Generic Sonix OV7630")}, | ||
1438 | {USB_DEVICE(0x0c45, 0x602d), DVNM("LIC-200 LG")}, | ||
1439 | {USB_DEVICE(0x0c45, 0x602e), DVNM("Genius VideoCam Messenger")}, | ||
1440 | {USB_DEVICE(0x0c45, 0x60af), DVNM("Trust WB3100P")}, | ||
1441 | {USB_DEVICE(0x0c45, 0x60b0), DVNM("Genius VideoCam Look")}, | ||
1442 | #endif | ||
1443 | {} | ||
1444 | }; | ||
1445 | MODULE_DEVICE_TABLE(usb, device_table); | ||
1446 | |||
1447 | /* -- device connect -- */ | ||
1448 | static int sd_probe(struct usb_interface *intf, | ||
1449 | const struct usb_device_id *id) | ||
1450 | { | ||
1451 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
1452 | THIS_MODULE); | ||
1453 | } | ||
1454 | |||
1455 | static struct usb_driver sd_driver = { | ||
1456 | .name = MODULE_NAME, | ||
1457 | .id_table = device_table, | ||
1458 | .probe = sd_probe, | ||
1459 | .disconnect = gspca_disconnect, | ||
1460 | }; | ||
1461 | |||
1462 | /* -- module insert / remove -- */ | ||
1463 | static int __init sd_mod_init(void) | ||
1464 | { | ||
1465 | if (usb_register(&sd_driver) < 0) | ||
1466 | return -1; | ||
1467 | PDEBUG(D_PROBE, "v%s registered", version); | ||
1468 | return 0; | ||
1469 | } | ||
1470 | static void __exit sd_mod_exit(void) | ||
1471 | { | ||
1472 | usb_deregister(&sd_driver); | ||
1473 | PDEBUG(D_PROBE, "deregistered"); | ||
1474 | } | ||
1475 | |||
1476 | module_init(sd_mod_init); | ||
1477 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c new file mode 100644 index 000000000000..3e68b9926956 --- /dev/null +++ b/drivers/media/video/gspca/sonixj.c | |||
@@ -0,0 +1,1671 @@ | |||
1 | /* | ||
2 | * Sonix sn9c102p sn9c105 sn9c120 (jpeg) library | ||
3 | * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr | ||
4 | * | ||
5 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #define MODULE_NAME "sonixj" | ||
23 | |||
24 | #include "gspca.h" | ||
25 | #include "jpeg.h" | ||
26 | |||
27 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) | ||
28 | static const char version[] = "2.1.7"; | ||
29 | |||
30 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
31 | MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); | ||
32 | MODULE_LICENSE("GPL"); | ||
33 | |||
34 | /* specific webcam descriptor */ | ||
35 | struct sd { | ||
36 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
37 | |||
38 | int avg_lum; | ||
39 | unsigned int exposure; | ||
40 | |||
41 | unsigned short brightness; | ||
42 | unsigned char contrast; | ||
43 | unsigned char colors; | ||
44 | unsigned char autogain; | ||
45 | |||
46 | signed char ag_cnt; | ||
47 | #define AG_CNT_START 13 | ||
48 | |||
49 | char qindex; | ||
50 | unsigned char bridge; | ||
51 | #define BRIDGE_SN9C102P 0 | ||
52 | #define BRIDGE_SN9C105 1 | ||
53 | #define BRIDGE_SN9C110 2 | ||
54 | #define BRIDGE_SN9C120 3 | ||
55 | #define BRIDGE_SN9C325 4 | ||
56 | char sensor; /* Type of image sensor chip */ | ||
57 | #define SENSOR_HV7131R 0 | ||
58 | #define SENSOR_MI0360 1 | ||
59 | #define SENSOR_MO4000 2 | ||
60 | #define SENSOR_OV7648 3 | ||
61 | #define SENSOR_OV7660 4 | ||
62 | unsigned char i2c_base; | ||
63 | }; | ||
64 | |||
65 | /* V4L2 controls supported by the driver */ | ||
66 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
67 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
68 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
69 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
70 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
71 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
72 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
73 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
74 | |||
75 | static struct ctrl sd_ctrls[] = { | ||
76 | { | ||
77 | { | ||
78 | .id = V4L2_CID_BRIGHTNESS, | ||
79 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
80 | .name = "Brightness", | ||
81 | .minimum = 0, | ||
82 | .maximum = 0xffff, | ||
83 | .step = 1, | ||
84 | #define BRIGHTNESS_DEF 0x7fff | ||
85 | .default_value = BRIGHTNESS_DEF, | ||
86 | }, | ||
87 | .set = sd_setbrightness, | ||
88 | .get = sd_getbrightness, | ||
89 | }, | ||
90 | { | ||
91 | { | ||
92 | .id = V4L2_CID_CONTRAST, | ||
93 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
94 | .name = "Contrast", | ||
95 | .minimum = 0, | ||
96 | .maximum = 127, | ||
97 | .step = 1, | ||
98 | #define CONTRAST_DEF 63 | ||
99 | .default_value = CONTRAST_DEF, | ||
100 | }, | ||
101 | .set = sd_setcontrast, | ||
102 | .get = sd_getcontrast, | ||
103 | }, | ||
104 | { | ||
105 | { | ||
106 | .id = V4L2_CID_SATURATION, | ||
107 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
108 | .name = "Color", | ||
109 | .minimum = 0, | ||
110 | .maximum = 255, | ||
111 | .step = 1, | ||
112 | #define COLOR_DEF 127 | ||
113 | .default_value = COLOR_DEF, | ||
114 | }, | ||
115 | .set = sd_setcolors, | ||
116 | .get = sd_getcolors, | ||
117 | }, | ||
118 | { | ||
119 | { | ||
120 | .id = V4L2_CID_AUTOGAIN, | ||
121 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
122 | .name = "Auto Gain", | ||
123 | .minimum = 0, | ||
124 | .maximum = 1, | ||
125 | .step = 1, | ||
126 | #define AUTOGAIN_DEF 1 | ||
127 | .default_value = AUTOGAIN_DEF, | ||
128 | }, | ||
129 | .set = sd_setautogain, | ||
130 | .get = sd_getautogain, | ||
131 | }, | ||
132 | }; | ||
133 | |||
134 | static struct v4l2_pix_format vga_mode[] = { | ||
135 | {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
136 | .bytesperline = 160, | ||
137 | .sizeimage = 160 * 120 * 3 / 8 + 590, | ||
138 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
139 | .priv = 2}, | ||
140 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
141 | .bytesperline = 320, | ||
142 | .sizeimage = 320 * 240 * 3 / 8 + 590, | ||
143 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
144 | .priv = 1}, | ||
145 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
146 | .bytesperline = 640, | ||
147 | .sizeimage = 640 * 480 * 3 / 8 + 590, | ||
148 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
149 | .priv = 0}, | ||
150 | }; | ||
151 | |||
152 | /*Data from sn9c102p+hv71331r */ | ||
153 | static const __u8 sn_hv7131[] = { | ||
154 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */ | ||
155 | 0x00, 0x03, 0x64, 0x00, 0x1A, 0x20, 0x20, 0x20, 0xA1, 0x11, | ||
156 | /* rega regb regc regd rege regf reg10 reg11 */ | ||
157 | 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, /* 00 */ | ||
158 | /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */ | ||
159 | 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, 0x0a, 0x00, 0x00, 0x00, | ||
160 | /* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */ | ||
161 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
162 | }; | ||
163 | |||
164 | static const __u8 sn_mi0360[] = { | ||
165 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */ | ||
166 | 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xb1, 0x5d, | ||
167 | /* rega regb regc regd rege regf reg10 reg11 */ | ||
168 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, | ||
169 | /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */ | ||
170 | 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, 0x06, 0x00, 0x00, 0x00, | ||
171 | /* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */ | ||
172 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
173 | }; | ||
174 | |||
175 | static const __u8 sn_mo4000[] = { | ||
176 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */ | ||
177 | 0x12, 0x23, 0x60, 0x00, 0x1A, 0x00, 0x20, 0x18, 0x81, | ||
178 | /* reg9 rega regb regc regd rege regf reg10 reg11*/ | ||
179 | 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, | ||
180 | /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/ | ||
181 | 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, 0x08, 0x00, 0x00, | ||
182 | /* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/ | ||
183 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x25, 0x39, 0x4b, | ||
184 | 0x5c, 0x6b, 0x79, 0x87, 0x95, 0xa2, 0xaf, 0xbb, 0xc7, | ||
185 | 0xd3, 0xdf, 0xea, 0xf5 | ||
186 | }; | ||
187 | |||
188 | static const __u8 sn_ov7648[] = { | ||
189 | 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xA1, 0x6E, 0x18, 0x65, | ||
190 | 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1E, 0x82, | ||
191 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
192 | }; | ||
193 | |||
194 | static const __u8 sn_ov7660[] = { | ||
195 | /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */ | ||
196 | 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x81, | ||
197 | /* reg9 rega regb regc regd rege regf reg10 reg11*/ | ||
198 | 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, | ||
199 | /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/ | ||
200 | 0x01, 0x01, 0x14, 0x28, 0x1e, 0x00, 0x07, 0x00, 0x00, | ||
201 | /* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/ | ||
202 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
203 | }; | ||
204 | |||
205 | /* sequence specific to the sensors - !! index = SENSOR_xxx */ | ||
206 | static const __u8 *sn_tb[] = { | ||
207 | sn_hv7131, | ||
208 | sn_mi0360, | ||
209 | sn_mo4000, | ||
210 | sn_ov7648, | ||
211 | sn_ov7660 | ||
212 | }; | ||
213 | |||
214 | static const __u8 regsn20[] = { | ||
215 | 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, | ||
216 | 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff | ||
217 | }; | ||
218 | static const __u8 regsn20_sn9c120[] = { | ||
219 | 0x00, 0x25, 0x3c, 0x50, 0x62, 0x72, 0x81, 0x90, | ||
220 | 0x9e, 0xab, 0xb8, 0xc5, 0xd1, 0xdd, 0xe9, 0xf4, 0xff | ||
221 | }; | ||
222 | static const __u8 regsn20_sn9c325[] = { | ||
223 | 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4, | ||
224 | 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5 | ||
225 | }; | ||
226 | |||
227 | static const __u8 reg84[] = { | ||
228 | 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f, | ||
229 | 0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f, | ||
230 | /* 0x00, 0x00, 0x00, 0x00, 0x00 */ | ||
231 | 0xf7, 0x0f, 0x0a, 0x00, 0x00 | ||
232 | }; | ||
233 | static const __u8 reg84_sn9c120_1[] = { | ||
234 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
235 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
236 | 0x00, 0x00, 0x0c, 0x00, 0x00 | ||
237 | }; | ||
238 | static const __u8 reg84_sn9c120_2[] = { | ||
239 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
240 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
241 | 0x00, 0x00, 0x0c, 0x02, 0x3b | ||
242 | }; | ||
243 | static const __u8 reg84_sn9c120_3[] = { | ||
244 | 0x14, 0x00, 0x27, 0x00, 0x08, 0x00, 0xeb, 0x0f, | ||
245 | 0xd5, 0x0f, 0x42, 0x00, 0x41, 0x00, 0xca, 0x0f, | ||
246 | 0xf5, 0x0f, 0x0c, 0x02, 0x3b | ||
247 | }; | ||
248 | static const __u8 reg84_sn9c325[] = { | ||
249 | 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f, | ||
250 | 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f, | ||
251 | 0xf8, 0x0f, 0x00, 0x00, 0x00 | ||
252 | }; | ||
253 | |||
254 | static const __u8 hv7131r_sensor_init[][8] = { | ||
255 | {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10}, | ||
256 | {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10}, | ||
257 | {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10}, | ||
258 | {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
259 | {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
260 | {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10}, | ||
261 | {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
262 | |||
263 | {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, | ||
264 | {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, | ||
265 | {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10}, | ||
266 | {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10}, | ||
267 | {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10}, | ||
268 | {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10}, | ||
269 | {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */ | ||
270 | {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */ | ||
271 | |||
272 | {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, | ||
273 | {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
274 | {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10}, | ||
275 | {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
276 | {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10}, | ||
277 | |||
278 | {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, | ||
279 | {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
280 | {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10}, | ||
281 | {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
282 | {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10}, | ||
283 | {} | ||
284 | }; | ||
285 | static const __u8 mi0360_sensor_init[][8] = { | ||
286 | {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, | ||
287 | {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10}, | ||
288 | {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
289 | {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10}, | ||
290 | {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10}, | ||
291 | {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10}, | ||
292 | {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10}, | ||
293 | {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
294 | {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
295 | {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
296 | {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
297 | {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
298 | {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
299 | {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
300 | {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
301 | {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
302 | {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
303 | {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
304 | {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10}, | ||
305 | {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
306 | {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
307 | {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10}, | ||
308 | {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10}, | ||
309 | {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
310 | {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10}, | ||
311 | {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10}, | ||
312 | {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10}, | ||
313 | {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10}, | ||
314 | {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10}, | ||
315 | {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
316 | {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
317 | {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10}, | ||
318 | {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10}, | ||
319 | |||
320 | {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10}, | ||
321 | {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10}, | ||
322 | {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10}, | ||
323 | {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10}, | ||
324 | {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10}, | ||
325 | |||
326 | {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */ | ||
327 | {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10}, | ||
328 | {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10}, | ||
329 | {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */ | ||
330 | |||
331 | {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10}, | ||
332 | {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */ | ||
333 | /* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */ | ||
334 | /* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */ | ||
335 | {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */ | ||
336 | {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */ | ||
337 | {} | ||
338 | }; | ||
339 | static const __u8 mo4000_sensor_init[][8] = { | ||
340 | {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10}, | ||
341 | {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
342 | {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
343 | {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
344 | {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
345 | {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10}, | ||
346 | {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10}, | ||
347 | {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10}, | ||
348 | {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
349 | {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
350 | {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10}, | ||
351 | {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10}, | ||
352 | {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, | ||
353 | {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, | ||
354 | {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
355 | {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
356 | {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10}, | ||
357 | {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, | ||
358 | {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
359 | {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, | ||
360 | {} | ||
361 | }; | ||
362 | static const __u8 ov7660_sensor_init[][8] = { | ||
363 | {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ | ||
364 | {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, | ||
365 | /* Outformat ?? rawRGB */ | ||
366 | {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */ | ||
367 | {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10}, | ||
368 | /* {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10}, */ | ||
369 | /* GAIN BLUE RED VREF */ | ||
370 | {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10}, | ||
371 | /* COM 1 BAVE GEAVE AECHH */ | ||
372 | {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */ | ||
373 | {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */ | ||
374 | {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xf8, 0x10}, | ||
375 | /* {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10}, */ | ||
376 | /* AECH CLKRC COM7 COM8 */ | ||
377 | {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */ | ||
378 | {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10}, | ||
379 | /* HSTART HSTOP VSTRT VSTOP */ | ||
380 | {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */ | ||
381 | {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */ | ||
382 | {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10}, | ||
383 | /* BOS GBOS GROS ROS (BGGR offset) */ | ||
384 | {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, | ||
385 | /* {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10}, */ | ||
386 | /* AEW AEB VPT BBIAS */ | ||
387 | {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10}, | ||
388 | /* GbBIAS RSVD EXHCH EXHCL */ | ||
389 | {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10}, | ||
390 | /* RBIAS ADVFL ASDVFH YAVE */ | ||
391 | {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10}, | ||
392 | /* HSYST HSYEN HREF */ | ||
393 | {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */ | ||
394 | {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10}, | ||
395 | /* ADC ACOM OFON TSLB */ | ||
396 | {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10}, | ||
397 | /* COM11 COM12 COM13 COM14 */ | ||
398 | {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10}, | ||
399 | /* EDGE COM15 COM16 COM17 */ | ||
400 | {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */ | ||
401 | {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */ | ||
402 | {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */ | ||
403 | {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */ | ||
404 | {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */ | ||
405 | {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */ | ||
406 | {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */ | ||
407 | {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */ | ||
408 | {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */ | ||
409 | {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10}, | ||
410 | /* LCC1 LCC2 LCC3 LCC4 */ | ||
411 | {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */ | ||
412 | {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, | ||
413 | {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10}, | ||
414 | /* band gap reference [0..3] DBLV */ | ||
415 | {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */ | ||
416 | {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */ | ||
417 | {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */ | ||
418 | {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */ | ||
419 | {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */ | ||
420 | {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */ | ||
421 | {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */ | ||
422 | {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ | ||
423 | {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ | ||
424 | {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
425 | /****** (some exchanges in the win trace) ******/ | ||
426 | {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, | ||
427 | /* bits[3..0]reserved */ | ||
428 | {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, | ||
429 | {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
430 | /* VREF vertical frame ctrl */ | ||
431 | {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
432 | {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* 0x20 */ | ||
433 | {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
434 | {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
435 | /* {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, */ | ||
436 | {0xa1, 0x21, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x10}, | ||
437 | {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, | ||
438 | /****** (some exchanges in the win trace) ******/ | ||
439 | {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */ | ||
440 | {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10},/* dummy line low */ | ||
441 | {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
442 | {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
443 | {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, | ||
444 | /****** (some exchanges in the win trace) ******/ | ||
445 | /**********startsensor KO if changed !!****/ | ||
446 | {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10}, | ||
447 | {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10}, | ||
448 | {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
449 | {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10}, | ||
450 | /* here may start the isoc exchanges */ | ||
451 | {} | ||
452 | }; | ||
453 | /* reg0x04 reg0x07 reg 0x10 */ | ||
454 | /* expo = (COM1 & 0x02) | (AECHH & 0x2f <<10) [ (AECh << 2) */ | ||
455 | |||
456 | static const __u8 ov7648_sensor_init[][8] = { | ||
457 | {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00}, | ||
458 | {0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}, | ||
459 | {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00}, | ||
460 | {0xA1, 0x6E, 0x3F, 0x20, 0x00, 0x00, 0x00, 0x10}, | ||
461 | {0xA1, 0x6E, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
462 | {0xA1, 0x6E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
463 | {0xD1, 0x6E, 0x04, 0x02, 0xB1, 0x02, 0x39, 0x10}, | ||
464 | {0xD1, 0x6E, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10}, | ||
465 | {0xD1, 0x6E, 0x0C, 0x02, 0x7F, 0x01, 0xE0, 0x10}, | ||
466 | {0xD1, 0x6E, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10}, | ||
467 | {0xD1, 0x6E, 0x16, 0x85, 0x40, 0x4A, 0x40, 0x10}, | ||
468 | {0xC1, 0x6E, 0x1A, 0x00, 0x80, 0x00, 0x00, 0x10}, | ||
469 | {0xD1, 0x6E, 0x1D, 0x08, 0x03, 0x00, 0x00, 0x10}, | ||
470 | {0xD1, 0x6E, 0x23, 0x00, 0xB0, 0x00, 0x94, 0x10}, | ||
471 | {0xD1, 0x6E, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10}, | ||
472 | {0xD1, 0x6E, 0x2D, 0x14, 0x35, 0x61, 0x84, 0x10}, | ||
473 | {0xD1, 0x6E, 0x31, 0xA2, 0xBD, 0xD8, 0xFF, 0x10}, | ||
474 | {0xD1, 0x6E, 0x35, 0x06, 0x1E, 0x12, 0x02, 0x10}, | ||
475 | {0xD1, 0x6E, 0x39, 0xAA, 0x53, 0x37, 0xD5, 0x10}, | ||
476 | {0xA1, 0x6E, 0x3D, 0xF2, 0x00, 0x00, 0x00, 0x10}, | ||
477 | {0xD1, 0x6E, 0x3E, 0x00, 0x00, 0x80, 0x03, 0x10}, | ||
478 | {0xD1, 0x6E, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10}, | ||
479 | {0xC1, 0x6E, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10}, | ||
480 | {0xD1, 0x6E, 0x4B, 0x02, 0xEF, 0x08, 0xCD, 0x10}, | ||
481 | {0xD1, 0x6E, 0x4F, 0x00, 0xD0, 0x00, 0xA0, 0x10}, | ||
482 | {0xD1, 0x6E, 0x53, 0x01, 0xAA, 0x01, 0x40, 0x10}, | ||
483 | {0xD1, 0x6E, 0x5A, 0x50, 0x04, 0x30, 0x03, 0x10}, | ||
484 | {0xA1, 0x6E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
485 | {0xD1, 0x6E, 0x5F, 0x10, 0x40, 0xFF, 0x00, 0x10}, | ||
486 | /* {0xD1, 0x6E, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10}, | ||
487 | {0xD1, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
488 | * This is currently setting a | ||
489 | * blue tint, and some things more , i leave it here for future test if | ||
490 | * somene is having problems with color on this sensor | ||
491 | {0xD1, 0x6E, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
492 | {0xD1, 0x6E, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x10}, | ||
493 | {0xC1, 0x6E, 0x73, 0x10, 0x80, 0xEB, 0x00, 0x10}, | ||
494 | {0xA1, 0x6E, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x10}, | ||
495 | {0xA1, 0x6E, 0x15, 0x01, 0x00, 0x00, 0x00, 0x10}, | ||
496 | {0xC1, 0x6E, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, | ||
497 | {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10}, | ||
498 | {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, | ||
499 | {0xA1, 0x6E, 0x07, 0xB5, 0x00, 0x00, 0x00, 0x10}, | ||
500 | {0xA1, 0x6E, 0x18, 0x6B, 0x00, 0x00, 0x00, 0x10}, | ||
501 | {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10}, | ||
502 | {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, | ||
503 | {0xA1, 0x6E, 0x07, 0xB8, 0x00, 0x00, 0x00, 0x10}, */ | ||
504 | {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00}, | ||
505 | {0xA1, 0x6E, 0x06, 0x03, 0x00, 0x00, 0x00, 0x10}, /* Bright... */ | ||
506 | {0xA1, 0x6E, 0x07, 0x66, 0x00, 0x00, 0x00, 0x10}, /* B.. */ | ||
507 | {0xC1, 0x6E, 0x1A, 0x03, 0x65, 0x90, 0x00, 0x10}, /* Bright/Witen....*/ | ||
508 | /* {0xC1, 0x6E, 0x16, 0x45, 0x40, 0x60, 0x00, 0x10}, * Bright/Witene */ | ||
509 | {} | ||
510 | }; | ||
511 | |||
512 | static const __u8 qtable4[] = { | ||
513 | 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06, | ||
514 | 0x06, 0x08, 0x0A, 0x11, | ||
515 | 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15, | ||
516 | 0x19, 0x19, 0x17, 0x15, | ||
517 | 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17, | ||
518 | 0x21, 0x2E, 0x21, 0x23, | ||
519 | 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32, | ||
520 | 0x25, 0x29, 0x2C, 0x29, | ||
521 | 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B, | ||
522 | 0x17, 0x1B, 0x29, 0x29, | ||
523 | 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, | ||
524 | 0x29, 0x29, 0x29, 0x29, | ||
525 | 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, | ||
526 | 0x29, 0x29, 0x29, 0x29, | ||
527 | 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, | ||
528 | 0x29, 0x29, 0x29, 0x29 | ||
529 | }; | ||
530 | |||
531 | /* read <len> bytes (len < sizeof gspca_dev->usb_buf) to gspca_dev->usb_buf */ | ||
532 | static void reg_r(struct gspca_dev *gspca_dev, | ||
533 | __u16 value, int len) | ||
534 | { | ||
535 | usb_control_msg(gspca_dev->dev, | ||
536 | usb_rcvctrlpipe(gspca_dev->dev, 0), | ||
537 | 0, | ||
538 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
539 | value, 0, | ||
540 | gspca_dev->usb_buf, len, | ||
541 | 500); | ||
542 | } | ||
543 | |||
544 | static void reg_w(struct gspca_dev *gspca_dev, | ||
545 | __u16 value, | ||
546 | const __u8 *buffer, | ||
547 | int len) | ||
548 | { | ||
549 | if (len <= sizeof gspca_dev->usb_buf) { | ||
550 | memcpy(gspca_dev->usb_buf, buffer, len); | ||
551 | usb_control_msg(gspca_dev->dev, | ||
552 | usb_sndctrlpipe(gspca_dev->dev, 0), | ||
553 | 0x08, | ||
554 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
555 | value, 0, | ||
556 | gspca_dev->usb_buf, len, | ||
557 | 500); | ||
558 | } else { | ||
559 | __u8 *tmpbuf; | ||
560 | |||
561 | tmpbuf = kmalloc(len, GFP_KERNEL); | ||
562 | memcpy(tmpbuf, buffer, len); | ||
563 | usb_control_msg(gspca_dev->dev, | ||
564 | usb_sndctrlpipe(gspca_dev->dev, 0), | ||
565 | 0x08, | ||
566 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
567 | value, 0, | ||
568 | tmpbuf, len, | ||
569 | 500); | ||
570 | kfree(tmpbuf); | ||
571 | } | ||
572 | } | ||
573 | |||
574 | /* I2C write 2 bytes */ | ||
575 | static void i2c_w2(struct gspca_dev *gspca_dev, | ||
576 | const __u8 *buffer) | ||
577 | { | ||
578 | struct sd *sd = (struct sd *) gspca_dev; | ||
579 | __u8 mode[8]; | ||
580 | |||
581 | /* is i2c ready */ | ||
582 | mode[0] = 0x81 | (2 << 4); | ||
583 | mode[1] = sd->i2c_base; | ||
584 | mode[2] = buffer[0]; | ||
585 | mode[3] = buffer[1]; | ||
586 | mode[4] = 0; | ||
587 | mode[5] = 0; | ||
588 | mode[6] = 0; | ||
589 | mode[7] = 0x10; | ||
590 | reg_w(gspca_dev, 0x08, mode, 8); | ||
591 | } | ||
592 | |||
593 | /* I2C write 8 bytes */ | ||
594 | static void i2c_w8(struct gspca_dev *gspca_dev, | ||
595 | const __u8 *buffer) | ||
596 | { | ||
597 | reg_w(gspca_dev, 0x08, buffer, 8); | ||
598 | msleep(1); | ||
599 | } | ||
600 | |||
601 | /* read 5 bytes in gspca_dev->usb_buf */ | ||
602 | static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg) | ||
603 | { | ||
604 | struct sd *sd = (struct sd *) gspca_dev; | ||
605 | __u8 mode[8]; | ||
606 | |||
607 | mode[0] = 0x81 | 0x10; | ||
608 | mode[1] = sd->i2c_base; | ||
609 | mode[2] = reg; | ||
610 | mode[3] = 0; | ||
611 | mode[4] = 0; | ||
612 | mode[5] = 0; | ||
613 | mode[6] = 0; | ||
614 | mode[7] = 0x10; | ||
615 | i2c_w8(gspca_dev, mode); | ||
616 | mode[0] = 0x81 | (5 << 4) | 0x02; | ||
617 | mode[2] = 0; | ||
618 | i2c_w8(gspca_dev, mode); | ||
619 | reg_r(gspca_dev, 0x0a, 5); | ||
620 | } | ||
621 | |||
622 | static int probesensor(struct gspca_dev *gspca_dev) | ||
623 | { | ||
624 | struct sd *sd = (struct sd *) gspca_dev; | ||
625 | __u8 reg02; | ||
626 | static const __u8 datasend[] = { 2, 0 }; | ||
627 | /* reg val1 val2 val3 val4 */ | ||
628 | |||
629 | i2c_w2(gspca_dev, datasend); | ||
630 | /* should write 0xa1 0x11 0x02 0x00 0x00 0x00 0x00 the 0x10 is add by i2cw */ | ||
631 | msleep(10); | ||
632 | reg02 = 0x66; | ||
633 | reg_w(gspca_dev, 0x02, ®02, 1); /* Gpio on */ | ||
634 | msleep(10); | ||
635 | i2c_r5(gspca_dev, 0); /* read sensor id */ | ||
636 | if (gspca_dev->usb_buf[0] == 0x02 | ||
637 | && gspca_dev->usb_buf[1] == 0x09 | ||
638 | && gspca_dev->usb_buf[2] == 0x01 | ||
639 | && gspca_dev->usb_buf[3] == 0x00 | ||
640 | && gspca_dev->usb_buf[4] == 0x00) { | ||
641 | PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R"); | ||
642 | sd->sensor = SENSOR_HV7131R; | ||
643 | return SENSOR_HV7131R; | ||
644 | } | ||
645 | PDEBUG(D_PROBE, "Find Sensor %d %d %d", | ||
646 | gspca_dev->usb_buf[0], gspca_dev->usb_buf[1], | ||
647 | gspca_dev->usb_buf[2]); | ||
648 | PDEBUG(D_PROBE, "Sensor sn9c102P Not found"); | ||
649 | return -ENODEV; | ||
650 | } | ||
651 | |||
652 | static int configure_gpio(struct gspca_dev *gspca_dev, | ||
653 | const __u8 *sn9c1xx) | ||
654 | { | ||
655 | struct sd *sd = (struct sd *) gspca_dev; | ||
656 | __u8 data; | ||
657 | __u8 regF1; | ||
658 | const __u8 *reg9a; | ||
659 | static const __u8 reg9a_def[] = | ||
660 | {0x08, 0x40, 0x20, 0x10, 0x00, 0x04}; | ||
661 | static const __u8 reg9a_sn9c120[] = /* from win trace */ | ||
662 | {0x00, 0x40, 0x38, 0x30, 0x00, 0x20}; | ||
663 | static const __u8 reg9a_sn9c325[] = | ||
664 | {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20}; | ||
665 | |||
666 | |||
667 | regF1 = 0x00; | ||
668 | reg_w(gspca_dev, 0xf1, ®F1, 1); | ||
669 | reg_w(gspca_dev, 0x01, &sn9c1xx[0], 1); /*fixme:jfm was [1] en v1*/ | ||
670 | |||
671 | /* configure gpio */ | ||
672 | reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); | ||
673 | reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); | ||
674 | reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm was 3 */ | ||
675 | switch (sd->bridge) { | ||
676 | case BRIDGE_SN9C325: | ||
677 | reg9a = reg9a_sn9c325; | ||
678 | break; | ||
679 | case BRIDGE_SN9C120: | ||
680 | reg9a = reg9a_sn9c120; | ||
681 | break; | ||
682 | default: | ||
683 | reg9a = reg9a_def; | ||
684 | break; | ||
685 | } | ||
686 | reg_w(gspca_dev, 0x9a, reg9a, 6); | ||
687 | |||
688 | data = 0x60; /*fixme:jfm 60 00 00 (3) */ | ||
689 | reg_w(gspca_dev, 0xd4, &data, 1); | ||
690 | |||
691 | reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); | ||
692 | |||
693 | switch (sd->bridge) { | ||
694 | case BRIDGE_SN9C120: /* from win trace */ | ||
695 | data = 0x61; | ||
696 | reg_w(gspca_dev, 0x01, &data, 1); | ||
697 | data = 0x20; | ||
698 | reg_w(gspca_dev, 0x17, &data, 1); | ||
699 | data = 0x60; | ||
700 | reg_w(gspca_dev, 0x01, &data, 1); | ||
701 | break; | ||
702 | case BRIDGE_SN9C325: | ||
703 | data = 0x43; | ||
704 | reg_w(gspca_dev, 0x01, &data, 1); | ||
705 | data = 0xae; | ||
706 | reg_w(gspca_dev, 0x17, &data, 1); | ||
707 | data = 0x42; | ||
708 | reg_w(gspca_dev, 0x01, &data, 1); | ||
709 | break; | ||
710 | default: | ||
711 | data = 0x43; | ||
712 | reg_w(gspca_dev, 0x01, &data, 1); | ||
713 | data = 0x61; | ||
714 | reg_w(gspca_dev, 0x17, &data, 1); | ||
715 | data = 0x42; | ||
716 | reg_w(gspca_dev, 0x01, &data, 1); | ||
717 | } | ||
718 | |||
719 | if (sd->sensor == SENSOR_HV7131R) { | ||
720 | if (probesensor(gspca_dev) < 0) | ||
721 | return -ENODEV; | ||
722 | } | ||
723 | return 0; | ||
724 | } | ||
725 | |||
726 | static void hv7131R_InitSensor(struct gspca_dev *gspca_dev) | ||
727 | { | ||
728 | int i = 0; | ||
729 | static const __u8 SetSensorClk[] = /* 0x08 Mclk */ | ||
730 | { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 }; | ||
731 | |||
732 | while (hv7131r_sensor_init[i][0]) { | ||
733 | i2c_w8(gspca_dev, hv7131r_sensor_init[i]); | ||
734 | i++; | ||
735 | } | ||
736 | i2c_w8(gspca_dev, SetSensorClk); | ||
737 | } | ||
738 | |||
739 | static void mi0360_InitSensor(struct gspca_dev *gspca_dev) | ||
740 | { | ||
741 | int i = 0; | ||
742 | |||
743 | while (mi0360_sensor_init[i][0]) { | ||
744 | i2c_w8(gspca_dev, mi0360_sensor_init[i]); | ||
745 | i++; | ||
746 | } | ||
747 | } | ||
748 | |||
749 | static void mo4000_InitSensor(struct gspca_dev *gspca_dev) | ||
750 | { | ||
751 | int i = 0; | ||
752 | |||
753 | while (mo4000_sensor_init[i][0]) { | ||
754 | i2c_w8(gspca_dev, mo4000_sensor_init[i]); | ||
755 | i++; | ||
756 | } | ||
757 | } | ||
758 | |||
759 | static void ov7648_InitSensor(struct gspca_dev *gspca_dev) | ||
760 | { | ||
761 | int i = 0; | ||
762 | |||
763 | while (ov7648_sensor_init[i][0]) { | ||
764 | i2c_w8(gspca_dev, ov7648_sensor_init[i]); | ||
765 | i++; | ||
766 | } | ||
767 | } | ||
768 | |||
769 | static void ov7660_InitSensor(struct gspca_dev *gspca_dev) | ||
770 | { | ||
771 | int i = 0; | ||
772 | |||
773 | while (ov7660_sensor_init[i][0]) { | ||
774 | i2c_w8(gspca_dev, ov7660_sensor_init[i]); | ||
775 | i++; | ||
776 | } | ||
777 | } | ||
778 | |||
779 | /* this function is called at probe time */ | ||
780 | static int sd_config(struct gspca_dev *gspca_dev, | ||
781 | const struct usb_device_id *id) | ||
782 | { | ||
783 | struct sd *sd = (struct sd *) gspca_dev; | ||
784 | struct cam *cam; | ||
785 | __u16 vendor; | ||
786 | __u16 product; | ||
787 | |||
788 | vendor = id->idVendor; | ||
789 | product = id->idProduct; | ||
790 | sd->sensor = -1; | ||
791 | switch (vendor) { | ||
792 | case 0x0458: /* Genius */ | ||
793 | /* switch (product) { | ||
794 | case 0x7025: */ | ||
795 | sd->bridge = BRIDGE_SN9C120; | ||
796 | sd->sensor = SENSOR_MI0360; | ||
797 | sd->i2c_base = 0x5d; | ||
798 | /* break; | ||
799 | } */ | ||
800 | break; | ||
801 | case 0x045e: | ||
802 | /* switch (product) { | ||
803 | case 0x00f5: | ||
804 | case 0x00f7: */ | ||
805 | sd->bridge = BRIDGE_SN9C105; | ||
806 | sd->sensor = SENSOR_OV7660; | ||
807 | sd->i2c_base = 0x21; | ||
808 | /* break; | ||
809 | } */ | ||
810 | break; | ||
811 | case 0x0471: /* Philips */ | ||
812 | /* switch (product) { | ||
813 | case 0x0327: | ||
814 | case 0x0328: | ||
815 | case 0x0330: */ | ||
816 | sd->bridge = BRIDGE_SN9C105; | ||
817 | sd->sensor = SENSOR_MI0360; | ||
818 | sd->i2c_base = 0x5d; | ||
819 | /* break; | ||
820 | } */ | ||
821 | break; | ||
822 | case 0x0c45: /* Sonix */ | ||
823 | switch (product) { | ||
824 | case 0x6040: | ||
825 | sd->bridge = BRIDGE_SN9C102P; | ||
826 | /* sd->sensor = SENSOR_MI0360; * from BW600.inf */ | ||
827 | /*fixme: MI0360 base=5d ? */ | ||
828 | sd->sensor = SENSOR_HV7131R; /* gspcav1 value */ | ||
829 | sd->i2c_base = 0x11; | ||
830 | break; | ||
831 | /* case 0x607a: * from BW600.inf | ||
832 | sd->bridge = BRIDGE_SN9C102P; | ||
833 | sd->sensor = SENSOR_OV7648; | ||
834 | sd->i2c_base = 0x??; | ||
835 | break; */ | ||
836 | case 0x607c: | ||
837 | sd->bridge = BRIDGE_SN9C102P; | ||
838 | sd->sensor = SENSOR_HV7131R; | ||
839 | sd->i2c_base = 0x11; | ||
840 | break; | ||
841 | /* case 0x607e: * from BW600.inf | ||
842 | sd->bridge = BRIDGE_SN9C102P; | ||
843 | sd->sensor = SENSOR_OV7630; | ||
844 | sd->i2c_base = 0x??; | ||
845 | break; */ | ||
846 | case 0x60c0: | ||
847 | sd->bridge = BRIDGE_SN9C105; | ||
848 | sd->sensor = SENSOR_MI0360; | ||
849 | sd->i2c_base = 0x5d; | ||
850 | break; | ||
851 | /* case 0x60c8: * from BW600.inf | ||
852 | sd->bridge = BRIDGE_SN9C105; | ||
853 | sd->sensor = SENSOR_OM6801; | ||
854 | sd->i2c_base = 0x??; | ||
855 | break; */ | ||
856 | /* case 0x60cc: * from BW600.inf | ||
857 | sd->bridge = BRIDGE_SN9C105; | ||
858 | sd->sensor = SENSOR_HV7131GP; | ||
859 | sd->i2c_base = 0x??; | ||
860 | break; */ | ||
861 | case 0x60ec: | ||
862 | sd->bridge = BRIDGE_SN9C105; | ||
863 | sd->sensor = SENSOR_MO4000; | ||
864 | sd->i2c_base = 0x21; | ||
865 | break; | ||
866 | /* case 0x60ef: * from BW600.inf | ||
867 | sd->bridge = BRIDGE_SN9C105; | ||
868 | sd->sensor = SENSOR_ICM105C; | ||
869 | sd->i2c_base = 0x??; | ||
870 | break; */ | ||
871 | /* case 0x60fa: * from BW600.inf | ||
872 | sd->bridge = BRIDGE_SN9C105; | ||
873 | sd->sensor = SENSOR_OV7648; | ||
874 | sd->i2c_base = 0x??; | ||
875 | break; */ | ||
876 | case 0x60fb: | ||
877 | sd->bridge = BRIDGE_SN9C105; | ||
878 | sd->sensor = SENSOR_OV7660; | ||
879 | sd->i2c_base = 0x21; | ||
880 | break; | ||
881 | case 0x60fc: | ||
882 | sd->bridge = BRIDGE_SN9C105; | ||
883 | sd->sensor = SENSOR_HV7131R; | ||
884 | sd->i2c_base = 0x11; | ||
885 | break; | ||
886 | /* case 0x60fe: * from BW600.inf | ||
887 | sd->bridge = BRIDGE_SN9C105; | ||
888 | sd->sensor = SENSOR_OV7630; | ||
889 | sd->i2c_base = 0x??; | ||
890 | break; */ | ||
891 | /* case 0x6108: * from BW600.inf | ||
892 | sd->bridge = BRIDGE_SN9C120; | ||
893 | sd->sensor = SENSOR_OM6801; | ||
894 | sd->i2c_base = 0x??; | ||
895 | break; */ | ||
896 | /* case 0x6122: * from BW600.inf | ||
897 | sd->bridge = BRIDGE_SN9C110; | ||
898 | sd->sensor = SENSOR_ICM105C; | ||
899 | sd->i2c_base = 0x??; | ||
900 | break; */ | ||
901 | case 0x612a: | ||
902 | /* sd->bridge = BRIDGE_SN9C110; * in BW600.inf */ | ||
903 | sd->bridge = BRIDGE_SN9C325; | ||
904 | sd->sensor = SENSOR_OV7648; | ||
905 | sd->i2c_base = 0x21; | ||
906 | /*fixme: sensor_init has base = 00 et 6e!*/ | ||
907 | break; | ||
908 | /* case 0x6123: * from BW600.inf | ||
909 | sd->bridge = BRIDGE_SN9C110; | ||
910 | sd->sensor = SENSOR_SanyoCCD; | ||
911 | sd->i2c_base = 0x??; | ||
912 | break; */ | ||
913 | case 0x612c: | ||
914 | sd->bridge = BRIDGE_SN9C110; | ||
915 | sd->sensor = SENSOR_MO4000; | ||
916 | sd->i2c_base = 0x21; | ||
917 | break; | ||
918 | /* case 0x612e: * from BW600.inf | ||
919 | sd->bridge = BRIDGE_SN9C110; | ||
920 | sd->sensor = SENSOR_OV7630; | ||
921 | sd->i2c_base = 0x??; | ||
922 | break; */ | ||
923 | /* case 0x612f: * from BW600.inf | ||
924 | sd->bridge = BRIDGE_SN9C110; | ||
925 | sd->sensor = SENSOR_ICM105C; | ||
926 | sd->i2c_base = 0x??; | ||
927 | break; */ | ||
928 | case 0x6130: | ||
929 | sd->bridge = BRIDGE_SN9C120; | ||
930 | sd->sensor = SENSOR_MI0360; | ||
931 | sd->i2c_base = 0x5d; | ||
932 | break; | ||
933 | case 0x6138: | ||
934 | sd->bridge = BRIDGE_SN9C120; | ||
935 | sd->sensor = SENSOR_MO4000; | ||
936 | sd->i2c_base = 0x21; | ||
937 | break; | ||
938 | /* case 0x613a: * from BW600.inf | ||
939 | sd->bridge = BRIDGE_SN9C120; | ||
940 | sd->sensor = SENSOR_OV7648; | ||
941 | sd->i2c_base = 0x??; | ||
942 | break; */ | ||
943 | case 0x613b: | ||
944 | sd->bridge = BRIDGE_SN9C120; | ||
945 | sd->sensor = SENSOR_OV7660; | ||
946 | sd->i2c_base = 0x21; | ||
947 | break; | ||
948 | case 0x613c: | ||
949 | sd->bridge = BRIDGE_SN9C120; | ||
950 | sd->sensor = SENSOR_HV7131R; | ||
951 | sd->i2c_base = 0x11; | ||
952 | break; | ||
953 | /* case 0x613e: * from BW600.inf | ||
954 | sd->bridge = BRIDGE_SN9C120; | ||
955 | sd->sensor = SENSOR_OV7630; | ||
956 | sd->i2c_base = 0x??; | ||
957 | break; */ | ||
958 | } | ||
959 | break; | ||
960 | } | ||
961 | if (sd->sensor < 0) { | ||
962 | PDEBUG(D_ERR, "Invalid vendor/product %04x:%04x", | ||
963 | vendor, product); | ||
964 | return -EINVAL; | ||
965 | } | ||
966 | |||
967 | cam = &gspca_dev->cam; | ||
968 | cam->dev_name = (char *) id->driver_info; | ||
969 | cam->epaddr = 0x01; | ||
970 | cam->cam_mode = vga_mode; | ||
971 | cam->nmodes = ARRAY_SIZE(vga_mode); | ||
972 | |||
973 | sd->qindex = 4; /* set the quantization table */ | ||
974 | sd->brightness = BRIGHTNESS_DEF; | ||
975 | sd->contrast = CONTRAST_DEF; | ||
976 | sd->colors = COLOR_DEF; | ||
977 | sd->autogain = AUTOGAIN_DEF; | ||
978 | return 0; | ||
979 | } | ||
980 | |||
981 | /* this function is called at open time */ | ||
982 | static int sd_open(struct gspca_dev *gspca_dev) | ||
983 | { | ||
984 | struct sd *sd = (struct sd *) gspca_dev; | ||
985 | /* const __u8 *sn9c1xx; */ | ||
986 | __u8 regF1; | ||
987 | __u8 regGpio[] = { 0x29, 0x74 }; | ||
988 | |||
989 | /* setup a selector by bridge */ | ||
990 | regF1 = 0x01; | ||
991 | reg_w(gspca_dev, 0xf1, ®F1, 1); | ||
992 | reg_r(gspca_dev, 0x00, 1); /* -> regF1 = 0x00 */ | ||
993 | regF1 = gspca_dev->usb_buf[0]; | ||
994 | reg_w(gspca_dev, 0xf1, ®F1, 1); | ||
995 | reg_r(gspca_dev, 0x00, 1); | ||
996 | regF1 = gspca_dev->usb_buf[0]; | ||
997 | switch (sd->bridge) { | ||
998 | case BRIDGE_SN9C102P: | ||
999 | if (regF1 != 0x11) | ||
1000 | return -ENODEV; | ||
1001 | reg_w(gspca_dev, 0x02, ®Gpio[1], 1); | ||
1002 | break; | ||
1003 | case BRIDGE_SN9C105: | ||
1004 | if (regF1 != 0x11) | ||
1005 | return -ENODEV; | ||
1006 | reg_w(gspca_dev, 0x02, regGpio, 2); | ||
1007 | break; | ||
1008 | case BRIDGE_SN9C110: | ||
1009 | if (regF1 != 0x12) | ||
1010 | return -ENODEV; | ||
1011 | regGpio[1] = 0x62; | ||
1012 | reg_w(gspca_dev, 0x02, ®Gpio[1], 1); | ||
1013 | break; | ||
1014 | case BRIDGE_SN9C120: | ||
1015 | if (regF1 != 0x12) | ||
1016 | return -ENODEV; | ||
1017 | regGpio[1] = 0x70; | ||
1018 | reg_w(gspca_dev, 0x02, regGpio, 2); | ||
1019 | break; | ||
1020 | default: | ||
1021 | /* case BRIDGE_SN9C325: */ | ||
1022 | if (regF1 != 0x12) | ||
1023 | return -ENODEV; | ||
1024 | regGpio[1] = 0x62; | ||
1025 | reg_w(gspca_dev, 0x02, ®Gpio[1], 1); | ||
1026 | break; | ||
1027 | } | ||
1028 | |||
1029 | regF1 = 0x01; | ||
1030 | reg_w(gspca_dev, 0xf1, ®F1, 1); | ||
1031 | |||
1032 | return 0; | ||
1033 | } | ||
1034 | |||
1035 | static unsigned int setexposure(struct gspca_dev *gspca_dev, | ||
1036 | unsigned int expo) | ||
1037 | { | ||
1038 | struct sd *sd = (struct sd *) gspca_dev; | ||
1039 | static const __u8 doit[] = /* update sensor */ | ||
1040 | { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 }; | ||
1041 | static const __u8 sensorgo[] = /* sensor on */ | ||
1042 | { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 }; | ||
1043 | static const __u8 gainMo[] = | ||
1044 | { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d }; | ||
1045 | |||
1046 | switch (sd->sensor) { | ||
1047 | case SENSOR_HV7131R: { | ||
1048 | __u8 Expodoit[] = | ||
1049 | { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 }; | ||
1050 | |||
1051 | Expodoit[3] = expo >> 16; | ||
1052 | Expodoit[4] = expo >> 8; | ||
1053 | Expodoit[5] = expo; | ||
1054 | i2c_w8(gspca_dev, Expodoit); | ||
1055 | break; | ||
1056 | } | ||
1057 | case SENSOR_MI0360: { | ||
1058 | __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */ | ||
1059 | { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 }; | ||
1060 | |||
1061 | if (expo > 0x0635) | ||
1062 | expo = 0x0635; | ||
1063 | else if (expo < 0x0001) | ||
1064 | expo = 0x0001; | ||
1065 | expoMi[3] = expo >> 8; | ||
1066 | expoMi[4] = expo; | ||
1067 | i2c_w8(gspca_dev, expoMi); | ||
1068 | i2c_w8(gspca_dev, doit); | ||
1069 | i2c_w8(gspca_dev, sensorgo); | ||
1070 | break; | ||
1071 | } | ||
1072 | case SENSOR_MO4000: { | ||
1073 | __u8 expoMof[] = | ||
1074 | { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 }; | ||
1075 | __u8 expoMo10[] = | ||
1076 | { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 }; | ||
1077 | |||
1078 | if (expo > 0x1fff) | ||
1079 | expo = 0x1fff; | ||
1080 | else if (expo < 0x0001) | ||
1081 | expo = 0x0001; | ||
1082 | expoMof[3] = (expo & 0x03fc) >> 2; | ||
1083 | i2c_w8(gspca_dev, expoMof); | ||
1084 | expoMo10[3] = ((expo & 0x1c00) >> 10) | ||
1085 | | ((expo & 0x0003) << 4); | ||
1086 | i2c_w8(gspca_dev, expoMo10); | ||
1087 | i2c_w8(gspca_dev, gainMo); | ||
1088 | PDEBUG(D_CONF, "set exposure %d", | ||
1089 | ((expoMo10[3] & 0x07) << 10) | ||
1090 | | (expoMof[3] << 2) | ||
1091 | | ((expoMo10[3] & 0x30) >> 4)); | ||
1092 | break; | ||
1093 | } | ||
1094 | } | ||
1095 | return expo; | ||
1096 | } | ||
1097 | |||
1098 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
1099 | { | ||
1100 | struct sd *sd = (struct sd *) gspca_dev; | ||
1101 | unsigned int expo; | ||
1102 | __u8 k2; | ||
1103 | |||
1104 | switch (sd->sensor) { | ||
1105 | case SENSOR_HV7131R: | ||
1106 | expo = sd->brightness << 4; | ||
1107 | if (expo > 0x002dc6c0) | ||
1108 | expo = 0x002dc6c0; | ||
1109 | else if (expo < 0x02a0) | ||
1110 | expo = 0x02a0; | ||
1111 | sd->exposure = setexposure(gspca_dev, expo); | ||
1112 | break; | ||
1113 | case SENSOR_MI0360: | ||
1114 | expo = sd->brightness >> 4; | ||
1115 | sd->exposure = setexposure(gspca_dev, expo); | ||
1116 | break; | ||
1117 | case SENSOR_MO4000: | ||
1118 | expo = sd->brightness >> 4; | ||
1119 | sd->exposure = setexposure(gspca_dev, expo); | ||
1120 | break; | ||
1121 | case SENSOR_OV7660: | ||
1122 | return; /*jfm??*/ | ||
1123 | } | ||
1124 | |||
1125 | k2 = sd->brightness >> 10; | ||
1126 | reg_w(gspca_dev, 0x96, &k2, 1); | ||
1127 | } | ||
1128 | |||
1129 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
1130 | { | ||
1131 | struct sd *sd = (struct sd *) gspca_dev; | ||
1132 | __u8 k2; | ||
1133 | __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 }; | ||
1134 | |||
1135 | if (sd->sensor == SENSOR_OV7660) | ||
1136 | return; /*jfm??*/ | ||
1137 | k2 = sd->contrast; | ||
1138 | contrast[2] = k2; | ||
1139 | contrast[0] = (k2 + 1) >> 1; | ||
1140 | contrast[4] = (k2 + 1) / 5; | ||
1141 | reg_w(gspca_dev, 0x84, contrast, 6); | ||
1142 | } | ||
1143 | |||
1144 | static void setcolors(struct gspca_dev *gspca_dev) | ||
1145 | { | ||
1146 | struct sd *sd = (struct sd *) gspca_dev; | ||
1147 | __u8 data; | ||
1148 | int colour; | ||
1149 | |||
1150 | colour = sd->colors - 128; | ||
1151 | if (colour > 0) | ||
1152 | data = (colour + 32) & 0x7f; /* blue */ | ||
1153 | else | ||
1154 | data = (-colour + 32) & 0x7f; /* red */ | ||
1155 | reg_w(gspca_dev, 0x05, &data, 1); | ||
1156 | } | ||
1157 | |||
1158 | /* -- start the camera -- */ | ||
1159 | static void sd_start(struct gspca_dev *gspca_dev) | ||
1160 | { | ||
1161 | struct sd *sd = (struct sd *) gspca_dev; | ||
1162 | int i; | ||
1163 | __u8 data; | ||
1164 | __u8 reg1; | ||
1165 | __u8 reg17; | ||
1166 | const __u8 *sn9c1xx; | ||
1167 | int mode; | ||
1168 | static const __u8 DC29[] = { 0x6a, 0x50, 0x00, 0x00, 0x50, 0x3c }; | ||
1169 | static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; | ||
1170 | static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; | ||
1171 | static const __u8 CA_sn9c120[] = | ||
1172 | { 0x14, 0xec, 0x0a, 0xf6 }; /* SN9C120 */ | ||
1173 | static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ | ||
1174 | static const __u8 CE_sn9c325[] = | ||
1175 | { 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */ | ||
1176 | |||
1177 | sn9c1xx = sn_tb[(int) sd->sensor]; | ||
1178 | configure_gpio(gspca_dev, sn9c1xx); | ||
1179 | |||
1180 | /*fixme:jfm this sequence should appear at end of sd_start */ | ||
1181 | /* with | ||
1182 | data = 0x44; | ||
1183 | reg_w(gspca_dev, 0x01, &data, 1); */ | ||
1184 | reg_w(gspca_dev, 0x15, &sn9c1xx[0x15], 1); | ||
1185 | reg_w(gspca_dev, 0x16, &sn9c1xx[0x16], 1); | ||
1186 | reg_w(gspca_dev, 0x12, &sn9c1xx[0x12], 1); | ||
1187 | reg_w(gspca_dev, 0x13, &sn9c1xx[0x13], 1); | ||
1188 | reg_w(gspca_dev, 0x18, &sn9c1xx[0x18], 1); | ||
1189 | reg_w(gspca_dev, 0xd2, &DC29[0], 1); | ||
1190 | reg_w(gspca_dev, 0xd3, &DC29[1], 1); | ||
1191 | reg_w(gspca_dev, 0xc6, &DC29[2], 1); | ||
1192 | reg_w(gspca_dev, 0xc7, &DC29[3], 1); | ||
1193 | reg_w(gspca_dev, 0xc8, &DC29[4], 1); | ||
1194 | reg_w(gspca_dev, 0xc9, &DC29[5], 1); | ||
1195 | /*fixme:jfm end of ending sequence */ | ||
1196 | reg_w(gspca_dev, 0x18, &sn9c1xx[0x18], 1); | ||
1197 | switch (sd->bridge) { | ||
1198 | case BRIDGE_SN9C325: | ||
1199 | data = 0xae; | ||
1200 | break; | ||
1201 | case BRIDGE_SN9C120: | ||
1202 | data = 0xa0; | ||
1203 | break; | ||
1204 | default: | ||
1205 | data = 0x60; | ||
1206 | break; | ||
1207 | } | ||
1208 | reg_w(gspca_dev, 0x17, &data, 1); | ||
1209 | reg_w(gspca_dev, 0x05, &sn9c1xx[5], 1); | ||
1210 | reg_w(gspca_dev, 0x07, &sn9c1xx[7], 1); | ||
1211 | reg_w(gspca_dev, 0x06, &sn9c1xx[6], 1); | ||
1212 | reg_w(gspca_dev, 0x14, &sn9c1xx[0x14], 1); | ||
1213 | switch (sd->bridge) { | ||
1214 | case BRIDGE_SN9C325: | ||
1215 | reg_w(gspca_dev, 0x20, regsn20_sn9c325, | ||
1216 | sizeof regsn20_sn9c325); | ||
1217 | for (i = 0; i < 8; i++) | ||
1218 | reg_w(gspca_dev, 0x84, reg84_sn9c325, | ||
1219 | sizeof reg84_sn9c325); | ||
1220 | data = 0x0a; | ||
1221 | reg_w(gspca_dev, 0x9a, &data, 1); | ||
1222 | data = 0x60; | ||
1223 | reg_w(gspca_dev, 0x99, &data, 1); | ||
1224 | break; | ||
1225 | case BRIDGE_SN9C120: | ||
1226 | reg_w(gspca_dev, 0x20, regsn20_sn9c120, | ||
1227 | sizeof regsn20_sn9c120); | ||
1228 | for (i = 0; i < 2; i++) | ||
1229 | reg_w(gspca_dev, 0x84, reg84_sn9c120_1, | ||
1230 | sizeof reg84_sn9c120_1); | ||
1231 | for (i = 0; i < 6; i++) | ||
1232 | reg_w(gspca_dev, 0x84, reg84_sn9c120_2, | ||
1233 | sizeof reg84_sn9c120_2); | ||
1234 | reg_w(gspca_dev, 0x84, reg84_sn9c120_3, | ||
1235 | sizeof reg84_sn9c120_3); | ||
1236 | data = 0x05; | ||
1237 | reg_w(gspca_dev, 0x9a, &data, 1); | ||
1238 | data = 0x5b; | ||
1239 | reg_w(gspca_dev, 0x99, &data, 1); | ||
1240 | break; | ||
1241 | default: | ||
1242 | reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20); | ||
1243 | for (i = 0; i < 8; i++) | ||
1244 | reg_w(gspca_dev, 0x84, reg84, sizeof reg84); | ||
1245 | data = 0x08; | ||
1246 | reg_w(gspca_dev, 0x9a, &data, 1); | ||
1247 | data = 0x59; | ||
1248 | reg_w(gspca_dev, 0x99, &data, 1); | ||
1249 | break; | ||
1250 | } | ||
1251 | |||
1252 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | ||
1253 | reg1 = 0x02; | ||
1254 | reg17 = 0x61; | ||
1255 | switch (sd->sensor) { | ||
1256 | case SENSOR_HV7131R: | ||
1257 | hv7131R_InitSensor(gspca_dev); | ||
1258 | if (mode) | ||
1259 | reg1 = 0x46; /* 320 clk 48Mhz */ | ||
1260 | else | ||
1261 | reg1 = 0x06; /* 640 clk 24Mz */ | ||
1262 | break; | ||
1263 | case SENSOR_MI0360: | ||
1264 | mi0360_InitSensor(gspca_dev); | ||
1265 | if (mode) | ||
1266 | reg1 = 0x46; /* 320 clk 48Mhz */ | ||
1267 | else | ||
1268 | reg1 = 0x06; /* 640 clk 24Mz */ | ||
1269 | break; | ||
1270 | case SENSOR_MO4000: | ||
1271 | mo4000_InitSensor(gspca_dev); | ||
1272 | if (mode) { | ||
1273 | /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */ | ||
1274 | reg1 = 0x06; /* clk 24Mz */ | ||
1275 | } else { | ||
1276 | reg17 = 0x22; /* 640 MCKSIZE */ | ||
1277 | reg1 = 0x06; /* 640 clk 24Mz */ | ||
1278 | } | ||
1279 | break; | ||
1280 | case SENSOR_OV7648: | ||
1281 | reg17 = 0xa2; | ||
1282 | reg1 = 0x44; | ||
1283 | ov7648_InitSensor(gspca_dev); | ||
1284 | /* if (mode) | ||
1285 | ; * 320x2... | ||
1286 | else | ||
1287 | ; * 640x... */ | ||
1288 | break; | ||
1289 | default: | ||
1290 | /* case SENSOR_OV7660: */ | ||
1291 | ov7660_InitSensor(gspca_dev); | ||
1292 | if (mode) { | ||
1293 | /* reg17 = 0x21; * 320 */ | ||
1294 | /* reg1 = 0x44; */ | ||
1295 | reg1 = 0x46; | ||
1296 | } else { | ||
1297 | reg17 = 0xa2; /* 640 */ | ||
1298 | reg1 = 0x40; | ||
1299 | } | ||
1300 | break; | ||
1301 | } | ||
1302 | reg_w(gspca_dev, 0xc0, C0, 6); | ||
1303 | switch (sd->bridge) { | ||
1304 | case BRIDGE_SN9C120: /*jfm ?? */ | ||
1305 | reg_w(gspca_dev, 0xca, CA_sn9c120, 4); | ||
1306 | break; | ||
1307 | default: | ||
1308 | reg_w(gspca_dev, 0xca, CA, 4); | ||
1309 | break; | ||
1310 | } | ||
1311 | switch (sd->bridge) { | ||
1312 | case BRIDGE_SN9C120: /*jfm ?? */ | ||
1313 | case BRIDGE_SN9C325: | ||
1314 | reg_w(gspca_dev, 0xce, CE_sn9c325, 4); | ||
1315 | break; | ||
1316 | default: | ||
1317 | reg_w(gspca_dev, 0xce, CE, 4); | ||
1318 | /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */ | ||
1319 | break; | ||
1320 | } | ||
1321 | |||
1322 | /* here change size mode 0 -> VGA; 1 -> CIF */ | ||
1323 | data = 0x40 | sn9c1xx[0x18] | (mode << 4); | ||
1324 | reg_w(gspca_dev, 0x18, &data, 1); | ||
1325 | |||
1326 | reg_w(gspca_dev, 0x100, qtable4, 0x40); | ||
1327 | reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40); | ||
1328 | |||
1329 | data = sn9c1xx[0x18] | (mode << 4); | ||
1330 | reg_w(gspca_dev, 0x18, &data, 1); | ||
1331 | |||
1332 | reg_w(gspca_dev, 0x17, ®17, 1); | ||
1333 | reg_w(gspca_dev, 0x01, ®1, 1); | ||
1334 | setbrightness(gspca_dev); | ||
1335 | setcontrast(gspca_dev); | ||
1336 | } | ||
1337 | |||
1338 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
1339 | { | ||
1340 | struct sd *sd = (struct sd *) gspca_dev; | ||
1341 | static const __u8 stophv7131[] = | ||
1342 | { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 }; | ||
1343 | static const __u8 stopmi0360[] = | ||
1344 | { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 }; | ||
1345 | __u8 regF1; | ||
1346 | __u8 data; | ||
1347 | const __u8 *sn9c1xx; | ||
1348 | |||
1349 | data = 0x0b; | ||
1350 | switch (sd->sensor) { | ||
1351 | case SENSOR_HV7131R: | ||
1352 | i2c_w8(gspca_dev, stophv7131); | ||
1353 | data = 0x2b; | ||
1354 | break; | ||
1355 | case SENSOR_MI0360: | ||
1356 | i2c_w8(gspca_dev, stopmi0360); | ||
1357 | data = 0x29; | ||
1358 | break; | ||
1359 | case SENSOR_MO4000: | ||
1360 | break; | ||
1361 | case SENSOR_OV7648: | ||
1362 | data = 0x29; | ||
1363 | break; | ||
1364 | default: | ||
1365 | /* case SENSOR_OV7660: */ | ||
1366 | break; | ||
1367 | } | ||
1368 | sn9c1xx = sn_tb[(int) sd->sensor]; | ||
1369 | reg_w(gspca_dev, 0x01, &sn9c1xx[1], 1); | ||
1370 | reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 1); | ||
1371 | reg_w(gspca_dev, 0x01, &sn9c1xx[1], 1); | ||
1372 | reg_w(gspca_dev, 0x01, &data, 1); | ||
1373 | regF1 = 0x01; | ||
1374 | reg_w(gspca_dev, 0xf1, ®F1, 1); | ||
1375 | } | ||
1376 | |||
1377 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
1378 | { | ||
1379 | } | ||
1380 | |||
1381 | static void sd_close(struct gspca_dev *gspca_dev) | ||
1382 | { | ||
1383 | } | ||
1384 | |||
1385 | static void setautogain(struct gspca_dev *gspca_dev) | ||
1386 | { | ||
1387 | struct sd *sd = (struct sd *) gspca_dev; | ||
1388 | /* Thanks S., without your advice, autobright should not work :) */ | ||
1389 | int delta; | ||
1390 | int expotimes = 0; | ||
1391 | __u8 luma_mean = 130; | ||
1392 | __u8 luma_delta = 20; | ||
1393 | |||
1394 | delta = sd->avg_lum; | ||
1395 | if (delta < luma_mean - luma_delta || | ||
1396 | delta > luma_mean + luma_delta) { | ||
1397 | switch (sd->sensor) { | ||
1398 | case SENSOR_HV7131R: | ||
1399 | expotimes = sd->exposure >> 8; | ||
1400 | expotimes += (luma_mean - delta) >> 4; | ||
1401 | if (expotimes < 0) | ||
1402 | expotimes = 0; | ||
1403 | sd->exposure = setexposure(gspca_dev, | ||
1404 | (unsigned int) (expotimes << 8)); | ||
1405 | break; | ||
1406 | case SENSOR_MO4000: | ||
1407 | case SENSOR_MI0360: | ||
1408 | expotimes = sd->exposure; | ||
1409 | expotimes += (luma_mean - delta) >> 6; | ||
1410 | if (expotimes < 0) | ||
1411 | expotimes = 0; | ||
1412 | sd->exposure = setexposure(gspca_dev, | ||
1413 | (unsigned int) expotimes); | ||
1414 | setcolors(gspca_dev); | ||
1415 | break; | ||
1416 | } | ||
1417 | } | ||
1418 | } | ||
1419 | |||
1420 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
1421 | struct gspca_frame *frame, /* target */ | ||
1422 | __u8 *data, /* isoc packet */ | ||
1423 | int len) /* iso packet length */ | ||
1424 | { | ||
1425 | struct sd *sd = (struct sd *) gspca_dev; | ||
1426 | int sof, avg_lum; | ||
1427 | |||
1428 | sof = len - 64; | ||
1429 | if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) { | ||
1430 | |||
1431 | /* end of frame */ | ||
1432 | gspca_frame_add(gspca_dev, LAST_PACKET, | ||
1433 | frame, data, sof + 2); | ||
1434 | if (sd->ag_cnt < 0) | ||
1435 | return; | ||
1436 | if (--sd->ag_cnt >= 0) | ||
1437 | return; | ||
1438 | sd->ag_cnt = AG_CNT_START; | ||
1439 | /* w1 w2 w3 */ | ||
1440 | /* w4 w5 w6 */ | ||
1441 | /* w7 w8 */ | ||
1442 | /* w4 */ | ||
1443 | avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6; | ||
1444 | /* w6 */ | ||
1445 | avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6; | ||
1446 | /* w2 */ | ||
1447 | avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6; | ||
1448 | /* w8 */ | ||
1449 | avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6; | ||
1450 | /* w5 */ | ||
1451 | avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4; | ||
1452 | avg_lum >>= 4; | ||
1453 | sd->avg_lum = avg_lum; | ||
1454 | PDEBUG(D_PACK, "mean lum %d", avg_lum); | ||
1455 | setautogain(gspca_dev); | ||
1456 | return; | ||
1457 | } | ||
1458 | if (gspca_dev->last_packet_type == LAST_PACKET) { | ||
1459 | |||
1460 | /* put the JPEG 422 header */ | ||
1461 | jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21); | ||
1462 | } | ||
1463 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
1464 | } | ||
1465 | |||
1466 | static unsigned int getexposure(struct gspca_dev *gspca_dev) | ||
1467 | { | ||
1468 | struct sd *sd = (struct sd *) gspca_dev; | ||
1469 | __u8 hexpo, mexpo, lexpo; | ||
1470 | |||
1471 | switch (sd->sensor) { | ||
1472 | case SENSOR_HV7131R: | ||
1473 | /* read sensor exposure */ | ||
1474 | i2c_r5(gspca_dev, 0x25); | ||
1475 | return (gspca_dev->usb_buf[0] << 16) | ||
1476 | | (gspca_dev->usb_buf[1] << 8) | ||
1477 | | gspca_dev->usb_buf[2]; | ||
1478 | case SENSOR_MI0360: | ||
1479 | /* read sensor exposure */ | ||
1480 | i2c_r5(gspca_dev, 0x09); | ||
1481 | return (gspca_dev->usb_buf[0] << 8) | ||
1482 | | gspca_dev->usb_buf[1]; | ||
1483 | case SENSOR_MO4000: | ||
1484 | i2c_r5(gspca_dev, 0x0e); | ||
1485 | hexpo = 0; /* gspca_dev->usb_buf[1] & 0x07; */ | ||
1486 | mexpo = 0x40; /* gspca_dev->usb_buf[2] & 0xff; */ | ||
1487 | lexpo = (gspca_dev->usb_buf[1] & 0x30) >> 4; | ||
1488 | PDEBUG(D_CONF, "exposure %d", | ||
1489 | (hexpo << 10) | (mexpo << 2) | lexpo); | ||
1490 | return (hexpo << 10) | (mexpo << 2) | lexpo; | ||
1491 | default: | ||
1492 | /* case SENSOR_OV7660: */ | ||
1493 | /* read sensor exposure */ | ||
1494 | i2c_r5(gspca_dev, 0x04); | ||
1495 | hexpo = gspca_dev->usb_buf[3] & 0x2f; | ||
1496 | lexpo = gspca_dev->usb_buf[0] & 0x02; | ||
1497 | i2c_r5(gspca_dev, 0x08); | ||
1498 | mexpo = gspca_dev->usb_buf[2]; | ||
1499 | return (hexpo << 10) | (mexpo << 2) | lexpo; | ||
1500 | } | ||
1501 | } | ||
1502 | |||
1503 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
1504 | { | ||
1505 | struct sd *sd = (struct sd *) gspca_dev; | ||
1506 | |||
1507 | /* hardcoded registers seem not readable */ | ||
1508 | switch (sd->sensor) { | ||
1509 | case SENSOR_HV7131R: | ||
1510 | /* sd->brightness = 0x7fff; */ | ||
1511 | sd->brightness = getexposure(gspca_dev) >> 4; | ||
1512 | break; | ||
1513 | case SENSOR_MI0360: | ||
1514 | sd->brightness = getexposure(gspca_dev) << 4; | ||
1515 | break; | ||
1516 | case SENSOR_MO4000: | ||
1517 | /* sd->brightness = 0x1fff; */ | ||
1518 | sd->brightness = getexposure(gspca_dev) << 4; | ||
1519 | break; | ||
1520 | } | ||
1521 | } | ||
1522 | |||
1523 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
1524 | { | ||
1525 | struct sd *sd = (struct sd *) gspca_dev; | ||
1526 | |||
1527 | sd->brightness = val; | ||
1528 | if (gspca_dev->streaming) | ||
1529 | setbrightness(gspca_dev); | ||
1530 | return 0; | ||
1531 | } | ||
1532 | |||
1533 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
1534 | { | ||
1535 | struct sd *sd = (struct sd *) gspca_dev; | ||
1536 | |||
1537 | getbrightness(gspca_dev); | ||
1538 | *val = sd->brightness; | ||
1539 | return 0; | ||
1540 | } | ||
1541 | |||
1542 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
1543 | { | ||
1544 | struct sd *sd = (struct sd *) gspca_dev; | ||
1545 | |||
1546 | sd->contrast = val; | ||
1547 | if (gspca_dev->streaming) | ||
1548 | setcontrast(gspca_dev); | ||
1549 | return 0; | ||
1550 | } | ||
1551 | |||
1552 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
1553 | { | ||
1554 | struct sd *sd = (struct sd *) gspca_dev; | ||
1555 | |||
1556 | *val = sd->contrast; | ||
1557 | return 0; | ||
1558 | } | ||
1559 | |||
1560 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
1561 | { | ||
1562 | struct sd *sd = (struct sd *) gspca_dev; | ||
1563 | |||
1564 | sd->colors = val; | ||
1565 | if (gspca_dev->streaming) | ||
1566 | setcolors(gspca_dev); | ||
1567 | return 0; | ||
1568 | } | ||
1569 | |||
1570 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
1571 | { | ||
1572 | struct sd *sd = (struct sd *) gspca_dev; | ||
1573 | |||
1574 | *val = sd->colors; | ||
1575 | return 0; | ||
1576 | } | ||
1577 | |||
1578 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
1579 | { | ||
1580 | struct sd *sd = (struct sd *) gspca_dev; | ||
1581 | |||
1582 | sd->autogain = val; | ||
1583 | if (val) | ||
1584 | sd->ag_cnt = AG_CNT_START; | ||
1585 | else | ||
1586 | sd->ag_cnt = -1; | ||
1587 | return 0; | ||
1588 | } | ||
1589 | |||
1590 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | ||
1591 | { | ||
1592 | struct sd *sd = (struct sd *) gspca_dev; | ||
1593 | |||
1594 | *val = sd->autogain; | ||
1595 | return 0; | ||
1596 | } | ||
1597 | |||
1598 | /* sub-driver description */ | ||
1599 | static const struct sd_desc sd_desc = { | ||
1600 | .name = MODULE_NAME, | ||
1601 | .ctrls = sd_ctrls, | ||
1602 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
1603 | .config = sd_config, | ||
1604 | .open = sd_open, | ||
1605 | .start = sd_start, | ||
1606 | .stopN = sd_stopN, | ||
1607 | .stop0 = sd_stop0, | ||
1608 | .close = sd_close, | ||
1609 | .pkt_scan = sd_pkt_scan, | ||
1610 | }; | ||
1611 | |||
1612 | /* -- module initialisation -- */ | ||
1613 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
1614 | static const __devinitdata struct usb_device_id device_table[] = { | ||
1615 | #ifndef CONFIG_USB_SN9C102 | ||
1616 | {USB_DEVICE(0x0458, 0x7025), DVNM("Genius Eye 311Q")}, | ||
1617 | {USB_DEVICE(0x045e, 0x00f5), DVNM("MicroSoft VX3000")}, | ||
1618 | {USB_DEVICE(0x045e, 0x00f7), DVNM("MicroSoft VX1000")}, | ||
1619 | {USB_DEVICE(0x0471, 0x0327), DVNM("Philips SPC 600 NC")}, | ||
1620 | {USB_DEVICE(0x0471, 0x0328), DVNM("Philips SPC 700 NC")}, | ||
1621 | #endif | ||
1622 | {USB_DEVICE(0x0471, 0x0330), DVNM("Philips SPC 710NC")}, | ||
1623 | {USB_DEVICE(0x0c45, 0x6040), DVNM("Speed NVC 350K")}, | ||
1624 | {USB_DEVICE(0x0c45, 0x607c), DVNM("Sonix sn9c102p Hv7131R")}, | ||
1625 | {USB_DEVICE(0x0c45, 0x60c0), DVNM("Sangha Sn535")}, | ||
1626 | {USB_DEVICE(0x0c45, 0x60ec), DVNM("SN9C105+MO4000")}, | ||
1627 | {USB_DEVICE(0x0c45, 0x60fb), DVNM("Surfer NoName")}, | ||
1628 | {USB_DEVICE(0x0c45, 0x60fc), DVNM("LG-LIC300")}, | ||
1629 | {USB_DEVICE(0x0c45, 0x612a), DVNM("Avant Camera")}, | ||
1630 | {USB_DEVICE(0x0c45, 0x612c), DVNM("Typhoon Rasy Cam 1.3MPix")}, | ||
1631 | #ifndef CONFIG_USB_SN9C102 | ||
1632 | {USB_DEVICE(0x0c45, 0x6130), DVNM("Sonix Pccam")}, | ||
1633 | {USB_DEVICE(0x0c45, 0x6138), DVNM("Sn9c120 Mo4000")}, | ||
1634 | {USB_DEVICE(0x0c45, 0x613b), DVNM("Surfer SN-206")}, | ||
1635 | {USB_DEVICE(0x0c45, 0x613c), DVNM("Sonix Pccam168")}, | ||
1636 | #endif | ||
1637 | {} | ||
1638 | }; | ||
1639 | MODULE_DEVICE_TABLE(usb, device_table); | ||
1640 | |||
1641 | /* -- device connect -- */ | ||
1642 | static int sd_probe(struct usb_interface *intf, | ||
1643 | const struct usb_device_id *id) | ||
1644 | { | ||
1645 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
1646 | THIS_MODULE); | ||
1647 | } | ||
1648 | |||
1649 | static struct usb_driver sd_driver = { | ||
1650 | .name = MODULE_NAME, | ||
1651 | .id_table = device_table, | ||
1652 | .probe = sd_probe, | ||
1653 | .disconnect = gspca_disconnect, | ||
1654 | }; | ||
1655 | |||
1656 | /* -- module insert / remove -- */ | ||
1657 | static int __init sd_mod_init(void) | ||
1658 | { | ||
1659 | if (usb_register(&sd_driver) < 0) | ||
1660 | return -1; | ||
1661 | info("v%s registered", version); | ||
1662 | return 0; | ||
1663 | } | ||
1664 | static void __exit sd_mod_exit(void) | ||
1665 | { | ||
1666 | usb_deregister(&sd_driver); | ||
1667 | info("deregistered"); | ||
1668 | } | ||
1669 | |||
1670 | module_init(sd_mod_init); | ||
1671 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c new file mode 100644 index 000000000000..156206118795 --- /dev/null +++ b/drivers/media/video/gspca/spca500.c | |||
@@ -0,0 +1,1216 @@ | |||
1 | /* | ||
2 | * SPCA500 chip based cameras initialization data | ||
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 | |||
22 | #define MODULE_NAME "spca500" | ||
23 | |||
24 | #include "gspca.h" | ||
25 | #include "jpeg.h" | ||
26 | |||
27 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) | ||
28 | static const char version[] = "2.1.7"; | ||
29 | |||
30 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
31 | MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver"); | ||
32 | MODULE_LICENSE("GPL"); | ||
33 | |||
34 | /* specific webcam descriptor */ | ||
35 | struct sd { | ||
36 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
37 | |||
38 | __u8 packet[ISO_MAX_SIZE + 128]; | ||
39 | /* !! no more than 128 ff in an ISO packet */ | ||
40 | |||
41 | unsigned char brightness; | ||
42 | unsigned char contrast; | ||
43 | unsigned char colors; | ||
44 | |||
45 | char qindex; | ||
46 | char subtype; | ||
47 | #define AgfaCl20 0 | ||
48 | #define AiptekPocketDV 1 | ||
49 | #define BenqDC1016 2 | ||
50 | #define CreativePCCam300 3 | ||
51 | #define DLinkDSC350 4 | ||
52 | #define Gsmartmini 5 | ||
53 | #define IntelPocketPCCamera 6 | ||
54 | #define KodakEZ200 7 | ||
55 | #define LogitechClickSmart310 8 | ||
56 | #define LogitechClickSmart510 9 | ||
57 | #define LogitechTraveler 10 | ||
58 | #define MustekGsmart300 11 | ||
59 | #define Optimedia 12 | ||
60 | #define PalmPixDC85 13 | ||
61 | #define ToptroIndus 14 | ||
62 | }; | ||
63 | |||
64 | /* V4L2 controls supported by the driver */ | ||
65 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
66 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
67 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
68 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
69 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
70 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
71 | |||
72 | static struct ctrl sd_ctrls[] = { | ||
73 | { | ||
74 | { | ||
75 | .id = V4L2_CID_BRIGHTNESS, | ||
76 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
77 | .name = "Brightness", | ||
78 | .minimum = 0, | ||
79 | .maximum = 255, | ||
80 | .step = 1, | ||
81 | #define BRIGHTNESS_DEF 127 | ||
82 | .default_value = BRIGHTNESS_DEF, | ||
83 | }, | ||
84 | .set = sd_setbrightness, | ||
85 | .get = sd_getbrightness, | ||
86 | }, | ||
87 | { | ||
88 | { | ||
89 | .id = V4L2_CID_CONTRAST, | ||
90 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
91 | .name = "Contrast", | ||
92 | .minimum = 0, | ||
93 | .maximum = 63, | ||
94 | .step = 1, | ||
95 | #define CONTRAST_DEF 31 | ||
96 | .default_value = CONTRAST_DEF, | ||
97 | }, | ||
98 | .set = sd_setcontrast, | ||
99 | .get = sd_getcontrast, | ||
100 | }, | ||
101 | { | ||
102 | { | ||
103 | .id = V4L2_CID_SATURATION, | ||
104 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
105 | .name = "Color", | ||
106 | .minimum = 0, | ||
107 | .maximum = 63, | ||
108 | .step = 1, | ||
109 | #define COLOR_DEF 31 | ||
110 | .default_value = COLOR_DEF, | ||
111 | }, | ||
112 | .set = sd_setcolors, | ||
113 | .get = sd_getcolors, | ||
114 | }, | ||
115 | }; | ||
116 | |||
117 | static struct v4l2_pix_format vga_mode[] = { | ||
118 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
119 | .bytesperline = 320, | ||
120 | .sizeimage = 320 * 240 * 3 / 8 + 590, | ||
121 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
122 | .priv = 1}, | ||
123 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
124 | .bytesperline = 640, | ||
125 | .sizeimage = 640 * 480 * 3 / 8 + 590, | ||
126 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
127 | .priv = 0}, | ||
128 | }; | ||
129 | |||
130 | static struct v4l2_pix_format sif_mode[] = { | ||
131 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
132 | .bytesperline = 176, | ||
133 | .sizeimage = 176 * 144 * 3 / 8 + 590, | ||
134 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
135 | .priv = 1}, | ||
136 | {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
137 | .bytesperline = 352, | ||
138 | .sizeimage = 352 * 288 * 3 / 8 + 590, | ||
139 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
140 | .priv = 0}, | ||
141 | }; | ||
142 | |||
143 | /* Frame packet header offsets for the spca500 */ | ||
144 | #define SPCA500_OFFSET_PADDINGLB 2 | ||
145 | #define SPCA500_OFFSET_PADDINGHB 3 | ||
146 | #define SPCA500_OFFSET_MODE 4 | ||
147 | #define SPCA500_OFFSET_IMGWIDTH 5 | ||
148 | #define SPCA500_OFFSET_IMGHEIGHT 6 | ||
149 | #define SPCA500_OFFSET_IMGMODE 7 | ||
150 | #define SPCA500_OFFSET_QTBLINDEX 8 | ||
151 | #define SPCA500_OFFSET_FRAMSEQ 9 | ||
152 | #define SPCA500_OFFSET_CDSPINFO 10 | ||
153 | #define SPCA500_OFFSET_GPIO 11 | ||
154 | #define SPCA500_OFFSET_AUGPIO 12 | ||
155 | #define SPCA500_OFFSET_DATA 16 | ||
156 | |||
157 | |||
158 | static const __u16 spca500_visual_defaults[][3] = { | ||
159 | {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync, | ||
160 | * hue (H byte) = 0, | ||
161 | * saturation/hue enable, | ||
162 | * brightness/contrast enable. | ||
163 | */ | ||
164 | {0x00, 0x0000, 0x8167}, /* brightness = 0 */ | ||
165 | {0x00, 0x0020, 0x8168}, /* contrast = 0 */ | ||
166 | {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync, | ||
167 | * hue (H byte) = 0, saturation/hue enable, | ||
168 | * brightness/contrast enable. | ||
169 | * was 0x0003, now 0x0000. | ||
170 | */ | ||
171 | {0x00, 0x0000, 0x816a}, /* hue (L byte) = 0 */ | ||
172 | {0x00, 0x0020, 0x8169}, /* saturation = 0x20 */ | ||
173 | {0x00, 0x0050, 0x8157}, /* edge gain high threshold */ | ||
174 | {0x00, 0x0030, 0x8158}, /* edge gain low threshold */ | ||
175 | {0x00, 0x0028, 0x8159}, /* edge bandwidth high threshold */ | ||
176 | {0x00, 0x000a, 0x815a}, /* edge bandwidth low threshold */ | ||
177 | {0x00, 0x0001, 0x8202}, /* clock rate compensation = 1/25 sec/frame */ | ||
178 | {0x0c, 0x0004, 0x0000}, | ||
179 | /* set interface */ | ||
180 | {} | ||
181 | }; | ||
182 | static const __u16 Clicksmart510_defaults[][3] = { | ||
183 | {0x00, 0x00, 0x8211}, | ||
184 | {0x00, 0x01, 0x82c0}, | ||
185 | {0x00, 0x10, 0x82cb}, | ||
186 | {0x00, 0x0f, 0x800d}, | ||
187 | {0x00, 0x82, 0x8225}, | ||
188 | {0x00, 0x21, 0x8228}, | ||
189 | {0x00, 0x00, 0x8203}, | ||
190 | {0x00, 0x00, 0x8204}, | ||
191 | {0x00, 0x08, 0x8205}, | ||
192 | {0x00, 0xf8, 0x8206}, | ||
193 | {0x00, 0x28, 0x8207}, | ||
194 | {0x00, 0xa0, 0x8208}, | ||
195 | {0x00, 0x08, 0x824a}, | ||
196 | {0x00, 0x08, 0x8214}, | ||
197 | {0x00, 0x80, 0x82c1}, | ||
198 | {0x00, 0x00, 0x82c2}, | ||
199 | {0x00, 0x00, 0x82ca}, | ||
200 | {0x00, 0x80, 0x82c1}, | ||
201 | {0x00, 0x04, 0x82c2}, | ||
202 | {0x00, 0x00, 0x82ca}, | ||
203 | {0x00, 0xfc, 0x8100}, | ||
204 | {0x00, 0xfc, 0x8105}, | ||
205 | {0x00, 0x30, 0x8101}, | ||
206 | {0x00, 0x00, 0x8102}, | ||
207 | {0x00, 0x00, 0x8103}, | ||
208 | {0x00, 0x66, 0x8107}, | ||
209 | {0x00, 0x00, 0x816b}, | ||
210 | {0x00, 0x00, 0x8155}, | ||
211 | {0x00, 0x01, 0x8156}, | ||
212 | {0x00, 0x60, 0x8157}, | ||
213 | {0x00, 0x40, 0x8158}, | ||
214 | {0x00, 0x0a, 0x8159}, | ||
215 | {0x00, 0x06, 0x815a}, | ||
216 | {0x00, 0x00, 0x813f}, | ||
217 | {0x00, 0x00, 0x8200}, | ||
218 | {0x00, 0x19, 0x8201}, | ||
219 | {0x00, 0x00, 0x82c1}, | ||
220 | {0x00, 0xa0, 0x82c2}, | ||
221 | {0x00, 0x00, 0x82ca}, | ||
222 | {0x00, 0x00, 0x8117}, | ||
223 | {0x00, 0x00, 0x8118}, | ||
224 | {0x00, 0x65, 0x8119}, | ||
225 | {0x00, 0x00, 0x811a}, | ||
226 | {0x00, 0x00, 0x811b}, | ||
227 | {0x00, 0x55, 0x811c}, | ||
228 | {0x00, 0x65, 0x811d}, | ||
229 | {0x00, 0x55, 0x811e}, | ||
230 | {0x00, 0x16, 0x811f}, | ||
231 | {0x00, 0x19, 0x8120}, | ||
232 | {0x00, 0x80, 0x8103}, | ||
233 | {0x00, 0x83, 0x816b}, | ||
234 | {0x00, 0x25, 0x8168}, | ||
235 | {0x00, 0x01, 0x820f}, | ||
236 | {0x00, 0xff, 0x8115}, | ||
237 | {0x00, 0x48, 0x8116}, | ||
238 | {0x00, 0x50, 0x8151}, | ||
239 | {0x00, 0x40, 0x8152}, | ||
240 | {0x00, 0x78, 0x8153}, | ||
241 | {0x00, 0x40, 0x8154}, | ||
242 | {0x00, 0x00, 0x8167}, | ||
243 | {0x00, 0x20, 0x8168}, | ||
244 | {0x00, 0x00, 0x816a}, | ||
245 | {0x00, 0x03, 0x816b}, | ||
246 | {0x00, 0x20, 0x8169}, | ||
247 | {0x00, 0x60, 0x8157}, | ||
248 | {0x00, 0x00, 0x8190}, | ||
249 | {0x00, 0x00, 0x81a1}, | ||
250 | {0x00, 0x00, 0x81b2}, | ||
251 | {0x00, 0x27, 0x8191}, | ||
252 | {0x00, 0x27, 0x81a2}, | ||
253 | {0x00, 0x27, 0x81b3}, | ||
254 | {0x00, 0x4b, 0x8192}, | ||
255 | {0x00, 0x4b, 0x81a3}, | ||
256 | {0x00, 0x4b, 0x81b4}, | ||
257 | {0x00, 0x66, 0x8193}, | ||
258 | {0x00, 0x66, 0x81a4}, | ||
259 | {0x00, 0x66, 0x81b5}, | ||
260 | {0x00, 0x79, 0x8194}, | ||
261 | {0x00, 0x79, 0x81a5}, | ||
262 | {0x00, 0x79, 0x81b6}, | ||
263 | {0x00, 0x8a, 0x8195}, | ||
264 | {0x00, 0x8a, 0x81a6}, | ||
265 | {0x00, 0x8a, 0x81b7}, | ||
266 | {0x00, 0x9b, 0x8196}, | ||
267 | {0x00, 0x9b, 0x81a7}, | ||
268 | {0x00, 0x9b, 0x81b8}, | ||
269 | {0x00, 0xa6, 0x8197}, | ||
270 | {0x00, 0xa6, 0x81a8}, | ||
271 | {0x00, 0xa6, 0x81b9}, | ||
272 | {0x00, 0xb2, 0x8198}, | ||
273 | {0x00, 0xb2, 0x81a9}, | ||
274 | {0x00, 0xb2, 0x81ba}, | ||
275 | {0x00, 0xbe, 0x8199}, | ||
276 | {0x00, 0xbe, 0x81aa}, | ||
277 | {0x00, 0xbe, 0x81bb}, | ||
278 | {0x00, 0xc8, 0x819a}, | ||
279 | {0x00, 0xc8, 0x81ab}, | ||
280 | {0x00, 0xc8, 0x81bc}, | ||
281 | {0x00, 0xd2, 0x819b}, | ||
282 | {0x00, 0xd2, 0x81ac}, | ||
283 | {0x00, 0xd2, 0x81bd}, | ||
284 | {0x00, 0xdb, 0x819c}, | ||
285 | {0x00, 0xdb, 0x81ad}, | ||
286 | {0x00, 0xdb, 0x81be}, | ||
287 | {0x00, 0xe4, 0x819d}, | ||
288 | {0x00, 0xe4, 0x81ae}, | ||
289 | {0x00, 0xe4, 0x81bf}, | ||
290 | {0x00, 0xed, 0x819e}, | ||
291 | {0x00, 0xed, 0x81af}, | ||
292 | {0x00, 0xed, 0x81c0}, | ||
293 | {0x00, 0xf7, 0x819f}, | ||
294 | {0x00, 0xf7, 0x81b0}, | ||
295 | {0x00, 0xf7, 0x81c1}, | ||
296 | {0x00, 0xff, 0x81a0}, | ||
297 | {0x00, 0xff, 0x81b1}, | ||
298 | {0x00, 0xff, 0x81c2}, | ||
299 | {0x00, 0x03, 0x8156}, | ||
300 | {0x00, 0x00, 0x8211}, | ||
301 | {0x00, 0x20, 0x8168}, | ||
302 | {0x00, 0x01, 0x8202}, | ||
303 | {0x00, 0x30, 0x8101}, | ||
304 | {0x00, 0x00, 0x8111}, | ||
305 | {0x00, 0x00, 0x8112}, | ||
306 | {0x00, 0x00, 0x8113}, | ||
307 | {0x00, 0x00, 0x8114}, | ||
308 | {} | ||
309 | }; | ||
310 | |||
311 | static const __u8 qtable_creative_pccam[2][64] = { | ||
312 | { /* Q-table Y-components */ | ||
313 | 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12, | ||
314 | 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11, | ||
315 | 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11, | ||
316 | 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13, | ||
317 | 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17, | ||
318 | 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c, | ||
319 | 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e, | ||
320 | 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e}, | ||
321 | { /* Q-table C-components */ | ||
322 | 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
323 | 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, | ||
324 | 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
325 | 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
326 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
327 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
328 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
329 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e} | ||
330 | }; | ||
331 | |||
332 | static const __u8 qtable_kodak_ez200[2][64] = { | ||
333 | { /* Q-table Y-components */ | ||
334 | 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06, | ||
335 | 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06, | ||
336 | 0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06, | ||
337 | 0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06, | ||
338 | 0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08, | ||
339 | 0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09, | ||
340 | 0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a, | ||
341 | 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a}, | ||
342 | { /* Q-table C-components */ | ||
343 | 0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a, | ||
344 | 0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, | ||
345 | 0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, | ||
346 | 0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, | ||
347 | 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, | ||
348 | 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, | ||
349 | 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, | ||
350 | 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a} | ||
351 | }; | ||
352 | |||
353 | static const __u8 qtable_pocketdv[2][64] = { | ||
354 | { /* Q-table Y-components start registers 0x8800 */ | ||
355 | 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18, | ||
356 | 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16, | ||
357 | 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16, | ||
358 | 0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19, | ||
359 | 0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f, | ||
360 | 0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25, | ||
361 | 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28, | ||
362 | 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28, | ||
363 | }, | ||
364 | { /* Q-table C-components start registers 0x8840 */ | ||
365 | 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28, | ||
366 | 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28, | ||
367 | 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28, | ||
368 | 0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, | ||
369 | 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, | ||
370 | 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, | ||
371 | 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, | ||
372 | 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28} | ||
373 | }; | ||
374 | |||
375 | /* read 'len' bytes to gspca_dev->usb_buf */ | ||
376 | static void reg_r(struct gspca_dev *gspca_dev, | ||
377 | __u16 index, | ||
378 | __u16 length) | ||
379 | { | ||
380 | usb_control_msg(gspca_dev->dev, | ||
381 | usb_rcvctrlpipe(gspca_dev->dev, 0), | ||
382 | 0, | ||
383 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
384 | 0, /* value */ | ||
385 | index, gspca_dev->usb_buf, length, 500); | ||
386 | } | ||
387 | |||
388 | static int reg_w(struct gspca_dev *gspca_dev, | ||
389 | __u16 req, __u16 index, __u16 value) | ||
390 | { | ||
391 | int ret; | ||
392 | |||
393 | PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value); | ||
394 | ret = usb_control_msg(gspca_dev->dev, | ||
395 | usb_sndctrlpipe(gspca_dev->dev, 0), | ||
396 | req, | ||
397 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
398 | value, index, NULL, 0, 500); | ||
399 | if (ret < 0) | ||
400 | PDEBUG(D_ERR, "reg write: error %d", ret); | ||
401 | return ret; | ||
402 | } | ||
403 | |||
404 | /* returns: negative is error, pos or zero is data */ | ||
405 | static int reg_r_12(struct gspca_dev *gspca_dev, | ||
406 | __u16 req, /* bRequest */ | ||
407 | __u16 index, /* wIndex */ | ||
408 | __u16 length) /* wLength (1 or 2 only) */ | ||
409 | { | ||
410 | int ret; | ||
411 | |||
412 | gspca_dev->usb_buf[1] = 0; | ||
413 | ret = usb_control_msg(gspca_dev->dev, | ||
414 | usb_rcvctrlpipe(gspca_dev->dev, 0), | ||
415 | req, | ||
416 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
417 | 0, /* value */ | ||
418 | index, | ||
419 | gspca_dev->usb_buf, length, | ||
420 | 500); /* timeout */ | ||
421 | if (ret < 0) { | ||
422 | PDEBUG(D_ERR, "reg_r_12 err %d", ret); | ||
423 | return -1; | ||
424 | } | ||
425 | return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; | ||
426 | } | ||
427 | |||
428 | /* | ||
429 | * Simple function to wait for a given 8-bit value to be returned from | ||
430 | * a reg_read call. | ||
431 | * Returns: negative is error or timeout, zero is success. | ||
432 | */ | ||
433 | static int reg_r_wait(struct gspca_dev *gspca_dev, | ||
434 | __u16 reg, __u16 index, __u16 value) | ||
435 | { | ||
436 | int ret, cnt = 20; | ||
437 | |||
438 | while (--cnt > 0) { | ||
439 | ret = reg_r_12(gspca_dev, reg, index, 1); | ||
440 | if (ret == value) | ||
441 | return 0; | ||
442 | msleep(50); | ||
443 | } | ||
444 | return -EIO; | ||
445 | } | ||
446 | |||
447 | static int write_vector(struct gspca_dev *gspca_dev, | ||
448 | const __u16 data[][3]) | ||
449 | { | ||
450 | int ret, i = 0; | ||
451 | |||
452 | while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { | ||
453 | ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]); | ||
454 | if (ret < 0) | ||
455 | return ret; | ||
456 | i++; | ||
457 | } | ||
458 | return 0; | ||
459 | } | ||
460 | |||
461 | static int spca50x_setup_qtable(struct gspca_dev *gspca_dev, | ||
462 | unsigned int request, | ||
463 | unsigned int ybase, | ||
464 | unsigned int cbase, | ||
465 | const __u8 qtable[2][64]) | ||
466 | { | ||
467 | int i, err; | ||
468 | |||
469 | /* loop over y components */ | ||
470 | for (i = 0; i < 64; i++) { | ||
471 | err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]); | ||
472 | if (err < 0) | ||
473 | return err; | ||
474 | } | ||
475 | |||
476 | /* loop over c components */ | ||
477 | for (i = 0; i < 64; i++) { | ||
478 | err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]); | ||
479 | if (err < 0) | ||
480 | return err; | ||
481 | } | ||
482 | return 0; | ||
483 | } | ||
484 | |||
485 | static void spca500_ping310(struct gspca_dev *gspca_dev) | ||
486 | { | ||
487 | reg_r(gspca_dev, 0x0d04, 2); | ||
488 | PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x", | ||
489 | gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]); | ||
490 | } | ||
491 | |||
492 | static void spca500_clksmart310_init(struct gspca_dev *gspca_dev) | ||
493 | { | ||
494 | reg_r(gspca_dev, 0x0d05, 2); | ||
495 | PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x", | ||
496 | gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]); | ||
497 | reg_w(gspca_dev, 0x00, 0x8167, 0x5a); | ||
498 | spca500_ping310(gspca_dev); | ||
499 | |||
500 | reg_w(gspca_dev, 0x00, 0x8168, 0x22); | ||
501 | reg_w(gspca_dev, 0x00, 0x816a, 0xc0); | ||
502 | reg_w(gspca_dev, 0x00, 0x816b, 0x0b); | ||
503 | reg_w(gspca_dev, 0x00, 0x8169, 0x25); | ||
504 | reg_w(gspca_dev, 0x00, 0x8157, 0x5b); | ||
505 | reg_w(gspca_dev, 0x00, 0x8158, 0x5b); | ||
506 | reg_w(gspca_dev, 0x00, 0x813f, 0x03); | ||
507 | reg_w(gspca_dev, 0x00, 0x8151, 0x4a); | ||
508 | reg_w(gspca_dev, 0x00, 0x8153, 0x78); | ||
509 | reg_w(gspca_dev, 0x00, 0x0d01, 0x04); | ||
510 | /* 00 for adjust shutter */ | ||
511 | reg_w(gspca_dev, 0x00, 0x0d02, 0x01); | ||
512 | reg_w(gspca_dev, 0x00, 0x8169, 0x25); | ||
513 | reg_w(gspca_dev, 0x00, 0x0d01, 0x02); | ||
514 | } | ||
515 | |||
516 | static void spca500_setmode(struct gspca_dev *gspca_dev, | ||
517 | __u8 xmult, __u8 ymult) | ||
518 | { | ||
519 | int mode; | ||
520 | |||
521 | /* set x multiplier */ | ||
522 | reg_w(gspca_dev, 0, 0x8001, xmult); | ||
523 | |||
524 | /* set y multiplier */ | ||
525 | reg_w(gspca_dev, 0, 0x8002, ymult); | ||
526 | |||
527 | /* use compressed mode, VGA, with mode specific subsample */ | ||
528 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | ||
529 | reg_w(gspca_dev, 0, 0x8003, mode << 4); | ||
530 | } | ||
531 | |||
532 | static int spca500_full_reset(struct gspca_dev *gspca_dev) | ||
533 | { | ||
534 | int err; | ||
535 | |||
536 | /* send the reset command */ | ||
537 | err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000); | ||
538 | if (err < 0) | ||
539 | return err; | ||
540 | |||
541 | /* wait for the reset to complete */ | ||
542 | err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000); | ||
543 | if (err < 0) | ||
544 | return err; | ||
545 | err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000); | ||
546 | if (err < 0) | ||
547 | return err; | ||
548 | err = reg_r_wait(gspca_dev, 0x06, 0, 0); | ||
549 | if (err < 0) { | ||
550 | PDEBUG(D_ERR, "reg_r_wait() failed"); | ||
551 | return err; | ||
552 | } | ||
553 | /* all ok */ | ||
554 | return 0; | ||
555 | } | ||
556 | |||
557 | /* Synchro the Bridge with sensor */ | ||
558 | /* Maybe that will work on all spca500 chip */ | ||
559 | /* because i only own a clicksmart310 try for that chip */ | ||
560 | /* using spca50x_set_packet_size() cause an Ooops here */ | ||
561 | /* usb_set_interface from kernel 2.6.x clear all the urb stuff */ | ||
562 | /* up-port the same feature as in 2.4.x kernel */ | ||
563 | static int spca500_synch310(struct gspca_dev *gspca_dev) | ||
564 | { | ||
565 | if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) { | ||
566 | PDEBUG(D_ERR, "Set packet size: set interface error"); | ||
567 | goto error; | ||
568 | } | ||
569 | spca500_ping310(gspca_dev); | ||
570 | |||
571 | reg_r(gspca_dev, 0x0d00, 1); | ||
572 | |||
573 | /* need alt setting here */ | ||
574 | PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt); | ||
575 | |||
576 | /* Windoze use pipe with altsetting 6 why 7 here */ | ||
577 | if (usb_set_interface(gspca_dev->dev, | ||
578 | gspca_dev->iface, | ||
579 | gspca_dev->alt) < 0) { | ||
580 | PDEBUG(D_ERR, "Set packet size: set interface error"); | ||
581 | goto error; | ||
582 | } | ||
583 | return 0; | ||
584 | error: | ||
585 | return -EBUSY; | ||
586 | } | ||
587 | |||
588 | static void spca500_reinit(struct gspca_dev *gspca_dev) | ||
589 | { | ||
590 | int err; | ||
591 | __u8 Data; | ||
592 | |||
593 | /* some unknow command from Aiptek pocket dv and family300 */ | ||
594 | |||
595 | reg_w(gspca_dev, 0x00, 0x0d01, 0x01); | ||
596 | reg_w(gspca_dev, 0x00, 0x0d03, 0x00); | ||
597 | reg_w(gspca_dev, 0x00, 0x0d02, 0x01); | ||
598 | |||
599 | /* enable drop packet */ | ||
600 | reg_w(gspca_dev, 0x00, 0x850a, 0x0001); | ||
601 | |||
602 | err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, | ||
603 | qtable_pocketdv); | ||
604 | if (err < 0) | ||
605 | PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init"); | ||
606 | |||
607 | /* set qtable index */ | ||
608 | reg_w(gspca_dev, 0x00, 0x8880, 2); | ||
609 | /* family cam Quicksmart stuff */ | ||
610 | reg_w(gspca_dev, 0x00, 0x800a, 0x00); | ||
611 | /* Set agc transfer: synced inbetween frames */ | ||
612 | reg_w(gspca_dev, 0x00, 0x820f, 0x01); | ||
613 | /* Init SDRAM - needed for SDRAM access */ | ||
614 | reg_w(gspca_dev, 0x00, 0x870a, 0x04); | ||
615 | /*Start init sequence or stream */ | ||
616 | reg_w(gspca_dev, 0, 0x8003, 0x00); | ||
617 | /* switch to video camera mode */ | ||
618 | reg_w(gspca_dev, 0x00, 0x8000, 0x0004); | ||
619 | msleep(2000); | ||
620 | if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) { | ||
621 | reg_r(gspca_dev, 0x816b, 1); | ||
622 | Data = gspca_dev->usb_buf[0]; | ||
623 | reg_w(gspca_dev, 0x00, 0x816b, Data); | ||
624 | } | ||
625 | } | ||
626 | |||
627 | /* this function is called at probe time */ | ||
628 | static int sd_config(struct gspca_dev *gspca_dev, | ||
629 | const struct usb_device_id *id) | ||
630 | { | ||
631 | struct sd *sd = (struct sd *) gspca_dev; | ||
632 | struct cam *cam; | ||
633 | __u16 vendor; | ||
634 | __u16 product; | ||
635 | |||
636 | vendor = id->idVendor; | ||
637 | product = id->idProduct; | ||
638 | switch (vendor) { | ||
639 | case 0x040a: /* Kodak cameras */ | ||
640 | /* switch (product) { */ | ||
641 | /* case 0x0300: */ | ||
642 | sd->subtype = KodakEZ200; | ||
643 | /* break; */ | ||
644 | /* } */ | ||
645 | break; | ||
646 | case 0x041e: /* Creative cameras */ | ||
647 | /* switch (product) { */ | ||
648 | /* case 0x400a: */ | ||
649 | sd->subtype = CreativePCCam300; | ||
650 | /* break; */ | ||
651 | /* } */ | ||
652 | break; | ||
653 | case 0x046d: /* Logitech Labtec */ | ||
654 | switch (product) { | ||
655 | case 0x0890: | ||
656 | sd->subtype = LogitechTraveler; | ||
657 | break; | ||
658 | case 0x0900: | ||
659 | sd->subtype = LogitechClickSmart310; | ||
660 | break; | ||
661 | case 0x0901: | ||
662 | sd->subtype = LogitechClickSmart510; | ||
663 | break; | ||
664 | } | ||
665 | break; | ||
666 | case 0x04a5: /* Benq */ | ||
667 | /* switch (product) { */ | ||
668 | /* case 0x300c: */ | ||
669 | sd->subtype = BenqDC1016; | ||
670 | /* break; */ | ||
671 | /* } */ | ||
672 | break; | ||
673 | case 0x04fc: /* SunPlus */ | ||
674 | /* switch (product) { */ | ||
675 | /* case 0x7333: */ | ||
676 | sd->subtype = PalmPixDC85; | ||
677 | /* break; */ | ||
678 | /* } */ | ||
679 | break; | ||
680 | case 0x055f: /* Mustek cameras */ | ||
681 | switch (product) { | ||
682 | case 0xc200: | ||
683 | sd->subtype = MustekGsmart300; | ||
684 | break; | ||
685 | case 0xc220: | ||
686 | sd->subtype = Gsmartmini; | ||
687 | break; | ||
688 | } | ||
689 | break; | ||
690 | case 0x06bd: /* Agfa Cl20 */ | ||
691 | /* switch (product) { */ | ||
692 | /* case 0x0404: */ | ||
693 | sd->subtype = AgfaCl20; | ||
694 | /* break; */ | ||
695 | /* } */ | ||
696 | break; | ||
697 | case 0x06be: /* Optimedia */ | ||
698 | /* switch (product) { */ | ||
699 | /* case 0x0800: */ | ||
700 | sd->subtype = Optimedia; | ||
701 | /* break; */ | ||
702 | /* } */ | ||
703 | break; | ||
704 | case 0x084d: /* D-Link / Minton */ | ||
705 | /* switch (product) { */ | ||
706 | /* case 0x0003: * DSC-350 / S-Cam F5 */ | ||
707 | sd->subtype = DLinkDSC350; | ||
708 | /* break; */ | ||
709 | /* } */ | ||
710 | break; | ||
711 | case 0x08ca: /* Aiptek */ | ||
712 | /* switch (product) { */ | ||
713 | /* case 0x0103: */ | ||
714 | sd->subtype = AiptekPocketDV; | ||
715 | /* break; */ | ||
716 | /* } */ | ||
717 | break; | ||
718 | case 0x2899: /* ToptroIndustrial */ | ||
719 | /* switch (product) { */ | ||
720 | /* case 0x012c: */ | ||
721 | sd->subtype = ToptroIndus; | ||
722 | /* break; */ | ||
723 | /* } */ | ||
724 | break; | ||
725 | case 0x8086: /* Intel */ | ||
726 | /* switch (product) { */ | ||
727 | /* case 0x0630: * Pocket PC Camera */ | ||
728 | sd->subtype = IntelPocketPCCamera; | ||
729 | /* break; */ | ||
730 | /* } */ | ||
731 | break; | ||
732 | } | ||
733 | cam = &gspca_dev->cam; | ||
734 | cam->dev_name = (char *) id->driver_info; | ||
735 | cam->epaddr = 0x01; | ||
736 | if (sd->subtype != LogitechClickSmart310) { | ||
737 | cam->cam_mode = vga_mode; | ||
738 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | ||
739 | } else { | ||
740 | cam->cam_mode = sif_mode; | ||
741 | cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; | ||
742 | } | ||
743 | sd->qindex = 5; | ||
744 | sd->brightness = BRIGHTNESS_DEF; | ||
745 | sd->contrast = CONTRAST_DEF; | ||
746 | sd->colors = COLOR_DEF; | ||
747 | return 0; | ||
748 | } | ||
749 | |||
750 | /* this function is called at open time */ | ||
751 | static int sd_open(struct gspca_dev *gspca_dev) | ||
752 | { | ||
753 | struct sd *sd = (struct sd *) gspca_dev; | ||
754 | |||
755 | /* initialisation of spca500 based cameras is deferred */ | ||
756 | PDEBUG(D_STREAM, "SPCA500 init"); | ||
757 | if (sd->subtype == LogitechClickSmart310) | ||
758 | spca500_clksmart310_init(gspca_dev); | ||
759 | /* else | ||
760 | spca500_initialise(gspca_dev); */ | ||
761 | PDEBUG(D_STREAM, "SPCA500 init done"); | ||
762 | return 0; | ||
763 | } | ||
764 | |||
765 | static void sd_start(struct gspca_dev *gspca_dev) | ||
766 | { | ||
767 | struct sd *sd = (struct sd *) gspca_dev; | ||
768 | int err; | ||
769 | __u8 Data; | ||
770 | __u8 xmult, ymult; | ||
771 | |||
772 | if (sd->subtype == LogitechClickSmart310) { | ||
773 | xmult = 0x16; | ||
774 | ymult = 0x12; | ||
775 | } else { | ||
776 | xmult = 0x28; | ||
777 | ymult = 0x1e; | ||
778 | } | ||
779 | |||
780 | /* is there a sensor here ? */ | ||
781 | reg_r(gspca_dev, 0x8a04, 1); | ||
782 | PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x", | ||
783 | gspca_dev->usb_buf[0]); | ||
784 | PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x", | ||
785 | gspca_dev->curr_mode, xmult, ymult); | ||
786 | |||
787 | /* setup qtable */ | ||
788 | switch (sd->subtype) { | ||
789 | case LogitechClickSmart310: | ||
790 | spca500_setmode(gspca_dev, xmult, ymult); | ||
791 | |||
792 | /* enable drop packet */ | ||
793 | reg_w(gspca_dev, 0x00, 0x850a, 0x0001); | ||
794 | reg_w(gspca_dev, 0x00, 0x8880, 3); | ||
795 | err = spca50x_setup_qtable(gspca_dev, | ||
796 | 0x00, 0x8800, 0x8840, | ||
797 | qtable_creative_pccam); | ||
798 | if (err < 0) | ||
799 | PDEBUG(D_ERR, "spca50x_setup_qtable failed"); | ||
800 | /* Init SDRAM - needed for SDRAM access */ | ||
801 | reg_w(gspca_dev, 0x00, 0x870a, 0x04); | ||
802 | |||
803 | /* switch to video camera mode */ | ||
804 | reg_w(gspca_dev, 0x00, 0x8000, 0x0004); | ||
805 | msleep(500); | ||
806 | if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) | ||
807 | PDEBUG(D_ERR, "reg_r_wait() failed"); | ||
808 | |||
809 | reg_r(gspca_dev, 0x816b, 1); | ||
810 | Data = gspca_dev->usb_buf[0]; | ||
811 | reg_w(gspca_dev, 0x00, 0x816b, Data); | ||
812 | |||
813 | spca500_synch310(gspca_dev); | ||
814 | |||
815 | write_vector(gspca_dev, spca500_visual_defaults); | ||
816 | spca500_setmode(gspca_dev, xmult, ymult); | ||
817 | /* enable drop packet */ | ||
818 | reg_w(gspca_dev, 0x00, 0x850a, 0x0001); | ||
819 | PDEBUG(D_ERR, "failed to enable drop packet"); | ||
820 | reg_w(gspca_dev, 0x00, 0x8880, 3); | ||
821 | err = spca50x_setup_qtable(gspca_dev, | ||
822 | 0x00, 0x8800, 0x8840, | ||
823 | qtable_creative_pccam); | ||
824 | if (err < 0) | ||
825 | PDEBUG(D_ERR, "spca50x_setup_qtable failed"); | ||
826 | |||
827 | /* Init SDRAM - needed for SDRAM access */ | ||
828 | reg_w(gspca_dev, 0x00, 0x870a, 0x04); | ||
829 | |||
830 | /* switch to video camera mode */ | ||
831 | reg_w(gspca_dev, 0x00, 0x8000, 0x0004); | ||
832 | |||
833 | if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) | ||
834 | PDEBUG(D_ERR, "reg_r_wait() failed"); | ||
835 | |||
836 | reg_r(gspca_dev, 0x816b, 1); | ||
837 | Data = gspca_dev->usb_buf[0]; | ||
838 | reg_w(gspca_dev, 0x00, 0x816b, Data); | ||
839 | break; | ||
840 | case CreativePCCam300: /* Creative PC-CAM 300 640x480 CCD */ | ||
841 | case IntelPocketPCCamera: /* FIXME: Temporary fix for | ||
842 | * Intel Pocket PC Camera | ||
843 | * - NWG (Sat 29th March 2003) */ | ||
844 | |||
845 | /* do a full reset */ | ||
846 | err = spca500_full_reset(gspca_dev); | ||
847 | if (err < 0) | ||
848 | PDEBUG(D_ERR, "spca500_full_reset failed"); | ||
849 | |||
850 | /* enable drop packet */ | ||
851 | err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001); | ||
852 | if (err < 0) | ||
853 | PDEBUG(D_ERR, "failed to enable drop packet"); | ||
854 | reg_w(gspca_dev, 0x00, 0x8880, 3); | ||
855 | err = spca50x_setup_qtable(gspca_dev, | ||
856 | 0x00, 0x8800, 0x8840, | ||
857 | qtable_creative_pccam); | ||
858 | if (err < 0) | ||
859 | PDEBUG(D_ERR, "spca50x_setup_qtable failed"); | ||
860 | |||
861 | spca500_setmode(gspca_dev, xmult, ymult); | ||
862 | reg_w(gspca_dev, 0x20, 0x0001, 0x0004); | ||
863 | |||
864 | /* switch to video camera mode */ | ||
865 | reg_w(gspca_dev, 0x00, 0x8000, 0x0004); | ||
866 | |||
867 | if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) | ||
868 | PDEBUG(D_ERR, "reg_r_wait() failed"); | ||
869 | |||
870 | reg_r(gspca_dev, 0x816b, 1); | ||
871 | Data = gspca_dev->usb_buf[0]; | ||
872 | reg_w(gspca_dev, 0x00, 0x816b, Data); | ||
873 | |||
874 | /* write_vector(gspca_dev, spca500_visual_defaults); */ | ||
875 | break; | ||
876 | case KodakEZ200: /* Kodak EZ200 */ | ||
877 | |||
878 | /* do a full reset */ | ||
879 | err = spca500_full_reset(gspca_dev); | ||
880 | if (err < 0) | ||
881 | PDEBUG(D_ERR, "spca500_full_reset failed"); | ||
882 | /* enable drop packet */ | ||
883 | reg_w(gspca_dev, 0x00, 0x850a, 0x0001); | ||
884 | reg_w(gspca_dev, 0x00, 0x8880, 0); | ||
885 | err = spca50x_setup_qtable(gspca_dev, | ||
886 | 0x00, 0x8800, 0x8840, | ||
887 | qtable_kodak_ez200); | ||
888 | if (err < 0) | ||
889 | PDEBUG(D_ERR, "spca50x_setup_qtable failed"); | ||
890 | spca500_setmode(gspca_dev, xmult, ymult); | ||
891 | |||
892 | reg_w(gspca_dev, 0x20, 0x0001, 0x0004); | ||
893 | |||
894 | /* switch to video camera mode */ | ||
895 | reg_w(gspca_dev, 0x00, 0x8000, 0x0004); | ||
896 | |||
897 | if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) | ||
898 | PDEBUG(D_ERR, "reg_r_wait() failed"); | ||
899 | |||
900 | reg_r(gspca_dev, 0x816b, 1); | ||
901 | Data = gspca_dev->usb_buf[0]; | ||
902 | reg_w(gspca_dev, 0x00, 0x816b, Data); | ||
903 | |||
904 | /* write_vector(gspca_dev, spca500_visual_defaults); */ | ||
905 | break; | ||
906 | |||
907 | case BenqDC1016: | ||
908 | case DLinkDSC350: /* FamilyCam 300 */ | ||
909 | case AiptekPocketDV: /* Aiptek PocketDV */ | ||
910 | case Gsmartmini: /*Mustek Gsmart Mini */ | ||
911 | case MustekGsmart300: /* Mustek Gsmart 300 */ | ||
912 | case PalmPixDC85: | ||
913 | case Optimedia: | ||
914 | case ToptroIndus: | ||
915 | case AgfaCl20: | ||
916 | spca500_reinit(gspca_dev); | ||
917 | reg_w(gspca_dev, 0x00, 0x0d01, 0x01); | ||
918 | /* enable drop packet */ | ||
919 | reg_w(gspca_dev, 0x00, 0x850a, 0x0001); | ||
920 | |||
921 | err = spca50x_setup_qtable(gspca_dev, | ||
922 | 0x00, 0x8800, 0x8840, qtable_pocketdv); | ||
923 | if (err < 0) | ||
924 | PDEBUG(D_ERR, "spca50x_setup_qtable failed"); | ||
925 | reg_w(gspca_dev, 0x00, 0x8880, 2); | ||
926 | |||
927 | /* familycam Quicksmart pocketDV stuff */ | ||
928 | reg_w(gspca_dev, 0x00, 0x800a, 0x00); | ||
929 | /* Set agc transfer: synced inbetween frames */ | ||
930 | reg_w(gspca_dev, 0x00, 0x820f, 0x01); | ||
931 | /* Init SDRAM - needed for SDRAM access */ | ||
932 | reg_w(gspca_dev, 0x00, 0x870a, 0x04); | ||
933 | |||
934 | spca500_setmode(gspca_dev, xmult, ymult); | ||
935 | /* switch to video camera mode */ | ||
936 | reg_w(gspca_dev, 0x00, 0x8000, 0x0004); | ||
937 | |||
938 | reg_r_wait(gspca_dev, 0, 0x8000, 0x44); | ||
939 | |||
940 | reg_r(gspca_dev, 0x816b, 1); | ||
941 | Data = gspca_dev->usb_buf[0]; | ||
942 | reg_w(gspca_dev, 0x00, 0x816b, Data); | ||
943 | break; | ||
944 | case LogitechTraveler: | ||
945 | case LogitechClickSmart510: | ||
946 | reg_w(gspca_dev, 0x02, 0x00, 0x00); | ||
947 | /* enable drop packet */ | ||
948 | reg_w(gspca_dev, 0x00, 0x850a, 0x0001); | ||
949 | |||
950 | err = spca50x_setup_qtable(gspca_dev, | ||
951 | 0x00, 0x8800, | ||
952 | 0x8840, qtable_creative_pccam); | ||
953 | if (err < 0) | ||
954 | PDEBUG(D_ERR, "spca50x_setup_qtable failed"); | ||
955 | reg_w(gspca_dev, 0x00, 0x8880, 3); | ||
956 | reg_w(gspca_dev, 0x00, 0x800a, 0x00); | ||
957 | /* Init SDRAM - needed for SDRAM access */ | ||
958 | reg_w(gspca_dev, 0x00, 0x870a, 0x04); | ||
959 | |||
960 | spca500_setmode(gspca_dev, xmult, ymult); | ||
961 | |||
962 | /* switch to video camera mode */ | ||
963 | reg_w(gspca_dev, 0x00, 0x8000, 0x0004); | ||
964 | reg_r_wait(gspca_dev, 0, 0x8000, 0x44); | ||
965 | |||
966 | reg_r(gspca_dev, 0x816b, 1); | ||
967 | Data = gspca_dev->usb_buf[0]; | ||
968 | reg_w(gspca_dev, 0x00, 0x816b, Data); | ||
969 | write_vector(gspca_dev, Clicksmart510_defaults); | ||
970 | break; | ||
971 | } | ||
972 | } | ||
973 | |||
974 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
975 | { | ||
976 | reg_w(gspca_dev, 0, 0x8003, 0x00); | ||
977 | |||
978 | /* switch to video camera mode */ | ||
979 | reg_w(gspca_dev, 0x00, 0x8000, 0x0004); | ||
980 | reg_r(gspca_dev, 0x8000, 1); | ||
981 | PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x", | ||
982 | gspca_dev->usb_buf[0]); | ||
983 | } | ||
984 | |||
985 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
986 | { | ||
987 | } | ||
988 | |||
989 | static void sd_close(struct gspca_dev *gspca_dev) | ||
990 | { | ||
991 | } | ||
992 | |||
993 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
994 | struct gspca_frame *frame, /* target */ | ||
995 | __u8 *data, /* isoc packet */ | ||
996 | int len) /* iso packet length */ | ||
997 | { | ||
998 | struct sd *sd = (struct sd *) gspca_dev; | ||
999 | int i; | ||
1000 | __u8 *s, *d; | ||
1001 | static __u8 ffd9[] = {0xff, 0xd9}; | ||
1002 | |||
1003 | /* frames are jpeg 4.1.1 without 0xff escape */ | ||
1004 | if (data[0] == 0xff) { | ||
1005 | if (data[1] != 0x01) { /* drop packet */ | ||
1006 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
1007 | return; | ||
1008 | } | ||
1009 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | ||
1010 | ffd9, 2); | ||
1011 | |||
1012 | /* put the JPEG header in the new frame */ | ||
1013 | jpeg_put_header(gspca_dev, frame, sd->qindex, 0x22); | ||
1014 | |||
1015 | data += SPCA500_OFFSET_DATA; | ||
1016 | len -= SPCA500_OFFSET_DATA; | ||
1017 | } else { | ||
1018 | data += 1; | ||
1019 | len -= 1; | ||
1020 | } | ||
1021 | |||
1022 | /* add 0x00 after 0xff */ | ||
1023 | for (i = len; --i >= 0; ) | ||
1024 | if (data[i] == 0xff) | ||
1025 | break; | ||
1026 | if (i < 0) { /* no 0xff */ | ||
1027 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
1028 | return; | ||
1029 | } | ||
1030 | s = data; | ||
1031 | d = sd->packet; | ||
1032 | for (i = 0; i < len; i++) { | ||
1033 | *d++ = *s++; | ||
1034 | if (s[-1] == 0xff) | ||
1035 | *d++ = 0x00; | ||
1036 | } | ||
1037 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
1038 | sd->packet, d - sd->packet); | ||
1039 | } | ||
1040 | |||
1041 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
1042 | { | ||
1043 | struct sd *sd = (struct sd *) gspca_dev; | ||
1044 | |||
1045 | reg_w(gspca_dev, 0x00, 0x8167, | ||
1046 | (__u8) (sd->brightness - 128)); | ||
1047 | } | ||
1048 | |||
1049 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
1050 | { | ||
1051 | struct sd *sd = (struct sd *) gspca_dev; | ||
1052 | int ret; | ||
1053 | |||
1054 | ret = reg_r_12(gspca_dev, 0x00, 0x8167, 1); | ||
1055 | if (ret >= 0) | ||
1056 | sd->brightness = ret + 128; | ||
1057 | } | ||
1058 | |||
1059 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
1060 | { | ||
1061 | struct sd *sd = (struct sd *) gspca_dev; | ||
1062 | |||
1063 | reg_w(gspca_dev, 0x00, 0x8168, sd->contrast); | ||
1064 | } | ||
1065 | |||
1066 | static void getcontrast(struct gspca_dev *gspca_dev) | ||
1067 | { | ||
1068 | struct sd *sd = (struct sd *) gspca_dev; | ||
1069 | int ret; | ||
1070 | |||
1071 | ret = reg_r_12(gspca_dev, 0x0, 0x8168, 1); | ||
1072 | if (ret >= 0) | ||
1073 | sd->contrast = ret; | ||
1074 | } | ||
1075 | |||
1076 | static void setcolors(struct gspca_dev *gspca_dev) | ||
1077 | { | ||
1078 | struct sd *sd = (struct sd *) gspca_dev; | ||
1079 | |||
1080 | reg_w(gspca_dev, 0x00, 0x8169, sd->colors); | ||
1081 | } | ||
1082 | |||
1083 | static void getcolors(struct gspca_dev *gspca_dev) | ||
1084 | { | ||
1085 | struct sd *sd = (struct sd *) gspca_dev; | ||
1086 | int ret; | ||
1087 | |||
1088 | ret = reg_r_12(gspca_dev, 0x0, 0x8169, 1); | ||
1089 | if (ret >= 0) | ||
1090 | sd->colors = ret; | ||
1091 | } | ||
1092 | |||
1093 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
1094 | { | ||
1095 | struct sd *sd = (struct sd *) gspca_dev; | ||
1096 | |||
1097 | sd->brightness = val; | ||
1098 | if (gspca_dev->streaming) | ||
1099 | setbrightness(gspca_dev); | ||
1100 | return 0; | ||
1101 | } | ||
1102 | |||
1103 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
1104 | { | ||
1105 | struct sd *sd = (struct sd *) gspca_dev; | ||
1106 | |||
1107 | getbrightness(gspca_dev); | ||
1108 | *val = sd->brightness; | ||
1109 | return 0; | ||
1110 | } | ||
1111 | |||
1112 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
1113 | { | ||
1114 | struct sd *sd = (struct sd *) gspca_dev; | ||
1115 | |||
1116 | sd->contrast = val; | ||
1117 | if (gspca_dev->streaming) | ||
1118 | setcontrast(gspca_dev); | ||
1119 | return 0; | ||
1120 | } | ||
1121 | |||
1122 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
1123 | { | ||
1124 | struct sd *sd = (struct sd *) gspca_dev; | ||
1125 | |||
1126 | getcontrast(gspca_dev); | ||
1127 | *val = sd->contrast; | ||
1128 | return 0; | ||
1129 | } | ||
1130 | |||
1131 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
1132 | { | ||
1133 | struct sd *sd = (struct sd *) gspca_dev; | ||
1134 | |||
1135 | sd->colors = val; | ||
1136 | if (gspca_dev->streaming) | ||
1137 | setcolors(gspca_dev); | ||
1138 | return 0; | ||
1139 | } | ||
1140 | |||
1141 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
1142 | { | ||
1143 | struct sd *sd = (struct sd *) gspca_dev; | ||
1144 | |||
1145 | getcolors(gspca_dev); | ||
1146 | *val = sd->colors; | ||
1147 | return 0; | ||
1148 | } | ||
1149 | |||
1150 | /* sub-driver description */ | ||
1151 | static struct sd_desc sd_desc = { | ||
1152 | .name = MODULE_NAME, | ||
1153 | .ctrls = sd_ctrls, | ||
1154 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
1155 | .config = sd_config, | ||
1156 | .open = sd_open, | ||
1157 | .start = sd_start, | ||
1158 | .stopN = sd_stopN, | ||
1159 | .stop0 = sd_stop0, | ||
1160 | .close = sd_close, | ||
1161 | .pkt_scan = sd_pkt_scan, | ||
1162 | }; | ||
1163 | |||
1164 | /* -- module initialisation -- */ | ||
1165 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
1166 | static const __devinitdata struct usb_device_id device_table[] = { | ||
1167 | {USB_DEVICE(0x040a, 0x0300), DVNM("Kodak EZ200")}, | ||
1168 | {USB_DEVICE(0x041e, 0x400a), DVNM("Creative PC-CAM 300")}, | ||
1169 | {USB_DEVICE(0x046d, 0x0890), DVNM("Logitech QuickCam traveler")}, | ||
1170 | {USB_DEVICE(0x046d, 0x0900), DVNM("Logitech Inc. ClickSmart 310")}, | ||
1171 | {USB_DEVICE(0x046d, 0x0901), DVNM("Logitech Inc. ClickSmart 510")}, | ||
1172 | {USB_DEVICE(0x04a5, 0x300c), DVNM("Benq DC1016")}, | ||
1173 | {USB_DEVICE(0x04fc, 0x7333), DVNM("PalmPixDC85")}, | ||
1174 | {USB_DEVICE(0x055f, 0xc200), DVNM("Mustek Gsmart 300")}, | ||
1175 | {USB_DEVICE(0x055f, 0xc220), DVNM("Gsmart Mini")}, | ||
1176 | {USB_DEVICE(0x06bd, 0x0404), DVNM("Agfa CL20")}, | ||
1177 | {USB_DEVICE(0x06be, 0x0800), DVNM("Optimedia")}, | ||
1178 | {USB_DEVICE(0x084d, 0x0003), DVNM("D-Link DSC-350")}, | ||
1179 | {USB_DEVICE(0x08ca, 0x0103), DVNM("Aiptek PocketDV")}, | ||
1180 | {USB_DEVICE(0x2899, 0x012c), DVNM("Toptro Industrial")}, | ||
1181 | {USB_DEVICE(0x8086, 0x0630), DVNM("Intel Pocket PC Camera")}, | ||
1182 | {} | ||
1183 | }; | ||
1184 | MODULE_DEVICE_TABLE(usb, device_table); | ||
1185 | |||
1186 | /* -- device connect -- */ | ||
1187 | static int sd_probe(struct usb_interface *intf, | ||
1188 | const struct usb_device_id *id) | ||
1189 | { | ||
1190 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
1191 | THIS_MODULE); | ||
1192 | } | ||
1193 | |||
1194 | static struct usb_driver sd_driver = { | ||
1195 | .name = MODULE_NAME, | ||
1196 | .id_table = device_table, | ||
1197 | .probe = sd_probe, | ||
1198 | .disconnect = gspca_disconnect, | ||
1199 | }; | ||
1200 | |||
1201 | /* -- module insert / remove -- */ | ||
1202 | static int __init sd_mod_init(void) | ||
1203 | { | ||
1204 | if (usb_register(&sd_driver) < 0) | ||
1205 | return -1; | ||
1206 | PDEBUG(D_PROBE, "v%s registered", version); | ||
1207 | return 0; | ||
1208 | } | ||
1209 | static void __exit sd_mod_exit(void) | ||
1210 | { | ||
1211 | usb_deregister(&sd_driver); | ||
1212 | PDEBUG(D_PROBE, "deregistered"); | ||
1213 | } | ||
1214 | |||
1215 | module_init(sd_mod_init); | ||
1216 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c new file mode 100644 index 000000000000..50e929de0203 --- /dev/null +++ b/drivers/media/video/gspca/spca501.c | |||
@@ -0,0 +1,2229 @@ | |||
1 | /* | ||
2 | * SPCA501 chip based cameras initialization data | ||
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 | |||
22 | #define MODULE_NAME "spca501" | ||
23 | |||
24 | #include "gspca.h" | ||
25 | |||
26 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) | ||
27 | static const char version[] = "2.1.7"; | ||
28 | |||
29 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
30 | MODULE_DESCRIPTION("GSPCA/SPCA501 USB Camera Driver"); | ||
31 | MODULE_LICENSE("GPL"); | ||
32 | |||
33 | /* specific webcam descriptor */ | ||
34 | struct sd { | ||
35 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
36 | |||
37 | unsigned short contrast; | ||
38 | __u8 brightness; | ||
39 | __u8 colors; | ||
40 | |||
41 | char subtype; | ||
42 | #define Arowana300KCMOSCamera 0 | ||
43 | #define IntelCreateAndShare 1 | ||
44 | #define KodakDVC325 2 | ||
45 | #define MystFromOriUnknownCamera 3 | ||
46 | #define SmileIntlCamera 4 | ||
47 | #define ThreeComHomeConnectLite 5 | ||
48 | #define ViewQuestM318B 6 | ||
49 | }; | ||
50 | |||
51 | /* V4L2 controls supported by the driver */ | ||
52 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
53 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
54 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
55 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
56 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
57 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
58 | |||
59 | static struct ctrl sd_ctrls[] = { | ||
60 | #define MY_BRIGHTNESS 0 | ||
61 | { | ||
62 | { | ||
63 | .id = V4L2_CID_BRIGHTNESS, | ||
64 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
65 | .name = "Brightness", | ||
66 | .minimum = 0, | ||
67 | .maximum = 127, | ||
68 | .step = 1, | ||
69 | .default_value = 63, | ||
70 | }, | ||
71 | .set = sd_setbrightness, | ||
72 | .get = sd_getbrightness, | ||
73 | }, | ||
74 | #define MY_CONTRAST 1 | ||
75 | { | ||
76 | { | ||
77 | .id = V4L2_CID_CONTRAST, | ||
78 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
79 | .name = "Contrast", | ||
80 | .minimum = 0, | ||
81 | .maximum = 0xffff, | ||
82 | .step = 1, | ||
83 | .default_value = 0xaa00, | ||
84 | }, | ||
85 | .set = sd_setcontrast, | ||
86 | .get = sd_getcontrast, | ||
87 | }, | ||
88 | #define MY_COLOR 2 | ||
89 | { | ||
90 | { | ||
91 | .id = V4L2_CID_SATURATION, | ||
92 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
93 | .name = "Color", | ||
94 | .minimum = 0, | ||
95 | .maximum = 63, | ||
96 | .step = 1, | ||
97 | .default_value = 31, | ||
98 | }, | ||
99 | .set = sd_setcolors, | ||
100 | .get = sd_getcolors, | ||
101 | }, | ||
102 | }; | ||
103 | |||
104 | static struct v4l2_pix_format vga_mode[] = { | ||
105 | {160, 120, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE, | ||
106 | .bytesperline = 160, | ||
107 | .sizeimage = 160 * 120 * 3 / 2, | ||
108 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
109 | .priv = 2}, | ||
110 | {320, 240, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE, | ||
111 | .bytesperline = 320, | ||
112 | .sizeimage = 320 * 240 * 3 / 2, | ||
113 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
114 | .priv = 1}, | ||
115 | {640, 480, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE, | ||
116 | .bytesperline = 640, | ||
117 | .sizeimage = 640 * 480 * 3 / 2, | ||
118 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
119 | .priv = 0}, | ||
120 | }; | ||
121 | |||
122 | #define SPCA50X_REG_USB 0x2 /* spca505 501 */ | ||
123 | /* | ||
124 | * Data to initialize a SPCA501. From a capture file provided by Bill Roehl | ||
125 | * With SPCA501 chip description | ||
126 | */ | ||
127 | #define CCDSP_SET /* set CCDSP parameters */ | ||
128 | #define TG_SET /* set time generator set */ | ||
129 | #undef DSPWIN_SET /* set DSP windows parameters */ | ||
130 | #undef ALTER_GAMA /* Set alternate set to YUV transform coeffs. */ | ||
131 | #define SPCA501_SNAPBIT 0x80 | ||
132 | #define SPCA501_SNAPCTRL 0x10 | ||
133 | /* Frame packet header offsets for the spca501 */ | ||
134 | #define SPCA501_OFFSET_GPIO 1 | ||
135 | #define SPCA501_OFFSET_TYPE 2 | ||
136 | #define SPCA501_OFFSET_TURN3A 3 | ||
137 | #define SPCA501_OFFSET_FRAMSEQ 4 | ||
138 | #define SPCA501_OFFSET_COMPRESS 5 | ||
139 | #define SPCA501_OFFSET_QUANT 6 | ||
140 | #define SPCA501_OFFSET_QUANT2 7 | ||
141 | #define SPCA501_OFFSET_DATA 8 | ||
142 | |||
143 | #define SPCA501_PROP_COMP_ENABLE(d) ((d) & 1) | ||
144 | #define SPCA501_PROP_SNAP(d) ((d) & 0x40) | ||
145 | #define SPCA501_PROP_SNAP_CTRL(d) ((d) & 0x10) | ||
146 | #define SPCA501_PROP_COMP_THRESH(d) (((d) & 0x0e) >> 1) | ||
147 | #define SPCA501_PROP_COMP_QUANT(d) (((d) & 0x70) >> 4) | ||
148 | |||
149 | /* SPCA501 CCDSP control */ | ||
150 | #define SPCA501_REG_CCDSP 0x01 | ||
151 | /* SPCA501 control/status registers */ | ||
152 | #define SPCA501_REG_CTLRL 0x02 | ||
153 | |||
154 | /* registers for color correction and YUV transformation */ | ||
155 | #define SPCA501_A11 0x08 | ||
156 | #define SPCA501_A12 0x09 | ||
157 | #define SPCA501_A13 0x0A | ||
158 | #define SPCA501_A21 0x0B | ||
159 | #define SPCA501_A22 0x0C | ||
160 | #define SPCA501_A23 0x0D | ||
161 | #define SPCA501_A31 0x0E | ||
162 | #define SPCA501_A32 0x0F | ||
163 | #define SPCA501_A33 0x10 | ||
164 | |||
165 | /* Data for video camera initialization before capturing */ | ||
166 | static const __u16 spca501_open_data[][3] = { | ||
167 | /* bmRequest,value,index */ | ||
168 | |||
169 | {0x2, 0x50, 0x00}, /* C/S enable soft reset */ | ||
170 | {0x2, 0x40, 0x00}, /* C/S disable soft reset */ | ||
171 | {0x2, 0x02, 0x05}, /* C/S general purpose I/O data */ | ||
172 | {0x2, 0x03, 0x05}, /* C/S general purpose I/O data */ | ||
173 | |||
174 | #ifdef CCDSP_SET | ||
175 | {0x1, 0x38, 0x01}, /* CCDSP options */ | ||
176 | {0x1, 0x05, 0x02}, /* CCDSP Optical black level for user settings */ | ||
177 | {0x1, 0xC0, 0x03}, /* CCDSP Optical black settings */ | ||
178 | |||
179 | {0x1, 0x67, 0x07}, | ||
180 | {0x1, 0x63, 0x3f}, /* CCDSP CCD gamma enable */ | ||
181 | {0x1, 0x03, 0x56}, /* Add gamma correction */ | ||
182 | |||
183 | {0x1, 0xFF, 0x15}, /* CCDSP High luminance for white balance */ | ||
184 | {0x1, 0x01, 0x16}, /* CCDSP Low luminance for white balance */ | ||
185 | |||
186 | /* Color correction and RGB-to-YUV transformation coefficients changing */ | ||
187 | #ifdef ALTER_GAMA | ||
188 | {0x0, 0x00, 0x08}, /* A11 */ | ||
189 | {0x0, 0x00, 0x09}, /* A12 */ | ||
190 | {0x0, 0x90, 0x0A}, /* A13 */ | ||
191 | {0x0, 0x12, 0x0B}, /* A21 */ | ||
192 | {0x0, 0x00, 0x0C}, /* A22 */ | ||
193 | {0x0, 0x00, 0x0D}, /* A23 */ | ||
194 | {0x0, 0x00, 0x0E}, /* A31 */ | ||
195 | {0x0, 0x02, 0x0F}, /* A32 */ | ||
196 | {0x0, 0x00, 0x10}, /* A33 */ | ||
197 | #else | ||
198 | {0x1, 0x2a, 0x08}, /* A11 0x31 */ | ||
199 | {0x1, 0xf8, 0x09}, /* A12 f8 */ | ||
200 | {0x1, 0xf8, 0x0A}, /* A13 f8 */ | ||
201 | {0x1, 0xf8, 0x0B}, /* A21 f8 */ | ||
202 | {0x1, 0x14, 0x0C}, /* A22 0x14 */ | ||
203 | {0x1, 0xf8, 0x0D}, /* A23 f8 */ | ||
204 | {0x1, 0xf8, 0x0E}, /* A31 f8 */ | ||
205 | {0x1, 0xf8, 0x0F}, /* A32 f8 */ | ||
206 | {0x1, 0x20, 0x10}, /* A33 0x20 */ | ||
207 | #endif | ||
208 | {0x1, 0x00, 0x11}, /* R offset */ | ||
209 | {0x1, 0x00, 0x12}, /* G offset */ | ||
210 | {0x1, 0x00, 0x13}, /* B offset */ | ||
211 | {0x1, 0x00, 0x14}, /* GB offset */ | ||
212 | |||
213 | #endif | ||
214 | |||
215 | #ifdef TG_SET | ||
216 | /* Time generator manipulations */ | ||
217 | {0x0, 0xfc, 0x0}, /* Set up high bits of shutter speed */ | ||
218 | {0x0, 0x01, 0x1}, /* Set up low bits of shutter speed */ | ||
219 | |||
220 | {0x0, 0xe4, 0x04}, /* DCLK*2 clock phase adjustment */ | ||
221 | {0x0, 0x08, 0x05}, /* ADCK phase adjustment, inv. ext. VB */ | ||
222 | {0x0, 0x03, 0x06}, /* FR phase adjustment */ | ||
223 | {0x0, 0x01, 0x07}, /* FCDS phase adjustment */ | ||
224 | {0x0, 0x39, 0x08}, /* FS phase adjustment */ | ||
225 | {0x0, 0x88, 0x0a}, /* FH1 phase and delay adjustment */ | ||
226 | {0x0, 0x03, 0x0f}, /* pixel identification */ | ||
227 | {0x0, 0x00, 0x11}, /* clock source selection (default) */ | ||
228 | |||
229 | /*VERY strange manipulations with | ||
230 | * select DMCLP or OBPX to be ADCLP output (0x0C) | ||
231 | * OPB always toggle or not (0x0D) but they allow | ||
232 | * us to set up brightness | ||
233 | */ | ||
234 | {0x0, 0x01, 0x0c}, | ||
235 | {0x0, 0xe0, 0x0d}, | ||
236 | /* Done */ | ||
237 | #endif | ||
238 | |||
239 | #ifdef DSPWIN_SET | ||
240 | {0x1, 0xa0, 0x01}, /* Setting image processing parameters */ | ||
241 | {0x1, 0x1c, 0x17}, /* Changing Windows positions X1 */ | ||
242 | {0x1, 0xe2, 0x19}, /* X2 */ | ||
243 | {0x1, 0x1c, 0x1b}, /* X3 */ | ||
244 | {0x1, 0xe2, 0x1d}, /* X4 */ | ||
245 | {0x1, 0x5f, 0x1f}, /* X5 */ | ||
246 | {0x1, 0x32, 0x20}, /* Y5 */ | ||
247 | {0x1, 0x01, 0x10}, /* Changing A33 */ | ||
248 | #endif | ||
249 | |||
250 | {0x2, 0x204a, 0x07},/* Setting video compression & resolution 160x120 */ | ||
251 | {0x2, 0x94, 0x06}, /* Setting video no compression */ | ||
252 | {} | ||
253 | }; | ||
254 | |||
255 | /* | ||
256 | The SPCAxxx docs from Sunplus document these values | ||
257 | in tables, one table per register number. In the data | ||
258 | below, dmRequest is the register number, index is the Addr, | ||
259 | and value is a combination of Bit values. | ||
260 | Bit Value (hex) | ||
261 | 0 01 | ||
262 | 1 02 | ||
263 | 2 04 | ||
264 | 3 08 | ||
265 | 4 10 | ||
266 | 5 20 | ||
267 | 6 40 | ||
268 | 7 80 | ||
269 | */ | ||
270 | |||
271 | /* Data for chip initialization (set default values) */ | ||
272 | static const __u16 spca501_init_data[][3] = { | ||
273 | /* Set all the values to powerup defaults */ | ||
274 | /* bmRequest,value,index */ | ||
275 | {0x0, 0xAA, 0x00}, | ||
276 | {0x0, 0x02, 0x01}, | ||
277 | {0x0, 0x01, 0x02}, | ||
278 | {0x0, 0x02, 0x03}, | ||
279 | {0x0, 0xCE, 0x04}, | ||
280 | {0x0, 0x00, 0x05}, | ||
281 | {0x0, 0x00, 0x06}, | ||
282 | {0x0, 0x00, 0x07}, | ||
283 | {0x0, 0x00, 0x08}, | ||
284 | {0x0, 0x00, 0x09}, | ||
285 | {0x0, 0x90, 0x0A}, | ||
286 | {0x0, 0x12, 0x0B}, | ||
287 | {0x0, 0x00, 0x0C}, | ||
288 | {0x0, 0x00, 0x0D}, | ||
289 | {0x0, 0x00, 0x0E}, | ||
290 | {0x0, 0x02, 0x0F}, | ||
291 | {0x0, 0x00, 0x10}, | ||
292 | {0x0, 0x00, 0x11}, | ||
293 | {0x0, 0x00, 0x12}, | ||
294 | {0x0, 0x00, 0x13}, | ||
295 | {0x0, 0x00, 0x14}, | ||
296 | {0x0, 0x00, 0x15}, | ||
297 | {0x0, 0x00, 0x16}, | ||
298 | {0x0, 0x00, 0x17}, | ||
299 | {0x0, 0x00, 0x18}, | ||
300 | {0x0, 0x00, 0x19}, | ||
301 | {0x0, 0x00, 0x1A}, | ||
302 | {0x0, 0x00, 0x1B}, | ||
303 | {0x0, 0x00, 0x1C}, | ||
304 | {0x0, 0x00, 0x1D}, | ||
305 | {0x0, 0x00, 0x1E}, | ||
306 | {0x0, 0x00, 0x1F}, | ||
307 | {0x0, 0x00, 0x20}, | ||
308 | {0x0, 0x00, 0x21}, | ||
309 | {0x0, 0x00, 0x22}, | ||
310 | {0x0, 0x00, 0x23}, | ||
311 | {0x0, 0x00, 0x24}, | ||
312 | {0x0, 0x00, 0x25}, | ||
313 | {0x0, 0x00, 0x26}, | ||
314 | {0x0, 0x00, 0x27}, | ||
315 | {0x0, 0x00, 0x28}, | ||
316 | {0x0, 0x00, 0x29}, | ||
317 | {0x0, 0x00, 0x2A}, | ||
318 | {0x0, 0x00, 0x2B}, | ||
319 | {0x0, 0x00, 0x2C}, | ||
320 | {0x0, 0x00, 0x2D}, | ||
321 | {0x0, 0x00, 0x2E}, | ||
322 | {0x0, 0x00, 0x2F}, | ||
323 | {0x0, 0x00, 0x30}, | ||
324 | {0x0, 0x00, 0x31}, | ||
325 | {0x0, 0x00, 0x32}, | ||
326 | {0x0, 0x00, 0x33}, | ||
327 | {0x0, 0x00, 0x34}, | ||
328 | {0x0, 0x00, 0x35}, | ||
329 | {0x0, 0x00, 0x36}, | ||
330 | {0x0, 0x00, 0x37}, | ||
331 | {0x0, 0x00, 0x38}, | ||
332 | {0x0, 0x00, 0x39}, | ||
333 | {0x0, 0x00, 0x3A}, | ||
334 | {0x0, 0x00, 0x3B}, | ||
335 | {0x0, 0x00, 0x3C}, | ||
336 | {0x0, 0x00, 0x3D}, | ||
337 | {0x0, 0x00, 0x3E}, | ||
338 | {0x0, 0x00, 0x3F}, | ||
339 | {0x0, 0x00, 0x40}, | ||
340 | {0x0, 0x00, 0x41}, | ||
341 | {0x0, 0x00, 0x42}, | ||
342 | {0x0, 0x00, 0x43}, | ||
343 | {0x0, 0x00, 0x44}, | ||
344 | {0x0, 0x00, 0x45}, | ||
345 | {0x0, 0x00, 0x46}, | ||
346 | {0x0, 0x00, 0x47}, | ||
347 | {0x0, 0x00, 0x48}, | ||
348 | {0x0, 0x00, 0x49}, | ||
349 | {0x0, 0x00, 0x4A}, | ||
350 | {0x0, 0x00, 0x4B}, | ||
351 | {0x0, 0x00, 0x4C}, | ||
352 | {0x0, 0x00, 0x4D}, | ||
353 | {0x0, 0x00, 0x4E}, | ||
354 | {0x0, 0x00, 0x4F}, | ||
355 | {0x0, 0x00, 0x50}, | ||
356 | {0x0, 0x00, 0x51}, | ||
357 | {0x0, 0x00, 0x52}, | ||
358 | {0x0, 0x00, 0x53}, | ||
359 | {0x0, 0x00, 0x54}, | ||
360 | {0x0, 0x00, 0x55}, | ||
361 | {0x0, 0x00, 0x56}, | ||
362 | {0x0, 0x00, 0x57}, | ||
363 | {0x0, 0x00, 0x58}, | ||
364 | {0x0, 0x00, 0x59}, | ||
365 | {0x0, 0x00, 0x5A}, | ||
366 | {0x0, 0x00, 0x5B}, | ||
367 | {0x0, 0x00, 0x5C}, | ||
368 | {0x0, 0x00, 0x5D}, | ||
369 | {0x0, 0x00, 0x5E}, | ||
370 | {0x0, 0x00, 0x5F}, | ||
371 | {0x0, 0x00, 0x60}, | ||
372 | {0x0, 0x00, 0x61}, | ||
373 | {0x0, 0x00, 0x62}, | ||
374 | {0x0, 0x00, 0x63}, | ||
375 | {0x0, 0x00, 0x64}, | ||
376 | {0x0, 0x00, 0x65}, | ||
377 | {0x0, 0x00, 0x66}, | ||
378 | {0x0, 0x00, 0x67}, | ||
379 | {0x0, 0x00, 0x68}, | ||
380 | {0x0, 0x00, 0x69}, | ||
381 | {0x0, 0x00, 0x6A}, | ||
382 | {0x0, 0x00, 0x6B}, | ||
383 | {0x0, 0x00, 0x6C}, | ||
384 | {0x0, 0x00, 0x6D}, | ||
385 | {0x0, 0x00, 0x6E}, | ||
386 | {0x0, 0x00, 0x6F}, | ||
387 | {0x0, 0x00, 0x70}, | ||
388 | {0x0, 0x00, 0x71}, | ||
389 | {0x0, 0x00, 0x72}, | ||
390 | {0x0, 0x00, 0x73}, | ||
391 | {0x0, 0x00, 0x74}, | ||
392 | {0x0, 0x00, 0x75}, | ||
393 | {0x0, 0x00, 0x76}, | ||
394 | {0x0, 0x00, 0x77}, | ||
395 | {0x0, 0x00, 0x78}, | ||
396 | {0x0, 0x00, 0x79}, | ||
397 | {0x0, 0x00, 0x7A}, | ||
398 | {0x0, 0x00, 0x7B}, | ||
399 | {0x0, 0x00, 0x7C}, | ||
400 | {0x0, 0x00, 0x7D}, | ||
401 | {0x0, 0x00, 0x7E}, | ||
402 | {0x0, 0x00, 0x7F}, | ||
403 | {0x0, 0x00, 0x80}, | ||
404 | {0x0, 0x00, 0x81}, | ||
405 | {0x0, 0x00, 0x82}, | ||
406 | {0x0, 0x00, 0x83}, | ||
407 | {0x0, 0x00, 0x84}, | ||
408 | {0x0, 0x00, 0x85}, | ||
409 | {0x0, 0x00, 0x86}, | ||
410 | {0x0, 0x00, 0x87}, | ||
411 | {0x0, 0x00, 0x88}, | ||
412 | {0x0, 0x00, 0x89}, | ||
413 | {0x0, 0x00, 0x8A}, | ||
414 | {0x0, 0x00, 0x8B}, | ||
415 | {0x0, 0x00, 0x8C}, | ||
416 | {0x0, 0x00, 0x8D}, | ||
417 | {0x0, 0x00, 0x8E}, | ||
418 | {0x0, 0x00, 0x8F}, | ||
419 | {0x0, 0x00, 0x90}, | ||
420 | {0x0, 0x00, 0x91}, | ||
421 | {0x0, 0x00, 0x92}, | ||
422 | {0x0, 0x00, 0x93}, | ||
423 | {0x0, 0x00, 0x94}, | ||
424 | {0x0, 0x00, 0x95}, | ||
425 | {0x0, 0x00, 0x96}, | ||
426 | {0x0, 0x00, 0x97}, | ||
427 | {0x0, 0x00, 0x98}, | ||
428 | {0x0, 0x00, 0x99}, | ||
429 | {0x0, 0x00, 0x9A}, | ||
430 | {0x0, 0x00, 0x9B}, | ||
431 | {0x0, 0x00, 0x9C}, | ||
432 | {0x0, 0x00, 0x9D}, | ||
433 | {0x0, 0x00, 0x9E}, | ||
434 | {0x0, 0x00, 0x9F}, | ||
435 | {0x0, 0x00, 0xA0}, | ||
436 | {0x0, 0x00, 0xA1}, | ||
437 | {0x0, 0x00, 0xA2}, | ||
438 | {0x0, 0x00, 0xA3}, | ||
439 | {0x0, 0x00, 0xA4}, | ||
440 | {0x0, 0x00, 0xA5}, | ||
441 | {0x0, 0x00, 0xA6}, | ||
442 | {0x0, 0x00, 0xA7}, | ||
443 | {0x0, 0x00, 0xA8}, | ||
444 | {0x0, 0x00, 0xA9}, | ||
445 | {0x0, 0x00, 0xAA}, | ||
446 | {0x0, 0x00, 0xAB}, | ||
447 | {0x0, 0x00, 0xAC}, | ||
448 | {0x0, 0x00, 0xAD}, | ||
449 | {0x0, 0x00, 0xAE}, | ||
450 | {0x0, 0x00, 0xAF}, | ||
451 | {0x0, 0x00, 0xB0}, | ||
452 | {0x0, 0x00, 0xB1}, | ||
453 | {0x0, 0x00, 0xB2}, | ||
454 | {0x0, 0x00, 0xB3}, | ||
455 | {0x0, 0x00, 0xB4}, | ||
456 | {0x0, 0x00, 0xB5}, | ||
457 | {0x0, 0x00, 0xB6}, | ||
458 | {0x0, 0x00, 0xB7}, | ||
459 | {0x0, 0x00, 0xB8}, | ||
460 | {0x0, 0x00, 0xB9}, | ||
461 | {0x0, 0x00, 0xBA}, | ||
462 | {0x0, 0x00, 0xBB}, | ||
463 | {0x0, 0x00, 0xBC}, | ||
464 | {0x0, 0x00, 0xBD}, | ||
465 | {0x0, 0x00, 0xBE}, | ||
466 | {0x0, 0x00, 0xBF}, | ||
467 | {0x0, 0x00, 0xC0}, | ||
468 | {0x0, 0x00, 0xC1}, | ||
469 | {0x0, 0x00, 0xC2}, | ||
470 | {0x0, 0x00, 0xC3}, | ||
471 | {0x0, 0x00, 0xC4}, | ||
472 | {0x0, 0x00, 0xC5}, | ||
473 | {0x0, 0x00, 0xC6}, | ||
474 | {0x0, 0x00, 0xC7}, | ||
475 | {0x0, 0x00, 0xC8}, | ||
476 | {0x0, 0x00, 0xC9}, | ||
477 | {0x0, 0x00, 0xCA}, | ||
478 | {0x0, 0x00, 0xCB}, | ||
479 | {0x0, 0x00, 0xCC}, | ||
480 | {0x1, 0xF4, 0x00}, | ||
481 | {0x1, 0x38, 0x01}, | ||
482 | {0x1, 0x40, 0x02}, | ||
483 | {0x1, 0x0A, 0x03}, | ||
484 | {0x1, 0x40, 0x04}, | ||
485 | {0x1, 0x40, 0x05}, | ||
486 | {0x1, 0x40, 0x06}, | ||
487 | {0x1, 0x67, 0x07}, | ||
488 | {0x1, 0x31, 0x08}, | ||
489 | {0x1, 0x00, 0x09}, | ||
490 | {0x1, 0x00, 0x0A}, | ||
491 | {0x1, 0x00, 0x0B}, | ||
492 | {0x1, 0x14, 0x0C}, | ||
493 | {0x1, 0x00, 0x0D}, | ||
494 | {0x1, 0x00, 0x0E}, | ||
495 | {0x1, 0x00, 0x0F}, | ||
496 | {0x1, 0x1E, 0x10}, | ||
497 | {0x1, 0x00, 0x11}, | ||
498 | {0x1, 0x00, 0x12}, | ||
499 | {0x1, 0x00, 0x13}, | ||
500 | {0x1, 0x00, 0x14}, | ||
501 | {0x1, 0xFF, 0x15}, | ||
502 | {0x1, 0x01, 0x16}, | ||
503 | {0x1, 0x32, 0x17}, | ||
504 | {0x1, 0x23, 0x18}, | ||
505 | {0x1, 0xCE, 0x19}, | ||
506 | {0x1, 0x23, 0x1A}, | ||
507 | {0x1, 0x32, 0x1B}, | ||
508 | {0x1, 0x8D, 0x1C}, | ||
509 | {0x1, 0xCE, 0x1D}, | ||
510 | {0x1, 0x8D, 0x1E}, | ||
511 | {0x1, 0x00, 0x1F}, | ||
512 | {0x1, 0x00, 0x20}, | ||
513 | {0x1, 0xFF, 0x3E}, | ||
514 | {0x1, 0x02, 0x3F}, | ||
515 | {0x1, 0x00, 0x40}, | ||
516 | {0x1, 0x00, 0x41}, | ||
517 | {0x1, 0x00, 0x42}, | ||
518 | {0x1, 0x00, 0x43}, | ||
519 | {0x1, 0x00, 0x44}, | ||
520 | {0x1, 0x00, 0x45}, | ||
521 | {0x1, 0x00, 0x46}, | ||
522 | {0x1, 0x00, 0x47}, | ||
523 | {0x1, 0x00, 0x48}, | ||
524 | {0x1, 0x00, 0x49}, | ||
525 | {0x1, 0x00, 0x4A}, | ||
526 | {0x1, 0x00, 0x4B}, | ||
527 | {0x1, 0x00, 0x4C}, | ||
528 | {0x1, 0x00, 0x4D}, | ||
529 | {0x1, 0x00, 0x4E}, | ||
530 | {0x1, 0x00, 0x4F}, | ||
531 | {0x1, 0x00, 0x50}, | ||
532 | {0x1, 0x00, 0x51}, | ||
533 | {0x1, 0x00, 0x52}, | ||
534 | {0x1, 0x00, 0x53}, | ||
535 | {0x1, 0x00, 0x54}, | ||
536 | {0x1, 0x00, 0x55}, | ||
537 | {0x1, 0x00, 0x56}, | ||
538 | {0x1, 0x00, 0x57}, | ||
539 | {0x1, 0x00, 0x58}, | ||
540 | {0x1, 0x00, 0x59}, | ||
541 | {0x1, 0x00, 0x5A}, | ||
542 | {0x2, 0x03, 0x00}, | ||
543 | {0x2, 0x00, 0x01}, | ||
544 | {0x2, 0x00, 0x05}, | ||
545 | {0x2, 0x00, 0x06}, | ||
546 | {0x2, 0x00, 0x07}, | ||
547 | {0x2, 0x00, 0x10}, | ||
548 | {0x2, 0x00, 0x11}, | ||
549 | /* Strange - looks like the 501 driver doesn't do anything | ||
550 | * at insert time except read the EEPROM | ||
551 | */ | ||
552 | {} | ||
553 | }; | ||
554 | |||
555 | /* Data for video camera init before capture. | ||
556 | * Capture and decoding by Colin Peart. | ||
557 | * This is is for the 3com HomeConnect Lite which is spca501a based. | ||
558 | */ | ||
559 | static const __u16 spca501_3com_open_data[][3] = { | ||
560 | /* bmRequest,value,index */ | ||
561 | {0x2, 0x0050, 0x0000}, /* C/S Enable TG soft reset, timing mode=010 */ | ||
562 | {0x2, 0x0043, 0x0000}, /* C/S Disable TG soft reset, timing mode=010 */ | ||
563 | {0x2, 0x0002, 0x0005}, /* C/S GPIO */ | ||
564 | {0x2, 0x0003, 0x0005}, /* C/S GPIO */ | ||
565 | |||
566 | #ifdef CCDSP_SET | ||
567 | {0x1, 0x0020, 0x0001}, /* CCDSP Options */ | ||
568 | |||
569 | {0x1, 0x0020, 0x0002}, /* CCDSP Black Level */ | ||
570 | {0x1, 0x006e, 0x0007}, /* CCDSP Gamma options */ | ||
571 | {0x1, 0x0090, 0x0015}, /* CCDSP Luminance Low */ | ||
572 | {0x1, 0x00ff, 0x0016}, /* CCDSP Luminance High */ | ||
573 | {0x1, 0x0003, 0x003F}, /* CCDSP Gamma correction toggle */ | ||
574 | |||
575 | #ifdef ALTER_GAMMA | ||
576 | {0x1, 0x0010, 0x0008}, /* CCDSP YUV A11 */ | ||
577 | {0x1, 0x0000, 0x0009}, /* CCDSP YUV A12 */ | ||
578 | {0x1, 0x0000, 0x000a}, /* CCDSP YUV A13 */ | ||
579 | {0x1, 0x0000, 0x000b}, /* CCDSP YUV A21 */ | ||
580 | {0x1, 0x0010, 0x000c}, /* CCDSP YUV A22 */ | ||
581 | {0x1, 0x0000, 0x000d}, /* CCDSP YUV A23 */ | ||
582 | {0x1, 0x0000, 0x000e}, /* CCDSP YUV A31 */ | ||
583 | {0x1, 0x0000, 0x000f}, /* CCDSP YUV A32 */ | ||
584 | {0x1, 0x0010, 0x0010}, /* CCDSP YUV A33 */ | ||
585 | {0x1, 0x0000, 0x0011}, /* CCDSP R Offset */ | ||
586 | {0x1, 0x0000, 0x0012}, /* CCDSP G Offset */ | ||
587 | {0x1, 0x0001, 0x0013}, /* CCDSP B Offset */ | ||
588 | {0x1, 0x0001, 0x0014}, /* CCDSP BG Offset */ | ||
589 | {0x1, 0x003f, 0x00C1}, /* CCDSP Gamma Correction Enable */ | ||
590 | #endif | ||
591 | #endif | ||
592 | |||
593 | #ifdef TG_SET | ||
594 | {0x0, 0x00fc, 0x0000}, /* TG Shutter Speed High Bits */ | ||
595 | {0x0, 0x0000, 0x0001}, /* TG Shutter Speed Low Bits */ | ||
596 | {0x0, 0x00e4, 0x0004}, /* TG DCLK*2 Adjust */ | ||
597 | {0x0, 0x0008, 0x0005}, /* TG ADCK Adjust */ | ||
598 | {0x0, 0x0003, 0x0006}, /* TG FR Phase Adjust */ | ||
599 | {0x0, 0x0001, 0x0007}, /* TG FCDS Phase Adjust */ | ||
600 | {0x0, 0x0039, 0x0008}, /* TG FS Phase Adjust */ | ||
601 | {0x0, 0x0088, 0x000a}, /* TG MH1 */ | ||
602 | {0x0, 0x0003, 0x000f}, /* TG Pixel ID */ | ||
603 | |||
604 | /* Like below, unexplained toglleing */ | ||
605 | {0x0, 0x0080, 0x000c}, | ||
606 | {0x0, 0x0000, 0x000d}, | ||
607 | {0x0, 0x0080, 0x000c}, | ||
608 | {0x0, 0x0004, 0x000d}, | ||
609 | {0x0, 0x0000, 0x000c}, | ||
610 | {0x0, 0x0000, 0x000d}, | ||
611 | {0x0, 0x0040, 0x000c}, | ||
612 | {0x0, 0x0017, 0x000d}, | ||
613 | {0x0, 0x00c0, 0x000c}, | ||
614 | {0x0, 0x0000, 0x000d}, | ||
615 | {0x0, 0x0080, 0x000c}, | ||
616 | {0x0, 0x0006, 0x000d}, | ||
617 | {0x0, 0x0080, 0x000c}, | ||
618 | {0x0, 0x0004, 0x000d}, | ||
619 | {0x0, 0x0002, 0x0003}, | ||
620 | #endif | ||
621 | |||
622 | #ifdef DSPWIN_SET | ||
623 | {0x1, 0x001c, 0x0017}, /* CCDSP W1 Start X */ | ||
624 | {0x1, 0x00e2, 0x0019}, /* CCDSP W2 Start X */ | ||
625 | {0x1, 0x001c, 0x001b}, /* CCDSP W3 Start X */ | ||
626 | {0x1, 0x00e2, 0x001d}, /* CCDSP W4 Start X */ | ||
627 | {0x1, 0x00aa, 0x001f}, /* CCDSP W5 Start X */ | ||
628 | {0x1, 0x0070, 0x0020}, /* CCDSP W5 Start Y */ | ||
629 | #endif | ||
630 | {0x0, 0x0001, 0x0010}, /* TG Start Clock */ | ||
631 | |||
632 | /* {0x2, 0x006a, 0x0001}, * C/S Enable ISOSYNCH Packet Engine */ | ||
633 | {0x2, 0x0068, 0x0001}, /* C/S Diable ISOSYNCH Packet Engine */ | ||
634 | {0x2, 0x0000, 0x0005}, | ||
635 | {0x2, 0x0043, 0x0000}, /* C/S Set Timing Mode, Disable TG soft reset */ | ||
636 | {0x2, 0x0043, 0x0000}, /* C/S Set Timing Mode, Disable TG soft reset */ | ||
637 | {0x2, 0x0002, 0x0005}, /* C/S GPIO */ | ||
638 | {0x2, 0x0003, 0x0005}, /* C/S GPIO */ | ||
639 | |||
640 | {0x2, 0x006a, 0x0001}, /* C/S Enable ISOSYNCH Packet Engine */ | ||
641 | {} | ||
642 | }; | ||
643 | |||
644 | /* | ||
645 | * Data used to initialize a SPCA501C with HV7131B sensor. | ||
646 | * From a capture file taken with USBSnoop v 1.5 | ||
647 | * I have a "SPCA501C pc camera chipset" manual by sunplus, but some | ||
648 | * of the value meanings are obscure or simply "reserved". | ||
649 | * to do list: | ||
650 | * 1) Understand what every value means | ||
651 | * 2) Understand why some values seem to appear more than once | ||
652 | * 3) Write a small comment for each line of the following arrays. | ||
653 | */ | ||
654 | static const __u16 spca501c_arowana_open_data[][3] = { | ||
655 | /* bmRequest,value,index */ | ||
656 | {0x02, 0x0007, 0x0005}, | ||
657 | {0x02, 0xa048, 0x0000}, | ||
658 | {0x05, 0x0022, 0x0004}, | ||
659 | {0x01, 0x0006, 0x0011}, | ||
660 | {0x01, 0x00ff, 0x0012}, | ||
661 | {0x01, 0x0014, 0x0013}, | ||
662 | {0x01, 0x0000, 0x0014}, | ||
663 | {0x01, 0x0042, 0x0051}, | ||
664 | {0x01, 0x0040, 0x0052}, | ||
665 | {0x01, 0x0051, 0x0053}, | ||
666 | {0x01, 0x0040, 0x0054}, | ||
667 | {0x01, 0x0000, 0x0055}, | ||
668 | {0x00, 0x0025, 0x0000}, | ||
669 | {0x00, 0x0026, 0x0000}, | ||
670 | {0x00, 0x0001, 0x0000}, | ||
671 | {0x00, 0x0027, 0x0000}, | ||
672 | {0x00, 0x008a, 0x0000}, | ||
673 | {} | ||
674 | }; | ||
675 | |||
676 | static const __u16 spca501c_arowana_init_data[][3] = { | ||
677 | /* bmRequest,value,index */ | ||
678 | {0x02, 0x0007, 0x0005}, | ||
679 | {0x02, 0xa048, 0x0000}, | ||
680 | {0x05, 0x0022, 0x0004}, | ||
681 | {0x01, 0x0006, 0x0011}, | ||
682 | {0x01, 0x00ff, 0x0012}, | ||
683 | {0x01, 0x0014, 0x0013}, | ||
684 | {0x01, 0x0000, 0x0014}, | ||
685 | {0x01, 0x0042, 0x0051}, | ||
686 | {0x01, 0x0040, 0x0052}, | ||
687 | {0x01, 0x0051, 0x0053}, | ||
688 | {0x01, 0x0040, 0x0054}, | ||
689 | {0x01, 0x0000, 0x0055}, | ||
690 | {0x00, 0x0025, 0x0000}, | ||
691 | {0x00, 0x0026, 0x0000}, | ||
692 | {0x00, 0x0001, 0x0000}, | ||
693 | {0x00, 0x0027, 0x0000}, | ||
694 | {0x00, 0x008a, 0x0000}, | ||
695 | {0x02, 0x0000, 0x0005}, | ||
696 | {0x02, 0x0007, 0x0005}, | ||
697 | {0x02, 0x2000, 0x0000}, | ||
698 | {0x05, 0x0022, 0x0004}, | ||
699 | {0x05, 0x0015, 0x0001}, | ||
700 | {0x05, 0x00ea, 0x0000}, | ||
701 | {0x05, 0x0021, 0x0001}, | ||
702 | {0x05, 0x00d2, 0x0000}, | ||
703 | {0x05, 0x0023, 0x0001}, | ||
704 | {0x05, 0x0003, 0x0000}, | ||
705 | {0x05, 0x0030, 0x0001}, | ||
706 | {0x05, 0x002b, 0x0000}, | ||
707 | {0x05, 0x0031, 0x0001}, | ||
708 | {0x05, 0x0023, 0x0000}, | ||
709 | {0x05, 0x0032, 0x0001}, | ||
710 | {0x05, 0x0023, 0x0000}, | ||
711 | {0x05, 0x0033, 0x0001}, | ||
712 | {0x05, 0x0023, 0x0000}, | ||
713 | {0x05, 0x0034, 0x0001}, | ||
714 | {0x05, 0x0002, 0x0000}, | ||
715 | {0x05, 0x0050, 0x0001}, | ||
716 | {0x05, 0x0000, 0x0000}, | ||
717 | {0x05, 0x0051, 0x0001}, | ||
718 | {0x05, 0x0000, 0x0000}, | ||
719 | {0x05, 0x0052, 0x0001}, | ||
720 | {0x05, 0x0000, 0x0000}, | ||
721 | {0x05, 0x0054, 0x0001}, | ||
722 | {0x05, 0x0001, 0x0000}, | ||
723 | {0x00, 0x0000, 0x0001}, | ||
724 | {0x00, 0x0000, 0x0002}, | ||
725 | {0x00, 0x000c, 0x0003}, | ||
726 | {0x00, 0x0000, 0x0004}, | ||
727 | {0x00, 0x0090, 0x0005}, | ||
728 | {0x00, 0x0000, 0x0006}, | ||
729 | {0x00, 0x0040, 0x0007}, | ||
730 | {0x00, 0x00c0, 0x0008}, | ||
731 | {0x00, 0x004a, 0x0009}, | ||
732 | {0x00, 0x0000, 0x000a}, | ||
733 | {0x00, 0x0000, 0x000b}, | ||
734 | {0x00, 0x0001, 0x000c}, | ||
735 | {0x00, 0x0001, 0x000d}, | ||
736 | {0x00, 0x0000, 0x000e}, | ||
737 | {0x00, 0x0002, 0x000f}, | ||
738 | {0x00, 0x0001, 0x0010}, | ||
739 | {0x00, 0x0000, 0x0011}, | ||
740 | {0x00, 0x0000, 0x0012}, | ||
741 | {0x00, 0x0002, 0x0020}, | ||
742 | {0x00, 0x0080, 0x0021}, | ||
743 | {0x00, 0x0001, 0x0022}, | ||
744 | {0x00, 0x00e0, 0x0023}, | ||
745 | {0x00, 0x0000, 0x0024}, | ||
746 | {0x00, 0x00d5, 0x0025}, | ||
747 | {0x00, 0x0000, 0x0026}, | ||
748 | {0x00, 0x000b, 0x0027}, | ||
749 | {0x00, 0x0000, 0x0046}, | ||
750 | {0x00, 0x0000, 0x0047}, | ||
751 | {0x00, 0x0000, 0x0048}, | ||
752 | {0x00, 0x0000, 0x0049}, | ||
753 | {0x00, 0x0008, 0x004a}, | ||
754 | {0xff, 0x0000, 0x00d0}, | ||
755 | {0xff, 0x00d8, 0x00d1}, | ||
756 | {0xff, 0x0000, 0x00d4}, | ||
757 | {0xff, 0x0000, 0x00d5}, | ||
758 | {0x01, 0x00a6, 0x0000}, | ||
759 | {0x01, 0x0028, 0x0001}, | ||
760 | {0x01, 0x0000, 0x0002}, | ||
761 | {0x01, 0x000a, 0x0003}, | ||
762 | {0x01, 0x0040, 0x0004}, | ||
763 | {0x01, 0x0066, 0x0007}, | ||
764 | {0x01, 0x0011, 0x0008}, | ||
765 | {0x01, 0x0032, 0x0009}, | ||
766 | {0x01, 0x00fd, 0x000a}, | ||
767 | {0x01, 0x0038, 0x000b}, | ||
768 | {0x01, 0x00d1, 0x000c}, | ||
769 | {0x01, 0x00f7, 0x000d}, | ||
770 | {0x01, 0x00ed, 0x000e}, | ||
771 | {0x01, 0x00d8, 0x000f}, | ||
772 | {0x01, 0x0038, 0x0010}, | ||
773 | {0x01, 0x00ff, 0x0015}, | ||
774 | {0x01, 0x0001, 0x0016}, | ||
775 | {0x01, 0x0032, 0x0017}, | ||
776 | {0x01, 0x0023, 0x0018}, | ||
777 | {0x01, 0x00ce, 0x0019}, | ||
778 | {0x01, 0x0023, 0x001a}, | ||
779 | {0x01, 0x0032, 0x001b}, | ||
780 | {0x01, 0x008d, 0x001c}, | ||
781 | {0x01, 0x00ce, 0x001d}, | ||
782 | {0x01, 0x008d, 0x001e}, | ||
783 | {0x01, 0x0000, 0x001f}, | ||
784 | {0x01, 0x0000, 0x0020}, | ||
785 | {0x01, 0x00ff, 0x003e}, | ||
786 | {0x01, 0x0003, 0x003f}, | ||
787 | {0x01, 0x0000, 0x0040}, | ||
788 | {0x01, 0x0035, 0x0041}, | ||
789 | {0x01, 0x0053, 0x0042}, | ||
790 | {0x01, 0x0069, 0x0043}, | ||
791 | {0x01, 0x007c, 0x0044}, | ||
792 | {0x01, 0x008c, 0x0045}, | ||
793 | {0x01, 0x009a, 0x0046}, | ||
794 | {0x01, 0x00a8, 0x0047}, | ||
795 | {0x01, 0x00b4, 0x0048}, | ||
796 | {0x01, 0x00bf, 0x0049}, | ||
797 | {0x01, 0x00ca, 0x004a}, | ||
798 | {0x01, 0x00d4, 0x004b}, | ||
799 | {0x01, 0x00dd, 0x004c}, | ||
800 | {0x01, 0x00e7, 0x004d}, | ||
801 | {0x01, 0x00ef, 0x004e}, | ||
802 | {0x01, 0x00f8, 0x004f}, | ||
803 | {0x01, 0x00ff, 0x0050}, | ||
804 | {0x01, 0x0001, 0x0056}, | ||
805 | {0x01, 0x0060, 0x0057}, | ||
806 | {0x01, 0x0040, 0x0058}, | ||
807 | {0x01, 0x0011, 0x0059}, | ||
808 | {0x01, 0x0001, 0x005a}, | ||
809 | {0x02, 0x0007, 0x0005}, | ||
810 | {0x02, 0xa048, 0x0000}, | ||
811 | {0x02, 0x0007, 0x0005}, | ||
812 | {0x02, 0x0015, 0x0006}, | ||
813 | {0x02, 0x100a, 0x0007}, | ||
814 | {0x02, 0xa048, 0x0000}, | ||
815 | {0x02, 0xc002, 0x0001}, | ||
816 | {0x02, 0x000f, 0x0005}, | ||
817 | {0x02, 0xa048, 0x0000}, | ||
818 | {0x05, 0x0022, 0x0004}, | ||
819 | {0x05, 0x0025, 0x0001}, | ||
820 | {0x05, 0x0000, 0x0000}, | ||
821 | {0x05, 0x0026, 0x0001}, | ||
822 | {0x05, 0x0001, 0x0000}, | ||
823 | {0x05, 0x0027, 0x0001}, | ||
824 | {0x05, 0x0000, 0x0000}, | ||
825 | {0x05, 0x0001, 0x0001}, | ||
826 | {0x05, 0x0000, 0x0000}, | ||
827 | {0x05, 0x0021, 0x0001}, | ||
828 | {0x05, 0x00d2, 0x0000}, | ||
829 | {0x05, 0x0020, 0x0001}, | ||
830 | {0x05, 0x0000, 0x0000}, | ||
831 | {0x00, 0x0090, 0x0005}, | ||
832 | {0x01, 0x00a6, 0x0000}, | ||
833 | {0x02, 0x0007, 0x0005}, | ||
834 | {0x02, 0x2000, 0x0000}, | ||
835 | {0x05, 0x0022, 0x0004}, | ||
836 | {0x05, 0x0015, 0x0001}, | ||
837 | {0x05, 0x00ea, 0x0000}, | ||
838 | {0x05, 0x0021, 0x0001}, | ||
839 | {0x05, 0x00d2, 0x0000}, | ||
840 | {0x05, 0x0023, 0x0001}, | ||
841 | {0x05, 0x0003, 0x0000}, | ||
842 | {0x05, 0x0030, 0x0001}, | ||
843 | {0x05, 0x002b, 0x0000}, | ||
844 | {0x05, 0x0031, 0x0001}, | ||
845 | {0x05, 0x0023, 0x0000}, | ||
846 | {0x05, 0x0032, 0x0001}, | ||
847 | {0x05, 0x0023, 0x0000}, | ||
848 | {0x05, 0x0033, 0x0001}, | ||
849 | {0x05, 0x0023, 0x0000}, | ||
850 | {0x05, 0x0034, 0x0001}, | ||
851 | {0x05, 0x0002, 0x0000}, | ||
852 | {0x05, 0x0050, 0x0001}, | ||
853 | {0x05, 0x0000, 0x0000}, | ||
854 | {0x05, 0x0051, 0x0001}, | ||
855 | {0x05, 0x0000, 0x0000}, | ||
856 | {0x05, 0x0052, 0x0001}, | ||
857 | {0x05, 0x0000, 0x0000}, | ||
858 | {0x05, 0x0054, 0x0001}, | ||
859 | {0x05, 0x0001, 0x0000}, | ||
860 | {0x00, 0x0000, 0x0001}, | ||
861 | {0x00, 0x0000, 0x0002}, | ||
862 | {0x00, 0x000c, 0x0003}, | ||
863 | {0x00, 0x0000, 0x0004}, | ||
864 | {0x00, 0x0090, 0x0005}, | ||
865 | {0x00, 0x0000, 0x0006}, | ||
866 | {0x00, 0x0040, 0x0007}, | ||
867 | {0x00, 0x00c0, 0x0008}, | ||
868 | {0x00, 0x004a, 0x0009}, | ||
869 | {0x00, 0x0000, 0x000a}, | ||
870 | {0x00, 0x0000, 0x000b}, | ||
871 | {0x00, 0x0001, 0x000c}, | ||
872 | {0x00, 0x0001, 0x000d}, | ||
873 | {0x00, 0x0000, 0x000e}, | ||
874 | {0x00, 0x0002, 0x000f}, | ||
875 | {0x00, 0x0001, 0x0010}, | ||
876 | {0x00, 0x0000, 0x0011}, | ||
877 | {0x00, 0x0000, 0x0012}, | ||
878 | {0x00, 0x0002, 0x0020}, | ||
879 | {0x00, 0x0080, 0x0021}, | ||
880 | {0x00, 0x0001, 0x0022}, | ||
881 | {0x00, 0x00e0, 0x0023}, | ||
882 | {0x00, 0x0000, 0x0024}, | ||
883 | {0x00, 0x00d5, 0x0025}, | ||
884 | {0x00, 0x0000, 0x0026}, | ||
885 | {0x00, 0x000b, 0x0027}, | ||
886 | {0x00, 0x0000, 0x0046}, | ||
887 | {0x00, 0x0000, 0x0047}, | ||
888 | {0x00, 0x0000, 0x0048}, | ||
889 | {0x00, 0x0000, 0x0049}, | ||
890 | {0x00, 0x0008, 0x004a}, | ||
891 | {0xff, 0x0000, 0x00d0}, | ||
892 | {0xff, 0x00d8, 0x00d1}, | ||
893 | {0xff, 0x0000, 0x00d4}, | ||
894 | {0xff, 0x0000, 0x00d5}, | ||
895 | {0x01, 0x00a6, 0x0000}, | ||
896 | {0x01, 0x0028, 0x0001}, | ||
897 | {0x01, 0x0000, 0x0002}, | ||
898 | {0x01, 0x000a, 0x0003}, | ||
899 | {0x01, 0x0040, 0x0004}, | ||
900 | {0x01, 0x0066, 0x0007}, | ||
901 | {0x01, 0x0011, 0x0008}, | ||
902 | {0x01, 0x0032, 0x0009}, | ||
903 | {0x01, 0x00fd, 0x000a}, | ||
904 | {0x01, 0x0038, 0x000b}, | ||
905 | {0x01, 0x00d1, 0x000c}, | ||
906 | {0x01, 0x00f7, 0x000d}, | ||
907 | {0x01, 0x00ed, 0x000e}, | ||
908 | {0x01, 0x00d8, 0x000f}, | ||
909 | {0x01, 0x0038, 0x0010}, | ||
910 | {0x01, 0x00ff, 0x0015}, | ||
911 | {0x01, 0x0001, 0x0016}, | ||
912 | {0x01, 0x0032, 0x0017}, | ||
913 | {0x01, 0x0023, 0x0018}, | ||
914 | {0x01, 0x00ce, 0x0019}, | ||
915 | {0x01, 0x0023, 0x001a}, | ||
916 | {0x01, 0x0032, 0x001b}, | ||
917 | {0x01, 0x008d, 0x001c}, | ||
918 | {0x01, 0x00ce, 0x001d}, | ||
919 | {0x01, 0x008d, 0x001e}, | ||
920 | {0x01, 0x0000, 0x001f}, | ||
921 | {0x01, 0x0000, 0x0020}, | ||
922 | {0x01, 0x00ff, 0x003e}, | ||
923 | {0x01, 0x0003, 0x003f}, | ||
924 | {0x01, 0x0000, 0x0040}, | ||
925 | {0x01, 0x0035, 0x0041}, | ||
926 | {0x01, 0x0053, 0x0042}, | ||
927 | {0x01, 0x0069, 0x0043}, | ||
928 | {0x01, 0x007c, 0x0044}, | ||
929 | {0x01, 0x008c, 0x0045}, | ||
930 | {0x01, 0x009a, 0x0046}, | ||
931 | {0x01, 0x00a8, 0x0047}, | ||
932 | {0x01, 0x00b4, 0x0048}, | ||
933 | {0x01, 0x00bf, 0x0049}, | ||
934 | {0x01, 0x00ca, 0x004a}, | ||
935 | {0x01, 0x00d4, 0x004b}, | ||
936 | {0x01, 0x00dd, 0x004c}, | ||
937 | {0x01, 0x00e7, 0x004d}, | ||
938 | {0x01, 0x00ef, 0x004e}, | ||
939 | {0x01, 0x00f8, 0x004f}, | ||
940 | {0x01, 0x00ff, 0x0050}, | ||
941 | {0x01, 0x0001, 0x0056}, | ||
942 | {0x01, 0x0060, 0x0057}, | ||
943 | {0x01, 0x0040, 0x0058}, | ||
944 | {0x01, 0x0011, 0x0059}, | ||
945 | {0x01, 0x0001, 0x005a}, | ||
946 | {0x02, 0x0007, 0x0005}, | ||
947 | {0x02, 0xa048, 0x0000}, | ||
948 | {0x02, 0x0007, 0x0005}, | ||
949 | {0x02, 0x0015, 0x0006}, | ||
950 | {0x02, 0x100a, 0x0007}, | ||
951 | {0x02, 0xa048, 0x0000}, | ||
952 | {0x02, 0xc002, 0x0001}, | ||
953 | {0x02, 0x000f, 0x0005}, | ||
954 | {0x02, 0xa048, 0x0000}, | ||
955 | {0x05, 0x0022, 0x0004}, | ||
956 | {0x05, 0x0025, 0x0001}, | ||
957 | {0x05, 0x0000, 0x0000}, | ||
958 | {0x05, 0x0026, 0x0001}, | ||
959 | {0x05, 0x0001, 0x0000}, | ||
960 | {0x05, 0x0027, 0x0001}, | ||
961 | {0x05, 0x0000, 0x0000}, | ||
962 | {0x05, 0x0001, 0x0001}, | ||
963 | {0x05, 0x0000, 0x0000}, | ||
964 | {0x05, 0x0021, 0x0001}, | ||
965 | {0x05, 0x00d2, 0x0000}, | ||
966 | {0x05, 0x0020, 0x0001}, | ||
967 | {0x05, 0x0000, 0x0000}, | ||
968 | {0x00, 0x0090, 0x0005}, | ||
969 | {0x01, 0x00a6, 0x0000}, | ||
970 | {0x01, 0x0003, 0x003f}, | ||
971 | {0x01, 0x0001, 0x0056}, | ||
972 | {0x01, 0x0011, 0x0008}, | ||
973 | {0x01, 0x0032, 0x0009}, | ||
974 | {0x01, 0xfffd, 0x000a}, | ||
975 | {0x01, 0x0023, 0x000b}, | ||
976 | {0x01, 0xffea, 0x000c}, | ||
977 | {0x01, 0xfff4, 0x000d}, | ||
978 | {0x01, 0xfffc, 0x000e}, | ||
979 | {0x01, 0xffe3, 0x000f}, | ||
980 | {0x01, 0x001f, 0x0010}, | ||
981 | {0x01, 0x00a8, 0x0001}, | ||
982 | {0x01, 0x0067, 0x0007}, | ||
983 | {0x01, 0x0032, 0x0017}, | ||
984 | {0x01, 0x0023, 0x0018}, | ||
985 | {0x01, 0x00ce, 0x0019}, | ||
986 | {0x01, 0x0023, 0x001a}, | ||
987 | {0x01, 0x0032, 0x001b}, | ||
988 | {0x01, 0x008d, 0x001c}, | ||
989 | {0x01, 0x00ce, 0x001d}, | ||
990 | {0x01, 0x008d, 0x001e}, | ||
991 | {0x01, 0x00c8, 0x0015}, | ||
992 | {0x01, 0x0032, 0x0016}, | ||
993 | {0x01, 0x0000, 0x0011}, | ||
994 | {0x01, 0x0000, 0x0012}, | ||
995 | {0x01, 0x0000, 0x0013}, | ||
996 | {0x01, 0x000a, 0x0003}, | ||
997 | {0x02, 0xc002, 0x0001}, | ||
998 | {0x02, 0x0007, 0x0005}, | ||
999 | {0x02, 0xc000, 0x0001}, | ||
1000 | {0x02, 0x0000, 0x0005}, | ||
1001 | {0x02, 0x0007, 0x0005}, | ||
1002 | {0x02, 0x2000, 0x0000}, | ||
1003 | {0x05, 0x0022, 0x0004}, | ||
1004 | {0x05, 0x0015, 0x0001}, | ||
1005 | {0x05, 0x00ea, 0x0000}, | ||
1006 | {0x05, 0x0021, 0x0001}, | ||
1007 | {0x05, 0x00d2, 0x0000}, | ||
1008 | {0x05, 0x0023, 0x0001}, | ||
1009 | {0x05, 0x0003, 0x0000}, | ||
1010 | {0x05, 0x0030, 0x0001}, | ||
1011 | {0x05, 0x002b, 0x0000}, | ||
1012 | {0x05, 0x0031, 0x0001}, | ||
1013 | {0x05, 0x0023, 0x0000}, | ||
1014 | {0x05, 0x0032, 0x0001}, | ||
1015 | {0x05, 0x0023, 0x0000}, | ||
1016 | {0x05, 0x0033, 0x0001}, | ||
1017 | {0x05, 0x0023, 0x0000}, | ||
1018 | {0x05, 0x0034, 0x0001}, | ||
1019 | {0x05, 0x0002, 0x0000}, | ||
1020 | {0x05, 0x0050, 0x0001}, | ||
1021 | {0x05, 0x0000, 0x0000}, | ||
1022 | {0x05, 0x0051, 0x0001}, | ||
1023 | {0x05, 0x0000, 0x0000}, | ||
1024 | {0x05, 0x0052, 0x0001}, | ||
1025 | {0x05, 0x0000, 0x0000}, | ||
1026 | {0x05, 0x0054, 0x0001}, | ||
1027 | {0x05, 0x0001, 0x0000}, | ||
1028 | {0x00, 0x0000, 0x0001}, | ||
1029 | {0x00, 0x0000, 0x0002}, | ||
1030 | {0x00, 0x000c, 0x0003}, | ||
1031 | {0x00, 0x0000, 0x0004}, | ||
1032 | {0x00, 0x0090, 0x0005}, | ||
1033 | {0x00, 0x0000, 0x0006}, | ||
1034 | {0x00, 0x0040, 0x0007}, | ||
1035 | {0x00, 0x00c0, 0x0008}, | ||
1036 | {0x00, 0x004a, 0x0009}, | ||
1037 | {0x00, 0x0000, 0x000a}, | ||
1038 | {0x00, 0x0000, 0x000b}, | ||
1039 | {0x00, 0x0001, 0x000c}, | ||
1040 | {0x00, 0x0001, 0x000d}, | ||
1041 | {0x00, 0x0000, 0x000e}, | ||
1042 | {0x00, 0x0002, 0x000f}, | ||
1043 | {0x00, 0x0001, 0x0010}, | ||
1044 | {0x00, 0x0000, 0x0011}, | ||
1045 | {0x00, 0x0000, 0x0012}, | ||
1046 | {0x00, 0x0002, 0x0020}, | ||
1047 | {0x00, 0x0080, 0x0021}, | ||
1048 | {0x00, 0x0001, 0x0022}, | ||
1049 | {0x00, 0x00e0, 0x0023}, | ||
1050 | {0x00, 0x0000, 0x0024}, | ||
1051 | {0x00, 0x00d5, 0x0025}, | ||
1052 | {0x00, 0x0000, 0x0026}, | ||
1053 | {0x00, 0x000b, 0x0027}, | ||
1054 | {0x00, 0x0000, 0x0046}, | ||
1055 | {0x00, 0x0000, 0x0047}, | ||
1056 | {0x00, 0x0000, 0x0048}, | ||
1057 | {0x00, 0x0000, 0x0049}, | ||
1058 | {0x00, 0x0008, 0x004a}, | ||
1059 | {0xff, 0x0000, 0x00d0}, | ||
1060 | {0xff, 0x00d8, 0x00d1}, | ||
1061 | {0xff, 0x0000, 0x00d4}, | ||
1062 | {0xff, 0x0000, 0x00d5}, | ||
1063 | {0x01, 0x00a6, 0x0000}, | ||
1064 | {0x01, 0x0028, 0x0001}, | ||
1065 | {0x01, 0x0000, 0x0002}, | ||
1066 | {0x01, 0x000a, 0x0003}, | ||
1067 | {0x01, 0x0040, 0x0004}, | ||
1068 | {0x01, 0x0066, 0x0007}, | ||
1069 | {0x01, 0x0011, 0x0008}, | ||
1070 | {0x01, 0x0032, 0x0009}, | ||
1071 | {0x01, 0x00fd, 0x000a}, | ||
1072 | {0x01, 0x0038, 0x000b}, | ||
1073 | {0x01, 0x00d1, 0x000c}, | ||
1074 | {0x01, 0x00f7, 0x000d}, | ||
1075 | {0x01, 0x00ed, 0x000e}, | ||
1076 | {0x01, 0x00d8, 0x000f}, | ||
1077 | {0x01, 0x0038, 0x0010}, | ||
1078 | {0x01, 0x00ff, 0x0015}, | ||
1079 | {0x01, 0x0001, 0x0016}, | ||
1080 | {0x01, 0x0032, 0x0017}, | ||
1081 | {0x01, 0x0023, 0x0018}, | ||
1082 | {0x01, 0x00ce, 0x0019}, | ||
1083 | {0x01, 0x0023, 0x001a}, | ||
1084 | {0x01, 0x0032, 0x001b}, | ||
1085 | {0x01, 0x008d, 0x001c}, | ||
1086 | {0x01, 0x00ce, 0x001d}, | ||
1087 | {0x01, 0x008d, 0x001e}, | ||
1088 | {0x01, 0x0000, 0x001f}, | ||
1089 | {0x01, 0x0000, 0x0020}, | ||
1090 | {0x01, 0x00ff, 0x003e}, | ||
1091 | {0x01, 0x0003, 0x003f}, | ||
1092 | {0x01, 0x0000, 0x0040}, | ||
1093 | {0x01, 0x0035, 0x0041}, | ||
1094 | {0x01, 0x0053, 0x0042}, | ||
1095 | {0x01, 0x0069, 0x0043}, | ||
1096 | {0x01, 0x007c, 0x0044}, | ||
1097 | {0x01, 0x008c, 0x0045}, | ||
1098 | {0x01, 0x009a, 0x0046}, | ||
1099 | {0x01, 0x00a8, 0x0047}, | ||
1100 | {0x01, 0x00b4, 0x0048}, | ||
1101 | {0x01, 0x00bf, 0x0049}, | ||
1102 | {0x01, 0x00ca, 0x004a}, | ||
1103 | {0x01, 0x00d4, 0x004b}, | ||
1104 | {0x01, 0x00dd, 0x004c}, | ||
1105 | {0x01, 0x00e7, 0x004d}, | ||
1106 | {0x01, 0x00ef, 0x004e}, | ||
1107 | {0x01, 0x00f8, 0x004f}, | ||
1108 | {0x01, 0x00ff, 0x0050}, | ||
1109 | {0x01, 0x0001, 0x0056}, | ||
1110 | {0x01, 0x0060, 0x0057}, | ||
1111 | {0x01, 0x0040, 0x0058}, | ||
1112 | {0x01, 0x0011, 0x0059}, | ||
1113 | {0x01, 0x0001, 0x005a}, | ||
1114 | {0x02, 0x0007, 0x0005}, | ||
1115 | {0x02, 0xa048, 0x0000}, | ||
1116 | {0x02, 0x0007, 0x0005}, | ||
1117 | {0x02, 0x0015, 0x0006}, | ||
1118 | {0x02, 0x100a, 0x0007}, | ||
1119 | {0x02, 0xa048, 0x0000}, | ||
1120 | {0x02, 0xc002, 0x0001}, | ||
1121 | {0x02, 0x000f, 0x0005}, | ||
1122 | {0x02, 0xa048, 0x0000}, | ||
1123 | {0x05, 0x0022, 0x0004}, | ||
1124 | {0x05, 0x0025, 0x0001}, | ||
1125 | {0x05, 0x0000, 0x0000}, | ||
1126 | {0x05, 0x0026, 0x0001}, | ||
1127 | {0x05, 0x0001, 0x0000}, | ||
1128 | {0x05, 0x0027, 0x0001}, | ||
1129 | {0x05, 0x0000, 0x0000}, | ||
1130 | {0x05, 0x0001, 0x0001}, | ||
1131 | {0x05, 0x0000, 0x0000}, | ||
1132 | {0x05, 0x0021, 0x0001}, | ||
1133 | {0x05, 0x00d2, 0x0000}, | ||
1134 | {0x05, 0x0020, 0x0001}, | ||
1135 | {0x05, 0x0000, 0x0000}, | ||
1136 | {0x00, 0x0090, 0x0005}, | ||
1137 | {0x01, 0x00a6, 0x0000}, | ||
1138 | {0x02, 0x0007, 0x0005}, | ||
1139 | {0x02, 0x2000, 0x0000}, | ||
1140 | {0x05, 0x0022, 0x0004}, | ||
1141 | {0x05, 0x0015, 0x0001}, | ||
1142 | {0x05, 0x00ea, 0x0000}, | ||
1143 | {0x05, 0x0021, 0x0001}, | ||
1144 | {0x05, 0x00d2, 0x0000}, | ||
1145 | {0x05, 0x0023, 0x0001}, | ||
1146 | {0x05, 0x0003, 0x0000}, | ||
1147 | {0x05, 0x0030, 0x0001}, | ||
1148 | {0x05, 0x002b, 0x0000}, | ||
1149 | {0x05, 0x0031, 0x0001}, | ||
1150 | {0x05, 0x0023, 0x0000}, | ||
1151 | {0x05, 0x0032, 0x0001}, | ||
1152 | {0x05, 0x0023, 0x0000}, | ||
1153 | {0x05, 0x0033, 0x0001}, | ||
1154 | {0x05, 0x0023, 0x0000}, | ||
1155 | {0x05, 0x0034, 0x0001}, | ||
1156 | {0x05, 0x0002, 0x0000}, | ||
1157 | {0x05, 0x0050, 0x0001}, | ||
1158 | {0x05, 0x0000, 0x0000}, | ||
1159 | {0x05, 0x0051, 0x0001}, | ||
1160 | {0x05, 0x0000, 0x0000}, | ||
1161 | {0x05, 0x0052, 0x0001}, | ||
1162 | {0x05, 0x0000, 0x0000}, | ||
1163 | {0x05, 0x0054, 0x0001}, | ||
1164 | {0x05, 0x0001, 0x0000}, | ||
1165 | {0x00, 0x0000, 0x0001}, | ||
1166 | {0x00, 0x0000, 0x0002}, | ||
1167 | {0x00, 0x000c, 0x0003}, | ||
1168 | {0x00, 0x0000, 0x0004}, | ||
1169 | {0x00, 0x0090, 0x0005}, | ||
1170 | {0x00, 0x0000, 0x0006}, | ||
1171 | {0x00, 0x0040, 0x0007}, | ||
1172 | {0x00, 0x00c0, 0x0008}, | ||
1173 | {0x00, 0x004a, 0x0009}, | ||
1174 | {0x00, 0x0000, 0x000a}, | ||
1175 | {0x00, 0x0000, 0x000b}, | ||
1176 | {0x00, 0x0001, 0x000c}, | ||
1177 | {0x00, 0x0001, 0x000d}, | ||
1178 | {0x00, 0x0000, 0x000e}, | ||
1179 | {0x00, 0x0002, 0x000f}, | ||
1180 | {0x00, 0x0001, 0x0010}, | ||
1181 | {0x00, 0x0000, 0x0011}, | ||
1182 | {0x00, 0x0000, 0x0012}, | ||
1183 | {0x00, 0x0002, 0x0020}, | ||
1184 | {0x00, 0x0080, 0x0021}, | ||
1185 | {0x00, 0x0001, 0x0022}, | ||
1186 | {0x00, 0x00e0, 0x0023}, | ||
1187 | {0x00, 0x0000, 0x0024}, | ||
1188 | {0x00, 0x00d5, 0x0025}, | ||
1189 | {0x00, 0x0000, 0x0026}, | ||
1190 | {0x00, 0x000b, 0x0027}, | ||
1191 | {0x00, 0x0000, 0x0046}, | ||
1192 | {0x00, 0x0000, 0x0047}, | ||
1193 | {0x00, 0x0000, 0x0048}, | ||
1194 | {0x00, 0x0000, 0x0049}, | ||
1195 | {0x00, 0x0008, 0x004a}, | ||
1196 | {0xff, 0x0000, 0x00d0}, | ||
1197 | {0xff, 0x00d8, 0x00d1}, | ||
1198 | {0xff, 0x0000, 0x00d4}, | ||
1199 | {0xff, 0x0000, 0x00d5}, | ||
1200 | {0x01, 0x00a6, 0x0000}, | ||
1201 | {0x01, 0x0028, 0x0001}, | ||
1202 | {0x01, 0x0000, 0x0002}, | ||
1203 | {0x01, 0x000a, 0x0003}, | ||
1204 | {0x01, 0x0040, 0x0004}, | ||
1205 | {0x01, 0x0066, 0x0007}, | ||
1206 | {0x01, 0x0011, 0x0008}, | ||
1207 | {0x01, 0x0032, 0x0009}, | ||
1208 | {0x01, 0x00fd, 0x000a}, | ||
1209 | {0x01, 0x0038, 0x000b}, | ||
1210 | {0x01, 0x00d1, 0x000c}, | ||
1211 | {0x01, 0x00f7, 0x000d}, | ||
1212 | {0x01, 0x00ed, 0x000e}, | ||
1213 | {0x01, 0x00d8, 0x000f}, | ||
1214 | {0x01, 0x0038, 0x0010}, | ||
1215 | {0x01, 0x00ff, 0x0015}, | ||
1216 | {0x01, 0x0001, 0x0016}, | ||
1217 | {0x01, 0x0032, 0x0017}, | ||
1218 | {0x01, 0x0023, 0x0018}, | ||
1219 | {0x01, 0x00ce, 0x0019}, | ||
1220 | {0x01, 0x0023, 0x001a}, | ||
1221 | {0x01, 0x0032, 0x001b}, | ||
1222 | {0x01, 0x008d, 0x001c}, | ||
1223 | {0x01, 0x00ce, 0x001d}, | ||
1224 | {0x01, 0x008d, 0x001e}, | ||
1225 | {0x01, 0x0000, 0x001f}, | ||
1226 | {0x01, 0x0000, 0x0020}, | ||
1227 | {0x01, 0x00ff, 0x003e}, | ||
1228 | {0x01, 0x0003, 0x003f}, | ||
1229 | {0x01, 0x0000, 0x0040}, | ||
1230 | {0x01, 0x0035, 0x0041}, | ||
1231 | {0x01, 0x0053, 0x0042}, | ||
1232 | {0x01, 0x0069, 0x0043}, | ||
1233 | {0x01, 0x007c, 0x0044}, | ||
1234 | {0x01, 0x008c, 0x0045}, | ||
1235 | {0x01, 0x009a, 0x0046}, | ||
1236 | {0x01, 0x00a8, 0x0047}, | ||
1237 | {0x01, 0x00b4, 0x0048}, | ||
1238 | {0x01, 0x00bf, 0x0049}, | ||
1239 | {0x01, 0x00ca, 0x004a}, | ||
1240 | {0x01, 0x00d4, 0x004b}, | ||
1241 | {0x01, 0x00dd, 0x004c}, | ||
1242 | {0x01, 0x00e7, 0x004d}, | ||
1243 | {0x01, 0x00ef, 0x004e}, | ||
1244 | {0x01, 0x00f8, 0x004f}, | ||
1245 | {0x01, 0x00ff, 0x0050}, | ||
1246 | {0x01, 0x0001, 0x0056}, | ||
1247 | {0x01, 0x0060, 0x0057}, | ||
1248 | {0x01, 0x0040, 0x0058}, | ||
1249 | {0x01, 0x0011, 0x0059}, | ||
1250 | {0x01, 0x0001, 0x005a}, | ||
1251 | {0x02, 0x0007, 0x0005}, | ||
1252 | {0x02, 0xa048, 0x0000}, | ||
1253 | {0x02, 0x0007, 0x0005}, | ||
1254 | {0x02, 0x0015, 0x0006}, | ||
1255 | {0x02, 0x100a, 0x0007}, | ||
1256 | {0x02, 0xa048, 0x0000}, | ||
1257 | {0x02, 0xc002, 0x0001}, | ||
1258 | {0x02, 0x000f, 0x0005}, | ||
1259 | {0x02, 0xa048, 0x0000}, | ||
1260 | {0x05, 0x0022, 0x0004}, | ||
1261 | {0x05, 0x0025, 0x0001}, | ||
1262 | {0x05, 0x0000, 0x0000}, | ||
1263 | {0x05, 0x0026, 0x0001}, | ||
1264 | {0x05, 0x0001, 0x0000}, | ||
1265 | {0x05, 0x0027, 0x0001}, | ||
1266 | {0x05, 0x0000, 0x0000}, | ||
1267 | {0x05, 0x0001, 0x0001}, | ||
1268 | {0x05, 0x0000, 0x0000}, | ||
1269 | {0x05, 0x0021, 0x0001}, | ||
1270 | {0x05, 0x00d2, 0x0000}, | ||
1271 | {0x05, 0x0020, 0x0001}, | ||
1272 | {0x05, 0x0000, 0x0000}, | ||
1273 | {0x00, 0x0090, 0x0005}, | ||
1274 | {0x01, 0x00a6, 0x0000}, | ||
1275 | {0x05, 0x0026, 0x0001}, | ||
1276 | {0x05, 0x0001, 0x0000}, | ||
1277 | {0x05, 0x0027, 0x0001}, | ||
1278 | {0x05, 0x000f, 0x0000}, | ||
1279 | {0x01, 0x0003, 0x003f}, | ||
1280 | {0x01, 0x0001, 0x0056}, | ||
1281 | {0x01, 0x0011, 0x0008}, | ||
1282 | {0x01, 0x0032, 0x0009}, | ||
1283 | {0x01, 0xfffd, 0x000a}, | ||
1284 | {0x01, 0x0023, 0x000b}, | ||
1285 | {0x01, 0xffea, 0x000c}, | ||
1286 | {0x01, 0xfff4, 0x000d}, | ||
1287 | {0x01, 0xfffc, 0x000e}, | ||
1288 | {0x01, 0xffe3, 0x000f}, | ||
1289 | {0x01, 0x001f, 0x0010}, | ||
1290 | {0x01, 0x00a8, 0x0001}, | ||
1291 | {0x01, 0x0067, 0x0007}, | ||
1292 | {0x01, 0x0042, 0x0051}, | ||
1293 | {0x01, 0x0051, 0x0053}, | ||
1294 | {0x01, 0x000a, 0x0003}, | ||
1295 | {0x02, 0xc002, 0x0001}, | ||
1296 | {0x02, 0x0007, 0x0005}, | ||
1297 | {0x02, 0xc000, 0x0001}, | ||
1298 | {0x02, 0x0000, 0x0005}, | ||
1299 | {0x02, 0x0007, 0x0005}, | ||
1300 | {0x02, 0x2000, 0x0000}, | ||
1301 | {0x05, 0x0022, 0x0004}, | ||
1302 | {0x05, 0x0015, 0x0001}, | ||
1303 | {0x05, 0x00ea, 0x0000}, | ||
1304 | {0x05, 0x0021, 0x0001}, | ||
1305 | {0x05, 0x00d2, 0x0000}, | ||
1306 | {0x05, 0x0023, 0x0001}, | ||
1307 | {0x05, 0x0003, 0x0000}, | ||
1308 | {0x05, 0x0030, 0x0001}, | ||
1309 | {0x05, 0x002b, 0x0000}, | ||
1310 | {0x05, 0x0031, 0x0001}, | ||
1311 | {0x05, 0x0023, 0x0000}, | ||
1312 | {0x05, 0x0032, 0x0001}, | ||
1313 | {0x05, 0x0023, 0x0000}, | ||
1314 | {0x05, 0x0033, 0x0001}, | ||
1315 | {0x05, 0x0023, 0x0000}, | ||
1316 | {0x05, 0x0034, 0x0001}, | ||
1317 | {0x05, 0x0002, 0x0000}, | ||
1318 | {0x05, 0x0050, 0x0001}, | ||
1319 | {0x05, 0x0000, 0x0000}, | ||
1320 | {0x05, 0x0051, 0x0001}, | ||
1321 | {0x05, 0x0000, 0x0000}, | ||
1322 | {0x05, 0x0052, 0x0001}, | ||
1323 | {0x05, 0x0000, 0x0000}, | ||
1324 | {0x05, 0x0054, 0x0001}, | ||
1325 | {0x05, 0x0001, 0x0000}, | ||
1326 | {0x00, 0x0000, 0x0001}, | ||
1327 | {0x00, 0x0000, 0x0002}, | ||
1328 | {0x00, 0x000c, 0x0003}, | ||
1329 | {0x00, 0x0000, 0x0004}, | ||
1330 | {0x00, 0x0090, 0x0005}, | ||
1331 | {0x00, 0x0000, 0x0006}, | ||
1332 | {0x00, 0x0040, 0x0007}, | ||
1333 | {0x00, 0x00c0, 0x0008}, | ||
1334 | {0x00, 0x004a, 0x0009}, | ||
1335 | {0x00, 0x0000, 0x000a}, | ||
1336 | {0x00, 0x0000, 0x000b}, | ||
1337 | {0x00, 0x0001, 0x000c}, | ||
1338 | {0x00, 0x0001, 0x000d}, | ||
1339 | {0x00, 0x0000, 0x000e}, | ||
1340 | {0x00, 0x0002, 0x000f}, | ||
1341 | {0x00, 0x0001, 0x0010}, | ||
1342 | {0x00, 0x0000, 0x0011}, | ||
1343 | {0x00, 0x0000, 0x0012}, | ||
1344 | {0x00, 0x0002, 0x0020}, | ||
1345 | {0x00, 0x0080, 0x0021}, | ||
1346 | {0x00, 0x0001, 0x0022}, | ||
1347 | {0x00, 0x00e0, 0x0023}, | ||
1348 | {0x00, 0x0000, 0x0024}, | ||
1349 | {0x00, 0x00d5, 0x0025}, | ||
1350 | {0x00, 0x0000, 0x0026}, | ||
1351 | {0x00, 0x000b, 0x0027}, | ||
1352 | {0x00, 0x0000, 0x0046}, | ||
1353 | {0x00, 0x0000, 0x0047}, | ||
1354 | {0x00, 0x0000, 0x0048}, | ||
1355 | {0x00, 0x0000, 0x0049}, | ||
1356 | {0x00, 0x0008, 0x004a}, | ||
1357 | {0xff, 0x0000, 0x00d0}, | ||
1358 | {0xff, 0x00d8, 0x00d1}, | ||
1359 | {0xff, 0x0000, 0x00d4}, | ||
1360 | {0xff, 0x0000, 0x00d5}, | ||
1361 | {0x01, 0x00a6, 0x0000}, | ||
1362 | {0x01, 0x0028, 0x0001}, | ||
1363 | {0x01, 0x0000, 0x0002}, | ||
1364 | {0x01, 0x000a, 0x0003}, | ||
1365 | {0x01, 0x0040, 0x0004}, | ||
1366 | {0x01, 0x0066, 0x0007}, | ||
1367 | {0x01, 0x0011, 0x0008}, | ||
1368 | {0x01, 0x0032, 0x0009}, | ||
1369 | {0x01, 0x00fd, 0x000a}, | ||
1370 | {0x01, 0x0038, 0x000b}, | ||
1371 | {0x01, 0x00d1, 0x000c}, | ||
1372 | {0x01, 0x00f7, 0x000d}, | ||
1373 | {0x01, 0x00ed, 0x000e}, | ||
1374 | {0x01, 0x00d8, 0x000f}, | ||
1375 | {0x01, 0x0038, 0x0010}, | ||
1376 | {0x01, 0x00ff, 0x0015}, | ||
1377 | {0x01, 0x0001, 0x0016}, | ||
1378 | {0x01, 0x0032, 0x0017}, | ||
1379 | {0x01, 0x0023, 0x0018}, | ||
1380 | {0x01, 0x00ce, 0x0019}, | ||
1381 | {0x01, 0x0023, 0x001a}, | ||
1382 | {0x01, 0x0032, 0x001b}, | ||
1383 | {0x01, 0x008d, 0x001c}, | ||
1384 | {0x01, 0x00ce, 0x001d}, | ||
1385 | {0x01, 0x008d, 0x001e}, | ||
1386 | {0x01, 0x0000, 0x001f}, | ||
1387 | {0x01, 0x0000, 0x0020}, | ||
1388 | {0x01, 0x00ff, 0x003e}, | ||
1389 | {0x01, 0x0003, 0x003f}, | ||
1390 | {0x01, 0x0000, 0x0040}, | ||
1391 | {0x01, 0x0035, 0x0041}, | ||
1392 | {0x01, 0x0053, 0x0042}, | ||
1393 | {0x01, 0x0069, 0x0043}, | ||
1394 | {0x01, 0x007c, 0x0044}, | ||
1395 | {0x01, 0x008c, 0x0045}, | ||
1396 | {0x01, 0x009a, 0x0046}, | ||
1397 | {0x01, 0x00a8, 0x0047}, | ||
1398 | {0x01, 0x00b4, 0x0048}, | ||
1399 | {0x01, 0x00bf, 0x0049}, | ||
1400 | {0x01, 0x00ca, 0x004a}, | ||
1401 | {0x01, 0x00d4, 0x004b}, | ||
1402 | {0x01, 0x00dd, 0x004c}, | ||
1403 | {0x01, 0x00e7, 0x004d}, | ||
1404 | {0x01, 0x00ef, 0x004e}, | ||
1405 | {0x01, 0x00f8, 0x004f}, | ||
1406 | {0x01, 0x00ff, 0x0050}, | ||
1407 | {0x01, 0x0001, 0x0056}, | ||
1408 | {0x01, 0x0060, 0x0057}, | ||
1409 | {0x01, 0x0040, 0x0058}, | ||
1410 | {0x01, 0x0011, 0x0059}, | ||
1411 | {0x01, 0x0001, 0x005a}, | ||
1412 | {0x02, 0x0007, 0x0005}, | ||
1413 | {0x02, 0xa048, 0x0000}, | ||
1414 | {0x02, 0x0007, 0x0005}, | ||
1415 | {0x02, 0x0015, 0x0006}, | ||
1416 | {0x02, 0x100a, 0x0007}, | ||
1417 | {0x02, 0xa048, 0x0000}, | ||
1418 | {0x02, 0xc002, 0x0001}, | ||
1419 | {0x02, 0x000f, 0x0005}, | ||
1420 | {0x02, 0xa048, 0x0000}, | ||
1421 | {0x05, 0x0022, 0x0004}, | ||
1422 | {0x05, 0x0025, 0x0001}, | ||
1423 | {0x05, 0x0000, 0x0000}, | ||
1424 | {0x05, 0x0026, 0x0001}, | ||
1425 | {0x05, 0x0001, 0x0000}, | ||
1426 | {0x05, 0x0027, 0x0001}, | ||
1427 | {0x05, 0x0000, 0x0000}, | ||
1428 | {0x05, 0x0001, 0x0001}, | ||
1429 | {0x05, 0x0000, 0x0000}, | ||
1430 | {0x05, 0x0021, 0x0001}, | ||
1431 | {0x05, 0x00d2, 0x0000}, | ||
1432 | {0x05, 0x0020, 0x0001}, | ||
1433 | {0x05, 0x0000, 0x0000}, | ||
1434 | {0x00, 0x0090, 0x0005}, | ||
1435 | {0x01, 0x00a6, 0x0000}, | ||
1436 | {0x02, 0x0007, 0x0005}, | ||
1437 | {0x02, 0x2000, 0x0000}, | ||
1438 | {0x05, 0x0022, 0x0004}, | ||
1439 | {0x05, 0x0015, 0x0001}, | ||
1440 | {0x05, 0x00ea, 0x0000}, | ||
1441 | {0x05, 0x0021, 0x0001}, | ||
1442 | {0x05, 0x00d2, 0x0000}, | ||
1443 | {0x05, 0x0023, 0x0001}, | ||
1444 | {0x05, 0x0003, 0x0000}, | ||
1445 | {0x05, 0x0030, 0x0001}, | ||
1446 | {0x05, 0x002b, 0x0000}, | ||
1447 | {0x05, 0x0031, 0x0001}, | ||
1448 | {0x05, 0x0023, 0x0000}, | ||
1449 | {0x05, 0x0032, 0x0001}, | ||
1450 | {0x05, 0x0023, 0x0000}, | ||
1451 | {0x05, 0x0033, 0x0001}, | ||
1452 | {0x05, 0x0023, 0x0000}, | ||
1453 | {0x05, 0x0034, 0x0001}, | ||
1454 | {0x05, 0x0002, 0x0000}, | ||
1455 | {0x05, 0x0050, 0x0001}, | ||
1456 | {0x05, 0x0000, 0x0000}, | ||
1457 | {0x05, 0x0051, 0x0001}, | ||
1458 | {0x05, 0x0000, 0x0000}, | ||
1459 | {0x05, 0x0052, 0x0001}, | ||
1460 | {0x05, 0x0000, 0x0000}, | ||
1461 | {0x05, 0x0054, 0x0001}, | ||
1462 | {0x05, 0x0001, 0x0000}, | ||
1463 | {0x00, 0x0000, 0x0001}, | ||
1464 | {0x00, 0x0000, 0x0002}, | ||
1465 | {0x00, 0x000c, 0x0003}, | ||
1466 | {0x00, 0x0000, 0x0004}, | ||
1467 | {0x00, 0x0090, 0x0005}, | ||
1468 | {0x00, 0x0000, 0x0006}, | ||
1469 | {0x00, 0x0040, 0x0007}, | ||
1470 | {0x00, 0x00c0, 0x0008}, | ||
1471 | {0x00, 0x004a, 0x0009}, | ||
1472 | {0x00, 0x0000, 0x000a}, | ||
1473 | {0x00, 0x0000, 0x000b}, | ||
1474 | {0x00, 0x0001, 0x000c}, | ||
1475 | {0x00, 0x0001, 0x000d}, | ||
1476 | {0x00, 0x0000, 0x000e}, | ||
1477 | {0x00, 0x0002, 0x000f}, | ||
1478 | {0x00, 0x0001, 0x0010}, | ||
1479 | {0x00, 0x0000, 0x0011}, | ||
1480 | {0x00, 0x0000, 0x0012}, | ||
1481 | {0x00, 0x0002, 0x0020}, | ||
1482 | {0x00, 0x0080, 0x0021}, | ||
1483 | {0x00, 0x0001, 0x0022}, | ||
1484 | {0x00, 0x00e0, 0x0023}, | ||
1485 | {0x00, 0x0000, 0x0024}, | ||
1486 | {0x00, 0x00d5, 0x0025}, | ||
1487 | {0x00, 0x0000, 0x0026}, | ||
1488 | {0x00, 0x000b, 0x0027}, | ||
1489 | {0x00, 0x0000, 0x0046}, | ||
1490 | {0x00, 0x0000, 0x0047}, | ||
1491 | {0x00, 0x0000, 0x0048}, | ||
1492 | {0x00, 0x0000, 0x0049}, | ||
1493 | {0x00, 0x0008, 0x004a}, | ||
1494 | {0xff, 0x0000, 0x00d0}, | ||
1495 | {0xff, 0x00d8, 0x00d1}, | ||
1496 | {0xff, 0x0000, 0x00d4}, | ||
1497 | {0xff, 0x0000, 0x00d5}, | ||
1498 | {0x01, 0x00a6, 0x0000}, | ||
1499 | {0x01, 0x0028, 0x0001}, | ||
1500 | {0x01, 0x0000, 0x0002}, | ||
1501 | {0x01, 0x000a, 0x0003}, | ||
1502 | {0x01, 0x0040, 0x0004}, | ||
1503 | {0x01, 0x0066, 0x0007}, | ||
1504 | {0x01, 0x0011, 0x0008}, | ||
1505 | {0x01, 0x0032, 0x0009}, | ||
1506 | {0x01, 0x00fd, 0x000a}, | ||
1507 | {0x01, 0x0038, 0x000b}, | ||
1508 | {0x01, 0x00d1, 0x000c}, | ||
1509 | {0x01, 0x00f7, 0x000d}, | ||
1510 | {0x01, 0x00ed, 0x000e}, | ||
1511 | {0x01, 0x00d8, 0x000f}, | ||
1512 | {0x01, 0x0038, 0x0010}, | ||
1513 | {0x01, 0x00ff, 0x0015}, | ||
1514 | {0x01, 0x0001, 0x0016}, | ||
1515 | {0x01, 0x0032, 0x0017}, | ||
1516 | {0x01, 0x0023, 0x0018}, | ||
1517 | {0x01, 0x00ce, 0x0019}, | ||
1518 | {0x01, 0x0023, 0x001a}, | ||
1519 | {0x01, 0x0032, 0x001b}, | ||
1520 | {0x01, 0x008d, 0x001c}, | ||
1521 | {0x01, 0x00ce, 0x001d}, | ||
1522 | {0x01, 0x008d, 0x001e}, | ||
1523 | {0x01, 0x0000, 0x001f}, | ||
1524 | {0x01, 0x0000, 0x0020}, | ||
1525 | {0x01, 0x00ff, 0x003e}, | ||
1526 | {0x01, 0x0003, 0x003f}, | ||
1527 | {0x01, 0x0000, 0x0040}, | ||
1528 | {0x01, 0x0035, 0x0041}, | ||
1529 | {0x01, 0x0053, 0x0042}, | ||
1530 | {0x01, 0x0069, 0x0043}, | ||
1531 | {0x01, 0x007c, 0x0044}, | ||
1532 | {0x01, 0x008c, 0x0045}, | ||
1533 | {0x01, 0x009a, 0x0046}, | ||
1534 | {0x01, 0x00a8, 0x0047}, | ||
1535 | {0x01, 0x00b4, 0x0048}, | ||
1536 | {0x01, 0x00bf, 0x0049}, | ||
1537 | {0x01, 0x00ca, 0x004a}, | ||
1538 | {0x01, 0x00d4, 0x004b}, | ||
1539 | {0x01, 0x00dd, 0x004c}, | ||
1540 | {0x01, 0x00e7, 0x004d}, | ||
1541 | {0x01, 0x00ef, 0x004e}, | ||
1542 | {0x01, 0x00f8, 0x004f}, | ||
1543 | {0x01, 0x00ff, 0x0050}, | ||
1544 | {0x01, 0x0001, 0x0056}, | ||
1545 | {0x01, 0x0060, 0x0057}, | ||
1546 | {0x01, 0x0040, 0x0058}, | ||
1547 | {0x01, 0x0011, 0x0059}, | ||
1548 | {0x01, 0x0001, 0x005a}, | ||
1549 | {0x02, 0x0007, 0x0005}, | ||
1550 | {0x02, 0xa048, 0x0000}, | ||
1551 | {0x02, 0x0007, 0x0005}, | ||
1552 | {0x02, 0x0015, 0x0006}, | ||
1553 | {0x02, 0x100a, 0x0007}, | ||
1554 | {0x02, 0xa048, 0x0000}, | ||
1555 | {0x02, 0xc002, 0x0001}, | ||
1556 | {0x02, 0x000f, 0x0005}, | ||
1557 | {0x02, 0xa048, 0x0000}, | ||
1558 | {0x05, 0x0022, 0x0004}, | ||
1559 | {0x05, 0x0025, 0x0001}, | ||
1560 | {0x05, 0x0000, 0x0000}, | ||
1561 | {0x05, 0x0026, 0x0001}, | ||
1562 | {0x05, 0x0001, 0x0000}, | ||
1563 | {0x05, 0x0027, 0x0001}, | ||
1564 | {0x05, 0x0000, 0x0000}, | ||
1565 | {0x05, 0x0001, 0x0001}, | ||
1566 | {0x05, 0x0000, 0x0000}, | ||
1567 | {0x05, 0x0021, 0x0001}, | ||
1568 | {0x05, 0x00d2, 0x0000}, | ||
1569 | {0x05, 0x0020, 0x0001}, | ||
1570 | {0x05, 0x0000, 0x0000}, | ||
1571 | {0x00, 0x0090, 0x0005}, | ||
1572 | {0x01, 0x00a6, 0x0000}, | ||
1573 | {0x05, 0x0026, 0x0001}, | ||
1574 | {0x05, 0x0001, 0x0000}, | ||
1575 | {0x05, 0x0027, 0x0001}, | ||
1576 | {0x05, 0x001e, 0x0000}, | ||
1577 | {0x01, 0x0003, 0x003f}, | ||
1578 | {0x01, 0x0001, 0x0056}, | ||
1579 | {0x01, 0x0011, 0x0008}, | ||
1580 | {0x01, 0x0032, 0x0009}, | ||
1581 | {0x01, 0xfffd, 0x000a}, | ||
1582 | {0x01, 0x0023, 0x000b}, | ||
1583 | {0x01, 0xffea, 0x000c}, | ||
1584 | {0x01, 0xfff4, 0x000d}, | ||
1585 | {0x01, 0xfffc, 0x000e}, | ||
1586 | {0x01, 0xffe3, 0x000f}, | ||
1587 | {0x01, 0x001f, 0x0010}, | ||
1588 | {0x01, 0x00a8, 0x0001}, | ||
1589 | {0x01, 0x0067, 0x0007}, | ||
1590 | {0x01, 0x0042, 0x0051}, | ||
1591 | {0x01, 0x0051, 0x0053}, | ||
1592 | {0x01, 0x000a, 0x0003}, | ||
1593 | {0x02, 0xc002, 0x0001}, | ||
1594 | {0x02, 0x0007, 0x0005}, | ||
1595 | {0x01, 0x0042, 0x0051}, | ||
1596 | {0x01, 0x0051, 0x0053}, | ||
1597 | {0x05, 0x0026, 0x0001}, | ||
1598 | {0x05, 0x0001, 0x0000}, | ||
1599 | {0x05, 0x0027, 0x0001}, | ||
1600 | {0x05, 0x002d, 0x0000}, | ||
1601 | {0x01, 0x0003, 0x003f}, | ||
1602 | {0x01, 0x0001, 0x0056}, | ||
1603 | {0x02, 0xc000, 0x0001}, | ||
1604 | {0x02, 0x0000, 0x0005}, | ||
1605 | {} | ||
1606 | }; | ||
1607 | |||
1608 | /* Unknow camera from Ori Usbid 0x0000:0x0000 */ | ||
1609 | /* Based on snoops from Ori Cohen */ | ||
1610 | static const __u16 spca501c_mysterious_open_data[][3] = { | ||
1611 | {0x02, 0x000f, 0x0005}, | ||
1612 | {0x02, 0xa048, 0x0000}, | ||
1613 | {0x05, 0x0022, 0x0004}, | ||
1614 | /* DSP Registers */ | ||
1615 | {0x01, 0x0016, 0x0011}, /* RGB offset */ | ||
1616 | {0x01, 0x0000, 0x0012}, | ||
1617 | {0x01, 0x0006, 0x0013}, | ||
1618 | {0x01, 0x0078, 0x0051}, | ||
1619 | {0x01, 0x0040, 0x0052}, | ||
1620 | {0x01, 0x0046, 0x0053}, | ||
1621 | {0x01, 0x0040, 0x0054}, | ||
1622 | {0x00, 0x0025, 0x0000}, | ||
1623 | /* {0x00, 0x0000, 0x0000 }, */ | ||
1624 | /* Part 2 */ | ||
1625 | /* TG Registers */ | ||
1626 | {0x00, 0x0026, 0x0000}, | ||
1627 | {0x00, 0x0001, 0x0000}, | ||
1628 | {0x00, 0x0027, 0x0000}, | ||
1629 | {0x00, 0x008a, 0x0000}, | ||
1630 | {0x02, 0x0007, 0x0005}, | ||
1631 | {0x02, 0x2000, 0x0000}, | ||
1632 | {0x05, 0x0022, 0x0004}, | ||
1633 | {0x05, 0x0015, 0x0001}, | ||
1634 | {0x05, 0x00ea, 0x0000}, | ||
1635 | {0x05, 0x0021, 0x0001}, | ||
1636 | {0x05, 0x00d2, 0x0000}, | ||
1637 | {0x05, 0x0023, 0x0001}, | ||
1638 | {0x05, 0x0003, 0x0000}, | ||
1639 | {0x05, 0x0030, 0x0001}, | ||
1640 | {0x05, 0x002b, 0x0000}, | ||
1641 | {0x05, 0x0031, 0x0001}, | ||
1642 | {0x05, 0x0023, 0x0000}, | ||
1643 | {0x05, 0x0032, 0x0001}, | ||
1644 | {0x05, 0x0023, 0x0000}, | ||
1645 | {0x05, 0x0033, 0x0001}, | ||
1646 | {0x05, 0x0023, 0x0000}, | ||
1647 | {0x05, 0x0034, 0x0001}, | ||
1648 | {0x05, 0x0002, 0x0000}, | ||
1649 | {0x05, 0x0050, 0x0001}, | ||
1650 | {0x05, 0x0000, 0x0000}, | ||
1651 | {0x05, 0x0051, 0x0001}, | ||
1652 | {0x05, 0x0000, 0x0000}, | ||
1653 | {0x05, 0x0052, 0x0001}, | ||
1654 | {0x05, 0x0000, 0x0000}, | ||
1655 | {0x05, 0x0054, 0x0001}, | ||
1656 | {0x05, 0x0001, 0x0000}, | ||
1657 | {} | ||
1658 | }; | ||
1659 | |||
1660 | /* Based on snoops from Ori Cohen */ | ||
1661 | static const __u16 spca501c_mysterious_init_data[][3] = { | ||
1662 | /* Part 3 */ | ||
1663 | /* TG registers */ | ||
1664 | /* {0x00, 0x0000, 0x0000}, */ | ||
1665 | {0x00, 0x0000, 0x0001}, | ||
1666 | {0x00, 0x0000, 0x0002}, | ||
1667 | {0x00, 0x0006, 0x0003}, | ||
1668 | {0x00, 0x0000, 0x0004}, | ||
1669 | {0x00, 0x0090, 0x0005}, | ||
1670 | {0x00, 0x0000, 0x0006}, | ||
1671 | {0x00, 0x0040, 0x0007}, | ||
1672 | {0x00, 0x00c0, 0x0008}, | ||
1673 | {0x00, 0x004a, 0x0009}, | ||
1674 | {0x00, 0x0000, 0x000a}, | ||
1675 | {0x00, 0x0000, 0x000b}, | ||
1676 | {0x00, 0x0001, 0x000c}, | ||
1677 | {0x00, 0x0001, 0x000d}, | ||
1678 | {0x00, 0x0000, 0x000e}, | ||
1679 | {0x00, 0x0002, 0x000f}, | ||
1680 | {0x00, 0x0001, 0x0010}, | ||
1681 | {0x00, 0x0000, 0x0011}, | ||
1682 | {0x00, 0x0001, 0x0012}, | ||
1683 | {0x00, 0x0002, 0x0020}, | ||
1684 | {0x00, 0x0080, 0x0021}, /* 640 */ | ||
1685 | {0x00, 0x0001, 0x0022}, | ||
1686 | {0x00, 0x00e0, 0x0023}, /* 480 */ | ||
1687 | {0x00, 0x0000, 0x0024}, /* Offset H hight */ | ||
1688 | {0x00, 0x00d3, 0x0025}, /* low */ | ||
1689 | {0x00, 0x0000, 0x0026}, /* Offset V */ | ||
1690 | {0x00, 0x000d, 0x0027}, /* low */ | ||
1691 | {0x00, 0x0000, 0x0046}, | ||
1692 | {0x00, 0x0000, 0x0047}, | ||
1693 | {0x00, 0x0000, 0x0048}, | ||
1694 | {0x00, 0x0000, 0x0049}, | ||
1695 | {0x00, 0x0008, 0x004a}, | ||
1696 | /* DSP Registers */ | ||
1697 | {0x01, 0x00a6, 0x0000}, | ||
1698 | {0x01, 0x0028, 0x0001}, | ||
1699 | {0x01, 0x0000, 0x0002}, | ||
1700 | {0x01, 0x000a, 0x0003}, /* Level Calc bit7 ->1 Auto */ | ||
1701 | {0x01, 0x0040, 0x0004}, | ||
1702 | {0x01, 0x0066, 0x0007}, | ||
1703 | {0x01, 0x000f, 0x0008}, /* A11 Color correction coeff */ | ||
1704 | {0x01, 0x002d, 0x0009}, /* A12 */ | ||
1705 | {0x01, 0x0005, 0x000a}, /* A13 */ | ||
1706 | {0x01, 0x0023, 0x000b}, /* A21 */ | ||
1707 | {0x01, 0x00e0, 0x000c}, /* A22 */ | ||
1708 | {0x01, 0x00fd, 0x000d}, /* A23 */ | ||
1709 | {0x01, 0x00f4, 0x000e}, /* A31 */ | ||
1710 | {0x01, 0x00e4, 0x000f}, /* A32 */ | ||
1711 | {0x01, 0x0028, 0x0010}, /* A33 */ | ||
1712 | {0x01, 0x00ff, 0x0015}, /* Reserved */ | ||
1713 | {0x01, 0x0001, 0x0016}, /* Reserved */ | ||
1714 | {0x01, 0x0032, 0x0017}, /* Win1 Start begin */ | ||
1715 | {0x01, 0x0023, 0x0018}, | ||
1716 | {0x01, 0x00ce, 0x0019}, | ||
1717 | {0x01, 0x0023, 0x001a}, | ||
1718 | {0x01, 0x0032, 0x001b}, | ||
1719 | {0x01, 0x008d, 0x001c}, | ||
1720 | {0x01, 0x00ce, 0x001d}, | ||
1721 | {0x01, 0x008d, 0x001e}, | ||
1722 | {0x01, 0x0000, 0x001f}, | ||
1723 | {0x01, 0x0000, 0x0020}, /* Win1 Start end */ | ||
1724 | {0x01, 0x00ff, 0x003e}, /* Reserved begin */ | ||
1725 | {0x01, 0x0002, 0x003f}, | ||
1726 | {0x01, 0x0000, 0x0040}, | ||
1727 | {0x01, 0x0035, 0x0041}, | ||
1728 | {0x01, 0x0053, 0x0042}, | ||
1729 | {0x01, 0x0069, 0x0043}, | ||
1730 | {0x01, 0x007c, 0x0044}, | ||
1731 | {0x01, 0x008c, 0x0045}, | ||
1732 | {0x01, 0x009a, 0x0046}, | ||
1733 | {0x01, 0x00a8, 0x0047}, | ||
1734 | {0x01, 0x00b4, 0x0048}, | ||
1735 | {0x01, 0x00bf, 0x0049}, | ||
1736 | {0x01, 0x00ca, 0x004a}, | ||
1737 | {0x01, 0x00d4, 0x004b}, | ||
1738 | {0x01, 0x00dd, 0x004c}, | ||
1739 | {0x01, 0x00e7, 0x004d}, | ||
1740 | {0x01, 0x00ef, 0x004e}, | ||
1741 | {0x01, 0x00f8, 0x004f}, | ||
1742 | {0x01, 0x00ff, 0x0050}, | ||
1743 | {0x01, 0x0003, 0x0056}, /* Reserved end */ | ||
1744 | {0x01, 0x0060, 0x0057}, /* Edge Gain */ | ||
1745 | {0x01, 0x0040, 0x0058}, | ||
1746 | {0x01, 0x0011, 0x0059}, /* Edge Bandwidth */ | ||
1747 | {0x01, 0x0001, 0x005a}, | ||
1748 | {0x02, 0x0007, 0x0005}, | ||
1749 | {0x02, 0xa048, 0x0000}, | ||
1750 | {0x02, 0x0007, 0x0005}, | ||
1751 | {0x02, 0x0015, 0x0006}, | ||
1752 | {0x02, 0x200a, 0x0007}, | ||
1753 | {0x02, 0xa048, 0x0000}, | ||
1754 | {0x02, 0xc000, 0x0001}, | ||
1755 | {0x02, 0x000f, 0x0005}, | ||
1756 | {0x02, 0xa048, 0x0000}, | ||
1757 | {0x05, 0x0022, 0x0004}, | ||
1758 | {0x05, 0x0025, 0x0001}, | ||
1759 | {0x05, 0x0000, 0x0000}, | ||
1760 | /* Part 4 */ | ||
1761 | {0x05, 0x0026, 0x0001}, | ||
1762 | {0x05, 0x0001, 0x0000}, | ||
1763 | {0x05, 0x0027, 0x0001}, | ||
1764 | {0x05, 0x0000, 0x0000}, | ||
1765 | {0x05, 0x0001, 0x0001}, | ||
1766 | {0x05, 0x0000, 0x0000}, | ||
1767 | {0x05, 0x0021, 0x0001}, | ||
1768 | {0x05, 0x00d2, 0x0000}, | ||
1769 | {0x05, 0x0020, 0x0001}, | ||
1770 | {0x05, 0x0000, 0x0000}, | ||
1771 | {0x00, 0x0090, 0x0005}, | ||
1772 | {0x01, 0x00a6, 0x0000}, | ||
1773 | {0x02, 0x0000, 0x0005}, | ||
1774 | {0x05, 0x0026, 0x0001}, | ||
1775 | {0x05, 0x0001, 0x0000}, | ||
1776 | {0x05, 0x0027, 0x0001}, | ||
1777 | {0x05, 0x004e, 0x0000}, | ||
1778 | /* Part 5 */ | ||
1779 | {0x01, 0x0003, 0x003f}, | ||
1780 | {0x01, 0x0001, 0x0056}, | ||
1781 | {0x01, 0x000f, 0x0008}, | ||
1782 | {0x01, 0x002d, 0x0009}, | ||
1783 | {0x01, 0x0005, 0x000a}, | ||
1784 | {0x01, 0x0023, 0x000b}, | ||
1785 | {0x01, 0xffe0, 0x000c}, | ||
1786 | {0x01, 0xfffd, 0x000d}, | ||
1787 | {0x01, 0xfff4, 0x000e}, | ||
1788 | {0x01, 0xffe4, 0x000f}, | ||
1789 | {0x01, 0x0028, 0x0010}, | ||
1790 | {0x01, 0x00a8, 0x0001}, | ||
1791 | {0x01, 0x0066, 0x0007}, | ||
1792 | {0x01, 0x0032, 0x0017}, | ||
1793 | {0x01, 0x0023, 0x0018}, | ||
1794 | {0x01, 0x00ce, 0x0019}, | ||
1795 | {0x01, 0x0023, 0x001a}, | ||
1796 | {0x01, 0x0032, 0x001b}, | ||
1797 | {0x01, 0x008d, 0x001c}, | ||
1798 | {0x01, 0x00ce, 0x001d}, | ||
1799 | {0x01, 0x008d, 0x001e}, | ||
1800 | {0x01, 0x00c8, 0x0015}, /* c8 Poids fort Luma */ | ||
1801 | {0x01, 0x0032, 0x0016}, /* 32 */ | ||
1802 | {0x01, 0x0016, 0x0011}, /* R 00 */ | ||
1803 | {0x01, 0x0016, 0x0012}, /* G 00 */ | ||
1804 | {0x01, 0x0016, 0x0013}, /* B 00 */ | ||
1805 | {0x01, 0x000a, 0x0003}, | ||
1806 | {0x02, 0xc002, 0x0001}, | ||
1807 | {0x02, 0x0007, 0x0005}, | ||
1808 | {} | ||
1809 | }; | ||
1810 | |||
1811 | static int reg_write(struct usb_device *dev, | ||
1812 | __u16 req, __u16 index, __u16 value) | ||
1813 | { | ||
1814 | int ret; | ||
1815 | |||
1816 | ret = usb_control_msg(dev, | ||
1817 | usb_sndctrlpipe(dev, 0), | ||
1818 | req, | ||
1819 | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
1820 | value, index, NULL, 0, 500); | ||
1821 | PDEBUG(D_USBO, "reg write: 0x%02x 0x%02x 0x%02x", | ||
1822 | req, index, value); | ||
1823 | if (ret < 0) | ||
1824 | PDEBUG(D_ERR, "reg write: error %d", ret); | ||
1825 | return ret; | ||
1826 | } | ||
1827 | |||
1828 | /* returns: negative is error, pos or zero is data */ | ||
1829 | static int reg_read(struct gspca_dev *gspca_dev, | ||
1830 | __u16 req, /* bRequest */ | ||
1831 | __u16 index, /* wIndex */ | ||
1832 | __u16 length) /* wLength (1 or 2 only) */ | ||
1833 | { | ||
1834 | int ret; | ||
1835 | |||
1836 | gspca_dev->usb_buf[1] = 0; | ||
1837 | ret = usb_control_msg(gspca_dev->dev, | ||
1838 | usb_rcvctrlpipe(gspca_dev->dev, 0), | ||
1839 | req, | ||
1840 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
1841 | 0, /* value */ | ||
1842 | index, | ||
1843 | gspca_dev->usb_buf, length, | ||
1844 | 500); /* timeout */ | ||
1845 | if (ret < 0) { | ||
1846 | PDEBUG(D_ERR, "reg_read err %d", ret); | ||
1847 | return -1; | ||
1848 | } | ||
1849 | return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; | ||
1850 | } | ||
1851 | |||
1852 | static int write_vector(struct gspca_dev *gspca_dev, | ||
1853 | const __u16 data[][3]) | ||
1854 | { | ||
1855 | struct usb_device *dev = gspca_dev->dev; | ||
1856 | int ret, i = 0; | ||
1857 | |||
1858 | while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { | ||
1859 | ret = reg_write(dev, data[i][0], data[i][2], data[i][1]); | ||
1860 | if (ret < 0) { | ||
1861 | PDEBUG(D_ERR, | ||
1862 | "Reg write failed for 0x%02x,0x%02x,0x%02x", | ||
1863 | data[i][0], data[i][1], data[i][2]); | ||
1864 | return ret; | ||
1865 | } | ||
1866 | i++; | ||
1867 | } | ||
1868 | return 0; | ||
1869 | } | ||
1870 | |||
1871 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
1872 | { | ||
1873 | struct sd *sd = (struct sd *) gspca_dev; | ||
1874 | |||
1875 | reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x11, sd->brightness); | ||
1876 | reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, sd->brightness); | ||
1877 | reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x13, sd->brightness); | ||
1878 | } | ||
1879 | |||
1880 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
1881 | { | ||
1882 | struct sd *sd = (struct sd *) gspca_dev; | ||
1883 | __u16 brightness; | ||
1884 | |||
1885 | brightness = reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x11, 2); | ||
1886 | sd->brightness = brightness << 1; | ||
1887 | } | ||
1888 | |||
1889 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
1890 | { | ||
1891 | struct sd *sd = (struct sd *) gspca_dev; | ||
1892 | |||
1893 | reg_write(gspca_dev->dev, 0x00, 0x00, | ||
1894 | (sd->contrast >> 8) & 0xff); | ||
1895 | reg_write(gspca_dev->dev, 0x00, 0x01, | ||
1896 | sd->contrast & 0xff); | ||
1897 | } | ||
1898 | |||
1899 | static void getcontrast(struct gspca_dev *gspca_dev) | ||
1900 | { | ||
1901 | /* spca50x->contrast = 0xaa01; */ | ||
1902 | } | ||
1903 | |||
1904 | static void setcolors(struct gspca_dev *gspca_dev) | ||
1905 | { | ||
1906 | struct sd *sd = (struct sd *) gspca_dev; | ||
1907 | |||
1908 | reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x0c, sd->colors); | ||
1909 | } | ||
1910 | |||
1911 | static void getcolors(struct gspca_dev *gspca_dev) | ||
1912 | { | ||
1913 | struct sd *sd = (struct sd *) gspca_dev; | ||
1914 | |||
1915 | sd->colors = reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x0c, 2); | ||
1916 | /* sd->hue = (reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x13, */ | ||
1917 | /* 2) & 0xFF) << 8; */ | ||
1918 | } | ||
1919 | |||
1920 | /* this function is called at probe time */ | ||
1921 | static int sd_config(struct gspca_dev *gspca_dev, | ||
1922 | const struct usb_device_id *id) | ||
1923 | { | ||
1924 | struct sd *sd = (struct sd *) gspca_dev; | ||
1925 | struct cam *cam; | ||
1926 | __u16 vendor; | ||
1927 | __u16 product; | ||
1928 | |||
1929 | vendor = id->idVendor; | ||
1930 | product = id->idProduct; | ||
1931 | switch (vendor) { | ||
1932 | case 0x0000: /* Unknow Camera */ | ||
1933 | /* switch (product) { */ | ||
1934 | /* case 0x0000: */ | ||
1935 | sd->subtype = MystFromOriUnknownCamera; | ||
1936 | /* break; */ | ||
1937 | /* } */ | ||
1938 | break; | ||
1939 | case 0x040a: /* Kodak cameras */ | ||
1940 | /* switch (product) { */ | ||
1941 | /* case 0x0002: */ | ||
1942 | sd->subtype = KodakDVC325; | ||
1943 | /* break; */ | ||
1944 | /* } */ | ||
1945 | break; | ||
1946 | case 0x0497: /* Smile International */ | ||
1947 | /* switch (product) { */ | ||
1948 | /* case 0xc001: */ | ||
1949 | sd->subtype = SmileIntlCamera; | ||
1950 | /* break; */ | ||
1951 | /* } */ | ||
1952 | break; | ||
1953 | case 0x0506: /* 3COM cameras */ | ||
1954 | /* switch (product) { */ | ||
1955 | /* case 0x00df: */ | ||
1956 | sd->subtype = ThreeComHomeConnectLite; | ||
1957 | /* break; */ | ||
1958 | /* } */ | ||
1959 | break; | ||
1960 | case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */ | ||
1961 | switch (product) { | ||
1962 | case 0x0401: | ||
1963 | sd->subtype = IntelCreateAndShare; | ||
1964 | break; | ||
1965 | case 0x0402: | ||
1966 | sd->subtype = ViewQuestM318B; | ||
1967 | break; | ||
1968 | } | ||
1969 | break; | ||
1970 | case 0x1776: /* Arowana */ | ||
1971 | /* switch (product) { */ | ||
1972 | /* case 0x501c: */ | ||
1973 | sd->subtype = Arowana300KCMOSCamera; | ||
1974 | /* break; */ | ||
1975 | /* } */ | ||
1976 | break; | ||
1977 | } | ||
1978 | cam = &gspca_dev->cam; | ||
1979 | cam->dev_name = (char *) id->driver_info; | ||
1980 | cam->epaddr = 0x01; | ||
1981 | cam->cam_mode = vga_mode; | ||
1982 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | ||
1983 | sd->brightness = sd_ctrls[MY_BRIGHTNESS].qctrl.default_value; | ||
1984 | sd->contrast = sd_ctrls[MY_CONTRAST].qctrl.default_value; | ||
1985 | sd->colors = sd_ctrls[MY_COLOR].qctrl.default_value; | ||
1986 | |||
1987 | switch (sd->subtype) { | ||
1988 | case Arowana300KCMOSCamera: | ||
1989 | case SmileIntlCamera: | ||
1990 | /* Arowana 300k CMOS Camera data */ | ||
1991 | if (write_vector(gspca_dev, spca501c_arowana_init_data)) | ||
1992 | goto error; | ||
1993 | break; | ||
1994 | case MystFromOriUnknownCamera: | ||
1995 | /* UnKnow Ori CMOS Camera data */ | ||
1996 | if (write_vector(gspca_dev, spca501c_mysterious_open_data)) | ||
1997 | goto error; | ||
1998 | break; | ||
1999 | default: | ||
2000 | /* generic spca501 init data */ | ||
2001 | if (write_vector(gspca_dev, spca501_init_data)) | ||
2002 | goto error; | ||
2003 | break; | ||
2004 | } | ||
2005 | return 0; | ||
2006 | error: | ||
2007 | return -EINVAL; | ||
2008 | } | ||
2009 | |||
2010 | /* this function is called at open time */ | ||
2011 | static int sd_open(struct gspca_dev *gspca_dev) | ||
2012 | { | ||
2013 | struct sd *sd = (struct sd *) gspca_dev; | ||
2014 | |||
2015 | switch (sd->subtype) { | ||
2016 | case ThreeComHomeConnectLite: | ||
2017 | /* Special handling for 3com data */ | ||
2018 | write_vector(gspca_dev, spca501_3com_open_data); | ||
2019 | break; | ||
2020 | case Arowana300KCMOSCamera: | ||
2021 | case SmileIntlCamera: | ||
2022 | /* Arowana 300k CMOS Camera data */ | ||
2023 | write_vector(gspca_dev, spca501c_arowana_open_data); | ||
2024 | break; | ||
2025 | case MystFromOriUnknownCamera: | ||
2026 | /* UnKnow CMOS Camera data */ | ||
2027 | write_vector(gspca_dev, spca501c_mysterious_init_data); | ||
2028 | break; | ||
2029 | default: | ||
2030 | /* Generic 501 open data */ | ||
2031 | write_vector(gspca_dev, spca501_open_data); | ||
2032 | } | ||
2033 | PDEBUG(D_STREAM, "Initializing SPCA501 finished"); | ||
2034 | return 0; | ||
2035 | } | ||
2036 | |||
2037 | static void sd_start(struct gspca_dev *gspca_dev) | ||
2038 | { | ||
2039 | struct usb_device *dev = gspca_dev->dev; | ||
2040 | int mode; | ||
2041 | |||
2042 | /* memorize the wanted pixel format */ | ||
2043 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | ||
2044 | |||
2045 | /* Enable ISO packet machine CTRL reg=2, | ||
2046 | * index=1 bitmask=0x2 (bit ordinal 1) */ | ||
2047 | reg_write(dev, SPCA50X_REG_USB, 0x6, 0x94); | ||
2048 | switch (mode) { | ||
2049 | case 0: /* 640x480 */ | ||
2050 | reg_write(dev, SPCA50X_REG_USB, 0x07, 0x004a); | ||
2051 | break; | ||
2052 | case 1: /* 320x240 */ | ||
2053 | reg_write(dev, SPCA50X_REG_USB, 0x07, 0x104a); | ||
2054 | break; | ||
2055 | default: | ||
2056 | /* case 2: * 160x120 */ | ||
2057 | reg_write(dev, SPCA50X_REG_USB, 0x07, 0x204a); | ||
2058 | break; | ||
2059 | } | ||
2060 | reg_write(dev, SPCA501_REG_CTLRL, 0x01, 0x02); | ||
2061 | |||
2062 | /* HDG atleast the Intel CreateAndShare needs to have one of its | ||
2063 | * brightness / contrast / color set otherwise it assumes what seems | ||
2064 | * max contrast. Note that strange enough setting any of these is | ||
2065 | * enough to fix the max contrast problem, to be sure we set all 3 */ | ||
2066 | setbrightness(gspca_dev); | ||
2067 | setcontrast(gspca_dev); | ||
2068 | setcolors(gspca_dev); | ||
2069 | } | ||
2070 | |||
2071 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
2072 | { | ||
2073 | /* Disable ISO packet | ||
2074 | * machine CTRL reg=2, index=1 bitmask=0x0 (bit ordinal 1) */ | ||
2075 | reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x01, 0x00); | ||
2076 | } | ||
2077 | |||
2078 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
2079 | { | ||
2080 | } | ||
2081 | |||
2082 | /* this function is called at close time */ | ||
2083 | static void sd_close(struct gspca_dev *gspca_dev) | ||
2084 | { | ||
2085 | reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x05, 0x00); | ||
2086 | } | ||
2087 | |||
2088 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
2089 | struct gspca_frame *frame, /* target */ | ||
2090 | __u8 *data, /* isoc packet */ | ||
2091 | int len) /* iso packet length */ | ||
2092 | { | ||
2093 | switch (data[0]) { | ||
2094 | case 0: /* start of frame */ | ||
2095 | frame = gspca_frame_add(gspca_dev, | ||
2096 | LAST_PACKET, | ||
2097 | frame, | ||
2098 | data, 0); | ||
2099 | data += SPCA501_OFFSET_DATA; | ||
2100 | len -= SPCA501_OFFSET_DATA; | ||
2101 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | ||
2102 | data, len); | ||
2103 | return; | ||
2104 | case 0xff: /* drop */ | ||
2105 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
2106 | return; | ||
2107 | } | ||
2108 | data++; | ||
2109 | len--; | ||
2110 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
2111 | data, len); | ||
2112 | } | ||
2113 | |||
2114 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
2115 | { | ||
2116 | struct sd *sd = (struct sd *) gspca_dev; | ||
2117 | |||
2118 | sd->brightness = val; | ||
2119 | if (gspca_dev->streaming) | ||
2120 | setbrightness(gspca_dev); | ||
2121 | return 0; | ||
2122 | } | ||
2123 | |||
2124 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
2125 | { | ||
2126 | struct sd *sd = (struct sd *) gspca_dev; | ||
2127 | |||
2128 | getbrightness(gspca_dev); | ||
2129 | *val = sd->brightness; | ||
2130 | return 0; | ||
2131 | } | ||
2132 | |||
2133 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
2134 | { | ||
2135 | struct sd *sd = (struct sd *) gspca_dev; | ||
2136 | |||
2137 | sd->contrast = val; | ||
2138 | if (gspca_dev->streaming) | ||
2139 | setcontrast(gspca_dev); | ||
2140 | return 0; | ||
2141 | } | ||
2142 | |||
2143 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
2144 | { | ||
2145 | struct sd *sd = (struct sd *) gspca_dev; | ||
2146 | |||
2147 | getcontrast(gspca_dev); | ||
2148 | *val = sd->contrast; | ||
2149 | return 0; | ||
2150 | } | ||
2151 | |||
2152 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
2153 | { | ||
2154 | struct sd *sd = (struct sd *) gspca_dev; | ||
2155 | |||
2156 | sd->colors = val; | ||
2157 | if (gspca_dev->streaming) | ||
2158 | setcolors(gspca_dev); | ||
2159 | return 0; | ||
2160 | } | ||
2161 | |||
2162 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
2163 | { | ||
2164 | struct sd *sd = (struct sd *) gspca_dev; | ||
2165 | |||
2166 | getcolors(gspca_dev); | ||
2167 | *val = sd->colors; | ||
2168 | return 0; | ||
2169 | } | ||
2170 | |||
2171 | /* sub-driver description */ | ||
2172 | static const struct sd_desc sd_desc = { | ||
2173 | .name = MODULE_NAME, | ||
2174 | .ctrls = sd_ctrls, | ||
2175 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
2176 | .config = sd_config, | ||
2177 | .open = sd_open, | ||
2178 | .start = sd_start, | ||
2179 | .stopN = sd_stopN, | ||
2180 | .stop0 = sd_stop0, | ||
2181 | .close = sd_close, | ||
2182 | .pkt_scan = sd_pkt_scan, | ||
2183 | }; | ||
2184 | |||
2185 | /* -- module initialisation -- */ | ||
2186 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
2187 | static const __devinitdata struct usb_device_id device_table[] = { | ||
2188 | {USB_DEVICE(0x040a, 0x0002), DVNM("Kodak DVC-325")}, | ||
2189 | {USB_DEVICE(0x0497, 0xc001), DVNM("Smile International")}, | ||
2190 | {USB_DEVICE(0x0506, 0x00df), DVNM("3Com HomeConnect Lite")}, | ||
2191 | {USB_DEVICE(0x0733, 0x0401), DVNM("Intel Create and Share")}, | ||
2192 | {USB_DEVICE(0x0733, 0x0402), DVNM("ViewQuest M318B")}, | ||
2193 | {USB_DEVICE(0x1776, 0x501c), DVNM("Arowana 300K CMOS Camera")}, | ||
2194 | {USB_DEVICE(0x0000, 0x0000), DVNM("MystFromOri Unknow Camera")}, | ||
2195 | {} | ||
2196 | }; | ||
2197 | MODULE_DEVICE_TABLE(usb, device_table); | ||
2198 | |||
2199 | /* -- device connect -- */ | ||
2200 | static int sd_probe(struct usb_interface *intf, | ||
2201 | const struct usb_device_id *id) | ||
2202 | { | ||
2203 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
2204 | THIS_MODULE); | ||
2205 | } | ||
2206 | |||
2207 | static struct usb_driver sd_driver = { | ||
2208 | .name = MODULE_NAME, | ||
2209 | .id_table = device_table, | ||
2210 | .probe = sd_probe, | ||
2211 | .disconnect = gspca_disconnect, | ||
2212 | }; | ||
2213 | |||
2214 | /* -- module insert / remove -- */ | ||
2215 | static int __init sd_mod_init(void) | ||
2216 | { | ||
2217 | if (usb_register(&sd_driver) < 0) | ||
2218 | return -1; | ||
2219 | PDEBUG(D_PROBE, "v%s registered", version); | ||
2220 | return 0; | ||
2221 | } | ||
2222 | static void __exit sd_mod_exit(void) | ||
2223 | { | ||
2224 | usb_deregister(&sd_driver); | ||
2225 | PDEBUG(D_PROBE, "deregistered"); | ||
2226 | } | ||
2227 | |||
2228 | module_init(sd_mod_init); | ||
2229 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c new file mode 100644 index 000000000000..ddea6e140aa8 --- /dev/null +++ b/drivers/media/video/gspca/spca505.c | |||
@@ -0,0 +1,951 @@ | |||
1 | /* | ||
2 | * SPCA505 chip based cameras initialization data | ||
3 | * | ||
4 | * V4L2 by Jean-Francis 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 | |||
22 | #define MODULE_NAME "spca505" | ||
23 | |||
24 | #include "gspca.h" | ||
25 | |||
26 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) | ||
27 | static const char version[] = "2.1.7"; | ||
28 | |||
29 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
30 | MODULE_DESCRIPTION("GSPCA/SPCA505 USB Camera Driver"); | ||
31 | MODULE_LICENSE("GPL"); | ||
32 | |||
33 | /* specific webcam descriptor */ | ||
34 | struct sd { | ||
35 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
36 | |||
37 | int buflen; | ||
38 | unsigned char tmpbuf[640 * 480 * 3 / 2]; /* YYUV per line */ | ||
39 | unsigned char tmpbuf2[640 * 480 * 2]; /* YUYV */ | ||
40 | |||
41 | unsigned char brightness; | ||
42 | |||
43 | char subtype; | ||
44 | #define IntelPCCameraPro 0 | ||
45 | #define Nxultra 1 | ||
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 | |||
52 | static struct ctrl sd_ctrls[] = { | ||
53 | #define SD_BRIGHTNESS 0 | ||
54 | { | ||
55 | { | ||
56 | .id = V4L2_CID_BRIGHTNESS, | ||
57 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
58 | .name = "Brightness", | ||
59 | .minimum = 0, | ||
60 | .maximum = 255, | ||
61 | .step = 1, | ||
62 | .default_value = 127, | ||
63 | }, | ||
64 | .set = sd_setbrightness, | ||
65 | .get = sd_getbrightness, | ||
66 | }, | ||
67 | }; | ||
68 | |||
69 | static struct v4l2_pix_format vga_mode[] = { | ||
70 | {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | ||
71 | .bytesperline = 160 * 2, | ||
72 | .sizeimage = 160 * 120 * 2, | ||
73 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
74 | .priv = 5}, | ||
75 | {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | ||
76 | .bytesperline = 176 * 2, | ||
77 | .sizeimage = 176 * 144 * 2, | ||
78 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
79 | .priv = 4}, | ||
80 | {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | ||
81 | .bytesperline = 320 * 2, | ||
82 | .sizeimage = 320 * 240 * 2, | ||
83 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
84 | .priv = 2}, | ||
85 | {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | ||
86 | .bytesperline = 352 * 2, | ||
87 | .sizeimage = 352 * 288 * 2, | ||
88 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
89 | .priv = 1}, | ||
90 | {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | ||
91 | .bytesperline = 640 * 2, | ||
92 | .sizeimage = 640 * 480 * 2, | ||
93 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
94 | .priv = 0}, | ||
95 | }; | ||
96 | |||
97 | #define SPCA50X_OFFSET_DATA 10 | ||
98 | |||
99 | #define SPCA50X_REG_USB 0x02 /* spca505 501 */ | ||
100 | |||
101 | #define SPCA50X_USB_CTRL 0x00 /* spca505 */ | ||
102 | #define SPCA50X_CUSB_ENABLE 0x01 /* spca505 */ | ||
103 | #define SPCA50X_REG_GLOBAL 0x03 /* spca505 */ | ||
104 | #define SPCA50X_GMISC0_IDSEL 0x01 /* Global control device ID select spca505 */ | ||
105 | #define SPCA50X_GLOBAL_MISC0 0x00 /* Global control miscellaneous 0 spca505 */ | ||
106 | |||
107 | #define SPCA50X_GLOBAL_MISC1 0x01 /* 505 */ | ||
108 | #define SPCA50X_GLOBAL_MISC3 0x03 /* 505 */ | ||
109 | #define SPCA50X_GMISC3_SAA7113RST 0x20 /* Not sure about this one spca505 */ | ||
110 | |||
111 | /* | ||
112 | * Data to initialize a SPCA505. Common to the CCD and external modes | ||
113 | */ | ||
114 | static const __u16 spca505_init_data[][3] = { | ||
115 | /* line bmRequest,value,index */ | ||
116 | /* 1819 */ | ||
117 | {SPCA50X_REG_GLOBAL, SPCA50X_GMISC3_SAA7113RST, SPCA50X_GLOBAL_MISC3}, | ||
118 | /* Sensor reset */ | ||
119 | /* 1822 */ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3}, | ||
120 | /* 1825 */ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1}, | ||
121 | /* Block USB reset */ | ||
122 | /* 1828 */ {SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL, | ||
123 | SPCA50X_GLOBAL_MISC0}, | ||
124 | |||
125 | /* 1831 */ {0x5, 0x01, 0x10}, | ||
126 | /* Maybe power down some stuff */ | ||
127 | /* 1834 */ {0x5, 0x0f, 0x11}, | ||
128 | |||
129 | /* Setup internal CCD ? */ | ||
130 | /* 1837 */ {0x6, 0x10, 0x08}, | ||
131 | /* 1840 */ {0x6, 0x00, 0x09}, | ||
132 | /* 1843 */ {0x6, 0x00, 0x0a}, | ||
133 | /* 1846 */ {0x6, 0x00, 0x0b}, | ||
134 | /* 1849 */ {0x6, 0x10, 0x0c}, | ||
135 | /* 1852 */ {0x6, 0x00, 0x0d}, | ||
136 | /* 1855 */ {0x6, 0x00, 0x0e}, | ||
137 | /* 1858 */ {0x6, 0x00, 0x0f}, | ||
138 | /* 1861 */ {0x6, 0x10, 0x10}, | ||
139 | /* 1864 */ {0x6, 0x02, 0x11}, | ||
140 | /* 1867 */ {0x6, 0x00, 0x12}, | ||
141 | /* 1870 */ {0x6, 0x04, 0x13}, | ||
142 | /* 1873 */ {0x6, 0x02, 0x14}, | ||
143 | /* 1876 */ {0x6, 0x8a, 0x51}, | ||
144 | /* 1879 */ {0x6, 0x40, 0x52}, | ||
145 | /* 1882 */ {0x6, 0xb6, 0x53}, | ||
146 | /* 1885 */ {0x6, 0x3d, 0x54}, | ||
147 | {} | ||
148 | }; | ||
149 | |||
150 | /* | ||
151 | * Data to initialize the camera using the internal CCD | ||
152 | */ | ||
153 | static const __u16 spca505_open_data_ccd[][3] = { | ||
154 | /* line bmRequest,value,index */ | ||
155 | /* Internal CCD data set */ | ||
156 | /* 1891 */ {0x3, 0x04, 0x01}, | ||
157 | /* This could be a reset */ | ||
158 | /* 1894 */ {0x3, 0x00, 0x01}, | ||
159 | |||
160 | /* Setup compression and image registers. 0x6 and 0x7 seem to be | ||
161 | related to H&V hold, and are resolution mode specific */ | ||
162 | /* 1897 */ {0x4, 0x10, 0x01}, | ||
163 | /* DIFF(0x50), was (0x10) */ | ||
164 | /* 1900 */ {0x4, 0x00, 0x04}, | ||
165 | /* 1903 */ {0x4, 0x00, 0x05}, | ||
166 | /* 1906 */ {0x4, 0x20, 0x06}, | ||
167 | /* 1909 */ {0x4, 0x20, 0x07}, | ||
168 | |||
169 | /* 1912 */ {0x8, 0x0a, 0x00}, | ||
170 | /* DIFF (0x4a), was (0xa) */ | ||
171 | |||
172 | /* 1915 */ {0x5, 0x00, 0x10}, | ||
173 | /* 1918 */ {0x5, 0x00, 0x11}, | ||
174 | /* 1921 */ {0x5, 0x00, 0x00}, | ||
175 | /* DIFF not written */ | ||
176 | /* 1924 */ {0x5, 0x00, 0x01}, | ||
177 | /* DIFF not written */ | ||
178 | /* 1927 */ {0x5, 0x00, 0x02}, | ||
179 | /* DIFF not written */ | ||
180 | /* 1930 */ {0x5, 0x00, 0x03}, | ||
181 | /* DIFF not written */ | ||
182 | /* 1933 */ {0x5, 0x00, 0x04}, | ||
183 | /* DIFF not written */ | ||
184 | /* 1936 */ {0x5, 0x80, 0x05}, | ||
185 | /* DIFF not written */ | ||
186 | /* 1939 */ {0x5, 0xe0, 0x06}, | ||
187 | /* DIFF not written */ | ||
188 | /* 1942 */ {0x5, 0x20, 0x07}, | ||
189 | /* DIFF not written */ | ||
190 | /* 1945 */ {0x5, 0xa0, 0x08}, | ||
191 | /* DIFF not written */ | ||
192 | /* 1948 */ {0x5, 0x0, 0x12}, | ||
193 | /* DIFF not written */ | ||
194 | /* 1951 */ {0x5, 0x02, 0x0f}, | ||
195 | /* DIFF not written */ | ||
196 | /* 1954 */ {0x5, 0x10, 0x46}, | ||
197 | /* DIFF not written */ | ||
198 | /* 1957 */ {0x5, 0x8, 0x4a}, | ||
199 | /* DIFF not written */ | ||
200 | |||
201 | /* 1960 */ {0x3, 0x08, 0x03}, | ||
202 | /* DIFF (0x3,0x28,0x3) */ | ||
203 | /* 1963 */ {0x3, 0x08, 0x01}, | ||
204 | /* 1966 */ {0x3, 0x0c, 0x03}, | ||
205 | /* DIFF not written */ | ||
206 | /* 1969 */ {0x3, 0x21, 0x00}, | ||
207 | /* DIFF (0x39) */ | ||
208 | |||
209 | /* Extra block copied from init to hopefully ensure CCD is in a sane state */ | ||
210 | /* 1837 */ {0x6, 0x10, 0x08}, | ||
211 | /* 1840 */ {0x6, 0x00, 0x09}, | ||
212 | /* 1843 */ {0x6, 0x00, 0x0a}, | ||
213 | /* 1846 */ {0x6, 0x00, 0x0b}, | ||
214 | /* 1849 */ {0x6, 0x10, 0x0c}, | ||
215 | /* 1852 */ {0x6, 0x00, 0x0d}, | ||
216 | /* 1855 */ {0x6, 0x00, 0x0e}, | ||
217 | /* 1858 */ {0x6, 0x00, 0x0f}, | ||
218 | /* 1861 */ {0x6, 0x10, 0x10}, | ||
219 | /* 1864 */ {0x6, 0x02, 0x11}, | ||
220 | /* 1867 */ {0x6, 0x00, 0x12}, | ||
221 | /* 1870 */ {0x6, 0x04, 0x13}, | ||
222 | /* 1873 */ {0x6, 0x02, 0x14}, | ||
223 | /* 1876 */ {0x6, 0x8a, 0x51}, | ||
224 | /* 1879 */ {0x6, 0x40, 0x52}, | ||
225 | /* 1882 */ {0x6, 0xb6, 0x53}, | ||
226 | /* 1885 */ {0x6, 0x3d, 0x54}, | ||
227 | /* End of extra block */ | ||
228 | |||
229 | /* 1972 */ {0x6, 0x3f, 0x1}, | ||
230 | /* Block skipped */ | ||
231 | /* 1975 */ {0x6, 0x10, 0x02}, | ||
232 | /* 1978 */ {0x6, 0x64, 0x07}, | ||
233 | /* 1981 */ {0x6, 0x10, 0x08}, | ||
234 | /* 1984 */ {0x6, 0x00, 0x09}, | ||
235 | /* 1987 */ {0x6, 0x00, 0x0a}, | ||
236 | /* 1990 */ {0x6, 0x00, 0x0b}, | ||
237 | /* 1993 */ {0x6, 0x10, 0x0c}, | ||
238 | /* 1996 */ {0x6, 0x00, 0x0d}, | ||
239 | /* 1999 */ {0x6, 0x00, 0x0e}, | ||
240 | /* 2002 */ {0x6, 0x00, 0x0f}, | ||
241 | /* 2005 */ {0x6, 0x10, 0x10}, | ||
242 | /* 2008 */ {0x6, 0x02, 0x11}, | ||
243 | /* 2011 */ {0x6, 0x00, 0x12}, | ||
244 | /* 2014 */ {0x6, 0x04, 0x13}, | ||
245 | /* 2017 */ {0x6, 0x02, 0x14}, | ||
246 | /* 2020 */ {0x6, 0x8a, 0x51}, | ||
247 | /* 2023 */ {0x6, 0x40, 0x52}, | ||
248 | /* 2026 */ {0x6, 0xb6, 0x53}, | ||
249 | /* 2029 */ {0x6, 0x3d, 0x54}, | ||
250 | /* 2032 */ {0x6, 0x60, 0x57}, | ||
251 | /* 2035 */ {0x6, 0x20, 0x58}, | ||
252 | /* 2038 */ {0x6, 0x15, 0x59}, | ||
253 | /* 2041 */ {0x6, 0x05, 0x5a}, | ||
254 | |||
255 | /* 2044 */ {0x5, 0x01, 0xc0}, | ||
256 | /* 2047 */ {0x5, 0x10, 0xcb}, | ||
257 | /* 2050 */ {0x5, 0x80, 0xc1}, | ||
258 | /* */ | ||
259 | /* 2053 */ {0x5, 0x0, 0xc2}, | ||
260 | /* 4 was 0 */ | ||
261 | /* 2056 */ {0x5, 0x00, 0xca}, | ||
262 | /* 2059 */ {0x5, 0x80, 0xc1}, | ||
263 | /* */ | ||
264 | /* 2062 */ {0x5, 0x04, 0xc2}, | ||
265 | /* 2065 */ {0x5, 0x00, 0xca}, | ||
266 | /* 2068 */ {0x5, 0x0, 0xc1}, | ||
267 | /* */ | ||
268 | /* 2071 */ {0x5, 0x00, 0xc2}, | ||
269 | /* 2074 */ {0x5, 0x00, 0xca}, | ||
270 | /* 2077 */ {0x5, 0x40, 0xc1}, | ||
271 | /* */ | ||
272 | /* 2080 */ {0x5, 0x17, 0xc2}, | ||
273 | /* 2083 */ {0x5, 0x00, 0xca}, | ||
274 | /* 2086 */ {0x5, 0x80, 0xc1}, | ||
275 | /* */ | ||
276 | /* 2089 */ {0x5, 0x06, 0xc2}, | ||
277 | /* 2092 */ {0x5, 0x00, 0xca}, | ||
278 | /* 2095 */ {0x5, 0x80, 0xc1}, | ||
279 | /* */ | ||
280 | /* 2098 */ {0x5, 0x04, 0xc2}, | ||
281 | /* 2101 */ {0x5, 0x00, 0xca}, | ||
282 | |||
283 | /* 2104 */ {0x3, 0x4c, 0x3}, | ||
284 | /* 2107 */ {0x3, 0x18, 0x1}, | ||
285 | |||
286 | /* 2110 */ {0x6, 0x70, 0x51}, | ||
287 | /* 2113 */ {0x6, 0xbe, 0x53}, | ||
288 | /* 2116 */ {0x6, 0x71, 0x57}, | ||
289 | /* 2119 */ {0x6, 0x20, 0x58}, | ||
290 | /* 2122 */ {0x6, 0x05, 0x59}, | ||
291 | /* 2125 */ {0x6, 0x15, 0x5a}, | ||
292 | |||
293 | /* 2128 */ {0x4, 0x00, 0x08}, | ||
294 | /* Compress = OFF (0x1 to turn on) */ | ||
295 | /* 2131 */ {0x4, 0x12, 0x09}, | ||
296 | /* 2134 */ {0x4, 0x21, 0x0a}, | ||
297 | /* 2137 */ {0x4, 0x10, 0x0b}, | ||
298 | /* 2140 */ {0x4, 0x21, 0x0c}, | ||
299 | /* 2143 */ {0x4, 0x05, 0x00}, | ||
300 | /* was 5 (Image Type ? ) */ | ||
301 | /* 2146 */ {0x4, 0x00, 0x01}, | ||
302 | |||
303 | /* 2149 */ {0x6, 0x3f, 0x01}, | ||
304 | |||
305 | /* 2152 */ {0x4, 0x00, 0x04}, | ||
306 | /* 2155 */ {0x4, 0x00, 0x05}, | ||
307 | /* 2158 */ {0x4, 0x40, 0x06}, | ||
308 | /* 2161 */ {0x4, 0x40, 0x07}, | ||
309 | |||
310 | /* 2164 */ {0x6, 0x1c, 0x17}, | ||
311 | /* 2167 */ {0x6, 0xe2, 0x19}, | ||
312 | /* 2170 */ {0x6, 0x1c, 0x1b}, | ||
313 | /* 2173 */ {0x6, 0xe2, 0x1d}, | ||
314 | /* 2176 */ {0x6, 0xaa, 0x1f}, | ||
315 | /* 2179 */ {0x6, 0x70, 0x20}, | ||
316 | |||
317 | /* 2182 */ {0x5, 0x01, 0x10}, | ||
318 | /* 2185 */ {0x5, 0x00, 0x11}, | ||
319 | /* 2188 */ {0x5, 0x01, 0x00}, | ||
320 | /* 2191 */ {0x5, 0x05, 0x01}, | ||
321 | /* 2194 */ {0x5, 0x00, 0xc1}, | ||
322 | /* */ | ||
323 | /* 2197 */ {0x5, 0x00, 0xc2}, | ||
324 | /* 2200 */ {0x5, 0x00, 0xca}, | ||
325 | |||
326 | /* 2203 */ {0x6, 0x70, 0x51}, | ||
327 | /* 2206 */ {0x6, 0xbe, 0x53}, | ||
328 | {} | ||
329 | }; | ||
330 | |||
331 | /* | ||
332 | Made by Tomasz Zablocki (skalamandra@poczta.onet.pl) | ||
333 | * SPCA505b chip based cameras initialization data | ||
334 | * | ||
335 | */ | ||
336 | /* jfm */ | ||
337 | #define initial_brightness 0x7f /* 0x0(white)-0xff(black) */ | ||
338 | /* #define initial_brightness 0x0 //0x0(white)-0xff(black) */ | ||
339 | /* | ||
340 | * Data to initialize a SPCA505. Common to the CCD and external modes | ||
341 | */ | ||
342 | static const __u16 spca505b_init_data[][3] = { | ||
343 | /* start */ | ||
344 | {0x02, 0x00, 0x00}, /* init */ | ||
345 | {0x02, 0x00, 0x01}, | ||
346 | {0x02, 0x00, 0x02}, | ||
347 | {0x02, 0x00, 0x03}, | ||
348 | {0x02, 0x00, 0x04}, | ||
349 | {0x02, 0x00, 0x05}, | ||
350 | {0x02, 0x00, 0x06}, | ||
351 | {0x02, 0x00, 0x07}, | ||
352 | {0x02, 0x00, 0x08}, | ||
353 | {0x02, 0x00, 0x09}, | ||
354 | {0x03, 0x00, 0x00}, | ||
355 | {0x03, 0x00, 0x01}, | ||
356 | {0x03, 0x00, 0x02}, | ||
357 | {0x03, 0x00, 0x03}, | ||
358 | {0x03, 0x00, 0x04}, | ||
359 | {0x03, 0x00, 0x05}, | ||
360 | {0x03, 0x00, 0x06}, | ||
361 | {0x04, 0x00, 0x00}, | ||
362 | {0x04, 0x00, 0x02}, | ||
363 | {0x04, 0x00, 0x04}, | ||
364 | {0x04, 0x00, 0x05}, | ||
365 | {0x04, 0x00, 0x06}, | ||
366 | {0x04, 0x00, 0x07}, | ||
367 | {0x04, 0x00, 0x08}, | ||
368 | {0x04, 0x00, 0x09}, | ||
369 | {0x04, 0x00, 0x0a}, | ||
370 | {0x04, 0x00, 0x0b}, | ||
371 | {0x04, 0x00, 0x0c}, | ||
372 | {0x07, 0x00, 0x00}, | ||
373 | {0x07, 0x00, 0x03}, | ||
374 | {0x08, 0x00, 0x00}, | ||
375 | {0x08, 0x00, 0x01}, | ||
376 | {0x08, 0x00, 0x02}, | ||
377 | {0x00, 0x01, 0x00}, | ||
378 | {0x00, 0x01, 0x01}, | ||
379 | {0x00, 0x01, 0x34}, | ||
380 | {0x00, 0x01, 0x35}, | ||
381 | {0x06, 0x18, 0x08}, | ||
382 | {0x06, 0xfc, 0x09}, | ||
383 | {0x06, 0xfc, 0x0a}, | ||
384 | {0x06, 0xfc, 0x0b}, | ||
385 | {0x06, 0x18, 0x0c}, | ||
386 | {0x06, 0xfc, 0x0d}, | ||
387 | {0x06, 0xfc, 0x0e}, | ||
388 | {0x06, 0xfc, 0x0f}, | ||
389 | {0x06, 0x18, 0x10}, | ||
390 | {0x06, 0xfe, 0x12}, | ||
391 | {0x06, 0x00, 0x11}, | ||
392 | {0x06, 0x00, 0x14}, | ||
393 | {0x06, 0x00, 0x13}, | ||
394 | {0x06, 0x28, 0x51}, | ||
395 | {0x06, 0xff, 0x53}, | ||
396 | {0x02, 0x00, 0x08}, | ||
397 | |||
398 | {0x03, 0x00, 0x03}, | ||
399 | {0x03, 0x10, 0x03}, | ||
400 | {} | ||
401 | }; | ||
402 | |||
403 | /* | ||
404 | * Data to initialize the camera using the internal CCD | ||
405 | */ | ||
406 | static const __u16 spca505b_open_data_ccd[][3] = { | ||
407 | |||
408 | /* {0x02,0x00,0x00}, */ | ||
409 | {0x03, 0x04, 0x01}, /* rst */ | ||
410 | {0x03, 0x00, 0x01}, | ||
411 | {0x03, 0x00, 0x00}, | ||
412 | {0x03, 0x21, 0x00}, | ||
413 | {0x03, 0x00, 0x04}, | ||
414 | {0x03, 0x00, 0x03}, | ||
415 | {0x03, 0x18, 0x03}, | ||
416 | {0x03, 0x08, 0x01}, | ||
417 | {0x03, 0x1c, 0x03}, | ||
418 | {0x03, 0x5c, 0x03}, | ||
419 | {0x03, 0x5c, 0x03}, | ||
420 | {0x03, 0x18, 0x01}, | ||
421 | |||
422 | /* same as 505 */ | ||
423 | {0x04, 0x10, 0x01}, | ||
424 | {0x04, 0x00, 0x04}, | ||
425 | {0x04, 0x00, 0x05}, | ||
426 | {0x04, 0x20, 0x06}, | ||
427 | {0x04, 0x20, 0x07}, | ||
428 | |||
429 | {0x08, 0x0a, 0x00}, | ||
430 | |||
431 | {0x05, 0x00, 0x10}, | ||
432 | {0x05, 0x00, 0x11}, | ||
433 | {0x05, 0x00, 0x12}, | ||
434 | {0x05, 0x6f, 0x00}, | ||
435 | {0x05, initial_brightness >> 6, 0x00}, | ||
436 | {0x05, initial_brightness << 2, 0x01}, | ||
437 | {0x05, 0x00, 0x02}, | ||
438 | {0x05, 0x01, 0x03}, | ||
439 | {0x05, 0x00, 0x04}, | ||
440 | {0x05, 0x03, 0x05}, | ||
441 | {0x05, 0xe0, 0x06}, | ||
442 | {0x05, 0x20, 0x07}, | ||
443 | {0x05, 0xa0, 0x08}, | ||
444 | {0x05, 0x00, 0x12}, | ||
445 | {0x05, 0x02, 0x0f}, | ||
446 | {0x05, 128, 0x14}, /* max exposure off (0=on) */ | ||
447 | {0x05, 0x01, 0xb0}, | ||
448 | {0x05, 0x01, 0xbf}, | ||
449 | {0x03, 0x02, 0x06}, | ||
450 | {0x05, 0x10, 0x46}, | ||
451 | {0x05, 0x08, 0x4a}, | ||
452 | |||
453 | {0x06, 0x00, 0x01}, | ||
454 | {0x06, 0x10, 0x02}, | ||
455 | {0x06, 0x64, 0x07}, | ||
456 | {0x06, 0x18, 0x08}, | ||
457 | {0x06, 0xfc, 0x09}, | ||
458 | {0x06, 0xfc, 0x0a}, | ||
459 | {0x06, 0xfc, 0x0b}, | ||
460 | {0x04, 0x00, 0x01}, | ||
461 | {0x06, 0x18, 0x0c}, | ||
462 | {0x06, 0xfc, 0x0d}, | ||
463 | {0x06, 0xfc, 0x0e}, | ||
464 | {0x06, 0xfc, 0x0f}, | ||
465 | {0x06, 0x11, 0x10}, /* contrast */ | ||
466 | {0x06, 0x00, 0x11}, | ||
467 | {0x06, 0xfe, 0x12}, | ||
468 | {0x06, 0x00, 0x13}, | ||
469 | {0x06, 0x00, 0x14}, | ||
470 | {0x06, 0x9d, 0x51}, | ||
471 | {0x06, 0x40, 0x52}, | ||
472 | {0x06, 0x7c, 0x53}, | ||
473 | {0x06, 0x40, 0x54}, | ||
474 | {0x06, 0x02, 0x57}, | ||
475 | {0x06, 0x03, 0x58}, | ||
476 | {0x06, 0x15, 0x59}, | ||
477 | {0x06, 0x05, 0x5a}, | ||
478 | {0x06, 0x03, 0x56}, | ||
479 | {0x06, 0x02, 0x3f}, | ||
480 | {0x06, 0x00, 0x40}, | ||
481 | {0x06, 0x39, 0x41}, | ||
482 | {0x06, 0x69, 0x42}, | ||
483 | {0x06, 0x87, 0x43}, | ||
484 | {0x06, 0x9e, 0x44}, | ||
485 | {0x06, 0xb1, 0x45}, | ||
486 | {0x06, 0xbf, 0x46}, | ||
487 | {0x06, 0xcc, 0x47}, | ||
488 | {0x06, 0xd5, 0x48}, | ||
489 | {0x06, 0xdd, 0x49}, | ||
490 | {0x06, 0xe3, 0x4a}, | ||
491 | {0x06, 0xe8, 0x4b}, | ||
492 | {0x06, 0xed, 0x4c}, | ||
493 | {0x06, 0xf2, 0x4d}, | ||
494 | {0x06, 0xf7, 0x4e}, | ||
495 | {0x06, 0xfc, 0x4f}, | ||
496 | {0x06, 0xff, 0x50}, | ||
497 | |||
498 | {0x05, 0x01, 0xc0}, | ||
499 | {0x05, 0x10, 0xcb}, | ||
500 | {0x05, 0x40, 0xc1}, | ||
501 | {0x05, 0x04, 0xc2}, | ||
502 | {0x05, 0x00, 0xca}, | ||
503 | {0x05, 0x40, 0xc1}, | ||
504 | {0x05, 0x09, 0xc2}, | ||
505 | {0x05, 0x00, 0xca}, | ||
506 | {0x05, 0xc0, 0xc1}, | ||
507 | {0x05, 0x09, 0xc2}, | ||
508 | {0x05, 0x00, 0xca}, | ||
509 | {0x05, 0x40, 0xc1}, | ||
510 | {0x05, 0x59, 0xc2}, | ||
511 | {0x05, 0x00, 0xca}, | ||
512 | {0x04, 0x00, 0x01}, | ||
513 | {0x05, 0x80, 0xc1}, | ||
514 | {0x05, 0xec, 0xc2}, | ||
515 | {0x05, 0x0, 0xca}, | ||
516 | |||
517 | {0x06, 0x02, 0x57}, | ||
518 | {0x06, 0x01, 0x58}, | ||
519 | {0x06, 0x15, 0x59}, | ||
520 | {0x06, 0x0a, 0x5a}, | ||
521 | {0x06, 0x01, 0x57}, | ||
522 | {0x06, 0x8a, 0x03}, | ||
523 | {0x06, 0x0a, 0x6c}, | ||
524 | {0x06, 0x30, 0x01}, | ||
525 | {0x06, 0x20, 0x02}, | ||
526 | {0x06, 0x00, 0x03}, | ||
527 | |||
528 | {0x05, 0x8c, 0x25}, | ||
529 | |||
530 | {0x06, 0x4d, 0x51}, /* maybe saturation (4d) */ | ||
531 | {0x06, 0x84, 0x53}, /* making green (84) */ | ||
532 | {0x06, 0x00, 0x57}, /* sharpness (1) */ | ||
533 | {0x06, 0x18, 0x08}, | ||
534 | {0x06, 0xfc, 0x09}, | ||
535 | {0x06, 0xfc, 0x0a}, | ||
536 | {0x06, 0xfc, 0x0b}, | ||
537 | {0x06, 0x18, 0x0c}, /* maybe hue (18) */ | ||
538 | {0x06, 0xfc, 0x0d}, | ||
539 | {0x06, 0xfc, 0x0e}, | ||
540 | {0x06, 0xfc, 0x0f}, | ||
541 | {0x06, 0x18, 0x10}, /* maybe contrast (18) */ | ||
542 | |||
543 | {0x05, 0x01, 0x02}, | ||
544 | |||
545 | {0x04, 0x00, 0x08}, /* compression */ | ||
546 | {0x04, 0x12, 0x09}, | ||
547 | {0x04, 0x21, 0x0a}, | ||
548 | {0x04, 0x10, 0x0b}, | ||
549 | {0x04, 0x21, 0x0c}, | ||
550 | {0x04, 0x1d, 0x00}, /* imagetype (1d) */ | ||
551 | {0x04, 0x41, 0x01}, /* hardware snapcontrol */ | ||
552 | |||
553 | {0x04, 0x00, 0x04}, | ||
554 | {0x04, 0x00, 0x05}, | ||
555 | {0x04, 0x10, 0x06}, | ||
556 | {0x04, 0x10, 0x07}, | ||
557 | {0x04, 0x40, 0x06}, | ||
558 | {0x04, 0x40, 0x07}, | ||
559 | {0x04, 0x00, 0x04}, | ||
560 | {0x04, 0x00, 0x05}, | ||
561 | |||
562 | {0x06, 0x1c, 0x17}, | ||
563 | {0x06, 0xe2, 0x19}, | ||
564 | {0x06, 0x1c, 0x1b}, | ||
565 | {0x06, 0xe2, 0x1d}, | ||
566 | {0x06, 0x5f, 0x1f}, | ||
567 | {0x06, 0x32, 0x20}, | ||
568 | |||
569 | {0x05, initial_brightness >> 6, 0x00}, | ||
570 | {0x05, initial_brightness << 2, 0x01}, | ||
571 | {0x05, 0x06, 0xc1}, | ||
572 | {0x05, 0x58, 0xc2}, | ||
573 | {0x05, 0x0, 0xca}, | ||
574 | {0x05, 0x0, 0x11}, | ||
575 | {} | ||
576 | }; | ||
577 | |||
578 | static int reg_write(struct usb_device *dev, | ||
579 | __u16 reg, __u16 index, __u16 value) | ||
580 | { | ||
581 | int ret; | ||
582 | |||
583 | ret = usb_control_msg(dev, | ||
584 | usb_sndctrlpipe(dev, 0), | ||
585 | reg, | ||
586 | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
587 | value, index, NULL, 0, 500); | ||
588 | PDEBUG(D_PACK, "reg write: 0x%02x,0x%02x:0x%02x, 0x%x", | ||
589 | reg, index, value, ret); | ||
590 | if (ret < 0) | ||
591 | PDEBUG(D_ERR, "reg write: error %d", ret); | ||
592 | return ret; | ||
593 | } | ||
594 | |||
595 | /* returns: negative is error, pos or zero is data */ | ||
596 | static int reg_read(struct gspca_dev *gspca_dev, | ||
597 | __u16 reg, /* bRequest */ | ||
598 | __u16 index, /* wIndex */ | ||
599 | __u16 length) /* wLength (1 or 2 only) */ | ||
600 | { | ||
601 | int ret; | ||
602 | |||
603 | gspca_dev->usb_buf[1] = 0; | ||
604 | ret = usb_control_msg(gspca_dev->dev, | ||
605 | usb_rcvctrlpipe(gspca_dev->dev, 0), | ||
606 | reg, | ||
607 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
608 | (__u16) 0, /* value */ | ||
609 | (__u16) index, | ||
610 | gspca_dev->usb_buf, length, | ||
611 | 500); /* timeout */ | ||
612 | if (ret < 0) { | ||
613 | PDEBUG(D_ERR, "reg_read err %d", ret); | ||
614 | return -1; | ||
615 | } | ||
616 | return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; | ||
617 | } | ||
618 | |||
619 | static int write_vector(struct gspca_dev *gspca_dev, | ||
620 | const __u16 data[][3]) | ||
621 | { | ||
622 | struct usb_device *dev = gspca_dev->dev; | ||
623 | int ret, i = 0; | ||
624 | |||
625 | while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { | ||
626 | ret = reg_write(dev, data[i][0], data[i][2], data[i][1]); | ||
627 | if (ret < 0) { | ||
628 | PDEBUG(D_ERR, | ||
629 | "Register write failed for 0x%x,0x%x,0x%x", | ||
630 | data[i][0], data[i][1], data[i][2]); | ||
631 | return ret; | ||
632 | } | ||
633 | i++; | ||
634 | } | ||
635 | return 0; | ||
636 | } | ||
637 | |||
638 | /* this function is called at probe time */ | ||
639 | static int sd_config(struct gspca_dev *gspca_dev, | ||
640 | const struct usb_device_id *id) | ||
641 | { | ||
642 | struct sd *sd = (struct sd *) gspca_dev; | ||
643 | struct cam *cam; | ||
644 | __u16 vendor; | ||
645 | __u16 product; | ||
646 | |||
647 | vendor = id->idVendor; | ||
648 | product = id->idProduct; | ||
649 | switch (vendor) { | ||
650 | case 0x041e: /* Creative cameras */ | ||
651 | /* switch (product) { */ | ||
652 | /* case 0x401d: * here505b */ | ||
653 | sd->subtype = Nxultra; | ||
654 | /* break; */ | ||
655 | /* } */ | ||
656 | break; | ||
657 | case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */ | ||
658 | /* switch (product) { */ | ||
659 | /* case 0x0430: */ | ||
660 | /* fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */ | ||
661 | sd->subtype = IntelPCCameraPro; | ||
662 | /* break; */ | ||
663 | /* } */ | ||
664 | break; | ||
665 | } | ||
666 | |||
667 | cam = &gspca_dev->cam; | ||
668 | cam->dev_name = (char *) id->driver_info; | ||
669 | cam->epaddr = 0x01; | ||
670 | cam->cam_mode = vga_mode; | ||
671 | if (sd->subtype != IntelPCCameraPro) | ||
672 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | ||
673 | else /* no 640x480 for IntelPCCameraPro */ | ||
674 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0] - 1; | ||
675 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
676 | |||
677 | if (sd->subtype == Nxultra) { | ||
678 | if (write_vector(gspca_dev, spca505b_init_data)) | ||
679 | return -EIO; | ||
680 | } else { | ||
681 | if (write_vector(gspca_dev, spca505_init_data)) | ||
682 | return -EIO; | ||
683 | } | ||
684 | return 0; | ||
685 | } | ||
686 | |||
687 | /* this function is called at open time */ | ||
688 | static int sd_open(struct gspca_dev *gspca_dev) | ||
689 | { | ||
690 | struct sd *sd = (struct sd *) gspca_dev; | ||
691 | int ret; | ||
692 | |||
693 | PDEBUG(D_STREAM, "Initializing SPCA505"); | ||
694 | if (sd->subtype == Nxultra) | ||
695 | write_vector(gspca_dev, spca505b_open_data_ccd); | ||
696 | else | ||
697 | write_vector(gspca_dev, spca505_open_data_ccd); | ||
698 | ret = reg_read(gspca_dev, 6, 0x16, 2); | ||
699 | |||
700 | if (ret < 0) { | ||
701 | PDEBUG(D_ERR|D_STREAM, | ||
702 | "register read failed for after vector read err = %d", | ||
703 | ret); | ||
704 | return -EIO; | ||
705 | } | ||
706 | PDEBUG(D_STREAM, | ||
707 | "After vector read returns : 0x%x should be 0x0101", | ||
708 | ret & 0xffff); | ||
709 | |||
710 | ret = reg_write(gspca_dev->dev, 6, 0x16, 0x0a); | ||
711 | if (ret < 0) { | ||
712 | PDEBUG(D_ERR, "register write failed for (6,0xa,0x16) err=%d", | ||
713 | ret); | ||
714 | return -EIO; | ||
715 | } | ||
716 | reg_write(gspca_dev->dev, 5, 0xc2, 18); | ||
717 | return 0; | ||
718 | } | ||
719 | |||
720 | static void sd_start(struct gspca_dev *gspca_dev) | ||
721 | { | ||
722 | struct usb_device *dev = gspca_dev->dev; | ||
723 | int ret; | ||
724 | |||
725 | /* necessary because without it we can see stream | ||
726 | * only once after loading module */ | ||
727 | /* stopping usb registers Tomasz change */ | ||
728 | reg_write(dev, 0x02, 0x0, 0x0); | ||
729 | switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { | ||
730 | case 0: | ||
731 | reg_write(dev, 0x04, 0x00, 0x00); | ||
732 | reg_write(dev, 0x04, 0x06, 0x10); | ||
733 | reg_write(dev, 0x04, 0x07, 0x10); | ||
734 | break; | ||
735 | case 1: | ||
736 | reg_write(dev, 0x04, 0x00, 0x01); | ||
737 | reg_write(dev, 0x04, 0x06, 0x1a); | ||
738 | reg_write(dev, 0x04, 0x07, 0x1a); | ||
739 | break; | ||
740 | case 2: | ||
741 | reg_write(dev, 0x04, 0x00, 0x02); | ||
742 | reg_write(dev, 0x04, 0x06, 0x1c); | ||
743 | reg_write(dev, 0x04, 0x07, 0x1d); | ||
744 | break; | ||
745 | case 4: | ||
746 | reg_write(dev, 0x04, 0x00, 0x04); | ||
747 | reg_write(dev, 0x04, 0x06, 0x34); | ||
748 | reg_write(dev, 0x04, 0x07, 0x34); | ||
749 | break; | ||
750 | default: | ||
751 | /* case 5: */ | ||
752 | reg_write(dev, 0x04, 0x00, 0x05); | ||
753 | reg_write(dev, 0x04, 0x06, 0x40); | ||
754 | reg_write(dev, 0x04, 0x07, 0x40); | ||
755 | break; | ||
756 | } | ||
757 | /* Enable ISO packet machine - should we do this here or in ISOC init ? */ | ||
758 | ret = reg_write(dev, SPCA50X_REG_USB, | ||
759 | SPCA50X_USB_CTRL, | ||
760 | SPCA50X_CUSB_ENABLE); | ||
761 | |||
762 | /* reg_write(dev, 0x5, 0x0, 0x0); */ | ||
763 | /* reg_write(dev, 0x5, 0x0, 0x1); */ | ||
764 | /* reg_write(dev, 0x5, 0x11, 0x2); */ | ||
765 | } | ||
766 | |||
767 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
768 | { | ||
769 | /* Disable ISO packet machine */ | ||
770 | reg_write(gspca_dev->dev, 0x02, 0x00, 0x00); | ||
771 | } | ||
772 | |||
773 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
774 | { | ||
775 | } | ||
776 | |||
777 | /* this function is called at close time */ | ||
778 | static void sd_close(struct gspca_dev *gspca_dev) | ||
779 | { | ||
780 | /* This maybe reset or power control */ | ||
781 | reg_write(gspca_dev->dev, 0x03, 0x03, 0x20); | ||
782 | reg_write(gspca_dev->dev, 0x03, 0x01, 0x0); | ||
783 | reg_write(gspca_dev->dev, 0x03, 0x00, 0x1); | ||
784 | reg_write(gspca_dev->dev, 0x05, 0x10, 0x1); | ||
785 | reg_write(gspca_dev->dev, 0x05, 0x11, 0xf); | ||
786 | } | ||
787 | |||
788 | /* convert YYUV per line to YUYV (YUV 4:2:2) */ | ||
789 | static void yyuv_decode(unsigned char *out, | ||
790 | unsigned char *in, | ||
791 | int width, | ||
792 | int height) | ||
793 | { | ||
794 | unsigned char *Ui, *Vi, *yi, *yi1; | ||
795 | unsigned char *out1; | ||
796 | int i, j; | ||
797 | |||
798 | yi = in; | ||
799 | for (i = height / 2; --i >= 0; ) { | ||
800 | out1 = out + width * 2; /* next line */ | ||
801 | yi1 = yi + width; | ||
802 | Ui = yi1 + width; | ||
803 | Vi = Ui + width / 2; | ||
804 | for (j = width / 2; --j >= 0; ) { | ||
805 | *out++ = 128 + *yi++; | ||
806 | *out++ = 128 + *Ui; | ||
807 | *out++ = 128 + *yi++; | ||
808 | *out++ = 128 + *Vi; | ||
809 | |||
810 | *out1++ = 128 + *yi1++; | ||
811 | *out1++ = 128 + *Ui++; | ||
812 | *out1++ = 128 + *yi1++; | ||
813 | *out1++ = 128 + *Vi++; | ||
814 | } | ||
815 | yi += width * 2; | ||
816 | out = out1; | ||
817 | } | ||
818 | } | ||
819 | |||
820 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
821 | struct gspca_frame *frame, /* target */ | ||
822 | __u8 *data, /* isoc packet */ | ||
823 | int len) /* iso packet length */ | ||
824 | { | ||
825 | struct sd *sd = (struct sd *) gspca_dev; | ||
826 | |||
827 | switch (data[0]) { | ||
828 | case 0: /* start of frame */ | ||
829 | if (gspca_dev->last_packet_type == FIRST_PACKET) { | ||
830 | yyuv_decode(sd->tmpbuf2, sd->tmpbuf, | ||
831 | gspca_dev->width, | ||
832 | gspca_dev->height); | ||
833 | frame = gspca_frame_add(gspca_dev, | ||
834 | LAST_PACKET, | ||
835 | frame, | ||
836 | sd->tmpbuf2, | ||
837 | gspca_dev->width | ||
838 | * gspca_dev->height | ||
839 | * 2); | ||
840 | } | ||
841 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | ||
842 | data, 0); | ||
843 | data += SPCA50X_OFFSET_DATA; | ||
844 | len -= SPCA50X_OFFSET_DATA; | ||
845 | if (len > 0) | ||
846 | memcpy(sd->tmpbuf, data, len); | ||
847 | else | ||
848 | len = 0; | ||
849 | sd->buflen = len; | ||
850 | return; | ||
851 | case 0xff: /* drop */ | ||
852 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
853 | return; | ||
854 | } | ||
855 | data += 1; | ||
856 | len -= 1; | ||
857 | memcpy(&sd->tmpbuf[sd->buflen], data, len); | ||
858 | sd->buflen += len; | ||
859 | } | ||
860 | |||
861 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
862 | { | ||
863 | struct sd *sd = (struct sd *) gspca_dev; | ||
864 | |||
865 | __u8 brightness = sd->brightness; | ||
866 | reg_write(gspca_dev->dev, 5, 0x00, (255 - brightness) >> 6); | ||
867 | reg_write(gspca_dev->dev, 5, 0x01, (255 - brightness) << 2); | ||
868 | |||
869 | } | ||
870 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
871 | { | ||
872 | struct sd *sd = (struct sd *) gspca_dev; | ||
873 | |||
874 | sd->brightness = 255 | ||
875 | - ((reg_read(gspca_dev, 5, 0x01, 1) >> 2) | ||
876 | + (reg_read(gspca_dev, 5, 0x0, 1) << 6)); | ||
877 | } | ||
878 | |||
879 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
880 | { | ||
881 | struct sd *sd = (struct sd *) gspca_dev; | ||
882 | |||
883 | sd->brightness = val; | ||
884 | if (gspca_dev->streaming) | ||
885 | setbrightness(gspca_dev); | ||
886 | return 0; | ||
887 | } | ||
888 | |||
889 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
890 | { | ||
891 | struct sd *sd = (struct sd *) gspca_dev; | ||
892 | |||
893 | getbrightness(gspca_dev); | ||
894 | *val = sd->brightness; | ||
895 | return 0; | ||
896 | } | ||
897 | |||
898 | /* sub-driver description */ | ||
899 | static const struct sd_desc sd_desc = { | ||
900 | .name = MODULE_NAME, | ||
901 | .ctrls = sd_ctrls, | ||
902 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
903 | .config = sd_config, | ||
904 | .open = sd_open, | ||
905 | .start = sd_start, | ||
906 | .stopN = sd_stopN, | ||
907 | .stop0 = sd_stop0, | ||
908 | .close = sd_close, | ||
909 | .pkt_scan = sd_pkt_scan, | ||
910 | }; | ||
911 | |||
912 | /* -- module initialisation -- */ | ||
913 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
914 | static const __devinitdata struct usb_device_id device_table[] = { | ||
915 | {USB_DEVICE(0x041e, 0x401d), DVNM("Creative Webcam NX ULTRA")}, | ||
916 | {USB_DEVICE(0x0733, 0x0430), DVNM("Intel PC Camera Pro")}, | ||
917 | {} | ||
918 | }; | ||
919 | MODULE_DEVICE_TABLE(usb, device_table); | ||
920 | |||
921 | /* -- device connect -- */ | ||
922 | static int sd_probe(struct usb_interface *intf, | ||
923 | const struct usb_device_id *id) | ||
924 | { | ||
925 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
926 | THIS_MODULE); | ||
927 | } | ||
928 | |||
929 | static struct usb_driver sd_driver = { | ||
930 | .name = MODULE_NAME, | ||
931 | .id_table = device_table, | ||
932 | .probe = sd_probe, | ||
933 | .disconnect = gspca_disconnect, | ||
934 | }; | ||
935 | |||
936 | /* -- module insert / remove -- */ | ||
937 | static int __init sd_mod_init(void) | ||
938 | { | ||
939 | if (usb_register(&sd_driver) < 0) | ||
940 | return -1; | ||
941 | PDEBUG(D_PROBE, "v%s registered", version); | ||
942 | return 0; | ||
943 | } | ||
944 | static void __exit sd_mod_exit(void) | ||
945 | { | ||
946 | usb_deregister(&sd_driver); | ||
947 | PDEBUG(D_PROBE, "deregistered"); | ||
948 | } | ||
949 | |||
950 | module_init(sd_mod_init); | ||
951 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c new file mode 100644 index 000000000000..143203c1fd9f --- /dev/null +++ b/drivers/media/video/gspca/spca506.c | |||
@@ -0,0 +1,847 @@ | |||
1 | /* | ||
2 | * SPCA506 chip based cameras function | ||
3 | * M Xhaard 15/04/2004 based on different work Mark Taylor and others | ||
4 | * and my own snoopy file on a pv-321c donate by a german compagny | ||
5 | * "Firma Frank Gmbh" from Saarbruecken | ||
6 | * | ||
7 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #define MODULE_NAME "spca506" | ||
25 | |||
26 | #include "gspca.h" | ||
27 | |||
28 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) | ||
29 | static const char version[] = "2.1.7"; | ||
30 | |||
31 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
32 | MODULE_DESCRIPTION("GSPCA/SPCA506 USB Camera Driver"); | ||
33 | MODULE_LICENSE("GPL"); | ||
34 | |||
35 | /* specific webcam descriptor */ | ||
36 | struct sd { | ||
37 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
38 | |||
39 | int buflen; | ||
40 | __u8 tmpbuf[640 * 480 * 3]; /* YYUV per line */ | ||
41 | __u8 tmpbuf2[640 * 480 * 2]; /* YUYV */ | ||
42 | |||
43 | unsigned char brightness; | ||
44 | unsigned char contrast; | ||
45 | unsigned char colors; | ||
46 | unsigned char hue; | ||
47 | char norme; | ||
48 | char channel; | ||
49 | }; | ||
50 | |||
51 | /* V4L2 controls supported by the driver */ | ||
52 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
53 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
54 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
55 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
56 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
57 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
58 | static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val); | ||
59 | static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val); | ||
60 | |||
61 | static struct ctrl sd_ctrls[] = { | ||
62 | #define SD_BRIGHTNESS 0 | ||
63 | { | ||
64 | { | ||
65 | .id = V4L2_CID_BRIGHTNESS, | ||
66 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
67 | .name = "Brightness", | ||
68 | .minimum = 0, | ||
69 | .maximum = 0xff, | ||
70 | .step = 1, | ||
71 | .default_value = 0x80, | ||
72 | }, | ||
73 | .set = sd_setbrightness, | ||
74 | .get = sd_getbrightness, | ||
75 | }, | ||
76 | #define SD_CONTRAST 1 | ||
77 | { | ||
78 | { | ||
79 | .id = V4L2_CID_CONTRAST, | ||
80 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
81 | .name = "Contrast", | ||
82 | .minimum = 0, | ||
83 | .maximum = 0xff, | ||
84 | .step = 1, | ||
85 | .default_value = 0x47, | ||
86 | }, | ||
87 | .set = sd_setcontrast, | ||
88 | .get = sd_getcontrast, | ||
89 | }, | ||
90 | #define SD_COLOR 2 | ||
91 | { | ||
92 | { | ||
93 | .id = V4L2_CID_SATURATION, | ||
94 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
95 | .name = "Saturation", | ||
96 | .minimum = 0, | ||
97 | .maximum = 0xff, | ||
98 | .step = 1, | ||
99 | .default_value = 0x40, | ||
100 | }, | ||
101 | .set = sd_setcolors, | ||
102 | .get = sd_getcolors, | ||
103 | }, | ||
104 | #define SD_HUE 3 | ||
105 | { | ||
106 | { | ||
107 | .id = V4L2_CID_HUE, | ||
108 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
109 | .name = "Hue", | ||
110 | .minimum = 0, | ||
111 | .maximum = 0xff, | ||
112 | .step = 1, | ||
113 | .default_value = 0, | ||
114 | }, | ||
115 | .set = sd_sethue, | ||
116 | .get = sd_gethue, | ||
117 | }, | ||
118 | }; | ||
119 | |||
120 | static struct v4l2_pix_format vga_mode[] = { | ||
121 | {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | ||
122 | .bytesperline = 160 * 2, | ||
123 | .sizeimage = 160 * 120 * 2, | ||
124 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
125 | .priv = 5}, | ||
126 | {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | ||
127 | .bytesperline = 176 * 2, | ||
128 | .sizeimage = 176 * 144 * 2, | ||
129 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
130 | .priv = 4}, | ||
131 | {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | ||
132 | .bytesperline = 320 * 2, | ||
133 | .sizeimage = 320 * 240 * 2, | ||
134 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
135 | .priv = 2}, | ||
136 | {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | ||
137 | .bytesperline = 352 * 2, | ||
138 | .sizeimage = 352 * 288 * 2, | ||
139 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
140 | .priv = 1}, | ||
141 | {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | ||
142 | .bytesperline = 640 * 2, | ||
143 | .sizeimage = 640 * 480 * 2, | ||
144 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
145 | .priv = 0}, | ||
146 | }; | ||
147 | |||
148 | #define SPCA50X_OFFSET_DATA 10 | ||
149 | |||
150 | #define SAA7113_bright 0x0a /* defaults 0x80 */ | ||
151 | #define SAA7113_contrast 0x0b /* defaults 0x47 */ | ||
152 | #define SAA7113_saturation 0x0c /* defaults 0x40 */ | ||
153 | #define SAA7113_hue 0x0d /* defaults 0x00 */ | ||
154 | #define SAA7113_I2C_BASE_WRITE 0x4a | ||
155 | |||
156 | /* read 'len' bytes to gspca_dev->usb_buf */ | ||
157 | static void reg_r(struct gspca_dev *gspca_dev, | ||
158 | __u16 req, | ||
159 | __u16 index, | ||
160 | __u16 length) | ||
161 | { | ||
162 | usb_control_msg(gspca_dev->dev, | ||
163 | usb_rcvctrlpipe(gspca_dev->dev, 0), | ||
164 | req, | ||
165 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
166 | 0, /* value */ | ||
167 | index, gspca_dev->usb_buf, length, | ||
168 | 500); | ||
169 | } | ||
170 | |||
171 | static void reg_w(struct usb_device *dev, | ||
172 | __u16 req, | ||
173 | __u16 value, | ||
174 | __u16 index) | ||
175 | { | ||
176 | usb_control_msg(dev, | ||
177 | usb_sndctrlpipe(dev, 0), | ||
178 | req, | ||
179 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
180 | value, index, | ||
181 | NULL, 0, 500); | ||
182 | } | ||
183 | |||
184 | static void spca506_Initi2c(struct gspca_dev *gspca_dev) | ||
185 | { | ||
186 | reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004); | ||
187 | } | ||
188 | |||
189 | static void spca506_WriteI2c(struct gspca_dev *gspca_dev, __u16 valeur, | ||
190 | __u16 reg) | ||
191 | { | ||
192 | int retry = 60; | ||
193 | |||
194 | reg_w(gspca_dev->dev, 0x07, reg, 0x0001); | ||
195 | reg_w(gspca_dev->dev, 0x07, valeur, 0x0000); | ||
196 | while (retry--) { | ||
197 | reg_r(gspca_dev, 0x07, 0x0003, 2); | ||
198 | if ((gspca_dev->usb_buf[0] | gspca_dev->usb_buf[1]) == 0x00) | ||
199 | break; | ||
200 | } | ||
201 | } | ||
202 | |||
203 | static int spca506_ReadI2c(struct gspca_dev *gspca_dev, __u16 reg) | ||
204 | { | ||
205 | int retry = 60; | ||
206 | |||
207 | reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004); | ||
208 | reg_w(gspca_dev->dev, 0x07, reg, 0x0001); | ||
209 | reg_w(gspca_dev->dev, 0x07, 0x01, 0x0002); | ||
210 | while (--retry) { | ||
211 | reg_r(gspca_dev, 0x07, 0x0003, 2); | ||
212 | if ((gspca_dev->usb_buf[0] | gspca_dev->usb_buf[1]) == 0x00) | ||
213 | break; | ||
214 | } | ||
215 | if (retry == 0) | ||
216 | return -1; | ||
217 | reg_r(gspca_dev, 0x07, 0x0000, 1); | ||
218 | return gspca_dev->usb_buf[0]; | ||
219 | } | ||
220 | |||
221 | static void spca506_SetNormeInput(struct gspca_dev *gspca_dev, | ||
222 | __u16 norme, | ||
223 | __u16 channel) | ||
224 | { | ||
225 | struct sd *sd = (struct sd *) gspca_dev; | ||
226 | /* fixme: check if channel == 0..3 and 6..9 (8 values) */ | ||
227 | __u8 setbit0 = 0x00; | ||
228 | __u8 setbit1 = 0x00; | ||
229 | __u8 videomask = 0x00; | ||
230 | |||
231 | PDEBUG(D_STREAM, "** Open Set Norme **"); | ||
232 | spca506_Initi2c(gspca_dev); | ||
233 | /* NTSC bit0 -> 1(525 l) PAL SECAM bit0 -> 0 (625 l) */ | ||
234 | /* Composite channel bit1 -> 1 S-video bit 1 -> 0 */ | ||
235 | /* and exclude SAA7113 reserved channel set default 0 otherwise */ | ||
236 | if (norme & V4L2_STD_NTSC) | ||
237 | setbit0 = 0x01; | ||
238 | if (channel == 4 || channel == 5 || channel > 9) | ||
239 | channel = 0; | ||
240 | if (channel < 4) | ||
241 | setbit1 = 0x02; | ||
242 | videomask = (0x48 | setbit0 | setbit1); | ||
243 | reg_w(gspca_dev->dev, 0x08, videomask, 0x0000); | ||
244 | spca506_WriteI2c(gspca_dev, (0xc0 | (channel & 0x0F)), 0x02); | ||
245 | |||
246 | if (norme & V4L2_STD_NTSC) | ||
247 | spca506_WriteI2c(gspca_dev, 0x33, 0x0e); | ||
248 | /* Chrominance Control NTSC N */ | ||
249 | else if (norme & V4L2_STD_SECAM) | ||
250 | spca506_WriteI2c(gspca_dev, 0x53, 0x0e); | ||
251 | /* Chrominance Control SECAM */ | ||
252 | else | ||
253 | spca506_WriteI2c(gspca_dev, 0x03, 0x0e); | ||
254 | /* Chrominance Control PAL BGHIV */ | ||
255 | |||
256 | sd->norme = norme; | ||
257 | sd->channel = channel; | ||
258 | PDEBUG(D_STREAM, "Set Video Byte to 0x%2x", videomask); | ||
259 | PDEBUG(D_STREAM, "Set Norme: %08x Channel %d", norme, channel); | ||
260 | } | ||
261 | |||
262 | static void spca506_GetNormeInput(struct gspca_dev *gspca_dev, | ||
263 | __u16 *norme, __u16 *channel) | ||
264 | { | ||
265 | struct sd *sd = (struct sd *) gspca_dev; | ||
266 | |||
267 | /* Read the register is not so good value change so | ||
268 | we use your own copy in spca50x struct */ | ||
269 | *norme = sd->norme; | ||
270 | *channel = sd->channel; | ||
271 | PDEBUG(D_STREAM, "Get Norme: %d Channel %d", *norme, *channel); | ||
272 | } | ||
273 | |||
274 | static void spca506_Setsize(struct gspca_dev *gspca_dev, __u16 code, | ||
275 | __u16 xmult, __u16 ymult) | ||
276 | { | ||
277 | struct usb_device *dev = gspca_dev->dev; | ||
278 | |||
279 | PDEBUG(D_STREAM, "** SetSize **"); | ||
280 | reg_w(dev, 0x04, (0x18 | (code & 0x07)), 0x0000); | ||
281 | /* Soft snap 0x40 Hard 0x41 */ | ||
282 | reg_w(dev, 0x04, 0x41, 0x0001); | ||
283 | reg_w(dev, 0x04, 0x00, 0x0002); | ||
284 | /* reserved */ | ||
285 | reg_w(dev, 0x04, 0x00, 0x0003); | ||
286 | |||
287 | /* reserved */ | ||
288 | reg_w(dev, 0x04, 0x00, 0x0004); | ||
289 | /* reserved */ | ||
290 | reg_w(dev, 0x04, 0x01, 0x0005); | ||
291 | /* reserced */ | ||
292 | reg_w(dev, 0x04, xmult, 0x0006); | ||
293 | /* reserved */ | ||
294 | reg_w(dev, 0x04, ymult, 0x0007); | ||
295 | /* compression 1 */ | ||
296 | reg_w(dev, 0x04, 0x00, 0x0008); | ||
297 | /* T=64 -> 2 */ | ||
298 | reg_w(dev, 0x04, 0x00, 0x0009); | ||
299 | /* threshold2D */ | ||
300 | reg_w(dev, 0x04, 0x21, 0x000a); | ||
301 | /* quantization */ | ||
302 | reg_w(dev, 0x04, 0x00, 0x000b); | ||
303 | } | ||
304 | |||
305 | /* this function is called at probe time */ | ||
306 | static int sd_config(struct gspca_dev *gspca_dev, | ||
307 | const struct usb_device_id *id) | ||
308 | { | ||
309 | struct sd *sd = (struct sd *) gspca_dev; | ||
310 | struct cam *cam; | ||
311 | |||
312 | cam = &gspca_dev->cam; | ||
313 | cam->dev_name = (char *) id->driver_info; | ||
314 | cam->epaddr = 0x01; | ||
315 | cam->cam_mode = vga_mode; | ||
316 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | ||
317 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
318 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | ||
319 | sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; | ||
320 | sd->hue = sd_ctrls[SD_HUE].qctrl.default_value; | ||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | /* this function is called at open time */ | ||
325 | static int sd_open(struct gspca_dev *gspca_dev) | ||
326 | { | ||
327 | struct usb_device *dev = gspca_dev->dev; | ||
328 | |||
329 | reg_w(dev, 0x03, 0x00, 0x0004); | ||
330 | reg_w(dev, 0x03, 0xFF, 0x0003); | ||
331 | reg_w(dev, 0x03, 0x00, 0x0000); | ||
332 | reg_w(dev, 0x03, 0x1c, 0x0001); | ||
333 | reg_w(dev, 0x03, 0x18, 0x0001); | ||
334 | /* Init on PAL and composite input0 */ | ||
335 | spca506_SetNormeInput(gspca_dev, 0, 0); | ||
336 | reg_w(dev, 0x03, 0x1c, 0x0001); | ||
337 | reg_w(dev, 0x03, 0x18, 0x0001); | ||
338 | reg_w(dev, 0x05, 0x00, 0x0000); | ||
339 | reg_w(dev, 0x05, 0xef, 0x0001); | ||
340 | reg_w(dev, 0x05, 0x00, 0x00c1); | ||
341 | reg_w(dev, 0x05, 0x00, 0x00c2); | ||
342 | reg_w(dev, 0x06, 0x18, 0x0002); | ||
343 | reg_w(dev, 0x06, 0xf5, 0x0011); | ||
344 | reg_w(dev, 0x06, 0x02, 0x0012); | ||
345 | reg_w(dev, 0x06, 0xfb, 0x0013); | ||
346 | reg_w(dev, 0x06, 0x00, 0x0014); | ||
347 | reg_w(dev, 0x06, 0xa4, 0x0051); | ||
348 | reg_w(dev, 0x06, 0x40, 0x0052); | ||
349 | reg_w(dev, 0x06, 0x71, 0x0053); | ||
350 | reg_w(dev, 0x06, 0x40, 0x0054); | ||
351 | /************************************************/ | ||
352 | reg_w(dev, 0x03, 0x00, 0x0004); | ||
353 | reg_w(dev, 0x03, 0x00, 0x0003); | ||
354 | reg_w(dev, 0x03, 0x00, 0x0004); | ||
355 | reg_w(dev, 0x03, 0xFF, 0x0003); | ||
356 | reg_w(dev, 0x02, 0x00, 0x0000); | ||
357 | reg_w(dev, 0x03, 0x60, 0x0000); | ||
358 | reg_w(dev, 0x03, 0x18, 0x0001); | ||
359 | /* for a better reading mx :) */ | ||
360 | /*sdca506_WriteI2c(value,register) */ | ||
361 | spca506_Initi2c(gspca_dev); | ||
362 | spca506_WriteI2c(gspca_dev, 0x08, 0x01); | ||
363 | spca506_WriteI2c(gspca_dev, 0xc0, 0x02); | ||
364 | /* input composite video */ | ||
365 | spca506_WriteI2c(gspca_dev, 0x33, 0x03); | ||
366 | spca506_WriteI2c(gspca_dev, 0x00, 0x04); | ||
367 | spca506_WriteI2c(gspca_dev, 0x00, 0x05); | ||
368 | spca506_WriteI2c(gspca_dev, 0x0d, 0x06); | ||
369 | spca506_WriteI2c(gspca_dev, 0xf0, 0x07); | ||
370 | spca506_WriteI2c(gspca_dev, 0x98, 0x08); | ||
371 | spca506_WriteI2c(gspca_dev, 0x03, 0x09); | ||
372 | spca506_WriteI2c(gspca_dev, 0x80, 0x0a); | ||
373 | spca506_WriteI2c(gspca_dev, 0x47, 0x0b); | ||
374 | spca506_WriteI2c(gspca_dev, 0x48, 0x0c); | ||
375 | spca506_WriteI2c(gspca_dev, 0x00, 0x0d); | ||
376 | spca506_WriteI2c(gspca_dev, 0x03, 0x0e); /* Chroma Pal adjust */ | ||
377 | spca506_WriteI2c(gspca_dev, 0x2a, 0x0f); | ||
378 | spca506_WriteI2c(gspca_dev, 0x00, 0x10); | ||
379 | spca506_WriteI2c(gspca_dev, 0x0c, 0x11); | ||
380 | spca506_WriteI2c(gspca_dev, 0xb8, 0x12); | ||
381 | spca506_WriteI2c(gspca_dev, 0x01, 0x13); | ||
382 | spca506_WriteI2c(gspca_dev, 0x00, 0x14); | ||
383 | spca506_WriteI2c(gspca_dev, 0x00, 0x15); | ||
384 | spca506_WriteI2c(gspca_dev, 0x00, 0x16); | ||
385 | spca506_WriteI2c(gspca_dev, 0x00, 0x17); | ||
386 | spca506_WriteI2c(gspca_dev, 0x00, 0x18); | ||
387 | spca506_WriteI2c(gspca_dev, 0x00, 0x19); | ||
388 | spca506_WriteI2c(gspca_dev, 0x00, 0x1a); | ||
389 | spca506_WriteI2c(gspca_dev, 0x00, 0x1b); | ||
390 | spca506_WriteI2c(gspca_dev, 0x00, 0x1c); | ||
391 | spca506_WriteI2c(gspca_dev, 0x00, 0x1d); | ||
392 | spca506_WriteI2c(gspca_dev, 0x00, 0x1e); | ||
393 | spca506_WriteI2c(gspca_dev, 0xa1, 0x1f); | ||
394 | spca506_WriteI2c(gspca_dev, 0x02, 0x40); | ||
395 | spca506_WriteI2c(gspca_dev, 0xff, 0x41); | ||
396 | spca506_WriteI2c(gspca_dev, 0xff, 0x42); | ||
397 | spca506_WriteI2c(gspca_dev, 0xff, 0x43); | ||
398 | spca506_WriteI2c(gspca_dev, 0xff, 0x44); | ||
399 | spca506_WriteI2c(gspca_dev, 0xff, 0x45); | ||
400 | spca506_WriteI2c(gspca_dev, 0xff, 0x46); | ||
401 | spca506_WriteI2c(gspca_dev, 0xff, 0x47); | ||
402 | spca506_WriteI2c(gspca_dev, 0xff, 0x48); | ||
403 | spca506_WriteI2c(gspca_dev, 0xff, 0x49); | ||
404 | spca506_WriteI2c(gspca_dev, 0xff, 0x4a); | ||
405 | spca506_WriteI2c(gspca_dev, 0xff, 0x4b); | ||
406 | spca506_WriteI2c(gspca_dev, 0xff, 0x4c); | ||
407 | spca506_WriteI2c(gspca_dev, 0xff, 0x4d); | ||
408 | spca506_WriteI2c(gspca_dev, 0xff, 0x4e); | ||
409 | spca506_WriteI2c(gspca_dev, 0xff, 0x4f); | ||
410 | spca506_WriteI2c(gspca_dev, 0xff, 0x50); | ||
411 | spca506_WriteI2c(gspca_dev, 0xff, 0x51); | ||
412 | spca506_WriteI2c(gspca_dev, 0xff, 0x52); | ||
413 | spca506_WriteI2c(gspca_dev, 0xff, 0x53); | ||
414 | spca506_WriteI2c(gspca_dev, 0xff, 0x54); | ||
415 | spca506_WriteI2c(gspca_dev, 0xff, 0x55); | ||
416 | spca506_WriteI2c(gspca_dev, 0xff, 0x56); | ||
417 | spca506_WriteI2c(gspca_dev, 0xff, 0x57); | ||
418 | spca506_WriteI2c(gspca_dev, 0x00, 0x58); | ||
419 | spca506_WriteI2c(gspca_dev, 0x54, 0x59); | ||
420 | spca506_WriteI2c(gspca_dev, 0x07, 0x5a); | ||
421 | spca506_WriteI2c(gspca_dev, 0x83, 0x5b); | ||
422 | spca506_WriteI2c(gspca_dev, 0x00, 0x5c); | ||
423 | spca506_WriteI2c(gspca_dev, 0x00, 0x5d); | ||
424 | spca506_WriteI2c(gspca_dev, 0x00, 0x5e); | ||
425 | spca506_WriteI2c(gspca_dev, 0x00, 0x5f); | ||
426 | spca506_WriteI2c(gspca_dev, 0x00, 0x60); | ||
427 | spca506_WriteI2c(gspca_dev, 0x05, 0x61); | ||
428 | spca506_WriteI2c(gspca_dev, 0x9f, 0x62); | ||
429 | PDEBUG(D_STREAM, "** Close Init *"); | ||
430 | return 0; | ||
431 | } | ||
432 | |||
433 | static void sd_start(struct gspca_dev *gspca_dev) | ||
434 | { | ||
435 | struct usb_device *dev = gspca_dev->dev; | ||
436 | __u16 norme; | ||
437 | __u16 channel; | ||
438 | |||
439 | /**************************************/ | ||
440 | reg_w(dev, 0x03, 0x00, 0x0004); | ||
441 | reg_w(dev, 0x03, 0x00, 0x0003); | ||
442 | reg_w(dev, 0x03, 0x00, 0x0004); | ||
443 | reg_w(dev, 0x03, 0xFF, 0x0003); | ||
444 | reg_w(dev, 0x02, 0x00, 0x0000); | ||
445 | reg_w(dev, 0x03, 0x60, 0x0000); | ||
446 | reg_w(dev, 0x03, 0x18, 0x0001); | ||
447 | |||
448 | /*sdca506_WriteI2c(value,register) */ | ||
449 | spca506_Initi2c(gspca_dev); | ||
450 | spca506_WriteI2c(gspca_dev, 0x08, 0x01); /* Increment Delay */ | ||
451 | /* spca506_WriteI2c(gspca_dev, 0xc0, 0x02); * Analog Input Control 1 */ | ||
452 | spca506_WriteI2c(gspca_dev, 0x33, 0x03); | ||
453 | /* Analog Input Control 2 */ | ||
454 | spca506_WriteI2c(gspca_dev, 0x00, 0x04); | ||
455 | /* Analog Input Control 3 */ | ||
456 | spca506_WriteI2c(gspca_dev, 0x00, 0x05); | ||
457 | /* Analog Input Control 4 */ | ||
458 | spca506_WriteI2c(gspca_dev, 0x0d, 0x06); | ||
459 | /* Horizontal Sync Start 0xe9-0x0d */ | ||
460 | spca506_WriteI2c(gspca_dev, 0xf0, 0x07); | ||
461 | /* Horizontal Sync Stop 0x0d-0xf0 */ | ||
462 | |||
463 | spca506_WriteI2c(gspca_dev, 0x98, 0x08); /* Sync Control */ | ||
464 | /* Defaults value */ | ||
465 | spca506_WriteI2c(gspca_dev, 0x03, 0x09); /* Luminance Control */ | ||
466 | spca506_WriteI2c(gspca_dev, 0x80, 0x0a); | ||
467 | /* Luminance Brightness */ | ||
468 | spca506_WriteI2c(gspca_dev, 0x47, 0x0b); /* Luminance Contrast */ | ||
469 | spca506_WriteI2c(gspca_dev, 0x48, 0x0c); | ||
470 | /* Chrominance Saturation */ | ||
471 | spca506_WriteI2c(gspca_dev, 0x00, 0x0d); | ||
472 | /* Chrominance Hue Control */ | ||
473 | spca506_WriteI2c(gspca_dev, 0x2a, 0x0f); | ||
474 | /* Chrominance Gain Control */ | ||
475 | /**************************************/ | ||
476 | spca506_WriteI2c(gspca_dev, 0x00, 0x10); | ||
477 | /* Format/Delay Control */ | ||
478 | spca506_WriteI2c(gspca_dev, 0x0c, 0x11); /* Output Control 1 */ | ||
479 | spca506_WriteI2c(gspca_dev, 0xb8, 0x12); /* Output Control 2 */ | ||
480 | spca506_WriteI2c(gspca_dev, 0x01, 0x13); /* Output Control 3 */ | ||
481 | spca506_WriteI2c(gspca_dev, 0x00, 0x14); /* reserved */ | ||
482 | spca506_WriteI2c(gspca_dev, 0x00, 0x15); /* VGATE START */ | ||
483 | spca506_WriteI2c(gspca_dev, 0x00, 0x16); /* VGATE STOP */ | ||
484 | spca506_WriteI2c(gspca_dev, 0x00, 0x17); /* VGATE Control (MSB) */ | ||
485 | spca506_WriteI2c(gspca_dev, 0x00, 0x18); | ||
486 | spca506_WriteI2c(gspca_dev, 0x00, 0x19); | ||
487 | spca506_WriteI2c(gspca_dev, 0x00, 0x1a); | ||
488 | spca506_WriteI2c(gspca_dev, 0x00, 0x1b); | ||
489 | spca506_WriteI2c(gspca_dev, 0x00, 0x1c); | ||
490 | spca506_WriteI2c(gspca_dev, 0x00, 0x1d); | ||
491 | spca506_WriteI2c(gspca_dev, 0x00, 0x1e); | ||
492 | spca506_WriteI2c(gspca_dev, 0xa1, 0x1f); | ||
493 | spca506_WriteI2c(gspca_dev, 0x02, 0x40); | ||
494 | spca506_WriteI2c(gspca_dev, 0xff, 0x41); | ||
495 | spca506_WriteI2c(gspca_dev, 0xff, 0x42); | ||
496 | spca506_WriteI2c(gspca_dev, 0xff, 0x43); | ||
497 | spca506_WriteI2c(gspca_dev, 0xff, 0x44); | ||
498 | spca506_WriteI2c(gspca_dev, 0xff, 0x45); | ||
499 | spca506_WriteI2c(gspca_dev, 0xff, 0x46); | ||
500 | spca506_WriteI2c(gspca_dev, 0xff, 0x47); | ||
501 | spca506_WriteI2c(gspca_dev, 0xff, 0x48); | ||
502 | spca506_WriteI2c(gspca_dev, 0xff, 0x49); | ||
503 | spca506_WriteI2c(gspca_dev, 0xff, 0x4a); | ||
504 | spca506_WriteI2c(gspca_dev, 0xff, 0x4b); | ||
505 | spca506_WriteI2c(gspca_dev, 0xff, 0x4c); | ||
506 | spca506_WriteI2c(gspca_dev, 0xff, 0x4d); | ||
507 | spca506_WriteI2c(gspca_dev, 0xff, 0x4e); | ||
508 | spca506_WriteI2c(gspca_dev, 0xff, 0x4f); | ||
509 | spca506_WriteI2c(gspca_dev, 0xff, 0x50); | ||
510 | spca506_WriteI2c(gspca_dev, 0xff, 0x51); | ||
511 | spca506_WriteI2c(gspca_dev, 0xff, 0x52); | ||
512 | spca506_WriteI2c(gspca_dev, 0xff, 0x53); | ||
513 | spca506_WriteI2c(gspca_dev, 0xff, 0x54); | ||
514 | spca506_WriteI2c(gspca_dev, 0xff, 0x55); | ||
515 | spca506_WriteI2c(gspca_dev, 0xff, 0x56); | ||
516 | spca506_WriteI2c(gspca_dev, 0xff, 0x57); | ||
517 | spca506_WriteI2c(gspca_dev, 0x00, 0x58); | ||
518 | spca506_WriteI2c(gspca_dev, 0x54, 0x59); | ||
519 | spca506_WriteI2c(gspca_dev, 0x07, 0x5a); | ||
520 | spca506_WriteI2c(gspca_dev, 0x83, 0x5b); | ||
521 | spca506_WriteI2c(gspca_dev, 0x00, 0x5c); | ||
522 | spca506_WriteI2c(gspca_dev, 0x00, 0x5d); | ||
523 | spca506_WriteI2c(gspca_dev, 0x00, 0x5e); | ||
524 | spca506_WriteI2c(gspca_dev, 0x00, 0x5f); | ||
525 | spca506_WriteI2c(gspca_dev, 0x00, 0x60); | ||
526 | spca506_WriteI2c(gspca_dev, 0x05, 0x61); | ||
527 | spca506_WriteI2c(gspca_dev, 0x9f, 0x62); | ||
528 | /**************************************/ | ||
529 | reg_w(dev, 0x05, 0x00, 0x0003); | ||
530 | reg_w(dev, 0x05, 0x00, 0x0004); | ||
531 | reg_w(dev, 0x03, 0x10, 0x0001); | ||
532 | reg_w(dev, 0x03, 0x78, 0x0000); | ||
533 | switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { | ||
534 | case 0: | ||
535 | spca506_Setsize(gspca_dev, 0, 0x10, 0x10); | ||
536 | break; | ||
537 | case 1: | ||
538 | spca506_Setsize(gspca_dev, 1, 0x1a, 0x1a); | ||
539 | break; | ||
540 | case 2: | ||
541 | spca506_Setsize(gspca_dev, 2, 0x1c, 0x1c); | ||
542 | break; | ||
543 | case 4: | ||
544 | spca506_Setsize(gspca_dev, 4, 0x34, 0x34); | ||
545 | break; | ||
546 | default: | ||
547 | /* case 5: */ | ||
548 | spca506_Setsize(gspca_dev, 5, 0x40, 0x40); | ||
549 | break; | ||
550 | } | ||
551 | |||
552 | /* compress setting and size */ | ||
553 | /* set i2c luma */ | ||
554 | reg_w(dev, 0x02, 0x01, 0x0000); | ||
555 | reg_w(dev, 0x03, 0x12, 0x0000); | ||
556 | reg_r(gspca_dev, 0x04, 0x0001, 2); | ||
557 | PDEBUG(D_STREAM, "webcam started"); | ||
558 | spca506_GetNormeInput(gspca_dev, &norme, &channel); | ||
559 | spca506_SetNormeInput(gspca_dev, norme, channel); | ||
560 | } | ||
561 | |||
562 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
563 | { | ||
564 | struct usb_device *dev = gspca_dev->dev; | ||
565 | |||
566 | reg_w(dev, 0x02, 0x00, 0x0000); | ||
567 | reg_w(dev, 0x03, 0x00, 0x0004); | ||
568 | reg_w(dev, 0x03, 0x00, 0x0003); | ||
569 | } | ||
570 | |||
571 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
572 | { | ||
573 | } | ||
574 | |||
575 | static void sd_close(struct gspca_dev *gspca_dev) | ||
576 | { | ||
577 | } | ||
578 | |||
579 | /* convert YYUV per line to YUYV (YUV 4:2:2) */ | ||
580 | static void yyuv_decode(unsigned char *out, | ||
581 | unsigned char *in, | ||
582 | int width, | ||
583 | int height) | ||
584 | { | ||
585 | unsigned char *Ui, *Vi, *yi, *yi1; | ||
586 | unsigned char *out1; | ||
587 | int i, j; | ||
588 | |||
589 | yi = in; | ||
590 | for (i = height / 2; --i >= 0; ) { | ||
591 | out1 = out + width * 2; /* next line */ | ||
592 | yi1 = yi + width; | ||
593 | Ui = yi1 + width; | ||
594 | Vi = Ui + width / 2; | ||
595 | for (j = width / 2; --j >= 0; ) { | ||
596 | *out++ = 128 + *yi++; | ||
597 | *out++ = 128 + *Ui; | ||
598 | *out++ = 128 + *yi++; | ||
599 | *out++ = 128 + *Vi; | ||
600 | |||
601 | *out1++ = 128 + *yi1++; | ||
602 | *out1++ = 128 + *Ui++; | ||
603 | *out1++ = 128 + *yi1++; | ||
604 | *out1++ = 128 + *Vi++; | ||
605 | } | ||
606 | yi += width * 2; | ||
607 | out = out1; | ||
608 | } | ||
609 | } | ||
610 | |||
611 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
612 | struct gspca_frame *frame, /* target */ | ||
613 | __u8 *data, /* isoc packet */ | ||
614 | int len) /* iso packet length */ | ||
615 | { | ||
616 | struct sd *sd = (struct sd *) gspca_dev; | ||
617 | |||
618 | switch (data[0]) { | ||
619 | case 0: /* start of frame */ | ||
620 | if (gspca_dev->last_packet_type == FIRST_PACKET) { | ||
621 | yyuv_decode(sd->tmpbuf2, sd->tmpbuf, | ||
622 | gspca_dev->width, | ||
623 | gspca_dev->height); | ||
624 | frame = gspca_frame_add(gspca_dev, | ||
625 | LAST_PACKET, | ||
626 | frame, | ||
627 | sd->tmpbuf2, | ||
628 | gspca_dev->width | ||
629 | * gspca_dev->height | ||
630 | * 2); | ||
631 | } | ||
632 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | ||
633 | data, 0); | ||
634 | data += SPCA50X_OFFSET_DATA; | ||
635 | len -= SPCA50X_OFFSET_DATA; | ||
636 | if (len > 0) | ||
637 | memcpy(sd->tmpbuf, data, len); | ||
638 | else | ||
639 | len = 0; | ||
640 | sd->buflen = len; | ||
641 | return; | ||
642 | case 0xff: /* drop */ | ||
643 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
644 | return; | ||
645 | } | ||
646 | data += 1; | ||
647 | len -= 1; | ||
648 | memcpy(&sd->tmpbuf[sd->buflen], data, len); | ||
649 | sd->buflen += len; | ||
650 | } | ||
651 | |||
652 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
653 | { | ||
654 | struct sd *sd = (struct sd *) gspca_dev; | ||
655 | |||
656 | spca506_Initi2c(gspca_dev); | ||
657 | spca506_WriteI2c(gspca_dev, sd->brightness, SAA7113_bright); | ||
658 | spca506_WriteI2c(gspca_dev, 0x01, 0x09); | ||
659 | } | ||
660 | |||
661 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
662 | { | ||
663 | struct sd *sd = (struct sd *) gspca_dev; | ||
664 | |||
665 | sd->brightness = spca506_ReadI2c(gspca_dev, SAA7113_bright); | ||
666 | } | ||
667 | |||
668 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
669 | { | ||
670 | struct sd *sd = (struct sd *) gspca_dev; | ||
671 | |||
672 | spca506_Initi2c(gspca_dev); | ||
673 | spca506_WriteI2c(gspca_dev, sd->contrast, SAA7113_contrast); | ||
674 | spca506_WriteI2c(gspca_dev, 0x01, 0x09); | ||
675 | } | ||
676 | |||
677 | static void getcontrast(struct gspca_dev *gspca_dev) | ||
678 | { | ||
679 | struct sd *sd = (struct sd *) gspca_dev; | ||
680 | |||
681 | sd->contrast = spca506_ReadI2c(gspca_dev, SAA7113_contrast); | ||
682 | } | ||
683 | |||
684 | static void setcolors(struct gspca_dev *gspca_dev) | ||
685 | { | ||
686 | struct sd *sd = (struct sd *) gspca_dev; | ||
687 | |||
688 | spca506_Initi2c(gspca_dev); | ||
689 | spca506_WriteI2c(gspca_dev, sd->colors, SAA7113_saturation); | ||
690 | spca506_WriteI2c(gspca_dev, 0x01, 0x09); | ||
691 | } | ||
692 | |||
693 | static void getcolors(struct gspca_dev *gspca_dev) | ||
694 | { | ||
695 | struct sd *sd = (struct sd *) gspca_dev; | ||
696 | |||
697 | sd->colors = spca506_ReadI2c(gspca_dev, SAA7113_saturation); | ||
698 | } | ||
699 | |||
700 | static void sethue(struct gspca_dev *gspca_dev) | ||
701 | { | ||
702 | struct sd *sd = (struct sd *) gspca_dev; | ||
703 | |||
704 | spca506_Initi2c(gspca_dev); | ||
705 | spca506_WriteI2c(gspca_dev, sd->hue, SAA7113_hue); | ||
706 | spca506_WriteI2c(gspca_dev, 0x01, 0x09); | ||
707 | } | ||
708 | |||
709 | static void gethue(struct gspca_dev *gspca_dev) | ||
710 | { | ||
711 | struct sd *sd = (struct sd *) gspca_dev; | ||
712 | |||
713 | sd->hue = spca506_ReadI2c(gspca_dev, SAA7113_hue); | ||
714 | } | ||
715 | |||
716 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
717 | { | ||
718 | struct sd *sd = (struct sd *) gspca_dev; | ||
719 | |||
720 | sd->brightness = val; | ||
721 | if (gspca_dev->streaming) | ||
722 | setbrightness(gspca_dev); | ||
723 | return 0; | ||
724 | } | ||
725 | |||
726 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
727 | { | ||
728 | struct sd *sd = (struct sd *) gspca_dev; | ||
729 | |||
730 | getbrightness(gspca_dev); | ||
731 | *val = sd->brightness; | ||
732 | return 0; | ||
733 | } | ||
734 | |||
735 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
736 | { | ||
737 | struct sd *sd = (struct sd *) gspca_dev; | ||
738 | |||
739 | sd->contrast = val; | ||
740 | if (gspca_dev->streaming) | ||
741 | setcontrast(gspca_dev); | ||
742 | return 0; | ||
743 | } | ||
744 | |||
745 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
746 | { | ||
747 | struct sd *sd = (struct sd *) gspca_dev; | ||
748 | |||
749 | getcontrast(gspca_dev); | ||
750 | *val = sd->contrast; | ||
751 | return 0; | ||
752 | } | ||
753 | |||
754 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
755 | { | ||
756 | struct sd *sd = (struct sd *) gspca_dev; | ||
757 | |||
758 | sd->colors = val; | ||
759 | if (gspca_dev->streaming) | ||
760 | setcolors(gspca_dev); | ||
761 | return 0; | ||
762 | } | ||
763 | |||
764 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
765 | { | ||
766 | struct sd *sd = (struct sd *) gspca_dev; | ||
767 | |||
768 | getcolors(gspca_dev); | ||
769 | *val = sd->colors; | ||
770 | return 0; | ||
771 | } | ||
772 | |||
773 | static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val) | ||
774 | { | ||
775 | struct sd *sd = (struct sd *) gspca_dev; | ||
776 | |||
777 | sd->hue = val; | ||
778 | if (gspca_dev->streaming) | ||
779 | sethue(gspca_dev); | ||
780 | return 0; | ||
781 | } | ||
782 | |||
783 | static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val) | ||
784 | { | ||
785 | struct sd *sd = (struct sd *) gspca_dev; | ||
786 | |||
787 | gethue(gspca_dev); | ||
788 | *val = sd->hue; | ||
789 | return 0; | ||
790 | } | ||
791 | |||
792 | /* sub-driver description */ | ||
793 | static struct sd_desc sd_desc = { | ||
794 | .name = MODULE_NAME, | ||
795 | .ctrls = sd_ctrls, | ||
796 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
797 | .config = sd_config, | ||
798 | .open = sd_open, | ||
799 | .start = sd_start, | ||
800 | .stopN = sd_stopN, | ||
801 | .stop0 = sd_stop0, | ||
802 | .close = sd_close, | ||
803 | .pkt_scan = sd_pkt_scan, | ||
804 | }; | ||
805 | |||
806 | /* -- module initialisation -- */ | ||
807 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
808 | static __devinitdata struct usb_device_id device_table[] = { | ||
809 | {USB_DEVICE(0x06e1, 0xa190), DVNM("ADS Instant VCD")}, | ||
810 | /* {USB_DEVICE(0x0733, 0x0430), DVNM("UsbGrabber PV321c")}, */ | ||
811 | {USB_DEVICE(0x0734, 0x043b), DVNM("3DeMon USB Capture aka")}, | ||
812 | {USB_DEVICE(0x99fa, 0x8988), DVNM("Grandtec V.cap")}, | ||
813 | {} | ||
814 | }; | ||
815 | MODULE_DEVICE_TABLE(usb, device_table); | ||
816 | |||
817 | /* -- device connect -- */ | ||
818 | static int sd_probe(struct usb_interface *intf, | ||
819 | const struct usb_device_id *id) | ||
820 | { | ||
821 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
822 | THIS_MODULE); | ||
823 | } | ||
824 | |||
825 | static struct usb_driver sd_driver = { | ||
826 | .name = MODULE_NAME, | ||
827 | .id_table = device_table, | ||
828 | .probe = sd_probe, | ||
829 | .disconnect = gspca_disconnect, | ||
830 | }; | ||
831 | |||
832 | /* -- module insert / remove -- */ | ||
833 | static int __init sd_mod_init(void) | ||
834 | { | ||
835 | if (usb_register(&sd_driver) < 0) | ||
836 | return -1; | ||
837 | PDEBUG(D_PROBE, "v%s registered", version); | ||
838 | return 0; | ||
839 | } | ||
840 | static void __exit sd_mod_exit(void) | ||
841 | { | ||
842 | usb_deregister(&sd_driver); | ||
843 | PDEBUG(D_PROBE, "deregistered"); | ||
844 | } | ||
845 | |||
846 | module_init(sd_mod_init); | ||
847 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c new file mode 100644 index 000000000000..d8cd93866a4a --- /dev/null +++ b/drivers/media/video/gspca/spca508.c | |||
@@ -0,0 +1,1791 @@ | |||
1 | /* | ||
2 | * SPCA508 chip based cameras subdriver | ||
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 "spca508" | ||
22 | |||
23 | #include "gspca.h" | ||
24 | |||
25 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) | ||
26 | static const char version[] = "2.1.7"; | ||
27 | |||
28 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
29 | MODULE_DESCRIPTION("GSPCA/SPCA508 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 | int buflen; | ||
37 | unsigned char tmpbuf[352 * 288 * 3 / 2]; /* YUVY per line */ | ||
38 | unsigned char tmpbuf2[352 * 288 * 2]; /* YUYV */ | ||
39 | |||
40 | unsigned char brightness; | ||
41 | |||
42 | char subtype; | ||
43 | #define CreativeVista 0 | ||
44 | #define HamaUSBSightcam 1 | ||
45 | #define HamaUSBSightcam2 2 | ||
46 | #define IntelEasyPCCamera 3 | ||
47 | #define MicroInnovationIC200 4 | ||
48 | #define ViewQuestVQ110 5 | ||
49 | }; | ||
50 | |||
51 | /* V4L2 controls supported by the driver */ | ||
52 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
53 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
54 | |||
55 | static struct ctrl sd_ctrls[] = { | ||
56 | { | ||
57 | { | ||
58 | .id = V4L2_CID_BRIGHTNESS, | ||
59 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
60 | .name = "Brightness", | ||
61 | .minimum = 0, | ||
62 | .maximum = 255, | ||
63 | .step = 1, | ||
64 | #define BRIGHTNESS_DEF 128 | ||
65 | .default_value = BRIGHTNESS_DEF, | ||
66 | }, | ||
67 | .set = sd_setbrightness, | ||
68 | .get = sd_getbrightness, | ||
69 | }, | ||
70 | }; | ||
71 | |||
72 | static struct v4l2_pix_format sif_mode[] = { | ||
73 | {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | ||
74 | .bytesperline = 160 * 2, | ||
75 | .sizeimage = 160 * 120 * 2, | ||
76 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
77 | .priv = 3}, | ||
78 | {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | ||
79 | .bytesperline = 176 * 2, | ||
80 | .sizeimage = 176 * 144 * 2, | ||
81 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
82 | .priv = 2}, | ||
83 | {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | ||
84 | .bytesperline = 320 * 2, | ||
85 | .sizeimage = 320 * 240 * 2, | ||
86 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
87 | .priv = 1}, | ||
88 | {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | ||
89 | .bytesperline = 352 * 2, | ||
90 | .sizeimage = 352 * 288 * 2, | ||
91 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
92 | .priv = 0}, | ||
93 | }; | ||
94 | |||
95 | /* Frame packet header offsets for the spca508 */ | ||
96 | #define SPCA508_OFFSET_TYPE 1 | ||
97 | #define SPCA508_OFFSET_COMPRESS 2 | ||
98 | #define SPCA508_OFFSET_FRAMSEQ 8 | ||
99 | #define SPCA508_OFFSET_WIN1LUM 11 | ||
100 | #define SPCA508_OFFSET_DATA 37 | ||
101 | |||
102 | #define SPCA508_SNAPBIT 0x20 | ||
103 | #define SPCA508_SNAPCTRL 0x40 | ||
104 | /*************** I2c ****************/ | ||
105 | #define SPCA508_INDEX_I2C_BASE 0x8800 | ||
106 | |||
107 | /* | ||
108 | * Initialization data: this is the first set-up data written to the | ||
109 | * device (before the open data). | ||
110 | */ | ||
111 | static const __u16 spca508_init_data[][3] = | ||
112 | #define IGN(x) /* nothing */ | ||
113 | { | ||
114 | /* line URB value, index */ | ||
115 | /* 44274 1804 */ {0x0000, 0x870b}, | ||
116 | |||
117 | /* 44299 1805 */ {0x0020, 0x8112}, | ||
118 | /* Video drop enable, ISO streaming disable */ | ||
119 | /* 44324 1806 */ {0x0003, 0x8111}, | ||
120 | /* Reset compression & memory */ | ||
121 | /* 44349 1807 */ {0x0000, 0x8110}, | ||
122 | /* Disable all outputs */ | ||
123 | /* 44372 1808 */ /* READ {0x0000, 0x8114} -> 0000: 00 */ | ||
124 | /* 44398 1809 */ {0x0000, 0x8114}, | ||
125 | /* SW GPIO data */ | ||
126 | /* 44423 1810 */ {0x0008, 0x8110}, | ||
127 | /* Enable charge pump output */ | ||
128 | /* 44527 1811 */ {0x0002, 0x8116}, | ||
129 | /* 200 kHz pump clock */ | ||
130 | /* 44555 1812 */ | ||
131 | /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE:) */ | ||
132 | /* 44590 1813 */ {0x0003, 0x8111}, | ||
133 | /* Reset compression & memory */ | ||
134 | /* 44615 1814 */ {0x0000, 0x8111}, | ||
135 | /* Normal mode (not reset) */ | ||
136 | /* 44640 1815 */ {0x0098, 0x8110}, | ||
137 | /* Enable charge pump output, sync.serial,external 2x clock */ | ||
138 | /* 44665 1816 */ {0x000d, 0x8114}, | ||
139 | /* SW GPIO data */ | ||
140 | /* 44690 1817 */ {0x0002, 0x8116}, | ||
141 | /* 200 kHz pump clock */ | ||
142 | /* 44715 1818 */ {0x0020, 0x8112}, | ||
143 | /* Video drop enable, ISO streaming disable */ | ||
144 | /* --------------------------------------- */ | ||
145 | /* 44740 1819 */ {0x000f, 0x8402}, | ||
146 | /* memory bank */ | ||
147 | /* 44765 1820 */ {0x0000, 0x8403}, | ||
148 | /* ... address */ | ||
149 | /* --------------------------------------- */ | ||
150 | /* 0x88__ is Synchronous Serial Interface. */ | ||
151 | /* TBD: This table could be expressed more compactly */ | ||
152 | /* using spca508_write_i2c_vector(). */ | ||
153 | /* TBD: Should see if the values in spca50x_i2c_data */ | ||
154 | /* would work with the VQ110 instead of the values */ | ||
155 | /* below. */ | ||
156 | /* 44790 1821 */ {0x00c0, 0x8804}, | ||
157 | /* SSI slave addr */ | ||
158 | /* 44815 1822 */ {0x0008, 0x8802}, | ||
159 | /* 375 Khz SSI clock */ | ||
160 | /* 44838 1823 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
161 | /* 44862 1824 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
162 | /* 44888 1825 */ {0x0008, 0x8802}, | ||
163 | /* 375 Khz SSI clock */ | ||
164 | /* 44913 1826 */ {0x0012, 0x8801}, | ||
165 | /* SSI reg addr */ | ||
166 | /* 44938 1827 */ {0x0080, 0x8800}, | ||
167 | /* SSI data to write */ | ||
168 | /* 44961 1828 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
169 | /* 44985 1829 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
170 | /* 45009 1830 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
171 | /* 45035 1831 */ {0x0008, 0x8802}, | ||
172 | /* 375 Khz SSI clock */ | ||
173 | /* 45060 1832 */ {0x0012, 0x8801}, | ||
174 | /* SSI reg addr */ | ||
175 | /* 45085 1833 */ {0x0000, 0x8800}, | ||
176 | /* SSI data to write */ | ||
177 | /* 45108 1834 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
178 | /* 45132 1835 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
179 | /* 45156 1836 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
180 | /* 45182 1837 */ {0x0008, 0x8802}, | ||
181 | /* 375 Khz SSI clock */ | ||
182 | /* 45207 1838 */ {0x0011, 0x8801}, | ||
183 | /* SSI reg addr */ | ||
184 | /* 45232 1839 */ {0x0040, 0x8800}, | ||
185 | /* SSI data to write */ | ||
186 | /* 45255 1840 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
187 | /* 45279 1841 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
188 | /* 45303 1842 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
189 | /* 45329 1843 */ {0x0008, 0x8802}, | ||
190 | /* 45354 1844 */ {0x0013, 0x8801}, | ||
191 | /* 45379 1845 */ {0x0000, 0x8800}, | ||
192 | /* 45402 1846 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
193 | /* 45426 1847 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
194 | /* 45450 1848 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
195 | /* 45476 1849 */ {0x0008, 0x8802}, | ||
196 | /* 45501 1850 */ {0x0014, 0x8801}, | ||
197 | /* 45526 1851 */ {0x0000, 0x8800}, | ||
198 | /* 45549 1852 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
199 | /* 45573 1853 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
200 | /* 45597 1854 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
201 | /* 45623 1855 */ {0x0008, 0x8802}, | ||
202 | /* 45648 1856 */ {0x0015, 0x8801}, | ||
203 | /* 45673 1857 */ {0x0001, 0x8800}, | ||
204 | /* 45696 1858 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
205 | /* 45720 1859 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
206 | /* 45744 1860 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
207 | /* 45770 1861 */ {0x0008, 0x8802}, | ||
208 | /* 45795 1862 */ {0x0016, 0x8801}, | ||
209 | /* 45820 1863 */ {0x0003, 0x8800}, | ||
210 | /* 45843 1864 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
211 | /* 45867 1865 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
212 | /* 45891 1866 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
213 | /* 45917 1867 */ {0x0008, 0x8802}, | ||
214 | /* 45942 1868 */ {0x0017, 0x8801}, | ||
215 | /* 45967 1869 */ {0x0036, 0x8800}, | ||
216 | /* 45990 1870 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
217 | /* 46014 1871 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
218 | /* 46038 1872 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
219 | /* 46064 1873 */ {0x0008, 0x8802}, | ||
220 | /* 46089 1874 */ {0x0018, 0x8801}, | ||
221 | /* 46114 1875 */ {0x00ec, 0x8800}, | ||
222 | /* 46137 1876 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
223 | /* 46161 1877 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
224 | /* 46185 1878 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
225 | /* 46211 1879 */ {0x0008, 0x8802}, | ||
226 | /* 46236 1880 */ {0x001a, 0x8801}, | ||
227 | /* 46261 1881 */ {0x0094, 0x8800}, | ||
228 | /* 46284 1882 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
229 | /* 46308 1883 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
230 | /* 46332 1884 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
231 | /* 46358 1885 */ {0x0008, 0x8802}, | ||
232 | /* 46383 1886 */ {0x001b, 0x8801}, | ||
233 | /* 46408 1887 */ {0x0000, 0x8800}, | ||
234 | /* 46431 1888 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
235 | /* 46455 1889 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
236 | /* 46479 1890 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
237 | /* 46505 1891 */ {0x0008, 0x8802}, | ||
238 | /* 46530 1892 */ {0x0027, 0x8801}, | ||
239 | /* 46555 1893 */ {0x00a2, 0x8800}, | ||
240 | /* 46578 1894 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
241 | /* 46602 1895 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
242 | /* 46626 1896 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
243 | /* 46652 1897 */ {0x0008, 0x8802}, | ||
244 | /* 46677 1898 */ {0x0028, 0x8801}, | ||
245 | /* 46702 1899 */ {0x0040, 0x8800}, | ||
246 | /* 46725 1900 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
247 | /* 46749 1901 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
248 | /* 46773 1902 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
249 | /* 46799 1903 */ {0x0008, 0x8802}, | ||
250 | /* 46824 1904 */ {0x002a, 0x8801}, | ||
251 | /* 46849 1905 */ {0x0084, 0x8800}, | ||
252 | /* 46872 1906 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
253 | /* 46896 1907 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
254 | /* 46920 1908 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
255 | /* 46946 1909 */ {0x0008, 0x8802}, | ||
256 | /* 46971 1910 */ {0x002b, 0x8801}, | ||
257 | /* 46996 1911 */ {0x00a8, 0x8800}, | ||
258 | /* 47019 1912 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
259 | /* 47043 1913 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
260 | /* 47067 1914 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
261 | /* 47093 1915 */ {0x0008, 0x8802}, | ||
262 | /* 47118 1916 */ {0x002c, 0x8801}, | ||
263 | /* 47143 1917 */ {0x00fe, 0x8800}, | ||
264 | /* 47166 1918 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
265 | /* 47190 1919 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
266 | /* 47214 1920 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
267 | /* 47240 1921 */ {0x0008, 0x8802}, | ||
268 | /* 47265 1922 */ {0x002d, 0x8801}, | ||
269 | /* 47290 1923 */ {0x0003, 0x8800}, | ||
270 | /* 47313 1924 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
271 | /* 47337 1925 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
272 | /* 47361 1926 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
273 | /* 47387 1927 */ {0x0008, 0x8802}, | ||
274 | /* 47412 1928 */ {0x0038, 0x8801}, | ||
275 | /* 47437 1929 */ {0x0083, 0x8800}, | ||
276 | /* 47460 1930 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
277 | /* 47484 1931 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
278 | /* 47508 1932 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
279 | /* 47534 1933 */ {0x0008, 0x8802}, | ||
280 | /* 47559 1934 */ {0x0033, 0x8801}, | ||
281 | /* 47584 1935 */ {0x0081, 0x8800}, | ||
282 | /* 47607 1936 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
283 | /* 47631 1937 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
284 | /* 47655 1938 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
285 | /* 47681 1939 */ {0x0008, 0x8802}, | ||
286 | /* 47706 1940 */ {0x0034, 0x8801}, | ||
287 | /* 47731 1941 */ {0x004a, 0x8800}, | ||
288 | /* 47754 1942 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
289 | /* 47778 1943 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
290 | /* 47802 1944 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
291 | /* 47828 1945 */ {0x0008, 0x8802}, | ||
292 | /* 47853 1946 */ {0x0039, 0x8801}, | ||
293 | /* 47878 1947 */ {0x0000, 0x8800}, | ||
294 | /* 47901 1948 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
295 | /* 47925 1949 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
296 | /* 47949 1950 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
297 | /* 47975 1951 */ {0x0008, 0x8802}, | ||
298 | /* 48000 1952 */ {0x0010, 0x8801}, | ||
299 | /* 48025 1953 */ {0x00a8, 0x8800}, | ||
300 | /* 48048 1954 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
301 | /* 48072 1955 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
302 | /* 48096 1956 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
303 | /* 48122 1957 */ {0x0008, 0x8802}, | ||
304 | /* 48147 1958 */ {0x0006, 0x8801}, | ||
305 | /* 48172 1959 */ {0x0058, 0x8800}, | ||
306 | /* 48195 1960 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
307 | /* 48219 1961 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
308 | /* 48243 1962 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
309 | /* 48269 1963 */ {0x0008, 0x8802}, | ||
310 | /* 48294 1964 */ {0x0000, 0x8801}, | ||
311 | /* 48319 1965 */ {0x0004, 0x8800}, | ||
312 | /* 48342 1966 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
313 | /* 48366 1967 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
314 | /* 48390 1968 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
315 | /* 48416 1969 */ {0x0008, 0x8802}, | ||
316 | /* 48441 1970 */ {0x0040, 0x8801}, | ||
317 | /* 48466 1971 */ {0x0080, 0x8800}, | ||
318 | /* 48489 1972 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
319 | /* 48513 1973 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
320 | /* 48537 1974 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
321 | /* 48563 1975 */ {0x0008, 0x8802}, | ||
322 | /* 48588 1976 */ {0x0041, 0x8801}, | ||
323 | /* 48613 1977 */ {0x000c, 0x8800}, | ||
324 | /* 48636 1978 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
325 | /* 48660 1979 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
326 | /* 48684 1980 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
327 | /* 48710 1981 */ {0x0008, 0x8802}, | ||
328 | /* 48735 1982 */ {0x0042, 0x8801}, | ||
329 | /* 48760 1983 */ {0x000c, 0x8800}, | ||
330 | /* 48783 1984 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
331 | /* 48807 1985 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
332 | /* 48831 1986 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
333 | /* 48857 1987 */ {0x0008, 0x8802}, | ||
334 | /* 48882 1988 */ {0x0043, 0x8801}, | ||
335 | /* 48907 1989 */ {0x0028, 0x8800}, | ||
336 | /* 48930 1990 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
337 | /* 48954 1991 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
338 | /* 48978 1992 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
339 | /* 49004 1993 */ {0x0008, 0x8802}, | ||
340 | /* 49029 1994 */ {0x0044, 0x8801}, | ||
341 | /* 49054 1995 */ {0x0080, 0x8800}, | ||
342 | /* 49077 1996 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
343 | /* 49101 1997 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
344 | /* 49125 1998 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
345 | /* 49151 1999 */ {0x0008, 0x8802}, | ||
346 | /* 49176 2000 */ {0x0045, 0x8801}, | ||
347 | /* 49201 2001 */ {0x0020, 0x8800}, | ||
348 | /* 49224 2002 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
349 | /* 49248 2003 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
350 | /* 49272 2004 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
351 | /* 49298 2005 */ {0x0008, 0x8802}, | ||
352 | /* 49323 2006 */ {0x0046, 0x8801}, | ||
353 | /* 49348 2007 */ {0x0020, 0x8800}, | ||
354 | /* 49371 2008 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
355 | /* 49395 2009 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
356 | /* 49419 2010 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
357 | /* 49445 2011 */ {0x0008, 0x8802}, | ||
358 | /* 49470 2012 */ {0x0047, 0x8801}, | ||
359 | /* 49495 2013 */ {0x0080, 0x8800}, | ||
360 | /* 49518 2014 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
361 | /* 49542 2015 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
362 | /* 49566 2016 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
363 | /* 49592 2017 */ {0x0008, 0x8802}, | ||
364 | /* 49617 2018 */ {0x0048, 0x8801}, | ||
365 | /* 49642 2019 */ {0x004c, 0x8800}, | ||
366 | /* 49665 2020 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
367 | /* 49689 2021 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
368 | /* 49713 2022 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
369 | /* 49739 2023 */ {0x0008, 0x8802}, | ||
370 | /* 49764 2024 */ {0x0049, 0x8801}, | ||
371 | /* 49789 2025 */ {0x0084, 0x8800}, | ||
372 | /* 49812 2026 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
373 | /* 49836 2027 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
374 | /* 49860 2028 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
375 | /* 49886 2029 */ {0x0008, 0x8802}, | ||
376 | /* 49911 2030 */ {0x004a, 0x8801}, | ||
377 | /* 49936 2031 */ {0x0084, 0x8800}, | ||
378 | /* 49959 2032 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
379 | /* 49983 2033 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
380 | /* 50007 2034 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
381 | /* 50033 2035 */ {0x0008, 0x8802}, | ||
382 | /* 50058 2036 */ {0x004b, 0x8801}, | ||
383 | /* 50083 2037 */ {0x0084, 0x8800}, | ||
384 | /* 50106 2038 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
385 | /* --------------------------------------- */ | ||
386 | /* 50132 2039 */ {0x0012, 0x8700}, | ||
387 | /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ | ||
388 | /* 50157 2040 */ {0x0000, 0x8701}, | ||
389 | /* CKx1 clock delay adj */ | ||
390 | /* 50182 2041 */ {0x0000, 0x8701}, | ||
391 | /* CKx1 clock delay adj */ | ||
392 | /* 50207 2042 */ {0x0001, 0x870c}, | ||
393 | /* CKOx2 output */ | ||
394 | /* --------------------------------------- */ | ||
395 | /* 50232 2043 */ {0x0080, 0x8600}, | ||
396 | /* Line memory read counter (L) */ | ||
397 | /* 50257 2044 */ {0x0001, 0x8606}, | ||
398 | /* reserved */ | ||
399 | /* 50282 2045 */ {0x0064, 0x8607}, | ||
400 | /* Line memory read counter (H) 0x6480=25,728 */ | ||
401 | /* 50307 2046 */ {0x002a, 0x8601}, | ||
402 | /* CDSP sharp interpolation mode, | ||
403 | * line sel for color sep, edge enhance enab */ | ||
404 | /* 50332 2047 */ {0x0000, 0x8602}, | ||
405 | /* optical black level for user settng = 0 */ | ||
406 | /* 50357 2048 */ {0x0080, 0x8600}, | ||
407 | /* Line memory read counter (L) */ | ||
408 | /* 50382 2049 */ {0x000a, 0x8603}, | ||
409 | /* optical black level calc mode: auto; optical black offset = 10 */ | ||
410 | /* 50407 2050 */ {0x00df, 0x865b}, | ||
411 | /* Horiz offset for valid pixels (L)=0xdf */ | ||
412 | /* 50432 2051 */ {0x0012, 0x865c}, | ||
413 | /* Vert offset for valid lines (L)=0x12 */ | ||
414 | |||
415 | /* The following two lines seem to be the "wrong" resolution. */ | ||
416 | /* But perhaps these indicate the actual size of the sensor */ | ||
417 | /* rather than the size of the current video mode. */ | ||
418 | /* 50457 2052 */ {0x0058, 0x865d}, | ||
419 | /* Horiz valid pixels (*4) (L) = 352 */ | ||
420 | /* 50482 2053 */ {0x0048, 0x865e}, | ||
421 | /* Vert valid lines (*4) (L) = 288 */ | ||
422 | |||
423 | /* 50507 2054 */ {0x0015, 0x8608}, | ||
424 | /* A11 Coef ... */ | ||
425 | /* 50532 2055 */ {0x0030, 0x8609}, | ||
426 | /* 50557 2056 */ {0x00fb, 0x860a}, | ||
427 | /* 50582 2057 */ {0x003e, 0x860b}, | ||
428 | /* 50607 2058 */ {0x00ce, 0x860c}, | ||
429 | /* 50632 2059 */ {0x00f4, 0x860d}, | ||
430 | /* 50657 2060 */ {0x00eb, 0x860e}, | ||
431 | /* 50682 2061 */ {0x00dc, 0x860f}, | ||
432 | /* 50707 2062 */ {0x0039, 0x8610}, | ||
433 | /* 50732 2063 */ {0x0001, 0x8611}, | ||
434 | /* R offset for white balance ... */ | ||
435 | /* 50757 2064 */ {0x0000, 0x8612}, | ||
436 | /* 50782 2065 */ {0x0001, 0x8613}, | ||
437 | /* 50807 2066 */ {0x0000, 0x8614}, | ||
438 | /* 50832 2067 */ {0x005b, 0x8651}, | ||
439 | /* R gain for white balance ... */ | ||
440 | /* 50857 2068 */ {0x0040, 0x8652}, | ||
441 | /* 50882 2069 */ {0x0060, 0x8653}, | ||
442 | /* 50907 2070 */ {0x0040, 0x8654}, | ||
443 | /* 50932 2071 */ {0x0000, 0x8655}, | ||
444 | /* 50957 2072 */ {0x0001, 0x863f}, | ||
445 | /* Fixed gamma correction enable, USB control, | ||
446 | * lum filter disable, lum noise clip disable */ | ||
447 | /* 50982 2073 */ {0x00a1, 0x8656}, | ||
448 | /* Window1 size 256x256, Windows2 size 64x64, | ||
449 | * gamma look-up disable, new edge enhancement enable */ | ||
450 | /* 51007 2074 */ {0x0018, 0x8657}, | ||
451 | /* Edge gain high thresh */ | ||
452 | /* 51032 2075 */ {0x0020, 0x8658}, | ||
453 | /* Edge gain low thresh */ | ||
454 | /* 51057 2076 */ {0x000a, 0x8659}, | ||
455 | /* Edge bandwidth high threshold */ | ||
456 | /* 51082 2077 */ {0x0005, 0x865a}, | ||
457 | /* Edge bandwidth low threshold */ | ||
458 | /* -------------------------------- */ | ||
459 | /* 51107 2078 */ {0x0030, 0x8112}, | ||
460 | /* Video drop enable, ISO streaming enable */ | ||
461 | /* 51130 2079 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
462 | /* 51154 2080 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
463 | /* 51180 2081 */ {0xa908, 0x8802}, | ||
464 | /* 51205 2082 */ {0x0034, 0x8801}, | ||
465 | /* SSI reg addr */ | ||
466 | /* 51230 2083 */ {0x00ca, 0x8800}, | ||
467 | /* SSI data to write */ | ||
468 | /* 51253 2084 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
469 | /* 51277 2085 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
470 | /* 51301 2086 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
471 | /* 51327 2087 */ {0x1f08, 0x8802}, | ||
472 | /* 51352 2088 */ {0x0006, 0x8801}, | ||
473 | /* 51377 2089 */ {0x0080, 0x8800}, | ||
474 | /* 51400 2090 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
475 | |||
476 | /* ----- Read back coefs we wrote earlier. */ | ||
477 | /* 51424 2091 */ /* READ { 0, 0x0000, 0x8608 } -> 0000: 15 */ | ||
478 | /* 51448 2092 */ /* READ { 0, 0x0000, 0x8609 } -> 0000: 30 */ | ||
479 | /* 51472 2093 */ /* READ { 0, 0x0000, 0x860a } -> 0000: fb */ | ||
480 | /* 51496 2094 */ /* READ { 0, 0x0000, 0x860b } -> 0000: 3e */ | ||
481 | /* 51520 2095 */ /* READ { 0, 0x0000, 0x860c } -> 0000: ce */ | ||
482 | /* 51544 2096 */ /* READ { 0, 0x0000, 0x860d } -> 0000: f4 */ | ||
483 | /* 51568 2097 */ /* READ { 0, 0x0000, 0x860e } -> 0000: eb */ | ||
484 | /* 51592 2098 */ /* READ { 0, 0x0000, 0x860f } -> 0000: dc */ | ||
485 | /* 51616 2099 */ /* READ { 0, 0x0000, 0x8610 } -> 0000: 39 */ | ||
486 | /* 51640 2100 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
487 | /* 51664 2101 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ | ||
488 | /* 51690 2102 */ {0xb008, 0x8802}, | ||
489 | /* 51715 2103 */ {0x0006, 0x8801}, | ||
490 | /* 51740 2104 */ {0x007d, 0x8800}, | ||
491 | /* 51763 2105 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
492 | |||
493 | |||
494 | /* This chunk is seemingly redundant with */ | ||
495 | /* earlier commands (A11 Coef...), but if I disable it, */ | ||
496 | /* the image appears too dark. Maybe there was some kind of */ | ||
497 | /* reset since the earlier commands, so this is necessary again. */ | ||
498 | /* 51789 2106 */ {0x0015, 0x8608}, | ||
499 | /* 51814 2107 */ {0x0030, 0x8609}, | ||
500 | /* 51839 2108 */ {0xfffb, 0x860a}, | ||
501 | /* 51864 2109 */ {0x003e, 0x860b}, | ||
502 | /* 51889 2110 */ {0xffce, 0x860c}, | ||
503 | /* 51914 2111 */ {0xfff4, 0x860d}, | ||
504 | /* 51939 2112 */ {0xffeb, 0x860e}, | ||
505 | /* 51964 2113 */ {0xffdc, 0x860f}, | ||
506 | /* 51989 2114 */ {0x0039, 0x8610}, | ||
507 | /* 52014 2115 */ {0x0018, 0x8657}, | ||
508 | |||
509 | /* 52039 2116 */ {0x0000, 0x8508}, | ||
510 | /* Disable compression. */ | ||
511 | /* Previous line was: | ||
512 | * 52039 2116 * { 0, 0x0021, 0x8508 }, * Enable compression. */ | ||
513 | /* 52064 2117 */ {0x0032, 0x850b}, | ||
514 | /* compression stuff */ | ||
515 | /* 52089 2118 */ {0x0003, 0x8509}, | ||
516 | /* compression stuff */ | ||
517 | /* 52114 2119 */ {0x0011, 0x850a}, | ||
518 | /* compression stuff */ | ||
519 | /* 52139 2120 */ {0x0021, 0x850d}, | ||
520 | /* compression stuff */ | ||
521 | /* 52164 2121 */ {0x0010, 0x850c}, | ||
522 | /* compression stuff */ | ||
523 | /* 52189 2122 */ {0x0003, 0x8500}, | ||
524 | /* *** Video mode: 160x120 */ | ||
525 | /* 52214 2123 */ {0x0001, 0x8501}, | ||
526 | /* Hardware-dominated snap control */ | ||
527 | /* 52239 2124 */ {0x0061, 0x8656}, | ||
528 | /* Window1 size 128x128, Windows2 size 128x128, | ||
529 | * gamma look-up disable, new edge enhancement enable */ | ||
530 | /* 52264 2125 */ {0x0018, 0x8617}, | ||
531 | /* Window1 start X (*2) */ | ||
532 | /* 52289 2126 */ {0x0008, 0x8618}, | ||
533 | /* Window1 start Y (*2) */ | ||
534 | /* 52314 2127 */ {0x0061, 0x8656}, | ||
535 | /* Window1 size 128x128, Windows2 size 128x128, | ||
536 | * gamma look-up disable, new edge enhancement enable */ | ||
537 | /* 52339 2128 */ {0x0058, 0x8619}, | ||
538 | /* Window2 start X (*2) */ | ||
539 | /* 52364 2129 */ {0x0008, 0x861a}, | ||
540 | /* Window2 start Y (*2) */ | ||
541 | /* 52389 2130 */ {0x00ff, 0x8615}, | ||
542 | /* High lum thresh for white balance */ | ||
543 | /* 52414 2131 */ {0x0000, 0x8616}, | ||
544 | /* Low lum thresh for white balance */ | ||
545 | /* 52439 2132 */ {0x0012, 0x8700}, | ||
546 | /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ | ||
547 | /* 52464 2133 */ {0x0012, 0x8700}, | ||
548 | /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ | ||
549 | /* 52487 2134 */ /* READ { 0, 0x0000, 0x8656 } -> 0000: 61 */ | ||
550 | /* 52513 2135 */ {0x0028, 0x8802}, | ||
551 | /* 375 Khz SSI clock, SSI r/w sync with VSYNC */ | ||
552 | /* 52536 2136 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
553 | /* 52560 2137 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */ | ||
554 | /* 52586 2138 */ {0x1f28, 0x8802}, | ||
555 | /* 375 Khz SSI clock, SSI r/w sync with VSYNC */ | ||
556 | /* 52611 2139 */ {0x0010, 0x8801}, | ||
557 | /* SSI reg addr */ | ||
558 | /* 52636 2140 */ {0x003e, 0x8800}, | ||
559 | /* SSI data to write */ | ||
560 | /* 52659 2141 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
561 | /* 52685 2142 */ {0x0028, 0x8802}, | ||
562 | /* 52708 2143 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
563 | /* 52732 2144 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */ | ||
564 | /* 52758 2145 */ {0x1f28, 0x8802}, | ||
565 | /* 52783 2146 */ {0x0000, 0x8801}, | ||
566 | /* 52808 2147 */ {0x001f, 0x8800}, | ||
567 | /* 52831 2148 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
568 | /* 52857 2149 */ {0x0001, 0x8602}, | ||
569 | /* optical black level for user settning = 1 */ | ||
570 | |||
571 | /* Original: */ | ||
572 | /* 52882 2150 */ {0x0023, 0x8700}, | ||
573 | /* Clock speed 48Mhz/(3+2)/4= 2.4 Mhz */ | ||
574 | /* 52907 2151 */ {0x000f, 0x8602}, | ||
575 | /* optical black level for user settning = 15 */ | ||
576 | |||
577 | /* 52932 2152 */ {0x0028, 0x8802}, | ||
578 | /* 52955 2153 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
579 | /* 52979 2154 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */ | ||
580 | /* 53005 2155 */ {0x1f28, 0x8802}, | ||
581 | /* 53030 2156 */ {0x0010, 0x8801}, | ||
582 | /* 53055 2157 */ {0x007b, 0x8800}, | ||
583 | /* 53078 2158 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ | ||
584 | /* 53104 2159 */ {0x002f, 0x8651}, | ||
585 | /* R gain for white balance ... */ | ||
586 | /* 53129 2160 */ {0x0080, 0x8653}, | ||
587 | /* 53152 2161 */ /* READ { 0, 0x0000, 0x8655 } -> 0000: 00 */ | ||
588 | /* 53178 2162 */ {0x0000, 0x8655}, | ||
589 | |||
590 | /* 53203 2163 */ {0x0030, 0x8112}, | ||
591 | /* Video drop enable, ISO streaming enable */ | ||
592 | /* 53228 2164 */ {0x0020, 0x8112}, | ||
593 | /* Video drop enable, ISO streaming disable */ | ||
594 | /* 53252 2165 */ | ||
595 | /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE: (ALT=0) ) */ | ||
596 | {} | ||
597 | }; | ||
598 | |||
599 | |||
600 | /* | ||
601 | * Initialization data for Intel EasyPC Camera CS110 | ||
602 | */ | ||
603 | static const __u16 spca508cs110_init_data[][3] = { | ||
604 | {0x0000, 0x870b}, /* Reset CTL3 */ | ||
605 | {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ | ||
606 | {0x0000, 0x8111}, /* Normal operation on reset */ | ||
607 | {0x0090, 0x8110}, | ||
608 | /* External Clock 2x & Synchronous Serial Interface Output */ | ||
609 | {0x0020, 0x8112}, /* Video Drop packet enable */ | ||
610 | {0x0000, 0x8114}, /* Software GPIO output data */ | ||
611 | {0x0001, 0x8114}, | ||
612 | {0x0001, 0x8114}, | ||
613 | {0x0001, 0x8114}, | ||
614 | {0x0003, 0x8114}, | ||
615 | |||
616 | /* Initial sequence Synchronous Serial Interface */ | ||
617 | {0x000f, 0x8402}, /* Memory bank Address */ | ||
618 | {0x0000, 0x8403}, /* Memory bank Address */ | ||
619 | {0x00ba, 0x8804}, /* SSI Slave address */ | ||
620 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ | ||
621 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock two DataByte */ | ||
622 | |||
623 | {0x0001, 0x8801}, | ||
624 | {0x000a, 0x8805},/* a - NWG: Dunno what this is about */ | ||
625 | {0x0000, 0x8800}, | ||
626 | {0x0010, 0x8802}, | ||
627 | |||
628 | {0x0002, 0x8801}, | ||
629 | {0x0000, 0x8805}, | ||
630 | {0x0000, 0x8800}, | ||
631 | {0x0010, 0x8802}, | ||
632 | |||
633 | {0x0003, 0x8801}, | ||
634 | {0x0027, 0x8805}, | ||
635 | {0x0001, 0x8800}, | ||
636 | {0x0010, 0x8802}, | ||
637 | |||
638 | {0x0004, 0x8801}, | ||
639 | {0x0065, 0x8805}, | ||
640 | {0x0001, 0x8800}, | ||
641 | {0x0010, 0x8802}, | ||
642 | |||
643 | {0x0005, 0x8801}, | ||
644 | {0x0003, 0x8805}, | ||
645 | {0x0000, 0x8800}, | ||
646 | {0x0010, 0x8802}, | ||
647 | |||
648 | {0x0006, 0x8801}, | ||
649 | {0x001c, 0x8805}, | ||
650 | {0x0000, 0x8800}, | ||
651 | {0x0010, 0x8802}, | ||
652 | |||
653 | {0x0007, 0x8801}, | ||
654 | {0x002a, 0x8805}, | ||
655 | {0x0000, 0x8800}, | ||
656 | {0x0010, 0x8802}, | ||
657 | |||
658 | {0x0002, 0x8704}, /* External input CKIx1 */ | ||
659 | {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ | ||
660 | {0x009a, 0x8600}, /* Line memory Read Counter (L) */ | ||
661 | {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ | ||
662 | {0x0003, 0x865c}, /* 3 Vertical Offset for Valid Lines(L) */ | ||
663 | {0x0058, 0x865d}, /* 58 Horizontal Valid Pixel Window(L) */ | ||
664 | |||
665 | {0x0006, 0x8660}, /* Nibble data + input order */ | ||
666 | |||
667 | {0x000a, 0x8602}, /* Optical black level set to 0x0a */ | ||
668 | /* 1945 */ {0x0000, 0x8603}, /* Optical black level Offset */ | ||
669 | |||
670 | /* 1962 * {0, 0x0000, 0x8611}, * 0 R Offset for white Balance */ | ||
671 | /* 1963 * {0, 0x0000, 0x8612}, * 1 Gr Offset for white Balance */ | ||
672 | /* 1964 * {0, 0x0000, 0x8613}, * 1f B Offset for white Balance */ | ||
673 | /* 1965 * {0, 0x0000, 0x8614}, * f0 Gb Offset for white Balance */ | ||
674 | |||
675 | {0x0040, 0x8651}, /* 2b BLUE gain for white balance good at all 60 */ | ||
676 | {0x0030, 0x8652}, /* 41 Gr Gain for white Balance (L) */ | ||
677 | {0x0035, 0x8653}, /* 26 RED gain for white balance */ | ||
678 | {0x0035, 0x8654}, /* 40Gb Gain for white Balance (L) */ | ||
679 | {0x0041, 0x863f}, | ||
680 | /* Fixed Gamma correction enabled (makes colours look better) */ | ||
681 | |||
682 | /* 2422 */ {0x0000, 0x8655}, | ||
683 | /* High bits for white balance*****brightness control*** */ | ||
684 | {} | ||
685 | }; | ||
686 | |||
687 | static const __u16 spca508_sightcam_init_data[][3] = { | ||
688 | /* This line seems to setup the frame/canvas */ | ||
689 | /*368 */ {0x000f, 0x8402}, | ||
690 | |||
691 | /* Theese 6 lines are needed to startup the webcam */ | ||
692 | /*398 */ {0x0090, 0x8110}, | ||
693 | /*399 */ {0x0001, 0x8114}, | ||
694 | /*400 */ {0x0001, 0x8114}, | ||
695 | /*401 */ {0x0001, 0x8114}, | ||
696 | /*402 */ {0x0003, 0x8114}, | ||
697 | /*403 */ {0x0080, 0x8804}, | ||
698 | |||
699 | /* This part seems to make the pictures darker? (autobrightness?) */ | ||
700 | /*436 */ {0x0001, 0x8801}, | ||
701 | /*437 */ {0x0004, 0x8800}, | ||
702 | /*439 */ {0x0003, 0x8801}, | ||
703 | /*440 */ {0x00e0, 0x8800}, | ||
704 | /*442 */ {0x0004, 0x8801}, | ||
705 | /*443 */ {0x00b4, 0x8800}, | ||
706 | /*445 */ {0x0005, 0x8801}, | ||
707 | /*446 */ {0x0000, 0x8800}, | ||
708 | |||
709 | /*448 */ {0x0006, 0x8801}, | ||
710 | /*449 */ {0x00e0, 0x8800}, | ||
711 | /*451 */ {0x0007, 0x8801}, | ||
712 | /*452 */ {0x000c, 0x8800}, | ||
713 | |||
714 | /* This section is just needed, it probably | ||
715 | * does something like the previous section, | ||
716 | * but the cam won't start if it's not included. | ||
717 | */ | ||
718 | /*484 */ {0x0014, 0x8801}, | ||
719 | /*485 */ {0x0008, 0x8800}, | ||
720 | /*487 */ {0x0015, 0x8801}, | ||
721 | /*488 */ {0x0067, 0x8800}, | ||
722 | /*490 */ {0x0016, 0x8801}, | ||
723 | /*491 */ {0x0000, 0x8800}, | ||
724 | /*493 */ {0x0017, 0x8801}, | ||
725 | /*494 */ {0x0020, 0x8800}, | ||
726 | /*496 */ {0x0018, 0x8801}, | ||
727 | /*497 */ {0x0044, 0x8800}, | ||
728 | |||
729 | /* Makes the picture darker - and the | ||
730 | * cam won't start if not included | ||
731 | */ | ||
732 | /*505 */ {0x001e, 0x8801}, | ||
733 | /*506 */ {0x00ea, 0x8800}, | ||
734 | /*508 */ {0x001f, 0x8801}, | ||
735 | /*509 */ {0x0001, 0x8800}, | ||
736 | /*511 */ {0x0003, 0x8801}, | ||
737 | /*512 */ {0x00e0, 0x8800}, | ||
738 | |||
739 | /* seems to place the colors ontop of each other #1 */ | ||
740 | /*517 */ {0x0006, 0x8704}, | ||
741 | /*518 */ {0x0001, 0x870c}, | ||
742 | /*519 */ {0x0016, 0x8600}, | ||
743 | /*520 */ {0x0002, 0x8606}, | ||
744 | |||
745 | /* if not included the pictures becomes _very_ dark */ | ||
746 | /*521 */ {0x0064, 0x8607}, | ||
747 | /*522 */ {0x003a, 0x8601}, | ||
748 | /*523 */ {0x0000, 0x8602}, | ||
749 | |||
750 | /* seems to place the colors ontop of each other #2 */ | ||
751 | /*524 */ {0x0016, 0x8600}, | ||
752 | /*525 */ {0x0018, 0x8617}, | ||
753 | /*526 */ {0x0008, 0x8618}, | ||
754 | /*527 */ {0x00a1, 0x8656}, | ||
755 | |||
756 | /* webcam won't start if not included */ | ||
757 | /*528 */ {0x0007, 0x865b}, | ||
758 | /*529 */ {0x0001, 0x865c}, | ||
759 | /*530 */ {0x0058, 0x865d}, | ||
760 | /*531 */ {0x0048, 0x865e}, | ||
761 | |||
762 | /* adjusts the colors */ | ||
763 | /*541 */ {0x0049, 0x8651}, | ||
764 | /*542 */ {0x0040, 0x8652}, | ||
765 | /*543 */ {0x004c, 0x8653}, | ||
766 | /*544 */ {0x0040, 0x8654}, | ||
767 | {} | ||
768 | }; | ||
769 | |||
770 | static const __u16 spca508_sightcam2_init_data[][3] = { | ||
771 | /* 35 */ {0x0020, 0x8112}, | ||
772 | |||
773 | /* 36 */ {0x000f, 0x8402}, | ||
774 | /* 37 */ {0x0000, 0x8403}, | ||
775 | |||
776 | /* 38 */ {0x0008, 0x8201}, | ||
777 | /* 39 */ {0x0008, 0x8200}, | ||
778 | /* 40 */ {0x0001, 0x8200}, | ||
779 | /* 43 */ {0x0009, 0x8201}, | ||
780 | /* 44 */ {0x0008, 0x8200}, | ||
781 | /* 45 */ {0x0001, 0x8200}, | ||
782 | /* 48 */ {0x000a, 0x8201}, | ||
783 | /* 49 */ {0x0008, 0x8200}, | ||
784 | /* 50 */ {0x0001, 0x8200}, | ||
785 | /* 53 */ {0x000b, 0x8201}, | ||
786 | /* 54 */ {0x0008, 0x8200}, | ||
787 | /* 55 */ {0x0001, 0x8200}, | ||
788 | /* 58 */ {0x000c, 0x8201}, | ||
789 | /* 59 */ {0x0008, 0x8200}, | ||
790 | /* 60 */ {0x0001, 0x8200}, | ||
791 | /* 63 */ {0x000d, 0x8201}, | ||
792 | /* 64 */ {0x0008, 0x8200}, | ||
793 | /* 65 */ {0x0001, 0x8200}, | ||
794 | /* 68 */ {0x000e, 0x8201}, | ||
795 | /* 69 */ {0x0008, 0x8200}, | ||
796 | /* 70 */ {0x0001, 0x8200}, | ||
797 | /* 73 */ {0x0007, 0x8201}, | ||
798 | /* 74 */ {0x0008, 0x8200}, | ||
799 | /* 75 */ {0x0001, 0x8200}, | ||
800 | /* 78 */ {0x000f, 0x8201}, | ||
801 | /* 79 */ {0x0008, 0x8200}, | ||
802 | /* 80 */ {0x0001, 0x8200}, | ||
803 | |||
804 | /* 84 */ {0x0018, 0x8660}, | ||
805 | /* 85 */ {0x0010, 0x8201}, | ||
806 | |||
807 | /* 86 */ {0x0008, 0x8200}, | ||
808 | /* 87 */ {0x0001, 0x8200}, | ||
809 | /* 90 */ {0x0011, 0x8201}, | ||
810 | /* 91 */ {0x0008, 0x8200}, | ||
811 | /* 92 */ {0x0001, 0x8200}, | ||
812 | |||
813 | /* 95 */ {0x0000, 0x86b0}, | ||
814 | /* 96 */ {0x0034, 0x86b1}, | ||
815 | /* 97 */ {0x0000, 0x86b2}, | ||
816 | /* 98 */ {0x0049, 0x86b3}, | ||
817 | /* 99 */ {0x0000, 0x86b4}, | ||
818 | /* 100 */ {0x0000, 0x86b4}, | ||
819 | |||
820 | /* 101 */ {0x0012, 0x8201}, | ||
821 | /* 102 */ {0x0008, 0x8200}, | ||
822 | /* 103 */ {0x0001, 0x8200}, | ||
823 | /* 106 */ {0x0013, 0x8201}, | ||
824 | /* 107 */ {0x0008, 0x8200}, | ||
825 | /* 108 */ {0x0001, 0x8200}, | ||
826 | |||
827 | /* 111 */ {0x0001, 0x86b0}, | ||
828 | /* 112 */ {0x00aa, 0x86b1}, | ||
829 | /* 113 */ {0x0000, 0x86b2}, | ||
830 | /* 114 */ {0x00e4, 0x86b3}, | ||
831 | /* 115 */ {0x0000, 0x86b4}, | ||
832 | /* 116 */ {0x0000, 0x86b4}, | ||
833 | |||
834 | /* 118 */ {0x0018, 0x8660}, | ||
835 | |||
836 | /* 119 */ {0x0090, 0x8110}, | ||
837 | /* 120 */ {0x0001, 0x8114}, | ||
838 | /* 121 */ {0x0001, 0x8114}, | ||
839 | /* 122 */ {0x0001, 0x8114}, | ||
840 | /* 123 */ {0x0003, 0x8114}, | ||
841 | |||
842 | /* 124 */ {0x0080, 0x8804}, | ||
843 | /* 157 */ {0x0003, 0x8801}, | ||
844 | /* 158 */ {0x0012, 0x8800}, | ||
845 | /* 160 */ {0x0004, 0x8801}, | ||
846 | /* 161 */ {0x0005, 0x8800}, | ||
847 | /* 163 */ {0x0005, 0x8801}, | ||
848 | /* 164 */ {0x0000, 0x8800}, | ||
849 | /* 166 */ {0x0006, 0x8801}, | ||
850 | /* 167 */ {0x0000, 0x8800}, | ||
851 | /* 169 */ {0x0007, 0x8801}, | ||
852 | /* 170 */ {0x0000, 0x8800}, | ||
853 | /* 172 */ {0x0008, 0x8801}, | ||
854 | /* 173 */ {0x0005, 0x8800}, | ||
855 | /* 175 */ {0x000a, 0x8700}, | ||
856 | /* 176 */ {0x000e, 0x8801}, | ||
857 | /* 177 */ {0x0004, 0x8800}, | ||
858 | /* 179 */ {0x0005, 0x8801}, | ||
859 | /* 180 */ {0x0047, 0x8800}, | ||
860 | /* 182 */ {0x0006, 0x8801}, | ||
861 | /* 183 */ {0x0000, 0x8800}, | ||
862 | /* 185 */ {0x0007, 0x8801}, | ||
863 | /* 186 */ {0x00c0, 0x8800}, | ||
864 | /* 188 */ {0x0008, 0x8801}, | ||
865 | /* 189 */ {0x0003, 0x8800}, | ||
866 | /* 191 */ {0x0013, 0x8801}, | ||
867 | /* 192 */ {0x0001, 0x8800}, | ||
868 | /* 194 */ {0x0009, 0x8801}, | ||
869 | /* 195 */ {0x0000, 0x8800}, | ||
870 | /* 197 */ {0x000a, 0x8801}, | ||
871 | /* 198 */ {0x0000, 0x8800}, | ||
872 | /* 200 */ {0x000b, 0x8801}, | ||
873 | /* 201 */ {0x0000, 0x8800}, | ||
874 | /* 203 */ {0x000c, 0x8801}, | ||
875 | /* 204 */ {0x0000, 0x8800}, | ||
876 | /* 206 */ {0x000e, 0x8801}, | ||
877 | /* 207 */ {0x0004, 0x8800}, | ||
878 | /* 209 */ {0x000f, 0x8801}, | ||
879 | /* 210 */ {0x0000, 0x8800}, | ||
880 | /* 212 */ {0x0010, 0x8801}, | ||
881 | /* 213 */ {0x0006, 0x8800}, | ||
882 | /* 215 */ {0x0011, 0x8801}, | ||
883 | /* 216 */ {0x0006, 0x8800}, | ||
884 | /* 218 */ {0x0012, 0x8801}, | ||
885 | /* 219 */ {0x0000, 0x8800}, | ||
886 | /* 221 */ {0x0013, 0x8801}, | ||
887 | /* 222 */ {0x0001, 0x8800}, | ||
888 | |||
889 | /* 224 */ {0x000a, 0x8700}, | ||
890 | /* 225 */ {0x0000, 0x8702}, | ||
891 | /* 226 */ {0x0000, 0x8703}, | ||
892 | /* 227 */ {0x00c2, 0x8704}, | ||
893 | /* 228 */ {0x0001, 0x870c}, | ||
894 | |||
895 | /* 229 */ {0x0044, 0x8600}, | ||
896 | /* 230 */ {0x0002, 0x8606}, | ||
897 | /* 231 */ {0x0064, 0x8607}, | ||
898 | /* 232 */ {0x003a, 0x8601}, | ||
899 | /* 233 */ {0x0008, 0x8602}, | ||
900 | /* 234 */ {0x0044, 0x8600}, | ||
901 | /* 235 */ {0x0018, 0x8617}, | ||
902 | /* 236 */ {0x0008, 0x8618}, | ||
903 | /* 237 */ {0x00a1, 0x8656}, | ||
904 | /* 238 */ {0x0004, 0x865b}, | ||
905 | /* 239 */ {0x0002, 0x865c}, | ||
906 | /* 240 */ {0x0058, 0x865d}, | ||
907 | /* 241 */ {0x0048, 0x865e}, | ||
908 | /* 242 */ {0x0012, 0x8608}, | ||
909 | /* 243 */ {0x002c, 0x8609}, | ||
910 | /* 244 */ {0x0002, 0x860a}, | ||
911 | /* 245 */ {0x002c, 0x860b}, | ||
912 | /* 246 */ {0x00db, 0x860c}, | ||
913 | /* 247 */ {0x00f9, 0x860d}, | ||
914 | /* 248 */ {0x00f1, 0x860e}, | ||
915 | /* 249 */ {0x00e3, 0x860f}, | ||
916 | /* 250 */ {0x002c, 0x8610}, | ||
917 | /* 251 */ {0x006c, 0x8651}, | ||
918 | /* 252 */ {0x0041, 0x8652}, | ||
919 | /* 253 */ {0x0059, 0x8653}, | ||
920 | /* 254 */ {0x0040, 0x8654}, | ||
921 | /* 255 */ {0x00fa, 0x8611}, | ||
922 | /* 256 */ {0x00ff, 0x8612}, | ||
923 | /* 257 */ {0x00f8, 0x8613}, | ||
924 | /* 258 */ {0x0000, 0x8614}, | ||
925 | /* 259 */ {0x0001, 0x863f}, | ||
926 | /* 260 */ {0x0000, 0x8640}, | ||
927 | /* 261 */ {0x0026, 0x8641}, | ||
928 | /* 262 */ {0x0045, 0x8642}, | ||
929 | /* 263 */ {0x0060, 0x8643}, | ||
930 | /* 264 */ {0x0075, 0x8644}, | ||
931 | /* 265 */ {0x0088, 0x8645}, | ||
932 | /* 266 */ {0x009b, 0x8646}, | ||
933 | /* 267 */ {0x00b0, 0x8647}, | ||
934 | /* 268 */ {0x00c5, 0x8648}, | ||
935 | /* 269 */ {0x00d2, 0x8649}, | ||
936 | /* 270 */ {0x00dc, 0x864a}, | ||
937 | /* 271 */ {0x00e5, 0x864b}, | ||
938 | /* 272 */ {0x00eb, 0x864c}, | ||
939 | /* 273 */ {0x00f0, 0x864d}, | ||
940 | /* 274 */ {0x00f6, 0x864e}, | ||
941 | /* 275 */ {0x00fa, 0x864f}, | ||
942 | /* 276 */ {0x00ff, 0x8650}, | ||
943 | /* 277 */ {0x0060, 0x8657}, | ||
944 | /* 278 */ {0x0010, 0x8658}, | ||
945 | /* 279 */ {0x0018, 0x8659}, | ||
946 | /* 280 */ {0x0005, 0x865a}, | ||
947 | /* 281 */ {0x0018, 0x8660}, | ||
948 | /* 282 */ {0x0003, 0x8509}, | ||
949 | /* 283 */ {0x0011, 0x850a}, | ||
950 | /* 284 */ {0x0032, 0x850b}, | ||
951 | /* 285 */ {0x0010, 0x850c}, | ||
952 | /* 286 */ {0x0021, 0x850d}, | ||
953 | /* 287 */ {0x0001, 0x8500}, | ||
954 | /* 288 */ {0x0000, 0x8508}, | ||
955 | /* 289 */ {0x0012, 0x8608}, | ||
956 | /* 290 */ {0x002c, 0x8609}, | ||
957 | /* 291 */ {0x0002, 0x860a}, | ||
958 | /* 292 */ {0x0039, 0x860b}, | ||
959 | /* 293 */ {0x00d0, 0x860c}, | ||
960 | /* 294 */ {0x00f7, 0x860d}, | ||
961 | /* 295 */ {0x00ed, 0x860e}, | ||
962 | /* 296 */ {0x00db, 0x860f}, | ||
963 | /* 297 */ {0x0039, 0x8610}, | ||
964 | /* 298 */ {0x0012, 0x8657}, | ||
965 | /* 299 */ {0x000c, 0x8619}, | ||
966 | /* 300 */ {0x0004, 0x861a}, | ||
967 | /* 301 */ {0x00a1, 0x8656}, | ||
968 | /* 302 */ {0x00c8, 0x8615}, | ||
969 | /* 303 */ {0x0032, 0x8616}, | ||
970 | |||
971 | /* 306 */ {0x0030, 0x8112}, | ||
972 | /* 313 */ {0x0020, 0x8112}, | ||
973 | /* 314 */ {0x0020, 0x8112}, | ||
974 | /* 315 */ {0x000f, 0x8402}, | ||
975 | /* 316 */ {0x0000, 0x8403}, | ||
976 | |||
977 | /* 317 */ {0x0090, 0x8110}, | ||
978 | /* 318 */ {0x0001, 0x8114}, | ||
979 | /* 319 */ {0x0001, 0x8114}, | ||
980 | /* 320 */ {0x0001, 0x8114}, | ||
981 | /* 321 */ {0x0003, 0x8114}, | ||
982 | /* 322 */ {0x0080, 0x8804}, | ||
983 | |||
984 | /* 355 */ {0x0003, 0x8801}, | ||
985 | /* 356 */ {0x0012, 0x8800}, | ||
986 | /* 358 */ {0x0004, 0x8801}, | ||
987 | /* 359 */ {0x0005, 0x8800}, | ||
988 | /* 361 */ {0x0005, 0x8801}, | ||
989 | /* 362 */ {0x0047, 0x8800}, | ||
990 | /* 364 */ {0x0006, 0x8801}, | ||
991 | /* 365 */ {0x0000, 0x8800}, | ||
992 | /* 367 */ {0x0007, 0x8801}, | ||
993 | /* 368 */ {0x00c0, 0x8800}, | ||
994 | /* 370 */ {0x0008, 0x8801}, | ||
995 | /* 371 */ {0x0003, 0x8800}, | ||
996 | /* 373 */ {0x000a, 0x8700}, | ||
997 | /* 374 */ {0x000e, 0x8801}, | ||
998 | /* 375 */ {0x0004, 0x8800}, | ||
999 | /* 377 */ {0x0005, 0x8801}, | ||
1000 | /* 378 */ {0x0047, 0x8800}, | ||
1001 | /* 380 */ {0x0006, 0x8801}, | ||
1002 | /* 381 */ {0x0000, 0x8800}, | ||
1003 | /* 383 */ {0x0007, 0x8801}, | ||
1004 | /* 384 */ {0x00c0, 0x8800}, | ||
1005 | /* 386 */ {0x0008, 0x8801}, | ||
1006 | /* 387 */ {0x0003, 0x8800}, | ||
1007 | /* 389 */ {0x0013, 0x8801}, | ||
1008 | /* 390 */ {0x0001, 0x8800}, | ||
1009 | /* 392 */ {0x0009, 0x8801}, | ||
1010 | /* 393 */ {0x0000, 0x8800}, | ||
1011 | /* 395 */ {0x000a, 0x8801}, | ||
1012 | /* 396 */ {0x0000, 0x8800}, | ||
1013 | /* 398 */ {0x000b, 0x8801}, | ||
1014 | /* 399 */ {0x0000, 0x8800}, | ||
1015 | /* 401 */ {0x000c, 0x8801}, | ||
1016 | /* 402 */ {0x0000, 0x8800}, | ||
1017 | /* 404 */ {0x000e, 0x8801}, | ||
1018 | /* 405 */ {0x0004, 0x8800}, | ||
1019 | /* 407 */ {0x000f, 0x8801}, | ||
1020 | /* 408 */ {0x0000, 0x8800}, | ||
1021 | /* 410 */ {0x0010, 0x8801}, | ||
1022 | /* 411 */ {0x0006, 0x8800}, | ||
1023 | /* 413 */ {0x0011, 0x8801}, | ||
1024 | /* 414 */ {0x0006, 0x8800}, | ||
1025 | /* 416 */ {0x0012, 0x8801}, | ||
1026 | /* 417 */ {0x0000, 0x8800}, | ||
1027 | /* 419 */ {0x0013, 0x8801}, | ||
1028 | /* 420 */ {0x0001, 0x8800}, | ||
1029 | /* 422 */ {0x000a, 0x8700}, | ||
1030 | /* 423 */ {0x0000, 0x8702}, | ||
1031 | /* 424 */ {0x0000, 0x8703}, | ||
1032 | /* 425 */ {0x00c2, 0x8704}, | ||
1033 | /* 426 */ {0x0001, 0x870c}, | ||
1034 | /* 427 */ {0x0044, 0x8600}, | ||
1035 | /* 428 */ {0x0002, 0x8606}, | ||
1036 | /* 429 */ {0x0064, 0x8607}, | ||
1037 | /* 430 */ {0x003a, 0x8601}, | ||
1038 | /* 431 */ {0x0008, 0x8602}, | ||
1039 | /* 432 */ {0x0044, 0x8600}, | ||
1040 | /* 433 */ {0x0018, 0x8617}, | ||
1041 | /* 434 */ {0x0008, 0x8618}, | ||
1042 | /* 435 */ {0x00a1, 0x8656}, | ||
1043 | /* 436 */ {0x0004, 0x865b}, | ||
1044 | /* 437 */ {0x0002, 0x865c}, | ||
1045 | /* 438 */ {0x0058, 0x865d}, | ||
1046 | /* 439 */ {0x0048, 0x865e}, | ||
1047 | /* 440 */ {0x0012, 0x8608}, | ||
1048 | /* 441 */ {0x002c, 0x8609}, | ||
1049 | /* 442 */ {0x0002, 0x860a}, | ||
1050 | /* 443 */ {0x002c, 0x860b}, | ||
1051 | /* 444 */ {0x00db, 0x860c}, | ||
1052 | /* 445 */ {0x00f9, 0x860d}, | ||
1053 | /* 446 */ {0x00f1, 0x860e}, | ||
1054 | /* 447 */ {0x00e3, 0x860f}, | ||
1055 | /* 448 */ {0x002c, 0x8610}, | ||
1056 | /* 449 */ {0x006c, 0x8651}, | ||
1057 | /* 450 */ {0x0041, 0x8652}, | ||
1058 | /* 451 */ {0x0059, 0x8653}, | ||
1059 | /* 452 */ {0x0040, 0x8654}, | ||
1060 | /* 453 */ {0x00fa, 0x8611}, | ||
1061 | /* 454 */ {0x00ff, 0x8612}, | ||
1062 | /* 455 */ {0x00f8, 0x8613}, | ||
1063 | /* 456 */ {0x0000, 0x8614}, | ||
1064 | /* 457 */ {0x0001, 0x863f}, | ||
1065 | /* 458 */ {0x0000, 0x8640}, | ||
1066 | /* 459 */ {0x0026, 0x8641}, | ||
1067 | /* 460 */ {0x0045, 0x8642}, | ||
1068 | /* 461 */ {0x0060, 0x8643}, | ||
1069 | /* 462 */ {0x0075, 0x8644}, | ||
1070 | /* 463 */ {0x0088, 0x8645}, | ||
1071 | /* 464 */ {0x009b, 0x8646}, | ||
1072 | /* 465 */ {0x00b0, 0x8647}, | ||
1073 | /* 466 */ {0x00c5, 0x8648}, | ||
1074 | /* 467 */ {0x00d2, 0x8649}, | ||
1075 | /* 468 */ {0x00dc, 0x864a}, | ||
1076 | /* 469 */ {0x00e5, 0x864b}, | ||
1077 | /* 470 */ {0x00eb, 0x864c}, | ||
1078 | /* 471 */ {0x00f0, 0x864d}, | ||
1079 | /* 472 */ {0x00f6, 0x864e}, | ||
1080 | /* 473 */ {0x00fa, 0x864f}, | ||
1081 | /* 474 */ {0x00ff, 0x8650}, | ||
1082 | /* 475 */ {0x0060, 0x8657}, | ||
1083 | /* 476 */ {0x0010, 0x8658}, | ||
1084 | /* 477 */ {0x0018, 0x8659}, | ||
1085 | /* 478 */ {0x0005, 0x865a}, | ||
1086 | /* 479 */ {0x0018, 0x8660}, | ||
1087 | /* 480 */ {0x0003, 0x8509}, | ||
1088 | /* 481 */ {0x0011, 0x850a}, | ||
1089 | /* 482 */ {0x0032, 0x850b}, | ||
1090 | /* 483 */ {0x0010, 0x850c}, | ||
1091 | /* 484 */ {0x0021, 0x850d}, | ||
1092 | /* 485 */ {0x0001, 0x8500}, | ||
1093 | /* 486 */ {0x0000, 0x8508}, | ||
1094 | |||
1095 | /* 487 */ {0x0012, 0x8608}, | ||
1096 | /* 488 */ {0x002c, 0x8609}, | ||
1097 | /* 489 */ {0x0002, 0x860a}, | ||
1098 | /* 490 */ {0x0039, 0x860b}, | ||
1099 | /* 491 */ {0x00d0, 0x860c}, | ||
1100 | /* 492 */ {0x00f7, 0x860d}, | ||
1101 | /* 493 */ {0x00ed, 0x860e}, | ||
1102 | /* 494 */ {0x00db, 0x860f}, | ||
1103 | /* 495 */ {0x0039, 0x8610}, | ||
1104 | /* 496 */ {0x0012, 0x8657}, | ||
1105 | /* 497 */ {0x0064, 0x8619}, | ||
1106 | |||
1107 | /* This line starts it all, it is not needed here */ | ||
1108 | /* since it has been build into the driver */ | ||
1109 | /* jfm: don't start now */ | ||
1110 | /* 590 * {0x0030, 0x8112}, */ | ||
1111 | {} | ||
1112 | }; | ||
1113 | |||
1114 | /* | ||
1115 | * Initialization data for Creative Webcam Vista | ||
1116 | */ | ||
1117 | static const __u16 spca508_vista_init_data[][3] = { | ||
1118 | {0x0008, 0x8200}, /* Clear register */ | ||
1119 | {0x0000, 0x870b}, /* Reset CTL3 */ | ||
1120 | {0x0020, 0x8112}, /* Video Drop packet enable */ | ||
1121 | {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ | ||
1122 | {0x0000, 0x8110}, /* Disable everything */ | ||
1123 | {0x0000, 0x8114}, /* Software GPIO output data */ | ||
1124 | {0x0000, 0x8114}, | ||
1125 | |||
1126 | {0x0003, 0x8111}, | ||
1127 | {0x0000, 0x8111}, | ||
1128 | {0x0090, 0x8110}, /* Enable: SSI output, External 2X clock output */ | ||
1129 | {0x0020, 0x8112}, | ||
1130 | {0x0000, 0x8114}, | ||
1131 | {0x0001, 0x8114}, | ||
1132 | {0x0001, 0x8114}, | ||
1133 | {0x0001, 0x8114}, | ||
1134 | {0x0003, 0x8114}, | ||
1135 | |||
1136 | {0x000f, 0x8402}, /* Memory bank Address */ | ||
1137 | {0x0000, 0x8403}, /* Memory bank Address */ | ||
1138 | {0x00ba, 0x8804}, /* SSI Slave address */ | ||
1139 | {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ | ||
1140 | |||
1141 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1142 | 0000: 00 */ | ||
1143 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1144 | 0000: 10 */ | ||
1145 | {0x0010, 0x8802}, /* Will write 2 bytes (DATA1+DATA2) */ | ||
1146 | {0x0020, 0x8801}, /* Register address for SSI read/write */ | ||
1147 | {0x0044, 0x8805}, /* DATA2 */ | ||
1148 | {0x0004, 0x8800}, /* DATA1 -> write triggered */ | ||
1149 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1150 | 0000: 00 */ | ||
1151 | |||
1152 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1153 | 0000: 00 */ | ||
1154 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1155 | 0000: 10 */ | ||
1156 | {0x0010, 0x8802}, | ||
1157 | {0x0009, 0x8801}, | ||
1158 | {0x0042, 0x8805}, | ||
1159 | {0x0001, 0x8800}, | ||
1160 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1161 | 0000: 00 */ | ||
1162 | |||
1163 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1164 | 0000: 00 */ | ||
1165 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1166 | 0000: 10 */ | ||
1167 | {0x0010, 0x8802}, | ||
1168 | {0x003c, 0x8801}, | ||
1169 | {0x0001, 0x8805}, | ||
1170 | {0x0000, 0x8800}, | ||
1171 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1172 | 0000: 00 */ | ||
1173 | |||
1174 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1175 | 0000: 00 */ | ||
1176 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1177 | 0000: 10 */ | ||
1178 | {0x0010, 0x8802}, | ||
1179 | {0x0001, 0x8801}, | ||
1180 | {0x000a, 0x8805}, | ||
1181 | {0x0000, 0x8800}, | ||
1182 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1183 | 0000: 00 */ | ||
1184 | |||
1185 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1186 | 0000: 00 */ | ||
1187 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1188 | 0000: 10 */ | ||
1189 | {0x0010, 0x8802}, | ||
1190 | {0x0002, 0x8801}, | ||
1191 | {0x0000, 0x8805}, | ||
1192 | {0x0000, 0x8800}, | ||
1193 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1194 | 0000: 00 */ | ||
1195 | |||
1196 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1197 | 0000: 00 */ | ||
1198 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1199 | 0000: 10 */ | ||
1200 | {0x0010, 0x8802}, | ||
1201 | {0x0003, 0x8801}, | ||
1202 | {0x0027, 0x8805}, | ||
1203 | {0x0001, 0x8800}, | ||
1204 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1205 | 0000: 00 */ | ||
1206 | |||
1207 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1208 | 0000: 00 */ | ||
1209 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1210 | 0000: 10 */ | ||
1211 | {0x0010, 0x8802}, | ||
1212 | {0x0004, 0x8801}, | ||
1213 | {0x0065, 0x8805}, | ||
1214 | {0x0001, 0x8800}, | ||
1215 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1216 | 0000: 00 */ | ||
1217 | |||
1218 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1219 | 0000: 00 */ | ||
1220 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1221 | 0000: 10 */ | ||
1222 | {0x0010, 0x8802}, | ||
1223 | {0x0005, 0x8801}, | ||
1224 | {0x0003, 0x8805}, | ||
1225 | {0x0000, 0x8800}, | ||
1226 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1227 | 0000: 00 */ | ||
1228 | |||
1229 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1230 | 0000: 00 */ | ||
1231 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1232 | 0000: 10 */ | ||
1233 | {0x0010, 0x8802}, | ||
1234 | {0x0006, 0x8801}, | ||
1235 | {0x001c, 0x8805}, | ||
1236 | {0x0000, 0x8800}, | ||
1237 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1238 | 0000: 00 */ | ||
1239 | |||
1240 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1241 | 0000: 00 */ | ||
1242 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1243 | 0000: 10 */ | ||
1244 | {0x0010, 0x8802}, | ||
1245 | {0x0007, 0x8801}, | ||
1246 | {0x002a, 0x8805}, | ||
1247 | {0x0000, 0x8800}, | ||
1248 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1249 | 0000: 00 */ | ||
1250 | |||
1251 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1252 | 0000: 00 */ | ||
1253 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1254 | 0000: 10 */ | ||
1255 | {0x0010, 0x8802}, | ||
1256 | {0x000e, 0x8801}, | ||
1257 | {0x0000, 0x8805}, | ||
1258 | {0x0000, 0x8800}, | ||
1259 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1260 | 0000: 00 */ | ||
1261 | |||
1262 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1263 | 0000: 00 */ | ||
1264 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1265 | 0000: 10 */ | ||
1266 | {0x0010, 0x8802}, | ||
1267 | {0x0028, 0x8801}, | ||
1268 | {0x002e, 0x8805}, | ||
1269 | {0x0000, 0x8800}, | ||
1270 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1271 | 0000: 00 */ | ||
1272 | |||
1273 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1274 | 0000: 00 */ | ||
1275 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1276 | 0000: 10 */ | ||
1277 | {0x0010, 0x8802}, | ||
1278 | {0x0039, 0x8801}, | ||
1279 | {0x0013, 0x8805}, | ||
1280 | {0x0000, 0x8800}, | ||
1281 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1282 | 0000: 00 */ | ||
1283 | |||
1284 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1285 | 0000: 00 */ | ||
1286 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1287 | 0000: 10 */ | ||
1288 | {0x0010, 0x8802}, | ||
1289 | {0x003b, 0x8801}, | ||
1290 | {0x000c, 0x8805}, | ||
1291 | {0x0000, 0x8800}, | ||
1292 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1293 | 0000: 00 */ | ||
1294 | |||
1295 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1296 | 0000: 00 */ | ||
1297 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1298 | 0000: 10 */ | ||
1299 | {0x0010, 0x8802}, | ||
1300 | {0x0035, 0x8801}, | ||
1301 | {0x0028, 0x8805}, | ||
1302 | {0x0000, 0x8800}, | ||
1303 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1304 | 0000: 00 */ | ||
1305 | |||
1306 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1307 | 0000: 00 */ | ||
1308 | /* READ { 0, 0x0001, 0x8802 } -> | ||
1309 | 0000: 10 */ | ||
1310 | {0x0010, 0x8802}, | ||
1311 | {0x0009, 0x8801}, | ||
1312 | {0x0042, 0x8805}, | ||
1313 | {0x0001, 0x8800}, | ||
1314 | /* READ { 0, 0x0001, 0x8803 } -> | ||
1315 | 0000: 00 */ | ||
1316 | |||
1317 | {0x0050, 0x8703}, | ||
1318 | {0x0002, 0x8704}, /* External input CKIx1 */ | ||
1319 | {0x0001, 0x870C}, /* Select CKOx2 output */ | ||
1320 | {0x009A, 0x8600}, /* Line memory Read Counter (L) */ | ||
1321 | {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ | ||
1322 | {0x0023, 0x8601}, | ||
1323 | {0x0010, 0x8602}, | ||
1324 | {0x000A, 0x8603}, | ||
1325 | {0x009A, 0x8600}, | ||
1326 | {0x0001, 0x865B}, /* 1 Horizontal Offset for Valid Pixel(L) */ | ||
1327 | {0x0003, 0x865C}, /* Vertical offset for valid lines (L) */ | ||
1328 | {0x0058, 0x865D}, /* Horizontal valid pixels window (L) */ | ||
1329 | {0x0048, 0x865E}, /* Vertical valid lines window (L) */ | ||
1330 | {0x0000, 0x865F}, | ||
1331 | |||
1332 | {0x0006, 0x8660}, | ||
1333 | /* Enable nibble data input, select nibble input order */ | ||
1334 | |||
1335 | {0x0013, 0x8608}, /* A11 Coeficients for color correction */ | ||
1336 | {0x0028, 0x8609}, | ||
1337 | /* Note: these values are confirmed at the end of array */ | ||
1338 | {0x0005, 0x860A}, /* ... */ | ||
1339 | {0x0025, 0x860B}, | ||
1340 | {0x00E1, 0x860C}, | ||
1341 | {0x00FA, 0x860D}, | ||
1342 | {0x00F4, 0x860E}, | ||
1343 | {0x00E8, 0x860F}, | ||
1344 | {0x0025, 0x8610}, /* A33 Coef. */ | ||
1345 | {0x00FC, 0x8611}, /* White balance offset: R */ | ||
1346 | {0x0001, 0x8612}, /* White balance offset: Gr */ | ||
1347 | {0x00FE, 0x8613}, /* White balance offset: B */ | ||
1348 | {0x0000, 0x8614}, /* White balance offset: Gb */ | ||
1349 | |||
1350 | {0x0064, 0x8651}, /* R gain for white balance (L) */ | ||
1351 | {0x0040, 0x8652}, /* Gr gain for white balance (L) */ | ||
1352 | {0x0066, 0x8653}, /* B gain for white balance (L) */ | ||
1353 | {0x0040, 0x8654}, /* Gb gain for white balance (L) */ | ||
1354 | {0x0001, 0x863F}, /* Enable fixed gamma correction */ | ||
1355 | |||
1356 | {0x00A1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128 */ | ||
1357 | /* UV division: UV no change, Enable New edge enhancement */ | ||
1358 | {0x0018, 0x8657}, /* Edge gain high threshold */ | ||
1359 | {0x0020, 0x8658}, /* Edge gain low threshold */ | ||
1360 | {0x000A, 0x8659}, /* Edge bandwidth high threshold */ | ||
1361 | {0x0005, 0x865A}, /* Edge bandwidth low threshold */ | ||
1362 | {0x0064, 0x8607}, /* UV filter enable */ | ||
1363 | |||
1364 | {0x0016, 0x8660}, | ||
1365 | {0x0000, 0x86B0}, /* Bad pixels compensation address */ | ||
1366 | {0x00DC, 0x86B1}, /* X coord for bad pixels compensation (L) */ | ||
1367 | {0x0000, 0x86B2}, | ||
1368 | {0x0009, 0x86B3}, /* Y coord for bad pixels compensation (L) */ | ||
1369 | {0x0000, 0x86B4}, | ||
1370 | |||
1371 | {0x0001, 0x86B0}, | ||
1372 | {0x00F5, 0x86B1}, | ||
1373 | {0x0000, 0x86B2}, | ||
1374 | {0x00C6, 0x86B3}, | ||
1375 | {0x0000, 0x86B4}, | ||
1376 | |||
1377 | {0x0002, 0x86B0}, | ||
1378 | {0x001C, 0x86B1}, | ||
1379 | {0x0001, 0x86B2}, | ||
1380 | {0x00D7, 0x86B3}, | ||
1381 | {0x0000, 0x86B4}, | ||
1382 | |||
1383 | {0x0003, 0x86B0}, | ||
1384 | {0x001C, 0x86B1}, | ||
1385 | {0x0001, 0x86B2}, | ||
1386 | {0x00D8, 0x86B3}, | ||
1387 | {0x0000, 0x86B4}, | ||
1388 | |||
1389 | {0x0004, 0x86B0}, | ||
1390 | {0x001D, 0x86B1}, | ||
1391 | {0x0001, 0x86B2}, | ||
1392 | {0x00D8, 0x86B3}, | ||
1393 | {0x0000, 0x86B4}, | ||
1394 | {0x001E, 0x8660}, | ||
1395 | |||
1396 | /* READ { 0, 0x0000, 0x8608 } -> | ||
1397 | 0000: 13 */ | ||
1398 | /* READ { 0, 0x0000, 0x8609 } -> | ||
1399 | 0000: 28 */ | ||
1400 | /* READ { 0, 0x0000, 0x8610 } -> | ||
1401 | 0000: 05 */ | ||
1402 | /* READ { 0, 0x0000, 0x8611 } -> | ||
1403 | 0000: 25 */ | ||
1404 | /* READ { 0, 0x0000, 0x8612 } -> | ||
1405 | 0000: e1 */ | ||
1406 | /* READ { 0, 0x0000, 0x8613 } -> | ||
1407 | 0000: fa */ | ||
1408 | /* READ { 0, 0x0000, 0x8614 } -> | ||
1409 | 0000: f4 */ | ||
1410 | /* READ { 0, 0x0000, 0x8615 } -> | ||
1411 | 0000: e8 */ | ||
1412 | /* READ { 0, 0x0000, 0x8616 } -> | ||
1413 | 0000: 25 */ | ||
1414 | {} | ||
1415 | }; | ||
1416 | |||
1417 | static int reg_write(struct usb_device *dev, | ||
1418 | __u16 index, __u16 value) | ||
1419 | { | ||
1420 | int ret; | ||
1421 | |||
1422 | ret = usb_control_msg(dev, | ||
1423 | usb_sndctrlpipe(dev, 0), | ||
1424 | 0, /* request */ | ||
1425 | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
1426 | value, index, NULL, 0, 500); | ||
1427 | PDEBUG(D_USBO, "reg write i:0x%04x = 0x%02x", | ||
1428 | index, value); | ||
1429 | if (ret < 0) | ||
1430 | PDEBUG(D_ERR|D_USBO, "reg write: error %d", ret); | ||
1431 | return ret; | ||
1432 | } | ||
1433 | |||
1434 | /* read 1 byte */ | ||
1435 | /* returns: negative is error, pos or zero is data */ | ||
1436 | static int reg_read(struct gspca_dev *gspca_dev, | ||
1437 | __u16 index) /* wIndex */ | ||
1438 | { | ||
1439 | int ret; | ||
1440 | |||
1441 | ret = usb_control_msg(gspca_dev->dev, | ||
1442 | usb_rcvctrlpipe(gspca_dev->dev, 0), | ||
1443 | 0, /* register */ | ||
1444 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
1445 | 0, /* value */ | ||
1446 | index, | ||
1447 | gspca_dev->usb_buf, 1, | ||
1448 | 500); /* timeout */ | ||
1449 | PDEBUG(D_USBI, "reg read i:%04x --> %02x", | ||
1450 | index, gspca_dev->usb_buf[0]); | ||
1451 | if (ret < 0) { | ||
1452 | PDEBUG(D_ERR|D_USBI, "reg_read err %d", ret); | ||
1453 | return ret; | ||
1454 | } | ||
1455 | return gspca_dev->usb_buf[0]; | ||
1456 | } | ||
1457 | |||
1458 | static int write_vector(struct gspca_dev *gspca_dev, | ||
1459 | const __u16 data[][3]) | ||
1460 | { | ||
1461 | struct usb_device *dev = gspca_dev->dev; | ||
1462 | int ret, i = 0; | ||
1463 | |||
1464 | while (data[i][1] != 0) { | ||
1465 | ret = reg_write(dev, data[i][1], data[i][0]); | ||
1466 | if (ret < 0) | ||
1467 | return ret; | ||
1468 | i++; | ||
1469 | } | ||
1470 | return 0; | ||
1471 | } | ||
1472 | |||
1473 | /* this function is called at probe time */ | ||
1474 | static int sd_config(struct gspca_dev *gspca_dev, | ||
1475 | const struct usb_device_id *id) | ||
1476 | { | ||
1477 | struct sd *sd = (struct sd *) gspca_dev; | ||
1478 | struct cam *cam; | ||
1479 | __u16 product; | ||
1480 | int data1, data2; | ||
1481 | |||
1482 | product = id->idProduct; | ||
1483 | switch (id->idVendor) { | ||
1484 | case 0x0130: /* Clone webcam */ | ||
1485 | /* switch (product) { */ | ||
1486 | /* case 0x0130: */ | ||
1487 | sd->subtype = HamaUSBSightcam; /* same as Hama 0010 */ | ||
1488 | /* break; */ | ||
1489 | /* } */ | ||
1490 | break; | ||
1491 | case 0x041e: /* Creative cameras */ | ||
1492 | /* switch (product) { */ | ||
1493 | /* case 0x4018: */ | ||
1494 | sd->subtype = CreativeVista; | ||
1495 | /* break; */ | ||
1496 | /* } */ | ||
1497 | break; | ||
1498 | case 0x0461: /* MicroInnovation */ | ||
1499 | /* switch (product) { */ | ||
1500 | /* case 0x0815: */ | ||
1501 | sd->subtype = MicroInnovationIC200; | ||
1502 | /* break; */ | ||
1503 | /* } */ | ||
1504 | break; | ||
1505 | case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */ | ||
1506 | /* switch (product) { */ | ||
1507 | /* case 0x110: */ | ||
1508 | sd->subtype = ViewQuestVQ110; | ||
1509 | /* break; */ | ||
1510 | /* } */ | ||
1511 | break; | ||
1512 | case 0x0af9: /* Hama cameras */ | ||
1513 | switch (product) { | ||
1514 | case 0x0010: | ||
1515 | sd->subtype = HamaUSBSightcam; | ||
1516 | break; | ||
1517 | case 0x0011: | ||
1518 | sd->subtype = HamaUSBSightcam2; | ||
1519 | break; | ||
1520 | } | ||
1521 | break; | ||
1522 | case 0x8086: /* Intel */ | ||
1523 | /* switch (product) { */ | ||
1524 | /* case 0x0110: */ | ||
1525 | sd->subtype = IntelEasyPCCamera; | ||
1526 | /* break; */ | ||
1527 | /* } */ | ||
1528 | break; | ||
1529 | } | ||
1530 | |||
1531 | /* Read from global register the USB product and vendor IDs, just to | ||
1532 | * prove that we can communicate with the device. This works, which | ||
1533 | * confirms at we are communicating properly and that the device | ||
1534 | * is a 508. */ | ||
1535 | data1 = reg_read(gspca_dev, 0x8104); | ||
1536 | data2 = reg_read(gspca_dev, 0x8105); | ||
1537 | PDEBUG(D_PROBE, "Webcam Vendor ID: 0x%02x%02x", data2, data1); | ||
1538 | |||
1539 | data1 = reg_read(gspca_dev, 0x8106); | ||
1540 | data2 = reg_read(gspca_dev, 0x8107); | ||
1541 | PDEBUG(D_PROBE, "Webcam Product ID: 0x%02x%02x", data2, data1); | ||
1542 | |||
1543 | data1 = reg_read(gspca_dev, 0x8621); | ||
1544 | PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1); | ||
1545 | |||
1546 | cam = &gspca_dev->cam; | ||
1547 | cam->dev_name = (char *) id->driver_info; | ||
1548 | cam->epaddr = 0x01; | ||
1549 | cam->cam_mode = sif_mode; | ||
1550 | cam->nmodes = ARRAY_SIZE(sif_mode); | ||
1551 | sd->brightness = BRIGHTNESS_DEF; | ||
1552 | |||
1553 | switch (sd->subtype) { | ||
1554 | case ViewQuestVQ110: | ||
1555 | if (write_vector(gspca_dev, spca508_init_data)) | ||
1556 | return -1; | ||
1557 | break; | ||
1558 | default: | ||
1559 | /* case MicroInnovationIC200: */ | ||
1560 | /* case IntelEasyPCCamera: */ | ||
1561 | if (write_vector(gspca_dev, spca508cs110_init_data)) | ||
1562 | return -1; | ||
1563 | break; | ||
1564 | case HamaUSBSightcam: | ||
1565 | if (write_vector(gspca_dev, spca508_sightcam_init_data)) | ||
1566 | return -1; | ||
1567 | break; | ||
1568 | case HamaUSBSightcam2: | ||
1569 | if (write_vector(gspca_dev, spca508_sightcam2_init_data)) | ||
1570 | return -1; | ||
1571 | break; | ||
1572 | case CreativeVista: | ||
1573 | if (write_vector(gspca_dev, spca508_vista_init_data)) | ||
1574 | return -1; | ||
1575 | break; | ||
1576 | } | ||
1577 | return 0; /* success */ | ||
1578 | } | ||
1579 | |||
1580 | /* this function is called at open time */ | ||
1581 | static int sd_open(struct gspca_dev *gspca_dev) | ||
1582 | { | ||
1583 | /* write_vector(gspca_dev, spca508_open_data); */ | ||
1584 | return 0; | ||
1585 | } | ||
1586 | |||
1587 | static void sd_start(struct gspca_dev *gspca_dev) | ||
1588 | { | ||
1589 | int mode; | ||
1590 | |||
1591 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | ||
1592 | reg_write(gspca_dev->dev, 0x8500, mode); | ||
1593 | switch (mode) { | ||
1594 | case 0: | ||
1595 | case 1: | ||
1596 | reg_write(gspca_dev->dev, 0x8700, 0x28); /* clock */ | ||
1597 | break; | ||
1598 | default: | ||
1599 | /* case 2: */ | ||
1600 | /* case 3: */ | ||
1601 | reg_write(gspca_dev->dev, 0x8700, 0x23); /* clock */ | ||
1602 | break; | ||
1603 | } | ||
1604 | reg_write(gspca_dev->dev, 0x8112, 0x10 | 0x20); | ||
1605 | } | ||
1606 | |||
1607 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
1608 | { | ||
1609 | /* Video ISO disable, Video Drop Packet enable: */ | ||
1610 | reg_write(gspca_dev->dev, 0x8112, 0x20); | ||
1611 | } | ||
1612 | |||
1613 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
1614 | { | ||
1615 | } | ||
1616 | |||
1617 | /* this function is called at close time */ | ||
1618 | static void sd_close(struct gspca_dev *gspca_dev) | ||
1619 | { | ||
1620 | } | ||
1621 | |||
1622 | /* convert YUVY per line to YUYV (YUV 4:2:2) */ | ||
1623 | static void yuvy_decode(unsigned char *out, | ||
1624 | unsigned char *in, | ||
1625 | int width, | ||
1626 | int height) | ||
1627 | { | ||
1628 | unsigned char *Ui, *Vi, *yi, *yi1; | ||
1629 | unsigned char *out1; | ||
1630 | int i, j; | ||
1631 | |||
1632 | yi = in; | ||
1633 | for (i = height / 2; --i >= 0; ) { | ||
1634 | out1 = out + width * 2; /* next line */ | ||
1635 | Ui = yi + width; | ||
1636 | Vi = Ui + width / 2; | ||
1637 | yi1 = Vi + width / 2; | ||
1638 | for (j = width / 2; --j >= 0; ) { | ||
1639 | *out++ = 128 + *yi++; | ||
1640 | *out++ = 128 + *Ui; | ||
1641 | *out++ = 128 + *yi++; | ||
1642 | *out++ = 128 + *Vi; | ||
1643 | |||
1644 | *out1++ = 128 + *yi1++; | ||
1645 | *out1++ = 128 + *Ui++; | ||
1646 | *out1++ = 128 + *yi1++; | ||
1647 | *out1++ = 128 + *Vi++; | ||
1648 | } | ||
1649 | yi += width * 2; | ||
1650 | out = out1; | ||
1651 | } | ||
1652 | } | ||
1653 | |||
1654 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
1655 | struct gspca_frame *frame, /* target */ | ||
1656 | __u8 *data, /* isoc packet */ | ||
1657 | int len) /* iso packet length */ | ||
1658 | { | ||
1659 | struct sd *sd = (struct sd *) gspca_dev; | ||
1660 | |||
1661 | switch (data[0]) { | ||
1662 | case 0: /* start of frame */ | ||
1663 | if (gspca_dev->last_packet_type == FIRST_PACKET) { | ||
1664 | yuvy_decode(sd->tmpbuf2, sd->tmpbuf, | ||
1665 | gspca_dev->width, | ||
1666 | gspca_dev->height); | ||
1667 | frame = gspca_frame_add(gspca_dev, | ||
1668 | LAST_PACKET, | ||
1669 | frame, | ||
1670 | sd->tmpbuf2, | ||
1671 | gspca_dev->width | ||
1672 | * gspca_dev->height | ||
1673 | * 2); | ||
1674 | } | ||
1675 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | ||
1676 | data, 0); | ||
1677 | data += SPCA508_OFFSET_DATA; | ||
1678 | len -= SPCA508_OFFSET_DATA; | ||
1679 | if (len > 0) | ||
1680 | memcpy(sd->tmpbuf, data, len); | ||
1681 | else | ||
1682 | len = 0; | ||
1683 | sd->buflen = len; | ||
1684 | return; | ||
1685 | case 0xff: /* drop */ | ||
1686 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
1687 | return; | ||
1688 | } | ||
1689 | data += 1; | ||
1690 | len -= 1; | ||
1691 | memcpy(&sd->tmpbuf[sd->buflen], data, len); | ||
1692 | sd->buflen += len; | ||
1693 | } | ||
1694 | |||
1695 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
1696 | { | ||
1697 | struct sd *sd = (struct sd *) gspca_dev; | ||
1698 | __u8 brightness = sd->brightness; | ||
1699 | |||
1700 | /* MX seem contrast */ | ||
1701 | reg_write(gspca_dev->dev, 0x8651, brightness); | ||
1702 | reg_write(gspca_dev->dev, 0x8652, brightness); | ||
1703 | reg_write(gspca_dev->dev, 0x8653, brightness); | ||
1704 | reg_write(gspca_dev->dev, 0x8654, brightness); | ||
1705 | } | ||
1706 | |||
1707 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
1708 | { | ||
1709 | struct sd *sd = (struct sd *) gspca_dev; | ||
1710 | |||
1711 | sd->brightness = reg_read(gspca_dev, 0x8651); | ||
1712 | } | ||
1713 | |||
1714 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
1715 | { | ||
1716 | struct sd *sd = (struct sd *) gspca_dev; | ||
1717 | |||
1718 | sd->brightness = val; | ||
1719 | if (gspca_dev->streaming) | ||
1720 | setbrightness(gspca_dev); | ||
1721 | return 0; | ||
1722 | } | ||
1723 | |||
1724 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
1725 | { | ||
1726 | struct sd *sd = (struct sd *) gspca_dev; | ||
1727 | |||
1728 | getbrightness(gspca_dev); | ||
1729 | *val = sd->brightness; | ||
1730 | return 0; | ||
1731 | } | ||
1732 | |||
1733 | /* sub-driver description */ | ||
1734 | static const struct sd_desc sd_desc = { | ||
1735 | .name = MODULE_NAME, | ||
1736 | .ctrls = sd_ctrls, | ||
1737 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
1738 | .config = sd_config, | ||
1739 | .open = sd_open, | ||
1740 | .start = sd_start, | ||
1741 | .stopN = sd_stopN, | ||
1742 | .stop0 = sd_stop0, | ||
1743 | .close = sd_close, | ||
1744 | .pkt_scan = sd_pkt_scan, | ||
1745 | }; | ||
1746 | |||
1747 | /* -- module initialisation -- */ | ||
1748 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
1749 | static const __devinitdata struct usb_device_id device_table[] = { | ||
1750 | {USB_DEVICE(0x0130, 0x0130), DVNM("Clone Digital Webcam 11043")}, | ||
1751 | {USB_DEVICE(0x041e, 0x4018), DVNM("Creative Webcam Vista (PD1100)")}, | ||
1752 | {USB_DEVICE(0x0461, 0x0815), DVNM("Micro Innovation IC200")}, | ||
1753 | {USB_DEVICE(0x0733, 0x0110), DVNM("ViewQuest VQ110")}, | ||
1754 | {USB_DEVICE(0x0af9, 0x0010), DVNM("Hama USB Sightcam 100")}, | ||
1755 | {USB_DEVICE(0x0af9, 0x0011), DVNM("Hama USB Sightcam 100")}, | ||
1756 | {USB_DEVICE(0x8086, 0x0110), DVNM("Intel Easy PC Camera")}, | ||
1757 | {} | ||
1758 | }; | ||
1759 | MODULE_DEVICE_TABLE(usb, device_table); | ||
1760 | |||
1761 | /* -- device connect -- */ | ||
1762 | static int sd_probe(struct usb_interface *intf, | ||
1763 | const struct usb_device_id *id) | ||
1764 | { | ||
1765 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
1766 | THIS_MODULE); | ||
1767 | } | ||
1768 | |||
1769 | static struct usb_driver sd_driver = { | ||
1770 | .name = MODULE_NAME, | ||
1771 | .id_table = device_table, | ||
1772 | .probe = sd_probe, | ||
1773 | .disconnect = gspca_disconnect, | ||
1774 | }; | ||
1775 | |||
1776 | /* -- module insert / remove -- */ | ||
1777 | static int __init sd_mod_init(void) | ||
1778 | { | ||
1779 | if (usb_register(&sd_driver) < 0) | ||
1780 | return -1; | ||
1781 | PDEBUG(D_PROBE, "v%s registered", version); | ||
1782 | return 0; | ||
1783 | } | ||
1784 | static void __exit sd_mod_exit(void) | ||
1785 | { | ||
1786 | usb_deregister(&sd_driver); | ||
1787 | PDEBUG(D_PROBE, "deregistered"); | ||
1788 | } | ||
1789 | |||
1790 | module_init(sd_mod_init); | ||
1791 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c new file mode 100644 index 000000000000..b659bd0f788d --- /dev/null +++ b/drivers/media/video/gspca/spca561.c | |||
@@ -0,0 +1,1052 @@ | |||
1 | /* | ||
2 | * Sunplus spca561 subdriver | ||
3 | * | ||
4 | * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr | ||
5 | * | ||
6 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #define MODULE_NAME "spca561" | ||
24 | |||
25 | #include "gspca.h" | ||
26 | |||
27 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) | ||
28 | static const char version[] = "2.1.7"; | ||
29 | |||
30 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
31 | MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver"); | ||
32 | MODULE_LICENSE("GPL"); | ||
33 | |||
34 | /* specific webcam descriptor */ | ||
35 | struct sd { | ||
36 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
37 | |||
38 | unsigned short contrast; | ||
39 | __u8 brightness; | ||
40 | __u8 autogain; | ||
41 | |||
42 | __u8 chip_revision; | ||
43 | signed char ag_cnt; | ||
44 | #define AG_CNT_START 13 | ||
45 | }; | ||
46 | |||
47 | /* V4L2 controls supported by the driver */ | ||
48 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
49 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
50 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
51 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
52 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
53 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
54 | |||
55 | static struct ctrl sd_ctrls[] = { | ||
56 | #define SD_BRIGHTNESS 0 | ||
57 | { | ||
58 | { | ||
59 | .id = V4L2_CID_BRIGHTNESS, | ||
60 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
61 | .name = "Brightness", | ||
62 | .minimum = 0, | ||
63 | .maximum = 63, | ||
64 | .step = 1, | ||
65 | .default_value = 32, | ||
66 | }, | ||
67 | .set = sd_setbrightness, | ||
68 | .get = sd_getbrightness, | ||
69 | }, | ||
70 | #define SD_CONTRAST 1 | ||
71 | { | ||
72 | { | ||
73 | .id = V4L2_CID_CONTRAST, | ||
74 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
75 | .name = "Contrast", | ||
76 | .minimum = 0, | ||
77 | .maximum = 0x3fff, | ||
78 | .step = 1, | ||
79 | .default_value = 0x2000, | ||
80 | }, | ||
81 | .set = sd_setcontrast, | ||
82 | .get = sd_getcontrast, | ||
83 | }, | ||
84 | #define SD_AUTOGAIN 2 | ||
85 | { | ||
86 | { | ||
87 | .id = V4L2_CID_AUTOGAIN, | ||
88 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
89 | .name = "Auto Gain", | ||
90 | .minimum = 0, | ||
91 | .maximum = 1, | ||
92 | .step = 1, | ||
93 | .default_value = 1, | ||
94 | }, | ||
95 | .set = sd_setautogain, | ||
96 | .get = sd_getautogain, | ||
97 | }, | ||
98 | }; | ||
99 | |||
100 | static struct v4l2_pix_format sif_mode[] = { | ||
101 | {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, | ||
102 | .bytesperline = 160, | ||
103 | .sizeimage = 160 * 120, | ||
104 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
105 | .priv = 3}, | ||
106 | {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, | ||
107 | .bytesperline = 176, | ||
108 | .sizeimage = 176 * 144, | ||
109 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
110 | .priv = 2}, | ||
111 | {320, 240, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE, | ||
112 | .bytesperline = 320, | ||
113 | .sizeimage = 320 * 240 * 4 / 8, | ||
114 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
115 | .priv = 1}, | ||
116 | {352, 288, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE, | ||
117 | .bytesperline = 352, | ||
118 | .sizeimage = 352 * 288 * 4 / 8, | ||
119 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
120 | .priv = 0}, | ||
121 | }; | ||
122 | |||
123 | /* | ||
124 | * Initialization data | ||
125 | * I'm not very sure how to split initialization from open data | ||
126 | * chunks. For now, we'll consider everything as initialization | ||
127 | */ | ||
128 | /* Frame packet header offsets for the spca561 */ | ||
129 | #define SPCA561_OFFSET_SNAP 1 | ||
130 | #define SPCA561_OFFSET_TYPE 2 | ||
131 | #define SPCA561_OFFSET_COMPRESS 3 | ||
132 | #define SPCA561_OFFSET_FRAMSEQ 4 | ||
133 | #define SPCA561_OFFSET_GPIO 5 | ||
134 | #define SPCA561_OFFSET_USBBUFF 6 | ||
135 | #define SPCA561_OFFSET_WIN2GRAVE 7 | ||
136 | #define SPCA561_OFFSET_WIN2RAVE 8 | ||
137 | #define SPCA561_OFFSET_WIN2BAVE 9 | ||
138 | #define SPCA561_OFFSET_WIN2GBAVE 10 | ||
139 | #define SPCA561_OFFSET_WIN1GRAVE 11 | ||
140 | #define SPCA561_OFFSET_WIN1RAVE 12 | ||
141 | #define SPCA561_OFFSET_WIN1BAVE 13 | ||
142 | #define SPCA561_OFFSET_WIN1GBAVE 14 | ||
143 | #define SPCA561_OFFSET_FREQ 15 | ||
144 | #define SPCA561_OFFSET_VSYNC 16 | ||
145 | #define SPCA561_OFFSET_DATA 1 | ||
146 | #define SPCA561_INDEX_I2C_BASE 0x8800 | ||
147 | #define SPCA561_SNAPBIT 0x20 | ||
148 | #define SPCA561_SNAPCTRL 0x40 | ||
149 | enum { | ||
150 | Rev072A = 0, | ||
151 | Rev012A, | ||
152 | }; | ||
153 | |||
154 | static void reg_w_val(struct usb_device *dev, __u16 index, __u16 value) | ||
155 | { | ||
156 | int ret; | ||
157 | |||
158 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
159 | 0, /* request */ | ||
160 | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
161 | value, index, NULL, 0, 500); | ||
162 | PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value); | ||
163 | if (ret < 0) | ||
164 | PDEBUG(D_ERR, "reg write: error %d", ret); | ||
165 | } | ||
166 | |||
167 | static void write_vector(struct gspca_dev *gspca_dev, | ||
168 | const __u16 data[][2]) | ||
169 | { | ||
170 | struct usb_device *dev = gspca_dev->dev; | ||
171 | int i; | ||
172 | |||
173 | i = 0; | ||
174 | while (data[i][1] != 0) { | ||
175 | reg_w_val(dev, data[i][1], data[i][0]); | ||
176 | i++; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | /* read 'len' bytes to gspca_dev->usb_buf */ | ||
181 | static void reg_r(struct gspca_dev *gspca_dev, | ||
182 | __u16 index, __u16 length) | ||
183 | { | ||
184 | usb_control_msg(gspca_dev->dev, | ||
185 | usb_rcvctrlpipe(gspca_dev->dev, 0), | ||
186 | 0, /* request */ | ||
187 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
188 | 0, /* value */ | ||
189 | index, gspca_dev->usb_buf, length, 500); | ||
190 | } | ||
191 | |||
192 | static void reg_w_buf(struct gspca_dev *gspca_dev, | ||
193 | __u16 index, const __u8 *buffer, __u16 len) | ||
194 | { | ||
195 | memcpy(gspca_dev->usb_buf, buffer, len); | ||
196 | usb_control_msg(gspca_dev->dev, | ||
197 | usb_sndctrlpipe(gspca_dev->dev, 0), | ||
198 | 0, /* request */ | ||
199 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
200 | 0, /* value */ | ||
201 | index, gspca_dev->usb_buf, len, 500); | ||
202 | } | ||
203 | |||
204 | static void i2c_init(struct gspca_dev *gspca_dev, __u8 mode) | ||
205 | { | ||
206 | reg_w_val(gspca_dev->dev, 0x92, 0x8804); | ||
207 | reg_w_val(gspca_dev->dev, mode, 0x8802); | ||
208 | } | ||
209 | |||
210 | static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg) | ||
211 | { | ||
212 | int retry = 60; | ||
213 | __u8 DataLow; | ||
214 | __u8 DataHight; | ||
215 | |||
216 | DataLow = valeur; | ||
217 | DataHight = valeur >> 8; | ||
218 | reg_w_val(gspca_dev->dev, reg, 0x8801); | ||
219 | reg_w_val(gspca_dev->dev, DataLow, 0x8805); | ||
220 | reg_w_val(gspca_dev->dev, DataHight, 0x8800); | ||
221 | while (retry--) { | ||
222 | reg_r(gspca_dev, 0x8803, 1); | ||
223 | if (!gspca_dev->usb_buf[0]) | ||
224 | break; | ||
225 | } | ||
226 | } | ||
227 | |||
228 | static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode) | ||
229 | { | ||
230 | int retry = 60; | ||
231 | __u8 value; | ||
232 | __u8 vallsb; | ||
233 | |||
234 | reg_w_val(gspca_dev->dev, 0x92, 0x8804); | ||
235 | reg_w_val(gspca_dev->dev, reg, 0x8801); | ||
236 | reg_w_val(gspca_dev->dev, (mode | 0x01), 0x8802); | ||
237 | while (retry--) { | ||
238 | reg_r(gspca_dev, 0x8803, 1); | ||
239 | if (!gspca_dev->usb_buf) | ||
240 | break; | ||
241 | } | ||
242 | if (retry == 0) | ||
243 | return -1; | ||
244 | reg_r(gspca_dev, 0x8800, 1); | ||
245 | value = gspca_dev->usb_buf[0]; | ||
246 | reg_r(gspca_dev, 0x8805, 1); | ||
247 | vallsb = gspca_dev->usb_buf[0]; | ||
248 | return ((int) value << 8) | vallsb; | ||
249 | } | ||
250 | |||
251 | static const __u16 spca561_init_data[][2] = { | ||
252 | {0x0000, 0x8114}, /* Software GPIO output data */ | ||
253 | {0x0001, 0x8114}, /* Software GPIO output data */ | ||
254 | {0x0000, 0x8112}, /* Some kind of reset */ | ||
255 | {0x0003, 0x8701}, /* PCLK clock delay adjustment */ | ||
256 | {0x0001, 0x8703}, /* HSYNC from cmos inverted */ | ||
257 | {0x0011, 0x8118}, /* Enable and conf sensor */ | ||
258 | {0x0001, 0x8118}, /* Conf sensor */ | ||
259 | {0x0092, 0x8804}, /* I know nothing about these */ | ||
260 | {0x0010, 0x8802}, /* 0x88xx registers, so I won't */ | ||
261 | /***************/ | ||
262 | {0x000d, 0x8805}, /* sensor default setting */ | ||
263 | {0x0001, 0x8801}, /* 1 <- 0x0d */ | ||
264 | {0x0000, 0x8800}, | ||
265 | {0x0018, 0x8805}, | ||
266 | {0x0002, 0x8801}, /* 2 <- 0x18 */ | ||
267 | {0x0000, 0x8800}, | ||
268 | {0x0065, 0x8805}, | ||
269 | {0x0004, 0x8801}, /* 4 <- 0x01 0x65 */ | ||
270 | {0x0001, 0x8800}, | ||
271 | {0x0021, 0x8805}, | ||
272 | {0x0005, 0x8801}, /* 5 <- 0x21 */ | ||
273 | {0x0000, 0x8800}, | ||
274 | {0x00aa, 0x8805}, | ||
275 | {0x0007, 0x8801}, /* 7 <- 0xaa */ | ||
276 | {0x0000, 0x8800}, | ||
277 | {0x0004, 0x8805}, | ||
278 | {0x0020, 0x8801}, /* 0x20 <- 0x15 0x04 */ | ||
279 | {0x0015, 0x8800}, | ||
280 | {0x0002, 0x8805}, | ||
281 | {0x0039, 0x8801}, /* 0x39 <- 0x02 */ | ||
282 | {0x0000, 0x8800}, | ||
283 | {0x0010, 0x8805}, | ||
284 | {0x0035, 0x8801}, /* 0x35 <- 0x10 */ | ||
285 | {0x0000, 0x8800}, | ||
286 | {0x0049, 0x8805}, | ||
287 | {0x0009, 0x8801}, /* 0x09 <- 0x10 0x49 */ | ||
288 | {0x0010, 0x8800}, | ||
289 | {0x000b, 0x8805}, | ||
290 | {0x0028, 0x8801}, /* 0x28 <- 0x0b */ | ||
291 | {0x0000, 0x8800}, | ||
292 | {0x000f, 0x8805}, | ||
293 | {0x003b, 0x8801}, /* 0x3b <- 0x0f */ | ||
294 | {0x0000, 0x8800}, | ||
295 | {0x0000, 0x8805}, | ||
296 | {0x003c, 0x8801}, /* 0x3c <- 0x00 */ | ||
297 | {0x0000, 0x8800}, | ||
298 | /***************/ | ||
299 | {0x0018, 0x8601}, /* Pixel/line selection for color separation */ | ||
300 | {0x0000, 0x8602}, /* Optical black level for user setting */ | ||
301 | {0x0060, 0x8604}, /* Optical black horizontal offset */ | ||
302 | {0x0002, 0x8605}, /* Optical black vertical offset */ | ||
303 | {0x0000, 0x8603}, /* Non-automatic optical black level */ | ||
304 | {0x0002, 0x865b}, /* Horizontal offset for valid pixels */ | ||
305 | {0x0000, 0x865f}, /* Vertical valid pixels window (x2) */ | ||
306 | {0x00b0, 0x865d}, /* Horizontal valid pixels window (x2) */ | ||
307 | {0x0090, 0x865e}, /* Vertical valid lines window (x2) */ | ||
308 | {0x00e0, 0x8406}, /* Memory buffer threshold */ | ||
309 | {0x0000, 0x8660}, /* Compensation memory stuff */ | ||
310 | {0x0002, 0x8201}, /* Output address for r/w serial EEPROM */ | ||
311 | {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */ | ||
312 | {0x0001, 0x8200}, /* OprMode to be executed by hardware */ | ||
313 | {0x0007, 0x8201}, /* Output address for r/w serial EEPROM */ | ||
314 | {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */ | ||
315 | {0x0001, 0x8200}, /* OprMode to be executed by hardware */ | ||
316 | {0x0010, 0x8660}, /* Compensation memory stuff */ | ||
317 | {0x0018, 0x8660}, /* Compensation memory stuff */ | ||
318 | |||
319 | {0x0004, 0x8611}, /* R offset for white balance */ | ||
320 | {0x0004, 0x8612}, /* Gr offset for white balance */ | ||
321 | {0x0007, 0x8613}, /* B offset for white balance */ | ||
322 | {0x0000, 0x8614}, /* Gb offset for white balance */ | ||
323 | {0x008c, 0x8651}, /* R gain for white balance */ | ||
324 | {0x008c, 0x8652}, /* Gr gain for white balance */ | ||
325 | {0x00b5, 0x8653}, /* B gain for white balance */ | ||
326 | {0x008c, 0x8654}, /* Gb gain for white balance */ | ||
327 | {0x0002, 0x8502}, /* Maximum average bit rate stuff */ | ||
328 | |||
329 | {0x0011, 0x8802}, | ||
330 | {0x0087, 0x8700}, /* Set master clock (96Mhz????) */ | ||
331 | {0x0081, 0x8702}, /* Master clock output enable */ | ||
332 | |||
333 | {0x0000, 0x8500}, /* Set image type (352x288 no compression) */ | ||
334 | /* Originally was 0x0010 (352x288 compression) */ | ||
335 | |||
336 | {0x0002, 0x865b}, /* Horizontal offset for valid pixels */ | ||
337 | {0x0003, 0x865c}, /* Vertical offset for valid lines */ | ||
338 | /***************//* sensor active */ | ||
339 | {0x0003, 0x8801}, /* 0x03 <- 0x01 0x21 //289 */ | ||
340 | {0x0021, 0x8805}, | ||
341 | {0x0001, 0x8800}, | ||
342 | {0x0004, 0x8801}, /* 0x04 <- 0x01 0x65 //357 */ | ||
343 | {0x0065, 0x8805}, | ||
344 | {0x0001, 0x8800}, | ||
345 | {0x0005, 0x8801}, /* 0x05 <- 0x2f */ | ||
346 | {0x002f, 0x8805}, | ||
347 | {0x0000, 0x8800}, | ||
348 | {0x0006, 0x8801}, /* 0x06 <- 0 */ | ||
349 | {0x0000, 0x8805}, | ||
350 | {0x0000, 0x8800}, | ||
351 | {0x000a, 0x8801}, /* 0x0a <- 2 */ | ||
352 | {0x0002, 0x8805}, | ||
353 | {0x0000, 0x8800}, | ||
354 | {0x0009, 0x8801}, /* 0x09 <- 0x1061 */ | ||
355 | {0x0061, 0x8805}, | ||
356 | {0x0010, 0x8800}, | ||
357 | {0x0035, 0x8801}, /* 0x35 <-0x14 */ | ||
358 | {0x0014, 0x8805}, | ||
359 | {0x0000, 0x8800}, | ||
360 | {0x0030, 0x8112}, /* ISO and drop packet enable */ | ||
361 | {0x0000, 0x8112}, /* Some kind of reset ???? */ | ||
362 | {0x0009, 0x8118}, /* Enable sensor and set standby */ | ||
363 | {0x0000, 0x8114}, /* Software GPIO output data */ | ||
364 | {0x0000, 0x8114}, /* Software GPIO output data */ | ||
365 | {0x0001, 0x8114}, /* Software GPIO output data */ | ||
366 | {0x0000, 0x8112}, /* Some kind of reset ??? */ | ||
367 | {0x0003, 0x8701}, | ||
368 | {0x0001, 0x8703}, | ||
369 | {0x0011, 0x8118}, | ||
370 | {0x0001, 0x8118}, | ||
371 | /***************/ | ||
372 | {0x0092, 0x8804}, | ||
373 | {0x0010, 0x8802}, | ||
374 | {0x000d, 0x8805}, | ||
375 | {0x0001, 0x8801}, | ||
376 | {0x0000, 0x8800}, | ||
377 | {0x0018, 0x8805}, | ||
378 | {0x0002, 0x8801}, | ||
379 | {0x0000, 0x8800}, | ||
380 | {0x0065, 0x8805}, | ||
381 | {0x0004, 0x8801}, | ||
382 | {0x0001, 0x8800}, | ||
383 | {0x0021, 0x8805}, | ||
384 | {0x0005, 0x8801}, | ||
385 | {0x0000, 0x8800}, | ||
386 | {0x00aa, 0x8805}, | ||
387 | {0x0007, 0x8801}, /* mode 0xaa */ | ||
388 | {0x0000, 0x8800}, | ||
389 | {0x0004, 0x8805}, | ||
390 | {0x0020, 0x8801}, | ||
391 | {0x0015, 0x8800}, /* mode 0x0415 */ | ||
392 | {0x0002, 0x8805}, | ||
393 | {0x0039, 0x8801}, | ||
394 | {0x0000, 0x8800}, | ||
395 | {0x0010, 0x8805}, | ||
396 | {0x0035, 0x8801}, | ||
397 | {0x0000, 0x8800}, | ||
398 | {0x0049, 0x8805}, | ||
399 | {0x0009, 0x8801}, | ||
400 | {0x0010, 0x8800}, | ||
401 | {0x000b, 0x8805}, | ||
402 | {0x0028, 0x8801}, | ||
403 | {0x0000, 0x8800}, | ||
404 | {0x000f, 0x8805}, | ||
405 | {0x003b, 0x8801}, | ||
406 | {0x0000, 0x8800}, | ||
407 | {0x0000, 0x8805}, | ||
408 | {0x003c, 0x8801}, | ||
409 | {0x0000, 0x8800}, | ||
410 | {0x0002, 0x8502}, | ||
411 | {0x0039, 0x8801}, | ||
412 | {0x0000, 0x8805}, | ||
413 | {0x0000, 0x8800}, | ||
414 | |||
415 | {0x0087, 0x8700}, /* overwrite by start */ | ||
416 | {0x0081, 0x8702}, | ||
417 | {0x0000, 0x8500}, | ||
418 | /* {0x0010, 0x8500}, -- Previous line was this */ | ||
419 | {0x0002, 0x865b}, | ||
420 | {0x0003, 0x865c}, | ||
421 | /***************/ | ||
422 | {0x0003, 0x8801}, /* 0x121-> 289 */ | ||
423 | {0x0021, 0x8805}, | ||
424 | {0x0001, 0x8800}, | ||
425 | {0x0004, 0x8801}, /* 0x165 -> 357 */ | ||
426 | {0x0065, 0x8805}, | ||
427 | {0x0001, 0x8800}, | ||
428 | {0x0005, 0x8801}, /* 0x2f //blanking control colonne */ | ||
429 | {0x002f, 0x8805}, | ||
430 | {0x0000, 0x8800}, | ||
431 | {0x0006, 0x8801}, /* 0x00 //blanking mode row */ | ||
432 | {0x0000, 0x8805}, | ||
433 | {0x0000, 0x8800}, | ||
434 | {0x000a, 0x8801}, /* 0x01 //0x02 */ | ||
435 | {0x0001, 0x8805}, | ||
436 | {0x0000, 0x8800}, | ||
437 | {0x0009, 0x8801}, /* 0x1061 - setexposure times && pixel clock | ||
438 | * 0001 0 | 000 0110 0001 */ | ||
439 | {0x0061, 0x8805}, /* 61 31 */ | ||
440 | {0x0008, 0x8800}, /* 08 */ | ||
441 | {0x0035, 0x8801}, /* 0x14 - set gain general */ | ||
442 | {0x001f, 0x8805}, /* 0x14 */ | ||
443 | {0x0000, 0x8800}, | ||
444 | {0x0030, 0x8112}, | ||
445 | {} | ||
446 | }; | ||
447 | |||
448 | static void sensor_reset(struct gspca_dev *gspca_dev) | ||
449 | { | ||
450 | reg_w_val(gspca_dev->dev, 0x8631, 0xc8); | ||
451 | reg_w_val(gspca_dev->dev, 0x8634, 0xc8); | ||
452 | reg_w_val(gspca_dev->dev, 0x8112, 0x00); | ||
453 | reg_w_val(gspca_dev->dev, 0x8114, 0x00); | ||
454 | reg_w_val(gspca_dev->dev, 0x8118, 0x21); | ||
455 | i2c_init(gspca_dev, 0x14); | ||
456 | i2c_write(gspca_dev, 1, 0x0d); | ||
457 | i2c_write(gspca_dev, 0, 0x0d); | ||
458 | } | ||
459 | |||
460 | /******************** QC Express etch2 stuff ********************/ | ||
461 | static const __u16 Pb100_1map8300[][2] = { | ||
462 | /* reg, value */ | ||
463 | {0x8320, 0x3304}, | ||
464 | |||
465 | {0x8303, 0x0125}, /* image area */ | ||
466 | {0x8304, 0x0169}, | ||
467 | {0x8328, 0x000b}, | ||
468 | {0x833c, 0x0001}, | ||
469 | |||
470 | {0x832f, 0x0419}, | ||
471 | {0x8307, 0x00aa}, | ||
472 | {0x8301, 0x0003}, | ||
473 | {0x8302, 0x000e}, | ||
474 | {} | ||
475 | }; | ||
476 | static const __u16 Pb100_2map8300[][2] = { | ||
477 | /* reg, value */ | ||
478 | {0x8339, 0x0000}, | ||
479 | {0x8307, 0x00aa}, | ||
480 | {} | ||
481 | }; | ||
482 | |||
483 | static const __u16 spca561_161rev12A_data1[][2] = { | ||
484 | {0x21, 0x8118}, | ||
485 | {0x01, 0x8114}, | ||
486 | {0x00, 0x8112}, | ||
487 | {0x92, 0x8804}, | ||
488 | {0x04, 0x8802}, /* windows uses 08 */ | ||
489 | {} | ||
490 | }; | ||
491 | static const __u16 spca561_161rev12A_data2[][2] = { | ||
492 | {0x21, 0x8118}, | ||
493 | {0x10, 0x8500}, | ||
494 | {0x07, 0x8601}, | ||
495 | {0x07, 0x8602}, | ||
496 | {0x04, 0x8501}, | ||
497 | {0x21, 0x8118}, | ||
498 | |||
499 | {0x07, 0x8201}, /* windows uses 02 */ | ||
500 | {0x08, 0x8200}, | ||
501 | {0x01, 0x8200}, | ||
502 | |||
503 | {0x00, 0x8114}, | ||
504 | {0x01, 0x8114}, /* windows uses 00 */ | ||
505 | |||
506 | {0x90, 0x8604}, | ||
507 | {0x00, 0x8605}, | ||
508 | {0xb0, 0x8603}, | ||
509 | |||
510 | /* sensor gains */ | ||
511 | {0x00, 0x8610}, /* *red */ | ||
512 | {0x00, 0x8611}, /* 3f *green */ | ||
513 | {0x00, 0x8612}, /* green *blue */ | ||
514 | {0x00, 0x8613}, /* blue *green */ | ||
515 | {0x35, 0x8614}, /* green *red */ | ||
516 | {0x35, 0x8615}, /* 40 *green */ | ||
517 | {0x35, 0x8616}, /* 7a *blue */ | ||
518 | {0x35, 0x8617}, /* 40 *green */ | ||
519 | |||
520 | {0x0c, 0x8620}, /* 0c */ | ||
521 | {0xc8, 0x8631}, /* c8 */ | ||
522 | {0xc8, 0x8634}, /* c8 */ | ||
523 | {0x23, 0x8635}, /* 23 */ | ||
524 | {0x1f, 0x8636}, /* 1f */ | ||
525 | {0xdd, 0x8637}, /* dd */ | ||
526 | {0xe1, 0x8638}, /* e1 */ | ||
527 | {0x1d, 0x8639}, /* 1d */ | ||
528 | {0x21, 0x863a}, /* 21 */ | ||
529 | {0xe3, 0x863b}, /* e3 */ | ||
530 | {0xdf, 0x863c}, /* df */ | ||
531 | {0xf0, 0x8505}, | ||
532 | {0x32, 0x850a}, | ||
533 | {} | ||
534 | }; | ||
535 | |||
536 | static void sensor_mapwrite(struct gspca_dev *gspca_dev, | ||
537 | const __u16 sensormap[][2]) | ||
538 | { | ||
539 | int i = 0; | ||
540 | __u8 usbval[2]; | ||
541 | |||
542 | while (sensormap[i][0]) { | ||
543 | usbval[0] = sensormap[i][1]; | ||
544 | usbval[1] = sensormap[i][1] >> 8; | ||
545 | reg_w_buf(gspca_dev, sensormap[i][0], usbval, 2); | ||
546 | i++; | ||
547 | } | ||
548 | } | ||
549 | static void init_161rev12A(struct gspca_dev *gspca_dev) | ||
550 | { | ||
551 | sensor_reset(gspca_dev); | ||
552 | write_vector(gspca_dev, spca561_161rev12A_data1); | ||
553 | sensor_mapwrite(gspca_dev, Pb100_1map8300); | ||
554 | write_vector(gspca_dev, spca561_161rev12A_data2); | ||
555 | sensor_mapwrite(gspca_dev, Pb100_2map8300); | ||
556 | } | ||
557 | |||
558 | /* this function is called at probe time */ | ||
559 | static int sd_config(struct gspca_dev *gspca_dev, | ||
560 | const struct usb_device_id *id) | ||
561 | { | ||
562 | struct sd *sd = (struct sd *) gspca_dev; | ||
563 | struct cam *cam; | ||
564 | __u16 vendor, product; | ||
565 | __u8 data1, data2; | ||
566 | |||
567 | /* Read frm global register the USB product and vendor IDs, just to | ||
568 | * prove that we can communicate with the device. This works, which | ||
569 | * confirms at we are communicating properly and that the device | ||
570 | * is a 561. */ | ||
571 | reg_r(gspca_dev, 0x8104, 1); | ||
572 | data1 = gspca_dev->usb_buf[0]; | ||
573 | reg_r(gspca_dev, 0x8105, 1); | ||
574 | data2 = gspca_dev->usb_buf[0]; | ||
575 | vendor = (data2 << 8) | data1; | ||
576 | reg_r(gspca_dev, 0x8106, 1); | ||
577 | data1 = gspca_dev->usb_buf[0]; | ||
578 | reg_r(gspca_dev, 0x8107, 1); | ||
579 | data2 = gspca_dev->usb_buf[0]; | ||
580 | product = (data2 << 8) | data1; | ||
581 | if (vendor != id->idVendor || product != id->idProduct) { | ||
582 | PDEBUG(D_PROBE, "Bad vendor / product from device"); | ||
583 | return -EINVAL; | ||
584 | } | ||
585 | switch (product) { | ||
586 | case 0x0928: | ||
587 | case 0x0929: | ||
588 | case 0x092a: | ||
589 | case 0x092b: | ||
590 | case 0x092c: | ||
591 | case 0x092d: | ||
592 | case 0x092e: | ||
593 | case 0x092f: | ||
594 | case 0x403b: | ||
595 | sd->chip_revision = Rev012A; | ||
596 | break; | ||
597 | default: | ||
598 | /* case 0x0561: | ||
599 | case 0x0815: * ?? in spca508.c | ||
600 | case 0x401a: | ||
601 | case 0x7004: | ||
602 | case 0x7e50: | ||
603 | case 0xa001: | ||
604 | case 0xcdee: */ | ||
605 | sd->chip_revision = Rev072A; | ||
606 | break; | ||
607 | } | ||
608 | cam = &gspca_dev->cam; | ||
609 | cam->dev_name = (char *) id->driver_info; | ||
610 | cam->epaddr = 0x01; | ||
611 | gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */ | ||
612 | cam->cam_mode = sif_mode; | ||
613 | cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; | ||
614 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
615 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | ||
616 | sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; | ||
617 | return 0; | ||
618 | } | ||
619 | |||
620 | /* this function is called at open time */ | ||
621 | static int sd_open(struct gspca_dev *gspca_dev) | ||
622 | { | ||
623 | struct sd *sd = (struct sd *) gspca_dev; | ||
624 | |||
625 | switch (sd->chip_revision) { | ||
626 | case Rev072A: | ||
627 | PDEBUG(D_STREAM, "Chip revision id: 072a"); | ||
628 | write_vector(gspca_dev, spca561_init_data); | ||
629 | break; | ||
630 | default: | ||
631 | /* case Rev012A: */ | ||
632 | PDEBUG(D_STREAM, "Chip revision id: 012a"); | ||
633 | init_161rev12A(gspca_dev); | ||
634 | break; | ||
635 | } | ||
636 | return 0; | ||
637 | } | ||
638 | |||
639 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
640 | { | ||
641 | struct sd *sd = (struct sd *) gspca_dev; | ||
642 | struct usb_device *dev = gspca_dev->dev; | ||
643 | __u8 lowb; | ||
644 | int expotimes; | ||
645 | |||
646 | switch (sd->chip_revision) { | ||
647 | case Rev072A: | ||
648 | lowb = sd->contrast >> 8; | ||
649 | reg_w_val(dev, lowb, 0x8651); | ||
650 | reg_w_val(dev, lowb, 0x8652); | ||
651 | reg_w_val(dev, lowb, 0x8653); | ||
652 | reg_w_val(dev, lowb, 0x8654); | ||
653 | break; | ||
654 | case Rev012A: { | ||
655 | __u8 Reg8391[] = | ||
656 | { 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00 }; | ||
657 | |||
658 | /* Write camera sensor settings */ | ||
659 | expotimes = (sd->contrast >> 5) & 0x07ff; | ||
660 | Reg8391[0] = expotimes & 0xff; /* exposure */ | ||
661 | Reg8391[1] = 0x18 | (expotimes >> 8); | ||
662 | Reg8391[2] = sd->brightness; /* gain */ | ||
663 | reg_w_buf(gspca_dev, 0x8391, Reg8391, 8); | ||
664 | reg_w_buf(gspca_dev, 0x8390, Reg8391, 8); | ||
665 | break; | ||
666 | } | ||
667 | } | ||
668 | } | ||
669 | |||
670 | static void sd_start(struct gspca_dev *gspca_dev) | ||
671 | { | ||
672 | struct sd *sd = (struct sd *) gspca_dev; | ||
673 | struct usb_device *dev = gspca_dev->dev; | ||
674 | int Clck; | ||
675 | __u8 Reg8307[] = { 0xaa, 0x00 }; | ||
676 | int mode; | ||
677 | |||
678 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | ||
679 | switch (sd->chip_revision) { | ||
680 | case Rev072A: | ||
681 | switch (mode) { | ||
682 | default: | ||
683 | /* case 0: | ||
684 | case 1: */ | ||
685 | Clck = 0x25; | ||
686 | break; | ||
687 | case 2: | ||
688 | Clck = 0x22; | ||
689 | break; | ||
690 | case 3: | ||
691 | Clck = 0x21; | ||
692 | break; | ||
693 | } | ||
694 | reg_w_val(dev, 0x8500, mode); /* mode */ | ||
695 | reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ | ||
696 | reg_w_val(dev, 0x8112, 0x10 | 0x20); | ||
697 | break; | ||
698 | default: | ||
699 | /* case Rev012A: */ | ||
700 | switch (mode) { | ||
701 | case 0: | ||
702 | case 1: | ||
703 | Clck = 0x8a; | ||
704 | break; | ||
705 | case 2: | ||
706 | Clck = 0x85; | ||
707 | break; | ||
708 | default: | ||
709 | Clck = 0x83; | ||
710 | break; | ||
711 | } | ||
712 | if (mode <= 1) { | ||
713 | /* Use compression on 320x240 and above */ | ||
714 | reg_w_val(dev, 0x8500, 0x10 | mode); | ||
715 | } else { | ||
716 | /* I couldn't get the compression to work below 320x240 | ||
717 | * Fortunately at these resolutions the bandwidth | ||
718 | * is sufficient to push raw frames at ~20fps */ | ||
719 | reg_w_val(dev, 0x8500, mode); | ||
720 | } /* -- qq@kuku.eu.org */ | ||
721 | reg_w_buf(gspca_dev, 0x8307, Reg8307, 2); | ||
722 | reg_w_val(gspca_dev->dev, 0x8700, Clck); | ||
723 | /* 0x8f 0x85 0x27 clock */ | ||
724 | reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20); | ||
725 | reg_w_val(gspca_dev->dev, 0x850b, 0x03); | ||
726 | setcontrast(gspca_dev); | ||
727 | break; | ||
728 | } | ||
729 | } | ||
730 | |||
731 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
732 | { | ||
733 | reg_w_val(gspca_dev->dev, 0x8112, 0x20); | ||
734 | } | ||
735 | |||
736 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
737 | { | ||
738 | } | ||
739 | |||
740 | /* this function is called at close time */ | ||
741 | static void sd_close(struct gspca_dev *gspca_dev) | ||
742 | { | ||
743 | reg_w_val(gspca_dev->dev, 0x8114, 0); | ||
744 | } | ||
745 | |||
746 | static void setautogain(struct gspca_dev *gspca_dev) | ||
747 | { | ||
748 | struct sd *sd = (struct sd *) gspca_dev; | ||
749 | int expotimes = 0; | ||
750 | int pixelclk = 0; | ||
751 | int gainG = 0; | ||
752 | __u8 R, Gr, Gb, B; | ||
753 | int y; | ||
754 | __u8 luma_mean = 110; | ||
755 | __u8 luma_delta = 20; | ||
756 | __u8 spring = 4; | ||
757 | |||
758 | switch (sd->chip_revision) { | ||
759 | case Rev072A: | ||
760 | reg_r(gspca_dev, 0x8621, 1); | ||
761 | Gr = gspca_dev->usb_buf[0]; | ||
762 | reg_r(gspca_dev, 0x8622, 1); | ||
763 | R = gspca_dev->usb_buf[0]; | ||
764 | reg_r(gspca_dev, 0x8623, 1); | ||
765 | B = gspca_dev->usb_buf[0]; | ||
766 | reg_r(gspca_dev, 0x8624, 1); | ||
767 | Gb = gspca_dev->usb_buf[0]; | ||
768 | y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8; | ||
769 | /* u= (128*B-(43*(Gr+Gb+R))) >> 8; */ | ||
770 | /* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */ | ||
771 | /* PDEBUG(D_CONF,"reading Y %d U %d V %d ",y,u,v); */ | ||
772 | |||
773 | if (y < luma_mean - luma_delta || | ||
774 | y > luma_mean + luma_delta) { | ||
775 | expotimes = i2c_read(gspca_dev, 0x09, 0x10); | ||
776 | pixelclk = 0x0800; | ||
777 | expotimes = expotimes & 0x07ff; | ||
778 | /* PDEBUG(D_PACK, | ||
779 | "Exposition Times 0x%03X Clock 0x%04X ", | ||
780 | expotimes,pixelclk); */ | ||
781 | gainG = i2c_read(gspca_dev, 0x35, 0x10); | ||
782 | /* PDEBUG(D_PACK, | ||
783 | "reading Gain register %d", gainG); */ | ||
784 | |||
785 | expotimes += (luma_mean - y) >> spring; | ||
786 | gainG += (luma_mean - y) / 50; | ||
787 | /* PDEBUG(D_PACK, | ||
788 | "compute expotimes %d gain %d", | ||
789 | expotimes,gainG); */ | ||
790 | |||
791 | if (gainG > 0x3f) | ||
792 | gainG = 0x3f; | ||
793 | else if (gainG < 4) | ||
794 | gainG = 3; | ||
795 | i2c_write(gspca_dev, gainG, 0x35); | ||
796 | |||
797 | if (expotimes >= 0x0256) | ||
798 | expotimes = 0x0256; | ||
799 | else if (expotimes < 4) | ||
800 | expotimes = 3; | ||
801 | i2c_write(gspca_dev, expotimes | pixelclk, 0x09); | ||
802 | } | ||
803 | break; | ||
804 | case Rev012A: | ||
805 | /* sensor registers is access and memory mapped to 0x8300 */ | ||
806 | /* readind all 0x83xx block the sensor */ | ||
807 | /* | ||
808 | * The data from the header seem wrong where is the luma | ||
809 | * and chroma mean value | ||
810 | * at the moment set exposure in contrast set | ||
811 | */ | ||
812 | break; | ||
813 | } | ||
814 | } | ||
815 | |||
816 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
817 | struct gspca_frame *frame, /* target */ | ||
818 | __u8 *data, /* isoc packet */ | ||
819 | int len) /* iso packet length */ | ||
820 | { | ||
821 | struct sd *sd = (struct sd *) gspca_dev; | ||
822 | |||
823 | switch (data[0]) { | ||
824 | case 0: /* start of frame */ | ||
825 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | ||
826 | data, 0); | ||
827 | if (sd->ag_cnt >= 0) { | ||
828 | if (--sd->ag_cnt < 0) { | ||
829 | sd->ag_cnt = AG_CNT_START; | ||
830 | setautogain(gspca_dev); | ||
831 | } | ||
832 | } | ||
833 | data += SPCA561_OFFSET_DATA; | ||
834 | len -= SPCA561_OFFSET_DATA; | ||
835 | if (data[1] & 0x10) { | ||
836 | /* compressed bayer */ | ||
837 | gspca_frame_add(gspca_dev, FIRST_PACKET, | ||
838 | frame, data, len); | ||
839 | } else { | ||
840 | /* raw bayer (with a header, which we skip) */ | ||
841 | data += 20; | ||
842 | len -= 20; | ||
843 | gspca_frame_add(gspca_dev, FIRST_PACKET, | ||
844 | frame, data, len); | ||
845 | } | ||
846 | return; | ||
847 | case 0xff: /* drop */ | ||
848 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
849 | return; | ||
850 | } | ||
851 | data++; | ||
852 | len--; | ||
853 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
854 | } | ||
855 | |||
856 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
857 | { | ||
858 | struct sd *sd = (struct sd *) gspca_dev; | ||
859 | __u8 value; | ||
860 | |||
861 | switch (sd->chip_revision) { | ||
862 | case Rev072A: | ||
863 | value = sd->brightness; | ||
864 | reg_w_val(gspca_dev->dev, value, 0x8611); | ||
865 | reg_w_val(gspca_dev->dev, value, 0x8612); | ||
866 | reg_w_val(gspca_dev->dev, value, 0x8613); | ||
867 | reg_w_val(gspca_dev->dev, value, 0x8614); | ||
868 | break; | ||
869 | default: | ||
870 | /* case Rev012A: */ | ||
871 | setcontrast(gspca_dev); | ||
872 | break; | ||
873 | } | ||
874 | } | ||
875 | |||
876 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
877 | { | ||
878 | struct sd *sd = (struct sd *) gspca_dev; | ||
879 | __u16 tot; | ||
880 | |||
881 | switch (sd->chip_revision) { | ||
882 | case Rev072A: | ||
883 | tot = 0; | ||
884 | reg_r(gspca_dev, 0x8611, 1); | ||
885 | tot += gspca_dev->usb_buf[0]; | ||
886 | reg_r(gspca_dev, 0x8612, 1); | ||
887 | tot += gspca_dev->usb_buf[0]; | ||
888 | reg_r(gspca_dev, 0x8613, 1); | ||
889 | tot += gspca_dev->usb_buf[0]; | ||
890 | reg_r(gspca_dev, 0x8614, 1); | ||
891 | tot += gspca_dev->usb_buf[0]; | ||
892 | sd->brightness = tot >> 2; | ||
893 | break; | ||
894 | default: | ||
895 | /* case Rev012A: */ | ||
896 | /* no way to read sensor settings */ | ||
897 | break; | ||
898 | } | ||
899 | } | ||
900 | |||
901 | static void getcontrast(struct gspca_dev *gspca_dev) | ||
902 | { | ||
903 | struct sd *sd = (struct sd *) gspca_dev; | ||
904 | __u16 tot; | ||
905 | |||
906 | switch (sd->chip_revision) { | ||
907 | case Rev072A: | ||
908 | tot = 0; | ||
909 | reg_r(gspca_dev, 0x8651, 1); | ||
910 | tot += gspca_dev->usb_buf[0]; | ||
911 | reg_r(gspca_dev, 0x8652, 1); | ||
912 | tot += gspca_dev->usb_buf[0]; | ||
913 | reg_r(gspca_dev, 0x8653, 1); | ||
914 | tot += gspca_dev->usb_buf[0]; | ||
915 | reg_r(gspca_dev, 0x8654, 1); | ||
916 | tot += gspca_dev->usb_buf[0]; | ||
917 | sd->contrast = tot << 6; | ||
918 | break; | ||
919 | default: | ||
920 | /* case Rev012A: */ | ||
921 | /* no way to read sensor settings */ | ||
922 | break; | ||
923 | } | ||
924 | PDEBUG(D_CONF, "get contrast %d", sd->contrast); | ||
925 | } | ||
926 | |||
927 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
928 | { | ||
929 | struct sd *sd = (struct sd *) gspca_dev; | ||
930 | |||
931 | sd->brightness = val; | ||
932 | if (gspca_dev->streaming) | ||
933 | setbrightness(gspca_dev); | ||
934 | return 0; | ||
935 | } | ||
936 | |||
937 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
938 | { | ||
939 | struct sd *sd = (struct sd *) gspca_dev; | ||
940 | |||
941 | getbrightness(gspca_dev); | ||
942 | *val = sd->brightness; | ||
943 | return 0; | ||
944 | } | ||
945 | |||
946 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
947 | { | ||
948 | struct sd *sd = (struct sd *) gspca_dev; | ||
949 | |||
950 | sd->contrast = val; | ||
951 | if (gspca_dev->streaming) | ||
952 | setcontrast(gspca_dev); | ||
953 | return 0; | ||
954 | } | ||
955 | |||
956 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
957 | { | ||
958 | struct sd *sd = (struct sd *) gspca_dev; | ||
959 | |||
960 | getcontrast(gspca_dev); | ||
961 | *val = sd->contrast; | ||
962 | return 0; | ||
963 | } | ||
964 | |||
965 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
966 | { | ||
967 | struct sd *sd = (struct sd *) gspca_dev; | ||
968 | |||
969 | sd->autogain = val; | ||
970 | if (val) | ||
971 | sd->ag_cnt = AG_CNT_START; | ||
972 | else | ||
973 | sd->ag_cnt = -1; | ||
974 | return 0; | ||
975 | } | ||
976 | |||
977 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | ||
978 | { | ||
979 | struct sd *sd = (struct sd *) gspca_dev; | ||
980 | |||
981 | *val = sd->autogain; | ||
982 | return 0; | ||
983 | } | ||
984 | |||
985 | /* sub-driver description */ | ||
986 | static const struct sd_desc sd_desc = { | ||
987 | .name = MODULE_NAME, | ||
988 | .ctrls = sd_ctrls, | ||
989 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
990 | .config = sd_config, | ||
991 | .open = sd_open, | ||
992 | .start = sd_start, | ||
993 | .stopN = sd_stopN, | ||
994 | .stop0 = sd_stop0, | ||
995 | .close = sd_close, | ||
996 | .pkt_scan = sd_pkt_scan, | ||
997 | }; | ||
998 | |||
999 | /* -- module initialisation -- */ | ||
1000 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
1001 | static const __devinitdata struct usb_device_id device_table[] = { | ||
1002 | {USB_DEVICE(0x041e, 0x401a), DVNM("Creative Webcam Vista (PD1100)")}, | ||
1003 | {USB_DEVICE(0x041e, 0x403b), DVNM("Creative Webcam Vista (VF0010)")}, | ||
1004 | {USB_DEVICE(0x0458, 0x7004), DVNM("Genius VideoCAM Express V2")}, | ||
1005 | {USB_DEVICE(0x046d, 0x0928), DVNM("Logitech QC Express Etch2")}, | ||
1006 | {USB_DEVICE(0x046d, 0x0929), DVNM("Labtec Webcam Elch2")}, | ||
1007 | {USB_DEVICE(0x046d, 0x092a), DVNM("Logitech QC for Notebook")}, | ||
1008 | {USB_DEVICE(0x046d, 0x092b), DVNM("Labtec Webcam Plus")}, | ||
1009 | {USB_DEVICE(0x046d, 0x092c), DVNM("Logitech QC chat Elch2")}, | ||
1010 | {USB_DEVICE(0x046d, 0x092d), DVNM("Logitech QC Elch2")}, | ||
1011 | {USB_DEVICE(0x046d, 0x092e), DVNM("Logitech QC Elch2")}, | ||
1012 | {USB_DEVICE(0x046d, 0x092f), DVNM("Logitech QC Elch2")}, | ||
1013 | {USB_DEVICE(0x04fc, 0x0561), DVNM("Flexcam 100")}, | ||
1014 | {USB_DEVICE(0x060b, 0xa001), DVNM("Maxell Compact Pc PM3")}, | ||
1015 | {USB_DEVICE(0x10fd, 0x7e50), DVNM("FlyCam Usb 100")}, | ||
1016 | {USB_DEVICE(0xabcd, 0xcdee), DVNM("Petcam")}, | ||
1017 | {} | ||
1018 | }; | ||
1019 | |||
1020 | MODULE_DEVICE_TABLE(usb, device_table); | ||
1021 | |||
1022 | /* -- device connect -- */ | ||
1023 | static int sd_probe(struct usb_interface *intf, | ||
1024 | const struct usb_device_id *id) | ||
1025 | { | ||
1026 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
1027 | THIS_MODULE); | ||
1028 | } | ||
1029 | |||
1030 | static struct usb_driver sd_driver = { | ||
1031 | .name = MODULE_NAME, | ||
1032 | .id_table = device_table, | ||
1033 | .probe = sd_probe, | ||
1034 | .disconnect = gspca_disconnect, | ||
1035 | }; | ||
1036 | |||
1037 | /* -- module insert / remove -- */ | ||
1038 | static int __init sd_mod_init(void) | ||
1039 | { | ||
1040 | if (usb_register(&sd_driver) < 0) | ||
1041 | return -1; | ||
1042 | PDEBUG(D_PROBE, "v%s registered", version); | ||
1043 | return 0; | ||
1044 | } | ||
1045 | static void __exit sd_mod_exit(void) | ||
1046 | { | ||
1047 | usb_deregister(&sd_driver); | ||
1048 | PDEBUG(D_PROBE, "deregistered"); | ||
1049 | } | ||
1050 | |||
1051 | module_init(sd_mod_init); | ||
1052 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c new file mode 100644 index 000000000000..c78ee0d3e59b --- /dev/null +++ b/drivers/media/video/gspca/stk014.c | |||
@@ -0,0 +1,592 @@ | |||
1 | /* | ||
2 | * Syntek DV4000 (STK014) subdriver | ||
3 | * | ||
4 | * Copyright (C) 2008 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 "stk014" | ||
22 | |||
23 | #include "gspca.h" | ||
24 | #include "jpeg.h" | ||
25 | |||
26 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) | ||
27 | static const char version[] = "2.1.7"; | ||
28 | |||
29 | MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); | ||
30 | MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver"); | ||
31 | MODULE_LICENSE("GPL"); | ||
32 | |||
33 | /* specific webcam descriptor */ | ||
34 | struct sd { | ||
35 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
36 | |||
37 | unsigned char brightness; | ||
38 | unsigned char contrast; | ||
39 | unsigned char colors; | ||
40 | unsigned char lightfreq; | ||
41 | }; | ||
42 | |||
43 | /* global parameters */ | ||
44 | static int sd_quant = 7; /* <= 4 KO - 7: good (enough!) */ | ||
45 | |||
46 | /* V4L2 controls supported by the driver */ | ||
47 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
48 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
49 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
50 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
51 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
52 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
53 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | ||
54 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | ||
55 | |||
56 | static struct ctrl sd_ctrls[] = { | ||
57 | { | ||
58 | { | ||
59 | .id = V4L2_CID_BRIGHTNESS, | ||
60 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
61 | .name = "Brightness", | ||
62 | .minimum = 0, | ||
63 | .maximum = 255, | ||
64 | .step = 1, | ||
65 | #define BRIGHTNESS_DEF 127 | ||
66 | .default_value = BRIGHTNESS_DEF, | ||
67 | }, | ||
68 | .set = sd_setbrightness, | ||
69 | .get = sd_getbrightness, | ||
70 | }, | ||
71 | { | ||
72 | { | ||
73 | .id = V4L2_CID_CONTRAST, | ||
74 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
75 | .name = "Contrast", | ||
76 | .minimum = 0, | ||
77 | .maximum = 255, | ||
78 | .step = 1, | ||
79 | #define CONTRAST_DEF 127 | ||
80 | .default_value = CONTRAST_DEF, | ||
81 | }, | ||
82 | .set = sd_setcontrast, | ||
83 | .get = sd_getcontrast, | ||
84 | }, | ||
85 | { | ||
86 | { | ||
87 | .id = V4L2_CID_SATURATION, | ||
88 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
89 | .name = "Color", | ||
90 | .minimum = 0, | ||
91 | .maximum = 255, | ||
92 | .step = 1, | ||
93 | #define COLOR_DEF 127 | ||
94 | .default_value = COLOR_DEF, | ||
95 | }, | ||
96 | .set = sd_setcolors, | ||
97 | .get = sd_getcolors, | ||
98 | }, | ||
99 | { | ||
100 | { | ||
101 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | ||
102 | .type = V4L2_CTRL_TYPE_MENU, | ||
103 | .name = "Light frequency filter", | ||
104 | .minimum = 1, | ||
105 | .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ | ||
106 | .step = 1, | ||
107 | #define FREQ_DEF 1 | ||
108 | .default_value = FREQ_DEF, | ||
109 | }, | ||
110 | .set = sd_setfreq, | ||
111 | .get = sd_getfreq, | ||
112 | }, | ||
113 | }; | ||
114 | |||
115 | static struct v4l2_pix_format vga_mode[] = { | ||
116 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
117 | .bytesperline = 320, | ||
118 | .sizeimage = 320 * 240 * 3 / 8 + 590, | ||
119 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
120 | .priv = 1}, | ||
121 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
122 | .bytesperline = 640, | ||
123 | .sizeimage = 640 * 480 * 3 / 8 + 590, | ||
124 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
125 | .priv = 0}, | ||
126 | }; | ||
127 | |||
128 | /* -- read a register -- */ | ||
129 | static int reg_r(struct gspca_dev *gspca_dev, | ||
130 | __u16 index) | ||
131 | { | ||
132 | struct usb_device *dev = gspca_dev->dev; | ||
133 | int ret; | ||
134 | |||
135 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | ||
136 | 0x00, | ||
137 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
138 | 0x00, | ||
139 | index, | ||
140 | gspca_dev->usb_buf, 1, | ||
141 | 500); | ||
142 | if (ret < 0) { | ||
143 | PDEBUG(D_ERR, "reg_r err %d", ret); | ||
144 | return ret; | ||
145 | } | ||
146 | return gspca_dev->usb_buf[0]; | ||
147 | } | ||
148 | |||
149 | /* -- write a register -- */ | ||
150 | static int reg_w(struct gspca_dev *gspca_dev, | ||
151 | __u16 index, __u16 value) | ||
152 | { | ||
153 | struct usb_device *dev = gspca_dev->dev; | ||
154 | int ret; | ||
155 | |||
156 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
157 | 0x01, | ||
158 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
159 | value, | ||
160 | index, | ||
161 | NULL, | ||
162 | 0, | ||
163 | 500); | ||
164 | if (ret < 0) | ||
165 | PDEBUG(D_ERR, "reg_w err %d", ret); | ||
166 | return ret; | ||
167 | } | ||
168 | |||
169 | /* -- get a bulk value (4 bytes) -- */ | ||
170 | static int rcv_val(struct gspca_dev *gspca_dev, | ||
171 | int ads) | ||
172 | { | ||
173 | struct usb_device *dev = gspca_dev->dev; | ||
174 | int alen, ret; | ||
175 | |||
176 | reg_w(gspca_dev, 0x634, (ads >> 16) & 0xff); | ||
177 | reg_w(gspca_dev, 0x635, (ads >> 8) & 0xff); | ||
178 | reg_w(gspca_dev, 0x636, ads & 0xff); | ||
179 | reg_w(gspca_dev, 0x637, 0); | ||
180 | reg_w(gspca_dev, 0x638, 4); /* len & 0xff */ | ||
181 | reg_w(gspca_dev, 0x639, 0); /* len >> 8 */ | ||
182 | reg_w(gspca_dev, 0x63a, 0); | ||
183 | reg_w(gspca_dev, 0x63b, 0); | ||
184 | reg_w(gspca_dev, 0x630, 5); | ||
185 | ret = usb_bulk_msg(dev, | ||
186 | usb_rcvbulkpipe(dev, 5), | ||
187 | gspca_dev->usb_buf, | ||
188 | 4, /* length */ | ||
189 | &alen, | ||
190 | 500); /* timeout in milliseconds */ | ||
191 | return ret; | ||
192 | } | ||
193 | |||
194 | /* -- send a bulk value -- */ | ||
195 | static int snd_val(struct gspca_dev *gspca_dev, | ||
196 | int ads, | ||
197 | unsigned int val) | ||
198 | { | ||
199 | struct usb_device *dev = gspca_dev->dev; | ||
200 | int alen, ret; | ||
201 | __u8 seq = 0; | ||
202 | |||
203 | if (ads == 0x003f08) { | ||
204 | ret = reg_r(gspca_dev, 0x0704); | ||
205 | if (ret < 0) | ||
206 | goto ko; | ||
207 | ret = reg_r(gspca_dev, 0x0705); | ||
208 | if (ret < 0) | ||
209 | goto ko; | ||
210 | seq = ret; /* keep the sequence number */ | ||
211 | ret = reg_r(gspca_dev, 0x0650); | ||
212 | if (ret < 0) | ||
213 | goto ko; | ||
214 | reg_w(gspca_dev, 0x654, seq); | ||
215 | } else { | ||
216 | reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff); | ||
217 | } | ||
218 | reg_w(gspca_dev, 0x655, (ads >> 8) & 0xff); | ||
219 | reg_w(gspca_dev, 0x656, ads & 0xff); | ||
220 | reg_w(gspca_dev, 0x657, 0); | ||
221 | reg_w(gspca_dev, 0x658, 0x04); /* size */ | ||
222 | reg_w(gspca_dev, 0x659, 0); | ||
223 | reg_w(gspca_dev, 0x65a, 0); | ||
224 | reg_w(gspca_dev, 0x65b, 0); | ||
225 | reg_w(gspca_dev, 0x650, 5); | ||
226 | gspca_dev->usb_buf[0] = val >> 24; | ||
227 | gspca_dev->usb_buf[1] = val >> 16; | ||
228 | gspca_dev->usb_buf[2] = val >> 8; | ||
229 | gspca_dev->usb_buf[3] = val; | ||
230 | ret = usb_bulk_msg(dev, | ||
231 | usb_sndbulkpipe(dev, 6), | ||
232 | gspca_dev->usb_buf, | ||
233 | 4, | ||
234 | &alen, | ||
235 | 500); /* timeout in milliseconds */ | ||
236 | if (ret < 0) | ||
237 | goto ko; | ||
238 | if (ads == 0x003f08) { | ||
239 | seq += 4; | ||
240 | seq &= 0x3f; | ||
241 | reg_w(gspca_dev, 0x705, seq); | ||
242 | } | ||
243 | return ret; | ||
244 | ko: | ||
245 | PDEBUG(D_ERR, "snd_val err %d", ret); | ||
246 | return ret; | ||
247 | } | ||
248 | |||
249 | /* set a camera parameter */ | ||
250 | static int set_par(struct gspca_dev *gspca_dev, | ||
251 | int parval) | ||
252 | { | ||
253 | return snd_val(gspca_dev, 0x003f08, parval); | ||
254 | } | ||
255 | |||
256 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
257 | { | ||
258 | struct sd *sd = (struct sd *) gspca_dev; | ||
259 | int parval; | ||
260 | |||
261 | parval = 0x06000000 /* whiteness */ | ||
262 | + (sd->brightness << 16); | ||
263 | set_par(gspca_dev, parval); | ||
264 | } | ||
265 | |||
266 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
267 | { | ||
268 | struct sd *sd = (struct sd *) gspca_dev; | ||
269 | int parval; | ||
270 | |||
271 | parval = 0x07000000 /* contrast */ | ||
272 | + (sd->contrast << 16); | ||
273 | set_par(gspca_dev, parval); | ||
274 | } | ||
275 | |||
276 | static void setcolors(struct gspca_dev *gspca_dev) | ||
277 | { | ||
278 | struct sd *sd = (struct sd *) gspca_dev; | ||
279 | int parval; | ||
280 | |||
281 | parval = 0x08000000 /* saturation */ | ||
282 | + (sd->colors << 16); | ||
283 | set_par(gspca_dev, parval); | ||
284 | } | ||
285 | |||
286 | static void setfreq(struct gspca_dev *gspca_dev) | ||
287 | { | ||
288 | struct sd *sd = (struct sd *) gspca_dev; | ||
289 | |||
290 | set_par(gspca_dev, sd->lightfreq == 1 | ||
291 | ? 0x33640000 /* 50 Hz */ | ||
292 | : 0x33780000); /* 60 Hz */ | ||
293 | } | ||
294 | |||
295 | /* this function is called at probe time */ | ||
296 | static int sd_config(struct gspca_dev *gspca_dev, | ||
297 | const struct usb_device_id *id) | ||
298 | { | ||
299 | struct sd *sd = (struct sd *) gspca_dev; | ||
300 | struct cam *cam = &gspca_dev->cam; | ||
301 | |||
302 | cam->dev_name = (char *) id->driver_info; | ||
303 | cam->epaddr = 0x02; | ||
304 | gspca_dev->cam.cam_mode = vga_mode; | ||
305 | gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); | ||
306 | sd->brightness = BRIGHTNESS_DEF; | ||
307 | sd->contrast = CONTRAST_DEF; | ||
308 | sd->colors = COLOR_DEF; | ||
309 | sd->lightfreq = FREQ_DEF; | ||
310 | return 0; | ||
311 | } | ||
312 | |||
313 | /* this function is called at open time */ | ||
314 | static int sd_open(struct gspca_dev *gspca_dev) | ||
315 | { | ||
316 | int ret; | ||
317 | |||
318 | /* check if the device responds */ | ||
319 | usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); | ||
320 | ret = reg_r(gspca_dev, 0x0740); | ||
321 | if (ret < 0) | ||
322 | return ret; | ||
323 | if (ret != 0xff) { | ||
324 | PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", ret); | ||
325 | return -1; | ||
326 | } | ||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | /* -- start the camera -- */ | ||
331 | static void sd_start(struct gspca_dev *gspca_dev) | ||
332 | { | ||
333 | int ret, value; | ||
334 | |||
335 | /* work on alternate 1 */ | ||
336 | usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); | ||
337 | |||
338 | set_par(gspca_dev, 0x10000000); | ||
339 | set_par(gspca_dev, 0x00000000); | ||
340 | set_par(gspca_dev, 0x8002e001); | ||
341 | set_par(gspca_dev, 0x14000000); | ||
342 | if (gspca_dev->width > 320) | ||
343 | value = 0x8002e001; /* 640x480 */ | ||
344 | else | ||
345 | value = 0x4001f000; /* 320x240 */ | ||
346 | set_par(gspca_dev, value); | ||
347 | ret = usb_set_interface(gspca_dev->dev, | ||
348 | gspca_dev->iface, | ||
349 | gspca_dev->alt); | ||
350 | if (ret < 0) { | ||
351 | PDEBUG(D_ERR|D_STREAM, "set intf %d %d failed", | ||
352 | gspca_dev->iface, gspca_dev->alt); | ||
353 | goto out; | ||
354 | } | ||
355 | ret = reg_r(gspca_dev, 0x0630); | ||
356 | if (ret < 0) | ||
357 | goto out; | ||
358 | rcv_val(gspca_dev, 0x000020); /* << (value ff ff ff ff) */ | ||
359 | ret = reg_r(gspca_dev, 0x0650); | ||
360 | if (ret < 0) | ||
361 | goto out; | ||
362 | snd_val(gspca_dev, 0x000020, 0xffffffff); | ||
363 | reg_w(gspca_dev, 0x0620, 0); | ||
364 | reg_w(gspca_dev, 0x0630, 0); | ||
365 | reg_w(gspca_dev, 0x0640, 0); | ||
366 | reg_w(gspca_dev, 0x0650, 0); | ||
367 | reg_w(gspca_dev, 0x0660, 0); | ||
368 | setbrightness(gspca_dev); /* whiteness */ | ||
369 | setcontrast(gspca_dev); /* contrast */ | ||
370 | setcolors(gspca_dev); /* saturation */ | ||
371 | set_par(gspca_dev, 0x09800000); /* Red ? */ | ||
372 | set_par(gspca_dev, 0x0a800000); /* Green ? */ | ||
373 | set_par(gspca_dev, 0x0b800000); /* Blue ? */ | ||
374 | set_par(gspca_dev, 0x0d030000); /* Gamma ? */ | ||
375 | setfreq(gspca_dev); /* light frequency */ | ||
376 | |||
377 | /* start the video flow */ | ||
378 | set_par(gspca_dev, 0x01000000); | ||
379 | set_par(gspca_dev, 0x01000000); | ||
380 | PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt); | ||
381 | return; | ||
382 | out: | ||
383 | PDEBUG(D_ERR|D_STREAM, "camera start err %d", ret); | ||
384 | } | ||
385 | |||
386 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
387 | { | ||
388 | struct usb_device *dev = gspca_dev->dev; | ||
389 | |||
390 | set_par(gspca_dev, 0x02000000); | ||
391 | set_par(gspca_dev, 0x02000000); | ||
392 | usb_set_interface(dev, gspca_dev->iface, 1); | ||
393 | reg_r(gspca_dev, 0x0630); | ||
394 | rcv_val(gspca_dev, 0x000020); /* << (value ff ff ff ff) */ | ||
395 | reg_r(gspca_dev, 0x0650); | ||
396 | snd_val(gspca_dev, 0x000020, 0xffffffff); | ||
397 | reg_w(gspca_dev, 0x0620, 0); | ||
398 | reg_w(gspca_dev, 0x0630, 0); | ||
399 | reg_w(gspca_dev, 0x0640, 0); | ||
400 | reg_w(gspca_dev, 0x0650, 0); | ||
401 | reg_w(gspca_dev, 0x0660, 0); | ||
402 | PDEBUG(D_STREAM, "camera stopped"); | ||
403 | } | ||
404 | |||
405 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
406 | { | ||
407 | } | ||
408 | |||
409 | static void sd_close(struct gspca_dev *gspca_dev) | ||
410 | { | ||
411 | } | ||
412 | |||
413 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
414 | struct gspca_frame *frame, /* target */ | ||
415 | __u8 *data, /* isoc packet */ | ||
416 | int len) /* iso packet length */ | ||
417 | { | ||
418 | static unsigned char ffd9[] = {0xff, 0xd9}; | ||
419 | |||
420 | /* a frame starts with: | ||
421 | * - 0xff 0xfe | ||
422 | * - 0x08 0x00 - length (little endian ?!) | ||
423 | * - 4 bytes = size of whole frame (BE - including header) | ||
424 | * - 0x00 0x0c | ||
425 | * - 0xff 0xd8 | ||
426 | * - .. JPEG image with escape sequences (ff 00) | ||
427 | * (without ending - ff d9) | ||
428 | */ | ||
429 | if (data[0] == 0xff && data[1] == 0xfe) { | ||
430 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | ||
431 | ffd9, 2); | ||
432 | |||
433 | /* put the JPEG 411 header */ | ||
434 | jpeg_put_header(gspca_dev, frame, sd_quant, 0x22); | ||
435 | |||
436 | /* beginning of the frame */ | ||
437 | #define STKHDRSZ 12 | ||
438 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
439 | data + STKHDRSZ, len - STKHDRSZ); | ||
440 | #undef STKHDRSZ | ||
441 | return; | ||
442 | } | ||
443 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
444 | } | ||
445 | |||
446 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
447 | { | ||
448 | struct sd *sd = (struct sd *) gspca_dev; | ||
449 | |||
450 | sd->brightness = val; | ||
451 | if (gspca_dev->streaming) | ||
452 | setbrightness(gspca_dev); | ||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
457 | { | ||
458 | struct sd *sd = (struct sd *) gspca_dev; | ||
459 | |||
460 | *val = sd->brightness; | ||
461 | return 0; | ||
462 | } | ||
463 | |||
464 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
465 | { | ||
466 | struct sd *sd = (struct sd *) gspca_dev; | ||
467 | |||
468 | sd->contrast = val; | ||
469 | if (gspca_dev->streaming) | ||
470 | setcontrast(gspca_dev); | ||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
475 | { | ||
476 | struct sd *sd = (struct sd *) gspca_dev; | ||
477 | |||
478 | *val = sd->contrast; | ||
479 | return 0; | ||
480 | } | ||
481 | |||
482 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
483 | { | ||
484 | struct sd *sd = (struct sd *) gspca_dev; | ||
485 | |||
486 | sd->colors = val; | ||
487 | if (gspca_dev->streaming) | ||
488 | setcolors(gspca_dev); | ||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
493 | { | ||
494 | struct sd *sd = (struct sd *) gspca_dev; | ||
495 | |||
496 | *val = sd->colors; | ||
497 | return 0; | ||
498 | } | ||
499 | |||
500 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | ||
501 | { | ||
502 | struct sd *sd = (struct sd *) gspca_dev; | ||
503 | |||
504 | sd->lightfreq = val; | ||
505 | if (gspca_dev->streaming) | ||
506 | setfreq(gspca_dev); | ||
507 | return 0; | ||
508 | } | ||
509 | |||
510 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) | ||
511 | { | ||
512 | struct sd *sd = (struct sd *) gspca_dev; | ||
513 | |||
514 | *val = sd->lightfreq; | ||
515 | return 0; | ||
516 | } | ||
517 | |||
518 | static int sd_querymenu(struct gspca_dev *gspca_dev, | ||
519 | struct v4l2_querymenu *menu) | ||
520 | { | ||
521 | switch (menu->id) { | ||
522 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
523 | switch (menu->index) { | ||
524 | case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ | ||
525 | strcpy((char *) menu->name, "50 Hz"); | ||
526 | return 0; | ||
527 | case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ | ||
528 | strcpy((char *) menu->name, "60 Hz"); | ||
529 | return 0; | ||
530 | } | ||
531 | break; | ||
532 | } | ||
533 | return -EINVAL; | ||
534 | } | ||
535 | |||
536 | /* sub-driver description */ | ||
537 | static const struct sd_desc sd_desc = { | ||
538 | .name = MODULE_NAME, | ||
539 | .ctrls = sd_ctrls, | ||
540 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
541 | .config = sd_config, | ||
542 | .open = sd_open, | ||
543 | .start = sd_start, | ||
544 | .stopN = sd_stopN, | ||
545 | .stop0 = sd_stop0, | ||
546 | .close = sd_close, | ||
547 | .pkt_scan = sd_pkt_scan, | ||
548 | .querymenu = sd_querymenu, | ||
549 | }; | ||
550 | |||
551 | /* -- module initialisation -- */ | ||
552 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
553 | static const __devinitdata struct usb_device_id device_table[] = { | ||
554 | {USB_DEVICE(0x05e1, 0x0893), DVNM("Syntek DV4000")}, | ||
555 | {} | ||
556 | }; | ||
557 | MODULE_DEVICE_TABLE(usb, device_table); | ||
558 | |||
559 | /* -- device connect -- */ | ||
560 | static int sd_probe(struct usb_interface *intf, | ||
561 | const struct usb_device_id *id) | ||
562 | { | ||
563 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
564 | THIS_MODULE); | ||
565 | } | ||
566 | |||
567 | static struct usb_driver sd_driver = { | ||
568 | .name = MODULE_NAME, | ||
569 | .id_table = device_table, | ||
570 | .probe = sd_probe, | ||
571 | .disconnect = gspca_disconnect, | ||
572 | }; | ||
573 | |||
574 | /* -- module insert / remove -- */ | ||
575 | static int __init sd_mod_init(void) | ||
576 | { | ||
577 | if (usb_register(&sd_driver) < 0) | ||
578 | return -1; | ||
579 | info("v%s registered", version); | ||
580 | return 0; | ||
581 | } | ||
582 | static void __exit sd_mod_exit(void) | ||
583 | { | ||
584 | usb_deregister(&sd_driver); | ||
585 | info("deregistered"); | ||
586 | } | ||
587 | |||
588 | module_init(sd_mod_init); | ||
589 | module_exit(sd_mod_exit); | ||
590 | |||
591 | module_param_named(quant, sd_quant, int, 0644); | ||
592 | MODULE_PARM_DESC(quant, "Quantization index (0..8)"); | ||
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c new file mode 100644 index 000000000000..abd7bef9b3d1 --- /dev/null +++ b/drivers/media/video/gspca/sunplus.c | |||
@@ -0,0 +1,1677 @@ | |||
1 | /* | ||
2 | * Sunplus spca504(abc) spca533 spca536 library | ||
3 | * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr | ||
4 | * | ||
5 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #define MODULE_NAME "sunplus" | ||
23 | |||
24 | #include "gspca.h" | ||
25 | #include "jpeg.h" | ||
26 | |||
27 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 8) | ||
28 | static const char version[] = "2.1.8"; | ||
29 | |||
30 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
31 | MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver"); | ||
32 | MODULE_LICENSE("GPL"); | ||
33 | |||
34 | /* specific webcam descriptor */ | ||
35 | struct sd { | ||
36 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
37 | |||
38 | __u8 packet[ISO_MAX_SIZE + 128]; | ||
39 | /* !! no more than 128 ff in an ISO packet */ | ||
40 | |||
41 | unsigned char brightness; | ||
42 | unsigned char contrast; | ||
43 | unsigned char colors; | ||
44 | unsigned char autogain; | ||
45 | |||
46 | char qindex; | ||
47 | char bridge; | ||
48 | #define BRIDGE_SPCA504 0 | ||
49 | #define BRIDGE_SPCA504B 1 | ||
50 | #define BRIDGE_SPCA504C 2 | ||
51 | #define BRIDGE_SPCA533 3 | ||
52 | #define BRIDGE_SPCA536 4 | ||
53 | char subtype; | ||
54 | #define AiptekMiniPenCam13 1 | ||
55 | #define LogitechClickSmart420 2 | ||
56 | #define LogitechClickSmart820 3 | ||
57 | #define MegapixV4 4 | ||
58 | }; | ||
59 | |||
60 | /* V4L2 controls supported by the driver */ | ||
61 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
62 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
63 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
64 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
65 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
66 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
67 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
68 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
69 | |||
70 | static struct ctrl sd_ctrls[] = { | ||
71 | #define SD_BRIGHTNESS 0 | ||
72 | { | ||
73 | { | ||
74 | .id = V4L2_CID_BRIGHTNESS, | ||
75 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
76 | .name = "Brightness", | ||
77 | .minimum = 0, | ||
78 | .maximum = 0xff, | ||
79 | .step = 1, | ||
80 | .default_value = 0, | ||
81 | }, | ||
82 | .set = sd_setbrightness, | ||
83 | .get = sd_getbrightness, | ||
84 | }, | ||
85 | #define SD_CONTRAST 1 | ||
86 | { | ||
87 | { | ||
88 | .id = V4L2_CID_CONTRAST, | ||
89 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
90 | .name = "Contrast", | ||
91 | .minimum = 0, | ||
92 | .maximum = 0xff, | ||
93 | .step = 1, | ||
94 | .default_value = 0x20, | ||
95 | }, | ||
96 | .set = sd_setcontrast, | ||
97 | .get = sd_getcontrast, | ||
98 | }, | ||
99 | #define SD_COLOR 2 | ||
100 | { | ||
101 | { | ||
102 | .id = V4L2_CID_SATURATION, | ||
103 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
104 | .name = "Color", | ||
105 | .minimum = 0, | ||
106 | .maximum = 0xff, | ||
107 | .step = 1, | ||
108 | .default_value = 0x1a, | ||
109 | }, | ||
110 | .set = sd_setcolors, | ||
111 | .get = sd_getcolors, | ||
112 | }, | ||
113 | #define SD_AUTOGAIN 3 | ||
114 | { | ||
115 | { | ||
116 | .id = V4L2_CID_AUTOGAIN, | ||
117 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
118 | .name = "Auto Gain", | ||
119 | .minimum = 0, | ||
120 | .maximum = 1, | ||
121 | .step = 1, | ||
122 | .default_value = 1, | ||
123 | }, | ||
124 | .set = sd_setautogain, | ||
125 | .get = sd_getautogain, | ||
126 | }, | ||
127 | }; | ||
128 | |||
129 | static struct v4l2_pix_format vga_mode[] = { | ||
130 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
131 | .bytesperline = 320, | ||
132 | .sizeimage = 320 * 240 * 3 / 8 + 590, | ||
133 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
134 | .priv = 2}, | ||
135 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
136 | .bytesperline = 640, | ||
137 | .sizeimage = 640 * 480 * 3 / 8 + 590, | ||
138 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
139 | .priv = 1}, | ||
140 | }; | ||
141 | |||
142 | static struct v4l2_pix_format custom_mode[] = { | ||
143 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
144 | .bytesperline = 320, | ||
145 | .sizeimage = 320 * 240 * 3 / 8 + 590, | ||
146 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
147 | .priv = 2}, | ||
148 | {464, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
149 | .bytesperline = 464, | ||
150 | .sizeimage = 464 * 480 * 3 / 8 + 590, | ||
151 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
152 | .priv = 1}, | ||
153 | }; | ||
154 | |||
155 | static struct v4l2_pix_format vga_mode2[] = { | ||
156 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
157 | .bytesperline = 176, | ||
158 | .sizeimage = 176 * 144 * 3 / 8 + 590, | ||
159 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
160 | .priv = 4}, | ||
161 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
162 | .bytesperline = 320, | ||
163 | .sizeimage = 320 * 240 * 3 / 8 + 590, | ||
164 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
165 | .priv = 3}, | ||
166 | {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
167 | .bytesperline = 352, | ||
168 | .sizeimage = 352 * 288 * 3 / 8 + 590, | ||
169 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
170 | .priv = 2}, | ||
171 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
172 | .bytesperline = 640, | ||
173 | .sizeimage = 640 * 480 * 3 / 8 + 590, | ||
174 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
175 | .priv = 1}, | ||
176 | }; | ||
177 | |||
178 | #define SPCA50X_OFFSET_DATA 10 | ||
179 | #define SPCA504_PCCAM600_OFFSET_SNAPSHOT 3 | ||
180 | #define SPCA504_PCCAM600_OFFSET_COMPRESS 4 | ||
181 | #define SPCA504_PCCAM600_OFFSET_MODE 5 | ||
182 | #define SPCA504_PCCAM600_OFFSET_DATA 14 | ||
183 | /* Frame packet header offsets for the spca533 */ | ||
184 | #define SPCA533_OFFSET_DATA 16 | ||
185 | #define SPCA533_OFFSET_FRAMSEQ 15 | ||
186 | /* Frame packet header offsets for the spca536 */ | ||
187 | #define SPCA536_OFFSET_DATA 4 | ||
188 | #define SPCA536_OFFSET_FRAMSEQ 1 | ||
189 | |||
190 | /* Initialisation data for the Creative PC-CAM 600 */ | ||
191 | static const __u16 spca504_pccam600_init_data[][3] = { | ||
192 | /* {0xa0, 0x0000, 0x0503}, * capture mode */ | ||
193 | {0x00, 0x0000, 0x2000}, | ||
194 | {0x00, 0x0013, 0x2301}, | ||
195 | {0x00, 0x0003, 0x2000}, | ||
196 | {0x00, 0x0001, 0x21ac}, | ||
197 | {0x00, 0x0001, 0x21a6}, | ||
198 | {0x00, 0x0000, 0x21a7}, /* brightness */ | ||
199 | {0x00, 0x0020, 0x21a8}, /* contrast */ | ||
200 | {0x00, 0x0001, 0x21ac}, /* sat/hue */ | ||
201 | {0x00, 0x0000, 0x21ad}, /* hue */ | ||
202 | {0x00, 0x001a, 0x21ae}, /* saturation */ | ||
203 | {0x00, 0x0002, 0x21a3}, /* gamma */ | ||
204 | {0x30, 0x0154, 0x0008}, | ||
205 | {0x30, 0x0004, 0x0006}, | ||
206 | {0x30, 0x0258, 0x0009}, | ||
207 | {0x30, 0x0004, 0x0000}, | ||
208 | {0x30, 0x0093, 0x0004}, | ||
209 | {0x30, 0x0066, 0x0005}, | ||
210 | {0x00, 0x0000, 0x2000}, | ||
211 | {0x00, 0x0013, 0x2301}, | ||
212 | {0x00, 0x0003, 0x2000}, | ||
213 | {0x00, 0x0013, 0x2301}, | ||
214 | {0x00, 0x0003, 0x2000}, | ||
215 | {} | ||
216 | }; | ||
217 | |||
218 | /* Creative PC-CAM 600 specific open data, sent before using the | ||
219 | * generic initialisation data from spca504_open_data. | ||
220 | */ | ||
221 | static const __u16 spca504_pccam600_open_data[][3] = { | ||
222 | {0x00, 0x0001, 0x2501}, | ||
223 | {0x20, 0x0500, 0x0001}, /* snapshot mode */ | ||
224 | {0x00, 0x0003, 0x2880}, | ||
225 | {0x00, 0x0001, 0x2881}, | ||
226 | {} | ||
227 | }; | ||
228 | |||
229 | /* Initialisation data for the logitech clicksmart 420 */ | ||
230 | static const __u16 spca504A_clicksmart420_init_data[][3] = { | ||
231 | /* {0xa0, 0x0000, 0x0503}, * capture mode */ | ||
232 | {0x00, 0x0000, 0x2000}, | ||
233 | {0x00, 0x0013, 0x2301}, | ||
234 | {0x00, 0x0003, 0x2000}, | ||
235 | {0x00, 0x0001, 0x21ac}, | ||
236 | {0x00, 0x0001, 0x21a6}, | ||
237 | {0x00, 0x0000, 0x21a7}, /* brightness */ | ||
238 | {0x00, 0x0020, 0x21a8}, /* contrast */ | ||
239 | {0x00, 0x0001, 0x21ac}, /* sat/hue */ | ||
240 | {0x00, 0x0000, 0x21ad}, /* hue */ | ||
241 | {0x00, 0x001a, 0x21ae}, /* saturation */ | ||
242 | {0x00, 0x0002, 0x21a3}, /* gamma */ | ||
243 | {0x30, 0x0004, 0x000a}, | ||
244 | {0xb0, 0x0001, 0x0000}, | ||
245 | |||
246 | |||
247 | {0x0a1, 0x0080, 0x0001}, | ||
248 | {0x30, 0x0049, 0x0000}, | ||
249 | {0x30, 0x0060, 0x0005}, | ||
250 | {0x0c, 0x0004, 0x0000}, | ||
251 | {0x00, 0x0000, 0x0000}, | ||
252 | {0x00, 0x0000, 0x2000}, | ||
253 | {0x00, 0x0013, 0x2301}, | ||
254 | {0x00, 0x0003, 0x2000}, | ||
255 | {0x00, 0x0000, 0x2000}, | ||
256 | |||
257 | {} | ||
258 | }; | ||
259 | |||
260 | /* clicksmart 420 open data ? */ | ||
261 | static const __u16 spca504A_clicksmart420_open_data[][3] = { | ||
262 | {0x00, 0x0001, 0x2501}, | ||
263 | {0x20, 0x0502, 0x0000}, | ||
264 | {0x06, 0x0000, 0x0000}, | ||
265 | {0x00, 0x0004, 0x2880}, | ||
266 | {0x00, 0x0001, 0x2881}, | ||
267 | /* look like setting a qTable */ | ||
268 | {0x00, 0x0006, 0x2800}, | ||
269 | {0x00, 0x0004, 0x2801}, | ||
270 | {0x00, 0x0004, 0x2802}, | ||
271 | {0x00, 0x0006, 0x2803}, | ||
272 | {0x00, 0x000a, 0x2804}, | ||
273 | {0x00, 0x0010, 0x2805}, | ||
274 | {0x00, 0x0014, 0x2806}, | ||
275 | {0x00, 0x0018, 0x2807}, | ||
276 | {0x00, 0x0005, 0x2808}, | ||
277 | {0x00, 0x0005, 0x2809}, | ||
278 | {0x00, 0x0006, 0x280a}, | ||
279 | {0x00, 0x0008, 0x280b}, | ||
280 | {0x00, 0x000a, 0x280c}, | ||
281 | {0x00, 0x0017, 0x280d}, | ||
282 | {0x00, 0x0018, 0x280e}, | ||
283 | {0x00, 0x0016, 0x280f}, | ||
284 | |||
285 | {0x00, 0x0006, 0x2810}, | ||
286 | {0x00, 0x0005, 0x2811}, | ||
287 | {0x00, 0x0006, 0x2812}, | ||
288 | {0x00, 0x000a, 0x2813}, | ||
289 | {0x00, 0x0010, 0x2814}, | ||
290 | {0x00, 0x0017, 0x2815}, | ||
291 | {0x00, 0x001c, 0x2816}, | ||
292 | {0x00, 0x0016, 0x2817}, | ||
293 | {0x00, 0x0006, 0x2818}, | ||
294 | {0x00, 0x0007, 0x2819}, | ||
295 | {0x00, 0x0009, 0x281a}, | ||
296 | {0x00, 0x000c, 0x281b}, | ||
297 | {0x00, 0x0014, 0x281c}, | ||
298 | {0x00, 0x0023, 0x281d}, | ||
299 | {0x00, 0x0020, 0x281e}, | ||
300 | {0x00, 0x0019, 0x281f}, | ||
301 | |||
302 | {0x00, 0x0007, 0x2820}, | ||
303 | {0x00, 0x0009, 0x2821}, | ||
304 | {0x00, 0x000f, 0x2822}, | ||
305 | {0x00, 0x0016, 0x2823}, | ||
306 | {0x00, 0x001b, 0x2824}, | ||
307 | {0x00, 0x002c, 0x2825}, | ||
308 | {0x00, 0x0029, 0x2826}, | ||
309 | {0x00, 0x001f, 0x2827}, | ||
310 | {0x00, 0x000a, 0x2828}, | ||
311 | {0x00, 0x000e, 0x2829}, | ||
312 | {0x00, 0x0016, 0x282a}, | ||
313 | {0x00, 0x001a, 0x282b}, | ||
314 | {0x00, 0x0020, 0x282c}, | ||
315 | {0x00, 0x002a, 0x282d}, | ||
316 | {0x00, 0x002d, 0x282e}, | ||
317 | {0x00, 0x0025, 0x282f}, | ||
318 | |||
319 | {0x00, 0x0014, 0x2830}, | ||
320 | {0x00, 0x001a, 0x2831}, | ||
321 | {0x00, 0x001f, 0x2832}, | ||
322 | {0x00, 0x0023, 0x2833}, | ||
323 | {0x00, 0x0029, 0x2834}, | ||
324 | {0x00, 0x0030, 0x2835}, | ||
325 | {0x00, 0x0030, 0x2836}, | ||
326 | {0x00, 0x0028, 0x2837}, | ||
327 | {0x00, 0x001d, 0x2838}, | ||
328 | {0x00, 0x0025, 0x2839}, | ||
329 | {0x00, 0x0026, 0x283a}, | ||
330 | {0x00, 0x0027, 0x283b}, | ||
331 | {0x00, 0x002d, 0x283c}, | ||
332 | {0x00, 0x0028, 0x283d}, | ||
333 | {0x00, 0x0029, 0x283e}, | ||
334 | {0x00, 0x0028, 0x283f}, | ||
335 | |||
336 | {0x00, 0x0007, 0x2840}, | ||
337 | {0x00, 0x0007, 0x2841}, | ||
338 | {0x00, 0x000a, 0x2842}, | ||
339 | {0x00, 0x0013, 0x2843}, | ||
340 | {0x00, 0x0028, 0x2844}, | ||
341 | {0x00, 0x0028, 0x2845}, | ||
342 | {0x00, 0x0028, 0x2846}, | ||
343 | {0x00, 0x0028, 0x2847}, | ||
344 | {0x00, 0x0007, 0x2848}, | ||
345 | {0x00, 0x0008, 0x2849}, | ||
346 | {0x00, 0x000a, 0x284a}, | ||
347 | {0x00, 0x001a, 0x284b}, | ||
348 | {0x00, 0x0028, 0x284c}, | ||
349 | {0x00, 0x0028, 0x284d}, | ||
350 | {0x00, 0x0028, 0x284e}, | ||
351 | {0x00, 0x0028, 0x284f}, | ||
352 | |||
353 | {0x00, 0x000a, 0x2850}, | ||
354 | {0x00, 0x000a, 0x2851}, | ||
355 | {0x00, 0x0016, 0x2852}, | ||
356 | {0x00, 0x0028, 0x2853}, | ||
357 | {0x00, 0x0028, 0x2854}, | ||
358 | {0x00, 0x0028, 0x2855}, | ||
359 | {0x00, 0x0028, 0x2856}, | ||
360 | {0x00, 0x0028, 0x2857}, | ||
361 | {0x00, 0x0013, 0x2858}, | ||
362 | {0x00, 0x001a, 0x2859}, | ||
363 | {0x00, 0x0028, 0x285a}, | ||
364 | {0x00, 0x0028, 0x285b}, | ||
365 | {0x00, 0x0028, 0x285c}, | ||
366 | {0x00, 0x0028, 0x285d}, | ||
367 | {0x00, 0x0028, 0x285e}, | ||
368 | {0x00, 0x0028, 0x285f}, | ||
369 | |||
370 | {0x00, 0x0028, 0x2860}, | ||
371 | {0x00, 0x0028, 0x2861}, | ||
372 | {0x00, 0x0028, 0x2862}, | ||
373 | {0x00, 0x0028, 0x2863}, | ||
374 | {0x00, 0x0028, 0x2864}, | ||
375 | {0x00, 0x0028, 0x2865}, | ||
376 | {0x00, 0x0028, 0x2866}, | ||
377 | {0x00, 0x0028, 0x2867}, | ||
378 | {0x00, 0x0028, 0x2868}, | ||
379 | {0x00, 0x0028, 0x2869}, | ||
380 | {0x00, 0x0028, 0x286a}, | ||
381 | {0x00, 0x0028, 0x286b}, | ||
382 | {0x00, 0x0028, 0x286c}, | ||
383 | {0x00, 0x0028, 0x286d}, | ||
384 | {0x00, 0x0028, 0x286e}, | ||
385 | {0x00, 0x0028, 0x286f}, | ||
386 | |||
387 | {0x00, 0x0028, 0x2870}, | ||
388 | {0x00, 0x0028, 0x2871}, | ||
389 | {0x00, 0x0028, 0x2872}, | ||
390 | {0x00, 0x0028, 0x2873}, | ||
391 | {0x00, 0x0028, 0x2874}, | ||
392 | {0x00, 0x0028, 0x2875}, | ||
393 | {0x00, 0x0028, 0x2876}, | ||
394 | {0x00, 0x0028, 0x2877}, | ||
395 | {0x00, 0x0028, 0x2878}, | ||
396 | {0x00, 0x0028, 0x2879}, | ||
397 | {0x00, 0x0028, 0x287a}, | ||
398 | {0x00, 0x0028, 0x287b}, | ||
399 | {0x00, 0x0028, 0x287c}, | ||
400 | {0x00, 0x0028, 0x287d}, | ||
401 | {0x00, 0x0028, 0x287e}, | ||
402 | {0x00, 0x0028, 0x287f}, | ||
403 | |||
404 | {0xa0, 0x0000, 0x0503}, | ||
405 | {} | ||
406 | }; | ||
407 | |||
408 | static const __u8 qtable_creative_pccam[2][64] = { | ||
409 | { /* Q-table Y-components */ | ||
410 | 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12, | ||
411 | 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11, | ||
412 | 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11, | ||
413 | 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13, | ||
414 | 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17, | ||
415 | 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c, | ||
416 | 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e, | ||
417 | 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e}, | ||
418 | { /* Q-table C-components */ | ||
419 | 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
420 | 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, | ||
421 | 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
422 | 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
423 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
424 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
425 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
426 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e} | ||
427 | }; | ||
428 | |||
429 | /* FIXME: This Q-table is identical to the Creative PC-CAM one, | ||
430 | * except for one byte. Possibly a typo? | ||
431 | * NWG: 18/05/2003. | ||
432 | */ | ||
433 | static const __u8 qtable_spca504_default[2][64] = { | ||
434 | { /* Q-table Y-components */ | ||
435 | 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12, | ||
436 | 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11, | ||
437 | 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11, | ||
438 | 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13, | ||
439 | 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17, | ||
440 | 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c, | ||
441 | 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e, | ||
442 | 0x16, 0x1c, 0x1d, 0x1d, 0x1d /* 0x22 */ , 0x1e, 0x1f, 0x1e, | ||
443 | }, | ||
444 | { /* Q-table C-components */ | ||
445 | 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
446 | 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, | ||
447 | 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
448 | 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
449 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
450 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
451 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, | ||
452 | 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e} | ||
453 | }; | ||
454 | |||
455 | static void reg_r(struct usb_device *dev, | ||
456 | __u16 req, | ||
457 | __u16 index, | ||
458 | __u8 *buffer, __u16 length) | ||
459 | { | ||
460 | usb_control_msg(dev, | ||
461 | usb_rcvctrlpipe(dev, 0), | ||
462 | req, | ||
463 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
464 | 0, /* value */ | ||
465 | index, buffer, length, | ||
466 | 500); | ||
467 | } | ||
468 | |||
469 | static void reg_w(struct usb_device *dev, | ||
470 | __u16 req, | ||
471 | __u16 value, | ||
472 | __u16 index, | ||
473 | __u8 *buffer, __u16 length) | ||
474 | { | ||
475 | usb_control_msg(dev, | ||
476 | usb_sndctrlpipe(dev, 0), | ||
477 | req, | ||
478 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
479 | value, index, buffer, length, | ||
480 | 500); | ||
481 | } | ||
482 | |||
483 | /* write req / index / value */ | ||
484 | static int reg_w_riv(struct usb_device *dev, | ||
485 | __u16 req, __u16 index, __u16 value) | ||
486 | { | ||
487 | int ret; | ||
488 | |||
489 | ret = usb_control_msg(dev, | ||
490 | usb_sndctrlpipe(dev, 0), | ||
491 | req, | ||
492 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
493 | value, index, NULL, 0, 500); | ||
494 | PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d", | ||
495 | req, index, value, ret); | ||
496 | if (ret < 0) | ||
497 | PDEBUG(D_ERR, "reg write: error %d", ret); | ||
498 | return ret; | ||
499 | } | ||
500 | |||
501 | /* read 1 byte */ | ||
502 | static int reg_r_1(struct gspca_dev *gspca_dev, | ||
503 | __u16 value) /* wValue */ | ||
504 | { | ||
505 | int ret; | ||
506 | |||
507 | ret = usb_control_msg(gspca_dev->dev, | ||
508 | usb_rcvctrlpipe(gspca_dev->dev, 0), | ||
509 | 0x20, /* request */ | ||
510 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
511 | value, | ||
512 | 0, /* index */ | ||
513 | gspca_dev->usb_buf, 1, | ||
514 | 500); /* timeout */ | ||
515 | if (ret < 0) { | ||
516 | PDEBUG(D_ERR, "reg_r_1 err %d", ret); | ||
517 | return 0; | ||
518 | } | ||
519 | return gspca_dev->usb_buf[0]; | ||
520 | } | ||
521 | |||
522 | /* read 1 or 2 bytes - returns < 0 if error */ | ||
523 | static int reg_r_12(struct gspca_dev *gspca_dev, | ||
524 | __u16 req, /* bRequest */ | ||
525 | __u16 index, /* wIndex */ | ||
526 | __u16 length) /* wLength (1 or 2 only) */ | ||
527 | { | ||
528 | int ret; | ||
529 | |||
530 | gspca_dev->usb_buf[1] = 0; | ||
531 | ret = usb_control_msg(gspca_dev->dev, | ||
532 | usb_rcvctrlpipe(gspca_dev->dev, 0), | ||
533 | req, | ||
534 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
535 | 0, /* value */ | ||
536 | index, | ||
537 | gspca_dev->usb_buf, length, | ||
538 | 500); | ||
539 | if (ret < 0) { | ||
540 | PDEBUG(D_ERR, "reg_read err %d", ret); | ||
541 | return -1; | ||
542 | } | ||
543 | return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; | ||
544 | } | ||
545 | |||
546 | static int write_vector(struct gspca_dev *gspca_dev, | ||
547 | const __u16 data[][3]) | ||
548 | { | ||
549 | struct usb_device *dev = gspca_dev->dev; | ||
550 | int ret, i = 0; | ||
551 | |||
552 | while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { | ||
553 | ret = reg_w_riv(dev, data[i][0], data[i][2], data[i][1]); | ||
554 | if (ret < 0) { | ||
555 | PDEBUG(D_ERR, | ||
556 | "Register write failed for 0x%x,0x%x,0x%x", | ||
557 | data[i][0], data[i][1], data[i][2]); | ||
558 | return ret; | ||
559 | } | ||
560 | i++; | ||
561 | } | ||
562 | return 0; | ||
563 | } | ||
564 | |||
565 | static int spca50x_setup_qtable(struct gspca_dev *gspca_dev, | ||
566 | unsigned int request, | ||
567 | unsigned int ybase, | ||
568 | unsigned int cbase, | ||
569 | const __u8 qtable[2][64]) | ||
570 | { | ||
571 | struct usb_device *dev = gspca_dev->dev; | ||
572 | int i, err; | ||
573 | |||
574 | /* loop over y components */ | ||
575 | for (i = 0; i < 64; i++) { | ||
576 | err = reg_w_riv(dev, request, ybase + i, qtable[0][i]); | ||
577 | if (err < 0) | ||
578 | return err; | ||
579 | } | ||
580 | |||
581 | /* loop over c components */ | ||
582 | for (i = 0; i < 64; i++) { | ||
583 | err = reg_w_riv(dev, request, cbase + i, qtable[1][i]); | ||
584 | if (err < 0) | ||
585 | return err; | ||
586 | } | ||
587 | return 0; | ||
588 | } | ||
589 | |||
590 | static void spca504_acknowledged_command(struct gspca_dev *gspca_dev, | ||
591 | __u16 req, __u16 idx, __u16 val) | ||
592 | { | ||
593 | struct usb_device *dev = gspca_dev->dev; | ||
594 | __u8 notdone; | ||
595 | |||
596 | reg_w_riv(dev, req, idx, val); | ||
597 | notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1); | ||
598 | reg_w_riv(dev, req, idx, val); | ||
599 | |||
600 | PDEBUG(D_FRAM, "before wait 0x%x", notdone); | ||
601 | |||
602 | msleep(200); | ||
603 | notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1); | ||
604 | PDEBUG(D_FRAM, "after wait 0x%x", notdone); | ||
605 | } | ||
606 | |||
607 | static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev, | ||
608 | __u16 req, | ||
609 | __u16 idx, __u16 val, __u8 stat, __u8 count) | ||
610 | { | ||
611 | struct usb_device *dev = gspca_dev->dev; | ||
612 | __u8 status; | ||
613 | __u8 endcode; | ||
614 | |||
615 | reg_w_riv(dev, req, idx, val); | ||
616 | status = reg_r_12(gspca_dev, 0x01, 0x0001, 1); | ||
617 | endcode = stat; | ||
618 | PDEBUG(D_FRAM, "Status 0x%x Need 0x%x", status, stat); | ||
619 | if (!count) | ||
620 | return; | ||
621 | count = 200; | ||
622 | while (--count > 0) { | ||
623 | msleep(10); | ||
624 | /* gsmart mini2 write a each wait setting 1 ms is enought */ | ||
625 | /* reg_w_riv(dev, req, idx, val); */ | ||
626 | status = reg_r_12(gspca_dev, 0x01, 0x0001, 1); | ||
627 | if (status == endcode) { | ||
628 | PDEBUG(D_FRAM, "status 0x%x after wait 0x%x", | ||
629 | status, 200 - count); | ||
630 | break; | ||
631 | } | ||
632 | } | ||
633 | } | ||
634 | |||
635 | static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev) | ||
636 | { | ||
637 | int count = 10; | ||
638 | |||
639 | while (--count > 0) { | ||
640 | reg_r(gspca_dev->dev, 0x21, 0, gspca_dev->usb_buf, 1); | ||
641 | if ((gspca_dev->usb_buf[0] & 0x01) == 0) | ||
642 | break; | ||
643 | msleep(10); | ||
644 | } | ||
645 | return gspca_dev->usb_buf[0]; | ||
646 | } | ||
647 | |||
648 | static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev) | ||
649 | { | ||
650 | struct usb_device *dev = gspca_dev->dev; | ||
651 | int count = 50; | ||
652 | |||
653 | while (--count > 0) { | ||
654 | reg_r(dev, 0x21, 1, gspca_dev->usb_buf, 1); | ||
655 | if (gspca_dev->usb_buf[0] != 0) { | ||
656 | gspca_dev->usb_buf[0] = 0; | ||
657 | reg_w(dev, 0x21, 0, 1, gspca_dev->usb_buf, 1); | ||
658 | reg_r(dev, 0x21, 1, gspca_dev->usb_buf, 1); | ||
659 | spca504B_PollingDataReady(gspca_dev); | ||
660 | break; | ||
661 | } | ||
662 | msleep(10); | ||
663 | } | ||
664 | } | ||
665 | |||
666 | static void spca50x_GetFirmware(struct gspca_dev *gspca_dev) | ||
667 | { | ||
668 | struct usb_device *dev = gspca_dev->dev; | ||
669 | __u8 *data; | ||
670 | |||
671 | data = kmalloc(64, GFP_KERNEL); | ||
672 | reg_r(dev, 0x20, 0, data, 5); | ||
673 | PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ", | ||
674 | data[0], data[1], data[2], data[3], data[4]); | ||
675 | reg_r(dev, 0x23, 0, data, 64); | ||
676 | reg_r(dev, 0x23, 1, data, 64); | ||
677 | kfree(data); | ||
678 | } | ||
679 | |||
680 | static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) | ||
681 | { | ||
682 | struct sd *sd = (struct sd *) gspca_dev; | ||
683 | struct usb_device *dev = gspca_dev->dev; | ||
684 | __u8 Size; | ||
685 | __u8 Type; | ||
686 | int rc; | ||
687 | |||
688 | Size = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | ||
689 | Type = 0; | ||
690 | switch (sd->bridge) { | ||
691 | case BRIDGE_SPCA533: | ||
692 | reg_w(dev, 0x31, 0, 0, NULL, 0); | ||
693 | spca504B_WaitCmdStatus(gspca_dev); | ||
694 | rc = spca504B_PollingDataReady(gspca_dev); | ||
695 | spca50x_GetFirmware(gspca_dev); | ||
696 | gspca_dev->usb_buf[0] = 2; /* type */ | ||
697 | reg_w(dev, 0x24, 0, 8, gspca_dev->usb_buf, 1); | ||
698 | reg_r(dev, 0x24, 8, gspca_dev->usb_buf, 1); | ||
699 | |||
700 | gspca_dev->usb_buf[0] = Size; | ||
701 | reg_w(dev, 0x25, 0, 4, gspca_dev->usb_buf, 1); | ||
702 | reg_r(dev, 0x25, 4, gspca_dev->usb_buf, 1); /* size */ | ||
703 | rc = spca504B_PollingDataReady(gspca_dev); | ||
704 | |||
705 | /* Init the cam width height with some values get on init ? */ | ||
706 | reg_w(dev, 0x31, 0, 4, NULL, 0); | ||
707 | spca504B_WaitCmdStatus(gspca_dev); | ||
708 | rc = spca504B_PollingDataReady(gspca_dev); | ||
709 | break; | ||
710 | default: | ||
711 | /* case BRIDGE_SPCA504B: */ | ||
712 | /* case BRIDGE_SPCA536: */ | ||
713 | gspca_dev->usb_buf[0] = Size; | ||
714 | reg_w(dev, 0x25, 0, 4, gspca_dev->usb_buf, 1); | ||
715 | reg_r(dev, 0x25, 4, gspca_dev->usb_buf, 1); /* size */ | ||
716 | Type = 6; | ||
717 | gspca_dev->usb_buf[0] = Type; | ||
718 | reg_w(dev, 0x27, 0, 0, gspca_dev->usb_buf, 1); | ||
719 | reg_r(dev, 0x27, 0, gspca_dev->usb_buf, 1); /* type */ | ||
720 | rc = spca504B_PollingDataReady(gspca_dev); | ||
721 | break; | ||
722 | case BRIDGE_SPCA504: | ||
723 | Size += 3; | ||
724 | if (sd->subtype == AiptekMiniPenCam13) { | ||
725 | /* spca504a aiptek */ | ||
726 | spca504A_acknowledged_command(gspca_dev, | ||
727 | 0x08, Size, 0, | ||
728 | 0x80 | (Size & 0x0f), 1); | ||
729 | spca504A_acknowledged_command(gspca_dev, | ||
730 | 1, 3, 0, 0x9f, 0); | ||
731 | } else { | ||
732 | spca504_acknowledged_command(gspca_dev, 0x08, Size, 0); | ||
733 | } | ||
734 | break; | ||
735 | case BRIDGE_SPCA504C: | ||
736 | /* capture mode */ | ||
737 | reg_w_riv(dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00); | ||
738 | reg_w_riv(dev, 0x20, 0x01, 0x0500 | (Size & 0x0f)); | ||
739 | break; | ||
740 | } | ||
741 | } | ||
742 | |||
743 | static void spca504_wait_status(struct gspca_dev *gspca_dev) | ||
744 | { | ||
745 | int cnt; | ||
746 | |||
747 | cnt = 256; | ||
748 | while (--cnt > 0) { | ||
749 | /* With this we get the status, when return 0 it's all ok */ | ||
750 | if (reg_r_12(gspca_dev, 0x06, 0x00, 1) == 0) | ||
751 | return; | ||
752 | msleep(10); | ||
753 | } | ||
754 | } | ||
755 | |||
756 | static void spca504B_setQtable(struct gspca_dev *gspca_dev) | ||
757 | { | ||
758 | struct usb_device *dev = gspca_dev->dev; | ||
759 | |||
760 | gspca_dev->usb_buf[0] = 3; | ||
761 | reg_w(dev, 0x26, 0, 0, gspca_dev->usb_buf, 1); | ||
762 | reg_r(dev, 0x26, 0, gspca_dev->usb_buf, 1); | ||
763 | spca504B_PollingDataReady(gspca_dev); | ||
764 | } | ||
765 | |||
766 | static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev) | ||
767 | { | ||
768 | struct sd *sd = (struct sd *) gspca_dev; | ||
769 | struct usb_device *dev = gspca_dev->dev; | ||
770 | int pollreg = 1; | ||
771 | |||
772 | switch (sd->bridge) { | ||
773 | case BRIDGE_SPCA504: | ||
774 | case BRIDGE_SPCA504C: | ||
775 | pollreg = 0; | ||
776 | /* fall thru */ | ||
777 | default: | ||
778 | /* case BRIDGE_SPCA533: */ | ||
779 | /* case BRIDGE_SPCA504B: */ | ||
780 | reg_w(dev, 0, 0, 0x21a7, NULL, 0); /* brightness */ | ||
781 | reg_w(dev, 0, 0x20, 0x21a8, NULL, 0); /* contrast */ | ||
782 | reg_w(dev, 0, 0, 0x21ad, NULL, 0); /* hue */ | ||
783 | reg_w(dev, 0, 1, 0x21ac, NULL, 0); /* sat/hue */ | ||
784 | reg_w(dev, 0, 0x20, 0x21ae, NULL, 0); /* saturation */ | ||
785 | reg_w(dev, 0, 0, 0x21a3, NULL, 0); /* gamma */ | ||
786 | break; | ||
787 | case BRIDGE_SPCA536: | ||
788 | reg_w(dev, 0, 0, 0x20f0, NULL, 0); | ||
789 | reg_w(dev, 0, 0x21, 0x20f1, NULL, 0); | ||
790 | reg_w(dev, 0, 0x40, 0x20f5, NULL, 0); | ||
791 | reg_w(dev, 0, 1, 0x20f4, NULL, 0); | ||
792 | reg_w(dev, 0, 0x40, 0x20f6, NULL, 0); | ||
793 | reg_w(dev, 0, 0, 0x2089, NULL, 0); | ||
794 | break; | ||
795 | } | ||
796 | if (pollreg) | ||
797 | spca504B_PollingDataReady(gspca_dev); | ||
798 | } | ||
799 | |||
800 | /* this function is called at probe time */ | ||
801 | static int sd_config(struct gspca_dev *gspca_dev, | ||
802 | const struct usb_device_id *id) | ||
803 | { | ||
804 | struct sd *sd = (struct sd *) gspca_dev; | ||
805 | struct usb_device *dev = gspca_dev->dev; | ||
806 | struct cam *cam; | ||
807 | __u16 vendor; | ||
808 | __u16 product; | ||
809 | __u8 fw; | ||
810 | |||
811 | vendor = id->idVendor; | ||
812 | product = id->idProduct; | ||
813 | switch (vendor) { | ||
814 | case 0x041e: /* Creative cameras */ | ||
815 | /* switch (product) { */ | ||
816 | /* case 0x400b: */ | ||
817 | /* case 0x4012: */ | ||
818 | /* case 0x4013: */ | ||
819 | /* sd->bridge = BRIDGE_SPCA504C; */ | ||
820 | /* break; */ | ||
821 | /* } */ | ||
822 | break; | ||
823 | case 0x0458: /* Genius KYE cameras */ | ||
824 | /* switch (product) { */ | ||
825 | /* case 0x7006: */ | ||
826 | sd->bridge = BRIDGE_SPCA504B; | ||
827 | /* break; */ | ||
828 | /* } */ | ||
829 | break; | ||
830 | case 0x0461: /* MicroInnovation */ | ||
831 | /* switch (product) { */ | ||
832 | /* case 0x0821: */ | ||
833 | sd->bridge = BRIDGE_SPCA533; | ||
834 | /* break; */ | ||
835 | /* } */ | ||
836 | break; | ||
837 | case 0x046d: /* Logitech Labtec */ | ||
838 | switch (product) { | ||
839 | case 0x0905: | ||
840 | sd->subtype = LogitechClickSmart820; | ||
841 | sd->bridge = BRIDGE_SPCA533; | ||
842 | break; | ||
843 | case 0x0960: | ||
844 | sd->subtype = LogitechClickSmart420; | ||
845 | sd->bridge = BRIDGE_SPCA504C; | ||
846 | break; | ||
847 | } | ||
848 | break; | ||
849 | case 0x0471: /* Philips */ | ||
850 | /* switch (product) { */ | ||
851 | /* case 0x0322: */ | ||
852 | sd->bridge = BRIDGE_SPCA504B; | ||
853 | /* break; */ | ||
854 | /* } */ | ||
855 | break; | ||
856 | case 0x04a5: /* Benq */ | ||
857 | switch (product) { | ||
858 | case 0x3003: | ||
859 | sd->bridge = BRIDGE_SPCA504B; | ||
860 | break; | ||
861 | case 0x3008: | ||
862 | case 0x300a: | ||
863 | sd->bridge = BRIDGE_SPCA533; | ||
864 | break; | ||
865 | } | ||
866 | break; | ||
867 | case 0x04f1: /* JVC */ | ||
868 | /* switch (product) { */ | ||
869 | /* case 0x1001: */ | ||
870 | sd->bridge = BRIDGE_SPCA504B; | ||
871 | /* break; */ | ||
872 | /* } */ | ||
873 | break; | ||
874 | case 0x04fc: /* SunPlus */ | ||
875 | switch (product) { | ||
876 | case 0x500c: | ||
877 | sd->bridge = BRIDGE_SPCA504B; | ||
878 | break; | ||
879 | case 0x504a: | ||
880 | /* try to get the firmware as some cam answer 2.0.1.2.2 | ||
881 | * and should be a spca504b then overwrite that setting */ | ||
882 | reg_r(dev, 0x20, 0, gspca_dev->usb_buf, 1); | ||
883 | fw = gspca_dev->usb_buf[0]; | ||
884 | if (fw == 1) { | ||
885 | sd->subtype = AiptekMiniPenCam13; | ||
886 | sd->bridge = BRIDGE_SPCA504; | ||
887 | } else if (fw == 2) { | ||
888 | sd->bridge = BRIDGE_SPCA504B; | ||
889 | } else | ||
890 | return -ENODEV; | ||
891 | break; | ||
892 | case 0x504b: | ||
893 | sd->bridge = BRIDGE_SPCA504B; | ||
894 | break; | ||
895 | case 0x5330: | ||
896 | sd->bridge = BRIDGE_SPCA533; | ||
897 | break; | ||
898 | case 0x5360: | ||
899 | sd->bridge = BRIDGE_SPCA536; | ||
900 | break; | ||
901 | case 0xffff: | ||
902 | sd->bridge = BRIDGE_SPCA504B; | ||
903 | break; | ||
904 | } | ||
905 | break; | ||
906 | case 0x052b: /* ?? Megapix */ | ||
907 | /* switch (product) { */ | ||
908 | /* case 0x1513: */ | ||
909 | sd->subtype = MegapixV4; | ||
910 | sd->bridge = BRIDGE_SPCA533; | ||
911 | /* break; */ | ||
912 | /* } */ | ||
913 | break; | ||
914 | case 0x0546: /* Polaroid */ | ||
915 | switch (product) { | ||
916 | case 0x3155: | ||
917 | sd->bridge = BRIDGE_SPCA533; | ||
918 | break; | ||
919 | case 0x3191: | ||
920 | case 0x3273: | ||
921 | sd->bridge = BRIDGE_SPCA504B; | ||
922 | break; | ||
923 | } | ||
924 | break; | ||
925 | case 0x055f: /* Mustek cameras */ | ||
926 | switch (product) { | ||
927 | case 0xc211: | ||
928 | sd->bridge = BRIDGE_SPCA536; | ||
929 | break; | ||
930 | case 0xc230: | ||
931 | case 0xc232: | ||
932 | sd->bridge = BRIDGE_SPCA533; | ||
933 | break; | ||
934 | case 0xc360: | ||
935 | sd->bridge = BRIDGE_SPCA536; | ||
936 | break; | ||
937 | case 0xc420: | ||
938 | sd->bridge = BRIDGE_SPCA504; | ||
939 | break; | ||
940 | case 0xc430: | ||
941 | case 0xc440: | ||
942 | sd->bridge = BRIDGE_SPCA533; | ||
943 | break; | ||
944 | case 0xc520: | ||
945 | sd->bridge = BRIDGE_SPCA504; | ||
946 | break; | ||
947 | case 0xc530: | ||
948 | case 0xc540: | ||
949 | case 0xc630: | ||
950 | case 0xc650: | ||
951 | sd->bridge = BRIDGE_SPCA533; | ||
952 | break; | ||
953 | } | ||
954 | break; | ||
955 | case 0x05da: /* Digital Dream cameras */ | ||
956 | /* switch (product) { */ | ||
957 | /* case 0x1018: */ | ||
958 | sd->bridge = BRIDGE_SPCA504B; | ||
959 | /* break; */ | ||
960 | /* } */ | ||
961 | break; | ||
962 | case 0x06d6: /* Trust */ | ||
963 | /* switch (product) { */ | ||
964 | /* case 0x0031: */ | ||
965 | sd->bridge = BRIDGE_SPCA533; /* SPCA533A */ | ||
966 | /* break; */ | ||
967 | /* } */ | ||
968 | break; | ||
969 | case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */ | ||
970 | switch (product) { | ||
971 | case 0x1311: | ||
972 | case 0x1314: | ||
973 | case 0x2211: | ||
974 | case 0x2221: | ||
975 | sd->bridge = BRIDGE_SPCA533; | ||
976 | break; | ||
977 | case 0x3261: | ||
978 | case 0x3281: | ||
979 | sd->bridge = BRIDGE_SPCA536; | ||
980 | break; | ||
981 | } | ||
982 | break; | ||
983 | case 0x08ca: /* Aiptek */ | ||
984 | switch (product) { | ||
985 | case 0x0104: | ||
986 | case 0x0106: | ||
987 | sd->bridge = BRIDGE_SPCA533; | ||
988 | break; | ||
989 | case 0x2008: | ||
990 | sd->bridge = BRIDGE_SPCA504B; | ||
991 | break; | ||
992 | case 0x2010: | ||
993 | sd->bridge = BRIDGE_SPCA533; | ||
994 | break; | ||
995 | case 0x2016: | ||
996 | case 0x2018: | ||
997 | sd->bridge = BRIDGE_SPCA504B; | ||
998 | break; | ||
999 | case 0x2020: | ||
1000 | case 0x2022: | ||
1001 | sd->bridge = BRIDGE_SPCA533; | ||
1002 | break; | ||
1003 | case 0x2024: | ||
1004 | sd->bridge = BRIDGE_SPCA536; | ||
1005 | break; | ||
1006 | case 0x2028: | ||
1007 | sd->bridge = BRIDGE_SPCA533; | ||
1008 | break; | ||
1009 | case 0x2040: | ||
1010 | case 0x2042: | ||
1011 | case 0x2050: | ||
1012 | case 0x2060: | ||
1013 | sd->bridge = BRIDGE_SPCA536; | ||
1014 | break; | ||
1015 | } | ||
1016 | break; | ||
1017 | case 0x0d64: /* SunPlus */ | ||
1018 | /* switch (product) { */ | ||
1019 | /* case 0x0303: */ | ||
1020 | sd->bridge = BRIDGE_SPCA536; | ||
1021 | /* break; */ | ||
1022 | /* } */ | ||
1023 | break; | ||
1024 | } | ||
1025 | |||
1026 | cam = &gspca_dev->cam; | ||
1027 | cam->dev_name = (char *) id->driver_info; | ||
1028 | cam->epaddr = 0x01; | ||
1029 | |||
1030 | switch (sd->bridge) { | ||
1031 | default: | ||
1032 | /* case BRIDGE_SPCA504B: */ | ||
1033 | /* case BRIDGE_SPCA504: */ | ||
1034 | /* case BRIDGE_SPCA536: */ | ||
1035 | cam->cam_mode = vga_mode; | ||
1036 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | ||
1037 | break; | ||
1038 | case BRIDGE_SPCA533: | ||
1039 | cam->cam_mode = custom_mode; | ||
1040 | cam->nmodes = sizeof custom_mode / sizeof custom_mode[0]; | ||
1041 | break; | ||
1042 | case BRIDGE_SPCA504C: | ||
1043 | cam->cam_mode = vga_mode2; | ||
1044 | cam->nmodes = sizeof vga_mode2 / sizeof vga_mode2[0]; | ||
1045 | break; | ||
1046 | } | ||
1047 | sd->qindex = 5; /* set the quantization table */ | ||
1048 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
1049 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | ||
1050 | sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; | ||
1051 | return 0; | ||
1052 | } | ||
1053 | |||
1054 | /* this function is called at open time */ | ||
1055 | static int sd_open(struct gspca_dev *gspca_dev) | ||
1056 | { | ||
1057 | struct sd *sd = (struct sd *) gspca_dev; | ||
1058 | struct usb_device *dev = gspca_dev->dev; | ||
1059 | int rc; | ||
1060 | __u8 i; | ||
1061 | __u8 info[6]; | ||
1062 | int err_code; | ||
1063 | |||
1064 | switch (sd->bridge) { | ||
1065 | case BRIDGE_SPCA504B: | ||
1066 | reg_w(dev, 0x1d, 0, 0, NULL, 0); | ||
1067 | reg_w(dev, 0, 1, 0x2306, NULL, 0); | ||
1068 | reg_w(dev, 0, 0, 0x0d04, NULL, 0); | ||
1069 | reg_w(dev, 0, 0, 0x2000, NULL, 0); | ||
1070 | reg_w(dev, 0, 0x13, 0x2301, NULL, 0); | ||
1071 | reg_w(dev, 0, 0, 0x2306, NULL, 0); | ||
1072 | /* fall thru */ | ||
1073 | case BRIDGE_SPCA533: | ||
1074 | rc = spca504B_PollingDataReady(gspca_dev); | ||
1075 | spca50x_GetFirmware(gspca_dev); | ||
1076 | break; | ||
1077 | case BRIDGE_SPCA536: | ||
1078 | spca50x_GetFirmware(gspca_dev); | ||
1079 | reg_r(dev, 0x00, 0x5002, gspca_dev->usb_buf, 1); | ||
1080 | gspca_dev->usb_buf[0] = 0; | ||
1081 | reg_w(dev, 0x24, 0, 0, gspca_dev->usb_buf, 1); | ||
1082 | reg_r(dev, 0x24, 0, gspca_dev->usb_buf, 1); | ||
1083 | rc = spca504B_PollingDataReady(gspca_dev); | ||
1084 | reg_w(dev, 0x34, 0, 0, NULL, 0); | ||
1085 | spca504B_WaitCmdStatus(gspca_dev); | ||
1086 | break; | ||
1087 | case BRIDGE_SPCA504C: /* pccam600 */ | ||
1088 | PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)"); | ||
1089 | reg_w_riv(dev, 0xe0, 0x0000, 0x0000); | ||
1090 | reg_w_riv(dev, 0xe0, 0x0000, 0x0001); /* reset */ | ||
1091 | spca504_wait_status(gspca_dev); | ||
1092 | if (sd->subtype == LogitechClickSmart420) | ||
1093 | write_vector(gspca_dev, | ||
1094 | spca504A_clicksmart420_open_data); | ||
1095 | else | ||
1096 | write_vector(gspca_dev, spca504_pccam600_open_data); | ||
1097 | err_code = spca50x_setup_qtable(gspca_dev, | ||
1098 | 0x00, 0x2800, | ||
1099 | 0x2840, qtable_creative_pccam); | ||
1100 | if (err_code < 0) { | ||
1101 | PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed"); | ||
1102 | return err_code; | ||
1103 | } | ||
1104 | break; | ||
1105 | default: | ||
1106 | /* case BRIDGE_SPCA504: */ | ||
1107 | PDEBUG(D_STREAM, "Opening SPCA504"); | ||
1108 | if (sd->subtype == AiptekMiniPenCam13) { | ||
1109 | /*****************************/ | ||
1110 | for (i = 0; i < 6; i++) | ||
1111 | info[i] = reg_r_1(gspca_dev, i); | ||
1112 | PDEBUG(D_STREAM, | ||
1113 | "Read info: %d %d %d %d %d %d." | ||
1114 | " Should be 1,0,2,2,0,0", | ||
1115 | info[0], info[1], info[2], | ||
1116 | info[3], info[4], info[5]); | ||
1117 | /* spca504a aiptek */ | ||
1118 | /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */ | ||
1119 | spca504A_acknowledged_command(gspca_dev, 0x24, | ||
1120 | 8, 3, 0x9e, 1); | ||
1121 | /* Twice sequencial need status 0xff->0x9e->0x9d */ | ||
1122 | spca504A_acknowledged_command(gspca_dev, 0x24, | ||
1123 | 8, 3, 0x9e, 0); | ||
1124 | |||
1125 | spca504A_acknowledged_command(gspca_dev, 0x24, | ||
1126 | 0, 0, 0x9d, 1); | ||
1127 | /******************************/ | ||
1128 | /* spca504a aiptek */ | ||
1129 | spca504A_acknowledged_command(gspca_dev, 0x08, | ||
1130 | 6, 0, 0x86, 1); | ||
1131 | /* reg_write (dev, 0, 0x2000, 0); */ | ||
1132 | /* reg_write (dev, 0, 0x2883, 1); */ | ||
1133 | /* spca504A_acknowledged_command (gspca_dev, 0x08, | ||
1134 | 6, 0, 0x86, 1); */ | ||
1135 | /* spca504A_acknowledged_command (gspca_dev, 0x24, | ||
1136 | 0, 0, 0x9D, 1); */ | ||
1137 | reg_w_riv(dev, 0x0, 0x270c, 0x05); /* L92 sno1t.txt */ | ||
1138 | reg_w_riv(dev, 0x0, 0x2310, 0x05); | ||
1139 | spca504A_acknowledged_command(gspca_dev, 0x01, | ||
1140 | 0x0f, 0, 0xff, 0); | ||
1141 | } | ||
1142 | /* setup qtable */ | ||
1143 | reg_w_riv(dev, 0, 0x2000, 0); | ||
1144 | reg_w_riv(dev, 0, 0x2883, 1); | ||
1145 | err_code = spca50x_setup_qtable(gspca_dev, | ||
1146 | 0x00, 0x2800, | ||
1147 | 0x2840, | ||
1148 | qtable_spca504_default); | ||
1149 | if (err_code < 0) { | ||
1150 | PDEBUG(D_ERR, "spca50x_setup_qtable failed"); | ||
1151 | return err_code; | ||
1152 | } | ||
1153 | break; | ||
1154 | } | ||
1155 | return 0; | ||
1156 | } | ||
1157 | |||
1158 | static void sd_start(struct gspca_dev *gspca_dev) | ||
1159 | { | ||
1160 | struct sd *sd = (struct sd *) gspca_dev; | ||
1161 | struct usb_device *dev = gspca_dev->dev; | ||
1162 | int rc; | ||
1163 | int enable; | ||
1164 | __u8 i; | ||
1165 | __u8 info[6]; | ||
1166 | |||
1167 | if (sd->bridge == BRIDGE_SPCA504B) | ||
1168 | spca504B_setQtable(gspca_dev); | ||
1169 | spca504B_SetSizeType(gspca_dev); | ||
1170 | switch (sd->bridge) { | ||
1171 | default: | ||
1172 | /* case BRIDGE_SPCA504B: */ | ||
1173 | /* case BRIDGE_SPCA533: */ | ||
1174 | /* case BRIDGE_SPCA536: */ | ||
1175 | if (sd->subtype == MegapixV4 || | ||
1176 | sd->subtype == LogitechClickSmart820) { | ||
1177 | reg_w(dev, 0xf0, 0, 0, NULL, 0); | ||
1178 | spca504B_WaitCmdStatus(gspca_dev); | ||
1179 | reg_r(dev, 0xf0, 4, NULL, 0); | ||
1180 | spca504B_WaitCmdStatus(gspca_dev); | ||
1181 | } else { | ||
1182 | reg_w(dev, 0x31, 0, 4, NULL, 0); | ||
1183 | spca504B_WaitCmdStatus(gspca_dev); | ||
1184 | rc = spca504B_PollingDataReady(gspca_dev); | ||
1185 | } | ||
1186 | break; | ||
1187 | case BRIDGE_SPCA504: | ||
1188 | if (sd->subtype == AiptekMiniPenCam13) { | ||
1189 | for (i = 0; i < 6; i++) | ||
1190 | info[i] = reg_r_1(gspca_dev, i); | ||
1191 | PDEBUG(D_STREAM, | ||
1192 | "Read info: %d %d %d %d %d %d." | ||
1193 | " Should be 1,0,2,2,0,0", | ||
1194 | info[0], info[1], info[2], | ||
1195 | info[3], info[4], info[5]); | ||
1196 | /* spca504a aiptek */ | ||
1197 | /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */ | ||
1198 | spca504A_acknowledged_command(gspca_dev, 0x24, | ||
1199 | 8, 3, 0x9e, 1); | ||
1200 | /* Twice sequencial need status 0xff->0x9e->0x9d */ | ||
1201 | spca504A_acknowledged_command(gspca_dev, 0x24, | ||
1202 | 8, 3, 0x9e, 0); | ||
1203 | spca504A_acknowledged_command(gspca_dev, 0x24, | ||
1204 | 0, 0, 0x9d, 1); | ||
1205 | } else { | ||
1206 | spca504_acknowledged_command(gspca_dev, 0x24, 8, 3); | ||
1207 | for (i = 0; i < 6; i++) | ||
1208 | info[i] = reg_r_1(gspca_dev, i); | ||
1209 | PDEBUG(D_STREAM, | ||
1210 | "Read info: %d %d %d %d %d %d." | ||
1211 | " Should be 1,0,2,2,0,0", | ||
1212 | info[0], info[1], info[2], | ||
1213 | info[3], info[4], info[5]); | ||
1214 | spca504_acknowledged_command(gspca_dev, 0x24, 8, 3); | ||
1215 | spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); | ||
1216 | } | ||
1217 | spca504B_SetSizeType(gspca_dev); | ||
1218 | reg_w_riv(dev, 0x0, 0x270c, 0x05); /* L92 sno1t.txt */ | ||
1219 | reg_w_riv(dev, 0x0, 0x2310, 0x05); | ||
1220 | break; | ||
1221 | case BRIDGE_SPCA504C: | ||
1222 | if (sd->subtype == LogitechClickSmart420) { | ||
1223 | write_vector(gspca_dev, | ||
1224 | spca504A_clicksmart420_init_data); | ||
1225 | } else { | ||
1226 | write_vector(gspca_dev, spca504_pccam600_init_data); | ||
1227 | } | ||
1228 | enable = (sd->autogain ? 0x04 : 0x01); | ||
1229 | reg_w_riv(dev, 0x0c, 0x0000, enable); /* auto exposure */ | ||
1230 | reg_w_riv(dev, 0xb0, 0x0000, enable); /* auto whiteness */ | ||
1231 | |||
1232 | /* set default exposure compensation and whiteness balance */ | ||
1233 | reg_w_riv(dev, 0x30, 0x0001, 800); /* ~ 20 fps */ | ||
1234 | reg_w_riv(dev, 0x30, 0x0002, 1600); | ||
1235 | spca504B_SetSizeType(gspca_dev); | ||
1236 | break; | ||
1237 | } | ||
1238 | sp5xx_initContBrigHueRegisters(gspca_dev); | ||
1239 | } | ||
1240 | |||
1241 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
1242 | { | ||
1243 | struct sd *sd = (struct sd *) gspca_dev; | ||
1244 | struct usb_device *dev = gspca_dev->dev; | ||
1245 | |||
1246 | switch (sd->bridge) { | ||
1247 | default: | ||
1248 | /* case BRIDGE_SPCA533: */ | ||
1249 | /* case BRIDGE_SPCA536: */ | ||
1250 | /* case BRIDGE_SPCA504B: */ | ||
1251 | reg_w(dev, 0x31, 0, 0, NULL, 0); | ||
1252 | spca504B_WaitCmdStatus(gspca_dev); | ||
1253 | spca504B_PollingDataReady(gspca_dev); | ||
1254 | break; | ||
1255 | case BRIDGE_SPCA504: | ||
1256 | case BRIDGE_SPCA504C: | ||
1257 | reg_w_riv(dev, 0x00, 0x2000, 0x0000); | ||
1258 | |||
1259 | if (sd->subtype == AiptekMiniPenCam13) { | ||
1260 | /* spca504a aiptek */ | ||
1261 | /* spca504A_acknowledged_command(gspca_dev, 0x08, | ||
1262 | 6, 0, 0x86, 1); */ | ||
1263 | spca504A_acknowledged_command(gspca_dev, 0x24, | ||
1264 | 0x00, 0x00, 0x9d, 1); | ||
1265 | spca504A_acknowledged_command(gspca_dev, 0x01, | ||
1266 | 0x0f, 0x00, 0xff, 1); | ||
1267 | } else { | ||
1268 | spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); | ||
1269 | reg_w_riv(dev, 0x01, 0x000f, 0x00); | ||
1270 | } | ||
1271 | break; | ||
1272 | } | ||
1273 | } | ||
1274 | |||
1275 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
1276 | { | ||
1277 | } | ||
1278 | |||
1279 | static void sd_close(struct gspca_dev *gspca_dev) | ||
1280 | { | ||
1281 | } | ||
1282 | |||
1283 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
1284 | struct gspca_frame *frame, /* target */ | ||
1285 | __u8 *data, /* isoc packet */ | ||
1286 | int len) /* iso packet length */ | ||
1287 | { | ||
1288 | struct sd *sd = (struct sd *) gspca_dev; | ||
1289 | int i, sof = 0; | ||
1290 | unsigned char *s, *d; | ||
1291 | static unsigned char ffd9[] = {0xff, 0xd9}; | ||
1292 | |||
1293 | /* frames are jpeg 4.1.1 without 0xff escape */ | ||
1294 | switch (sd->bridge) { | ||
1295 | case BRIDGE_SPCA533: | ||
1296 | if (data[0] == 0xff) { | ||
1297 | if (data[1] != 0x01) { /* drop packet */ | ||
1298 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
1299 | return; | ||
1300 | } | ||
1301 | sof = 1; | ||
1302 | data += SPCA533_OFFSET_DATA; | ||
1303 | len -= SPCA533_OFFSET_DATA; | ||
1304 | } else { | ||
1305 | data += 1; | ||
1306 | len -= 1; | ||
1307 | } | ||
1308 | break; | ||
1309 | case BRIDGE_SPCA536: | ||
1310 | if (data[0] == 0xff) { | ||
1311 | sof = 1; | ||
1312 | data += SPCA536_OFFSET_DATA; | ||
1313 | len -= SPCA536_OFFSET_DATA; | ||
1314 | } else { | ||
1315 | data += 2; | ||
1316 | len -= 2; | ||
1317 | } | ||
1318 | break; | ||
1319 | default: | ||
1320 | /* case BRIDGE_SPCA504: */ | ||
1321 | /* case BRIDGE_SPCA504B: */ | ||
1322 | switch (data[0]) { | ||
1323 | case 0xfe: /* start of frame */ | ||
1324 | sof = 1; | ||
1325 | data += SPCA50X_OFFSET_DATA; | ||
1326 | len -= SPCA50X_OFFSET_DATA; | ||
1327 | break; | ||
1328 | case 0xff: /* drop packet */ | ||
1329 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
1330 | return; | ||
1331 | default: | ||
1332 | data += 1; | ||
1333 | len -= 1; | ||
1334 | break; | ||
1335 | } | ||
1336 | break; | ||
1337 | case BRIDGE_SPCA504C: | ||
1338 | switch (data[0]) { | ||
1339 | case 0xfe: /* start of frame */ | ||
1340 | sof = 1; | ||
1341 | data += SPCA504_PCCAM600_OFFSET_DATA; | ||
1342 | len -= SPCA504_PCCAM600_OFFSET_DATA; | ||
1343 | break; | ||
1344 | case 0xff: /* drop packet */ | ||
1345 | /* gspca_dev->last_packet_type = DISCARD_PACKET; */ | ||
1346 | return; | ||
1347 | default: | ||
1348 | data += 1; | ||
1349 | len -= 1; | ||
1350 | break; | ||
1351 | } | ||
1352 | break; | ||
1353 | } | ||
1354 | if (sof) { /* start of frame */ | ||
1355 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | ||
1356 | ffd9, 2); | ||
1357 | |||
1358 | /* put the JPEG header in the new frame */ | ||
1359 | jpeg_put_header(gspca_dev, frame, | ||
1360 | ((struct sd *) gspca_dev)->qindex, | ||
1361 | 0x22); | ||
1362 | } | ||
1363 | |||
1364 | /* add 0x00 after 0xff */ | ||
1365 | for (i = len; --i >= 0; ) | ||
1366 | if (data[i] == 0xff) | ||
1367 | break; | ||
1368 | if (i < 0) { /* no 0xff */ | ||
1369 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
1370 | return; | ||
1371 | } | ||
1372 | s = data; | ||
1373 | d = sd->packet; | ||
1374 | for (i = 0; i < len; i++) { | ||
1375 | *d++ = *s++; | ||
1376 | if (s[-1] == 0xff) | ||
1377 | *d++ = 0x00; | ||
1378 | } | ||
1379 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | ||
1380 | sd->packet, d - sd->packet); | ||
1381 | } | ||
1382 | |||
1383 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
1384 | { | ||
1385 | struct sd *sd = (struct sd *) gspca_dev; | ||
1386 | struct usb_device *dev = gspca_dev->dev; | ||
1387 | |||
1388 | switch (sd->bridge) { | ||
1389 | default: | ||
1390 | /* case BRIDGE_SPCA533: */ | ||
1391 | /* case BRIDGE_SPCA504B: */ | ||
1392 | /* case BRIDGE_SPCA504: */ | ||
1393 | /* case BRIDGE_SPCA504C: */ | ||
1394 | reg_w_riv(dev, 0x0, 0x21a7, sd->brightness); | ||
1395 | break; | ||
1396 | case BRIDGE_SPCA536: | ||
1397 | reg_w_riv(dev, 0x0, 0x20f0, sd->brightness); | ||
1398 | break; | ||
1399 | } | ||
1400 | } | ||
1401 | |||
1402 | static void getbrightness(struct gspca_dev *gspca_dev) | ||
1403 | { | ||
1404 | struct sd *sd = (struct sd *) gspca_dev; | ||
1405 | __u16 brightness = 0; | ||
1406 | |||
1407 | switch (sd->bridge) { | ||
1408 | default: | ||
1409 | /* case BRIDGE_SPCA533: */ | ||
1410 | /* case BRIDGE_SPCA504B: */ | ||
1411 | /* case BRIDGE_SPCA504: */ | ||
1412 | /* case BRIDGE_SPCA504C: */ | ||
1413 | brightness = reg_r_12(gspca_dev, 0x00, 0x21a7, 2); | ||
1414 | break; | ||
1415 | case BRIDGE_SPCA536: | ||
1416 | brightness = reg_r_12(gspca_dev, 0x00, 0x20f0, 2); | ||
1417 | break; | ||
1418 | } | ||
1419 | sd->brightness = ((brightness & 0xff) - 128) % 255; | ||
1420 | } | ||
1421 | |||
1422 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
1423 | { | ||
1424 | struct sd *sd = (struct sd *) gspca_dev; | ||
1425 | struct usb_device *dev = gspca_dev->dev; | ||
1426 | |||
1427 | switch (sd->bridge) { | ||
1428 | default: | ||
1429 | /* case BRIDGE_SPCA533: */ | ||
1430 | /* case BRIDGE_SPCA504B: */ | ||
1431 | /* case BRIDGE_SPCA504: */ | ||
1432 | /* case BRIDGE_SPCA504C: */ | ||
1433 | reg_w_riv(dev, 0x0, 0x21a8, sd->contrast); | ||
1434 | break; | ||
1435 | case BRIDGE_SPCA536: | ||
1436 | reg_w_riv(dev, 0x0, 0x20f1, sd->contrast); | ||
1437 | break; | ||
1438 | } | ||
1439 | } | ||
1440 | |||
1441 | static void getcontrast(struct gspca_dev *gspca_dev) | ||
1442 | { | ||
1443 | struct sd *sd = (struct sd *) gspca_dev; | ||
1444 | |||
1445 | switch (sd->bridge) { | ||
1446 | default: | ||
1447 | /* case BRIDGE_SPCA533: */ | ||
1448 | /* case BRIDGE_SPCA504B: */ | ||
1449 | /* case BRIDGE_SPCA504: */ | ||
1450 | /* case BRIDGE_SPCA504C: */ | ||
1451 | sd->contrast = reg_r_12(gspca_dev, 0x00, 0x21a8, 2); | ||
1452 | break; | ||
1453 | case BRIDGE_SPCA536: | ||
1454 | sd->contrast = reg_r_12(gspca_dev, 0x00, 0x20f1, 2); | ||
1455 | break; | ||
1456 | } | ||
1457 | } | ||
1458 | |||
1459 | static void setcolors(struct gspca_dev *gspca_dev) | ||
1460 | { | ||
1461 | struct sd *sd = (struct sd *) gspca_dev; | ||
1462 | struct usb_device *dev = gspca_dev->dev; | ||
1463 | |||
1464 | switch (sd->bridge) { | ||
1465 | default: | ||
1466 | /* case BRIDGE_SPCA533: */ | ||
1467 | /* case BRIDGE_SPCA504B: */ | ||
1468 | /* case BRIDGE_SPCA504: */ | ||
1469 | /* case BRIDGE_SPCA504C: */ | ||
1470 | reg_w_riv(dev, 0x0, 0x21ae, sd->colors); | ||
1471 | break; | ||
1472 | case BRIDGE_SPCA536: | ||
1473 | reg_w_riv(dev, 0x0, 0x20f6, sd->colors); | ||
1474 | break; | ||
1475 | } | ||
1476 | } | ||
1477 | |||
1478 | static void getcolors(struct gspca_dev *gspca_dev) | ||
1479 | { | ||
1480 | struct sd *sd = (struct sd *) gspca_dev; | ||
1481 | |||
1482 | switch (sd->bridge) { | ||
1483 | default: | ||
1484 | /* case BRIDGE_SPCA533: */ | ||
1485 | /* case BRIDGE_SPCA504B: */ | ||
1486 | /* case BRIDGE_SPCA504: */ | ||
1487 | /* case BRIDGE_SPCA504C: */ | ||
1488 | sd->colors = reg_r_12(gspca_dev, 0x00, 0x21ae, 2) >> 1; | ||
1489 | break; | ||
1490 | case BRIDGE_SPCA536: | ||
1491 | sd->colors = reg_r_12(gspca_dev, 0x00, 0x20f6, 2) >> 1; | ||
1492 | break; | ||
1493 | } | ||
1494 | } | ||
1495 | |||
1496 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
1497 | { | ||
1498 | struct sd *sd = (struct sd *) gspca_dev; | ||
1499 | |||
1500 | sd->brightness = val; | ||
1501 | if (gspca_dev->streaming) | ||
1502 | setbrightness(gspca_dev); | ||
1503 | return 0; | ||
1504 | } | ||
1505 | |||
1506 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
1507 | { | ||
1508 | struct sd *sd = (struct sd *) gspca_dev; | ||
1509 | |||
1510 | getbrightness(gspca_dev); | ||
1511 | *val = sd->brightness; | ||
1512 | return 0; | ||
1513 | } | ||
1514 | |||
1515 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
1516 | { | ||
1517 | struct sd *sd = (struct sd *) gspca_dev; | ||
1518 | |||
1519 | sd->contrast = val; | ||
1520 | if (gspca_dev->streaming) | ||
1521 | setcontrast(gspca_dev); | ||
1522 | return 0; | ||
1523 | } | ||
1524 | |||
1525 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
1526 | { | ||
1527 | struct sd *sd = (struct sd *) gspca_dev; | ||
1528 | |||
1529 | getcontrast(gspca_dev); | ||
1530 | *val = sd->contrast; | ||
1531 | return 0; | ||
1532 | } | ||
1533 | |||
1534 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
1535 | { | ||
1536 | struct sd *sd = (struct sd *) gspca_dev; | ||
1537 | |||
1538 | sd->colors = val; | ||
1539 | if (gspca_dev->streaming) | ||
1540 | setcolors(gspca_dev); | ||
1541 | return 0; | ||
1542 | } | ||
1543 | |||
1544 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
1545 | { | ||
1546 | struct sd *sd = (struct sd *) gspca_dev; | ||
1547 | |||
1548 | getcolors(gspca_dev); | ||
1549 | *val = sd->colors; | ||
1550 | return 0; | ||
1551 | } | ||
1552 | |||
1553 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
1554 | { | ||
1555 | struct sd *sd = (struct sd *) gspca_dev; | ||
1556 | |||
1557 | sd->autogain = val; | ||
1558 | return 0; | ||
1559 | } | ||
1560 | |||
1561 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | ||
1562 | { | ||
1563 | struct sd *sd = (struct sd *) gspca_dev; | ||
1564 | |||
1565 | *val = sd->autogain; | ||
1566 | return 0; | ||
1567 | } | ||
1568 | |||
1569 | /* sub-driver description */ | ||
1570 | static const struct sd_desc sd_desc = { | ||
1571 | .name = MODULE_NAME, | ||
1572 | .ctrls = sd_ctrls, | ||
1573 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
1574 | .config = sd_config, | ||
1575 | .open = sd_open, | ||
1576 | .start = sd_start, | ||
1577 | .stopN = sd_stopN, | ||
1578 | .stop0 = sd_stop0, | ||
1579 | .close = sd_close, | ||
1580 | .pkt_scan = sd_pkt_scan, | ||
1581 | }; | ||
1582 | |||
1583 | /* -- module initialisation -- */ | ||
1584 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
1585 | static const __devinitdata struct usb_device_id device_table[] = { | ||
1586 | {USB_DEVICE(0x041e, 0x400b), DVNM("Creative PC-CAM 600")}, | ||
1587 | {USB_DEVICE(0x041e, 0x4012), DVNM("PC-Cam350")}, | ||
1588 | {USB_DEVICE(0x041e, 0x4013), DVNM("Creative Pccam750")}, | ||
1589 | {USB_DEVICE(0x0458, 0x7006), DVNM("Genius Dsc 1.3 Smart")}, | ||
1590 | {USB_DEVICE(0x0461, 0x0821), DVNM("Fujifilm MV-1")}, | ||
1591 | {USB_DEVICE(0x046d, 0x0905), DVNM("Logitech ClickSmart 820")}, | ||
1592 | {USB_DEVICE(0x046d, 0x0960), DVNM("Logitech ClickSmart 420")}, | ||
1593 | {USB_DEVICE(0x0471, 0x0322), DVNM("Philips DMVC1300K")}, | ||
1594 | {USB_DEVICE(0x04a5, 0x3003), DVNM("Benq DC 1300")}, | ||
1595 | {USB_DEVICE(0x04a5, 0x3008), DVNM("Benq DC 1500")}, | ||
1596 | {USB_DEVICE(0x04a5, 0x300a), DVNM("Benq DC3410")}, | ||
1597 | {USB_DEVICE(0x04f1, 0x1001), DVNM("JVC GC A50")}, | ||
1598 | {USB_DEVICE(0x04fc, 0x500c), DVNM("Sunplus CA500C")}, | ||
1599 | {USB_DEVICE(0x04fc, 0x504a), DVNM("Aiptek Mini PenCam 1.3")}, | ||
1600 | {USB_DEVICE(0x04fc, 0x504b), DVNM("Maxell MaxPocket LE 1.3")}, | ||
1601 | {USB_DEVICE(0x04fc, 0x5330), DVNM("Digitrex 2110")}, | ||
1602 | {USB_DEVICE(0x04fc, 0x5360), DVNM("Sunplus Generic")}, | ||
1603 | {USB_DEVICE(0x04fc, 0xffff), DVNM("Pure DigitalDakota")}, | ||
1604 | {USB_DEVICE(0x052b, 0x1513), DVNM("Megapix V4")}, | ||
1605 | {USB_DEVICE(0x0546, 0x3155), DVNM("Polaroid PDC3070")}, | ||
1606 | {USB_DEVICE(0x0546, 0x3191), DVNM("Polaroid Ion 80")}, | ||
1607 | {USB_DEVICE(0x0546, 0x3273), DVNM("Polaroid PDC2030")}, | ||
1608 | {USB_DEVICE(0x055f, 0xc211), DVNM("Kowa Bs888e Microcamera")}, | ||
1609 | {USB_DEVICE(0x055f, 0xc230), DVNM("Mustek Digicam 330K")}, | ||
1610 | {USB_DEVICE(0x055f, 0xc232), DVNM("Mustek MDC3500")}, | ||
1611 | {USB_DEVICE(0x055f, 0xc360), DVNM("Mustek DV4000 Mpeg4 ")}, | ||
1612 | {USB_DEVICE(0x055f, 0xc420), DVNM("Mustek gSmart Mini 2")}, | ||
1613 | {USB_DEVICE(0x055f, 0xc430), DVNM("Mustek Gsmart LCD 2")}, | ||
1614 | {USB_DEVICE(0x055f, 0xc440), DVNM("Mustek DV 3000")}, | ||
1615 | {USB_DEVICE(0x055f, 0xc520), DVNM("Mustek gSmart Mini 3")}, | ||
1616 | {USB_DEVICE(0x055f, 0xc530), DVNM("Mustek Gsmart LCD 3")}, | ||
1617 | {USB_DEVICE(0x055f, 0xc540), DVNM("Gsmart D30")}, | ||
1618 | {USB_DEVICE(0x055f, 0xc630), DVNM("Mustek MDC4000")}, | ||
1619 | {USB_DEVICE(0x055f, 0xc650), DVNM("Mustek MDC5500Z")}, | ||
1620 | {USB_DEVICE(0x05da, 0x1018), DVNM("Digital Dream Enigma 1.3")}, | ||
1621 | {USB_DEVICE(0x06d6, 0x0031), DVNM("Trust 610 LCD PowerC@m Zoom")}, | ||
1622 | {USB_DEVICE(0x0733, 0x1311), DVNM("Digital Dream Epsilon 1.3")}, | ||
1623 | {USB_DEVICE(0x0733, 0x1314), DVNM("Mercury 2.1MEG Deluxe Classic Cam")}, | ||
1624 | {USB_DEVICE(0x0733, 0x2211), DVNM("Jenoptik jdc 21 LCD")}, | ||
1625 | {USB_DEVICE(0x0733, 0x2221), DVNM("Mercury Digital Pro 3.1p")}, | ||
1626 | {USB_DEVICE(0x0733, 0x3261), DVNM("Concord 3045 spca536a")}, | ||
1627 | {USB_DEVICE(0x0733, 0x3281), DVNM("Cyberpix S550V")}, | ||
1628 | {USB_DEVICE(0x08ca, 0x0104), DVNM("Aiptek PocketDVII 1.3")}, | ||
1629 | {USB_DEVICE(0x08ca, 0x0106), DVNM("Aiptek Pocket DV3100+")}, | ||
1630 | {USB_DEVICE(0x08ca, 0x2008), DVNM("Aiptek Mini PenCam 2 M")}, | ||
1631 | {USB_DEVICE(0x08ca, 0x2010), DVNM("Aiptek PocketCam 3M")}, | ||
1632 | {USB_DEVICE(0x08ca, 0x2016), DVNM("Aiptek PocketCam 2 Mega")}, | ||
1633 | {USB_DEVICE(0x08ca, 0x2018), DVNM("Aiptek Pencam SD 2M")}, | ||
1634 | {USB_DEVICE(0x08ca, 0x2020), DVNM("Aiptek Slim 3000F")}, | ||
1635 | {USB_DEVICE(0x08ca, 0x2022), DVNM("Aiptek Slim 3200")}, | ||
1636 | {USB_DEVICE(0x08ca, 0x2024), DVNM("Aiptek DV3500 Mpeg4 ")}, | ||
1637 | {USB_DEVICE(0x08ca, 0x2028), DVNM("Aiptek PocketCam4M")}, | ||
1638 | {USB_DEVICE(0x08ca, 0x2040), DVNM("Aiptek PocketDV4100M")}, | ||
1639 | {USB_DEVICE(0x08ca, 0x2042), DVNM("Aiptek PocketDV5100")}, | ||
1640 | {USB_DEVICE(0x08ca, 0x2050), DVNM("Medion MD 41437")}, | ||
1641 | {USB_DEVICE(0x08ca, 0x2060), DVNM("Aiptek PocketDV5300")}, | ||
1642 | {USB_DEVICE(0x0d64, 0x0303), DVNM("Sunplus FashionCam DXG")}, | ||
1643 | {} | ||
1644 | }; | ||
1645 | MODULE_DEVICE_TABLE(usb, device_table); | ||
1646 | |||
1647 | /* -- device connect -- */ | ||
1648 | static int sd_probe(struct usb_interface *intf, | ||
1649 | const struct usb_device_id *id) | ||
1650 | { | ||
1651 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
1652 | THIS_MODULE); | ||
1653 | } | ||
1654 | |||
1655 | static struct usb_driver sd_driver = { | ||
1656 | .name = MODULE_NAME, | ||
1657 | .id_table = device_table, | ||
1658 | .probe = sd_probe, | ||
1659 | .disconnect = gspca_disconnect, | ||
1660 | }; | ||
1661 | |||
1662 | /* -- module insert / remove -- */ | ||
1663 | static int __init sd_mod_init(void) | ||
1664 | { | ||
1665 | if (usb_register(&sd_driver) < 0) | ||
1666 | return -1; | ||
1667 | PDEBUG(D_PROBE, "v%s registered", version); | ||
1668 | return 0; | ||
1669 | } | ||
1670 | static void __exit sd_mod_exit(void) | ||
1671 | { | ||
1672 | usb_deregister(&sd_driver); | ||
1673 | PDEBUG(D_PROBE, "deregistered"); | ||
1674 | } | ||
1675 | |||
1676 | module_init(sd_mod_init); | ||
1677 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c new file mode 100644 index 000000000000..00f47e463a05 --- /dev/null +++ b/drivers/media/video/gspca/t613.c | |||
@@ -0,0 +1,1038 @@ | |||
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, 7) | ||
30 | static const char version[] = "2.1.7"; | ||
31 | |||
32 | #define MAX_GAMMA 0x10 /* 0 to 15 */ | ||
33 | |||
34 | /* From LUVCVIEW */ | ||
35 | #define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 3) | ||
36 | |||
37 | MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>"); | ||
38 | MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver"); | ||
39 | MODULE_LICENSE("GPL"); | ||
40 | |||
41 | struct sd { | ||
42 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
43 | |||
44 | unsigned char brightness; | ||
45 | unsigned char contrast; | ||
46 | unsigned char colors; | ||
47 | unsigned char autogain; | ||
48 | unsigned char gamma; | ||
49 | unsigned char sharpness; | ||
50 | unsigned char freq; | ||
51 | unsigned char whitebalance; | ||
52 | unsigned char mirror; | ||
53 | unsigned char effect; | ||
54 | }; | ||
55 | |||
56 | /* V4L2 controls supported by the driver */ | ||
57 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
58 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
59 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
60 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
61 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
62 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
63 | static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val); | ||
64 | static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val); | ||
65 | static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val); | ||
66 | static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val); | ||
67 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); | ||
68 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | ||
69 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | ||
70 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | ||
71 | static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val); | ||
72 | static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val); | ||
73 | static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val); | ||
74 | static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
75 | static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val); | ||
76 | static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val); | ||
77 | static int sd_querymenu(struct gspca_dev *gspca_dev, | ||
78 | struct v4l2_querymenu *menu); | ||
79 | |||
80 | static struct ctrl sd_ctrls[] = { | ||
81 | #define SD_BRIGHTNESS 0 | ||
82 | { | ||
83 | { | ||
84 | .id = V4L2_CID_BRIGHTNESS, | ||
85 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
86 | .name = "Brightness", | ||
87 | .minimum = 0, | ||
88 | .maximum = 0x0f, | ||
89 | .step = 1, | ||
90 | .default_value = 0x09, | ||
91 | }, | ||
92 | .set = sd_setbrightness, | ||
93 | .get = sd_getbrightness, | ||
94 | }, | ||
95 | #define SD_CONTRAST 1 | ||
96 | { | ||
97 | { | ||
98 | .id = V4L2_CID_CONTRAST, | ||
99 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
100 | .name = "Contrast", | ||
101 | .minimum = 0, | ||
102 | .maximum = 0x0d, | ||
103 | .step = 1, | ||
104 | .default_value = 0x07, | ||
105 | }, | ||
106 | .set = sd_setcontrast, | ||
107 | .get = sd_getcontrast, | ||
108 | }, | ||
109 | #define SD_COLOR 2 | ||
110 | { | ||
111 | { | ||
112 | .id = V4L2_CID_SATURATION, | ||
113 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
114 | .name = "Color", | ||
115 | .minimum = 0, | ||
116 | .maximum = 0x0f, | ||
117 | .step = 1, | ||
118 | .default_value = 0x05, | ||
119 | }, | ||
120 | .set = sd_setcolors, | ||
121 | .get = sd_getcolors, | ||
122 | }, | ||
123 | #define SD_GAMMA 3 | ||
124 | { | ||
125 | { | ||
126 | .id = V4L2_CID_GAMMA, /* (gamma on win) */ | ||
127 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
128 | .name = "Gamma (Untested)", | ||
129 | .minimum = 0, | ||
130 | .maximum = MAX_GAMMA, | ||
131 | .step = 1, | ||
132 | .default_value = 0x09, | ||
133 | }, | ||
134 | .set = sd_setgamma, | ||
135 | .get = sd_getgamma, | ||
136 | }, | ||
137 | #define SD_AUTOGAIN 4 | ||
138 | { | ||
139 | { | ||
140 | .id = V4L2_CID_GAIN, /* here, i activate only the lowlight, | ||
141 | * some apps dont bring up the | ||
142 | * backligth_compensation control) */ | ||
143 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
144 | .name = "Low Light", | ||
145 | .minimum = 0, | ||
146 | .maximum = 1, | ||
147 | .step = 1, | ||
148 | .default_value = 0x01, | ||
149 | }, | ||
150 | .set = sd_setlowlight, | ||
151 | .get = sd_getlowlight, | ||
152 | }, | ||
153 | #define SD_MIRROR 5 | ||
154 | { | ||
155 | { | ||
156 | .id = V4L2_CID_HFLIP, | ||
157 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
158 | .name = "Mirror Image", | ||
159 | .minimum = 0, | ||
160 | .maximum = 1, | ||
161 | .step = 1, | ||
162 | .default_value = 0, | ||
163 | }, | ||
164 | .set = sd_setflip, | ||
165 | .get = sd_getflip | ||
166 | }, | ||
167 | #define SD_LIGHTFREQ 6 | ||
168 | { | ||
169 | { | ||
170 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | ||
171 | .type = V4L2_CTRL_TYPE_MENU, | ||
172 | .name = "Light Frequency Filter", | ||
173 | .minimum = 1, /* 1 -> 0x50, 2->0x60 */ | ||
174 | .maximum = 2, | ||
175 | .step = 1, | ||
176 | .default_value = 1, | ||
177 | }, | ||
178 | .set = sd_setfreq, | ||
179 | .get = sd_getfreq}, | ||
180 | |||
181 | #define SD_WHITE_BALANCE 7 | ||
182 | { | ||
183 | { | ||
184 | .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE, | ||
185 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
186 | .name = "White Balance", | ||
187 | .minimum = 0, | ||
188 | .maximum = 1, | ||
189 | .step = 1, | ||
190 | .default_value = 1, | ||
191 | }, | ||
192 | .set = sd_setwhitebalance, | ||
193 | .get = sd_getwhitebalance | ||
194 | }, | ||
195 | #define SD_SHARPNESS 8 /* (aka definition on win) */ | ||
196 | { | ||
197 | { | ||
198 | .id = V4L2_CID_SHARPNESS, | ||
199 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
200 | .name = "Sharpness", | ||
201 | .minimum = 0, | ||
202 | .maximum = MAX_GAMMA, /* 0 to 16 */ | ||
203 | .step = 1, | ||
204 | .default_value = 0x06, | ||
205 | }, | ||
206 | .set = sd_setsharpness, | ||
207 | .get = sd_getsharpness, | ||
208 | }, | ||
209 | #define SD_EFFECTS 9 | ||
210 | { | ||
211 | { | ||
212 | .id = V4L2_CID_EFFECTS, | ||
213 | .type = V4L2_CTRL_TYPE_MENU, | ||
214 | .name = "Webcam Effects", | ||
215 | .minimum = 0, | ||
216 | .maximum = 4, | ||
217 | .step = 1, | ||
218 | .default_value = 0, | ||
219 | }, | ||
220 | .set = sd_seteffect, | ||
221 | .get = sd_geteffect | ||
222 | }, | ||
223 | }; | ||
224 | |||
225 | static char *effects_control[] = { | ||
226 | "Normal", | ||
227 | "Emboss", /* disabled */ | ||
228 | "Monochrome", | ||
229 | "Sepia", | ||
230 | "Sketch", | ||
231 | "Sun Effect", /* disabled */ | ||
232 | "Negative", | ||
233 | }; | ||
234 | |||
235 | static struct v4l2_pix_format vga_mode_t16[] = { | ||
236 | {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
237 | .bytesperline = 160, | ||
238 | .sizeimage = 160 * 120 * 3 / 8 + 590, | ||
239 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
240 | .priv = 4}, | ||
241 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
242 | .bytesperline = 176, | ||
243 | .sizeimage = 176 * 144 * 3 / 8 + 590, | ||
244 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
245 | .priv = 3}, | ||
246 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
247 | .bytesperline = 320, | ||
248 | .sizeimage = 320 * 240 * 3 / 8 + 590, | ||
249 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
250 | .priv = 2}, | ||
251 | {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
252 | .bytesperline = 352, | ||
253 | .sizeimage = 352 * 288 * 3 / 8 + 590, | ||
254 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
255 | .priv = 1}, | ||
256 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
257 | .bytesperline = 640, | ||
258 | .sizeimage = 640 * 480 * 3 / 8 + 590, | ||
259 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
260 | .priv = 0}, | ||
261 | }; | ||
262 | |||
263 | #define T16_OFFSET_DATA 631 | ||
264 | #define MAX_EFFECTS 7 | ||
265 | /* easily done by soft, this table could be removed, | ||
266 | * i keep it here just in case */ | ||
267 | static const __u8 effects_table[MAX_EFFECTS][6] = { | ||
268 | {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */ | ||
269 | {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */ | ||
270 | {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */ | ||
271 | {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80}, /* Sepia */ | ||
272 | {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02}, /* Croquis */ | ||
273 | {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10}, /* Sun Effect */ | ||
274 | {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */ | ||
275 | }; | ||
276 | |||
277 | static const __u8 gamma_table[MAX_GAMMA][34] = { | ||
278 | {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85, | ||
279 | 0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9, | ||
280 | 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb, | ||
281 | 0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8, | ||
282 | 0xa0, 0xff}, | ||
283 | {0x90, 0x00, 0x91, 0x33, 0x92, 0x5A, 0x93, 0x75, | ||
284 | 0x94, 0x85, 0x95, 0x93, 0x96, 0xA1, 0x97, 0xAD, | ||
285 | 0x98, 0xB7, 0x99, 0xC2, 0x9A, 0xCB, 0x9B, 0xD4, | ||
286 | 0x9C, 0xDE, 0x9D, 0xE7, 0x9E, 0xF0, 0x9F, 0xF7, | ||
287 | 0xa0, 0xff}, | ||
288 | {0x90, 0x00, 0x91, 0x2F, 0x92, 0x51, 0x93, 0x6B, | ||
289 | 0x94, 0x7C, 0x95, 0x8A, 0x96, 0x99, 0x97, 0xA6, | ||
290 | 0x98, 0xB1, 0x99, 0xBC, 0x9A, 0xC6, 0x9B, 0xD0, | ||
291 | 0x9C, 0xDB, 0x9D, 0xE4, 0x9E, 0xED, 0x9F, 0xF6, | ||
292 | 0xa0, 0xff}, | ||
293 | {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60, | ||
294 | 0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9E, | ||
295 | 0x98, 0xAA, 0x99, 0xB5, 0x9A, 0xBF, 0x9B, 0xCB, | ||
296 | 0x9C, 0xD6, 0x9D, 0xE1, 0x9E, 0xEB, 0x9F, 0xF5, | ||
297 | 0xa0, 0xff}, | ||
298 | {0x90, 0x00, 0x91, 0x23, 0x92, 0x3F, 0x93, 0x55, | ||
299 | 0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95, | ||
300 | 0x98, 0xA2, 0x99, 0xAD, 0x9A, 0xB9, 0x9B, 0xC6, | ||
301 | 0x9C, 0xD2, 0x9D, 0xDE, 0x9E, 0xE9, 0x9F, 0xF4, | ||
302 | 0xa0, 0xff}, | ||
303 | {0x90, 0x00, 0x91, 0x1B, 0x92, 0x33, 0x93, 0x48, | ||
304 | 0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87, | ||
305 | 0x98, 0x96, 0x99, 0xA3, 0x9A, 0xB1, 0x9B, 0xBE, | ||
306 | 0x9C, 0xCC, 0x9D, 0xDA, 0x9E, 0xE7, 0x9F, 0xF3, | ||
307 | 0xa0, 0xff}, | ||
308 | {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20, | ||
309 | 0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67, | ||
310 | 0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa, | ||
311 | 0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee, | ||
312 | 0xa0, 0xff}, | ||
313 | {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26, | ||
314 | 0x94, 0x38, 0x95, 0x4A, 0x96, 0x60, 0x97, 0x70, | ||
315 | 0x98, 0x80, 0x99, 0x90, 0x9A, 0xA0, 0x9B, 0xB0, | ||
316 | 0x9C, 0xC0, 0x9D, 0xD0, 0x9E, 0xE0, 0x9F, 0xF0, | ||
317 | 0xa0, 0xff}, | ||
318 | {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35, | ||
319 | 0x94, 0x47, 0x95, 0x5A, 0x96, 0x69, 0x97, 0x79, | ||
320 | 0x98, 0x88, 0x99, 0x97, 0x9A, 0xA7, 0x9B, 0xB6, | ||
321 | 0x9C, 0xC4, 0x9D, 0xD3, 0x9E, 0xE0, 0x9F, 0xF0, | ||
322 | 0xa0, 0xff}, | ||
323 | {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40, | ||
324 | 0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84, | ||
325 | 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd, | ||
326 | 0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0, | ||
327 | 0xa0, 0xff}, | ||
328 | {0x90, 0x00, 0x91, 0x18, 0x92, 0x2B, 0x93, 0x44, | ||
329 | 0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8E, | ||
330 | 0x98, 0x9C, 0x99, 0xAA, 0x9A, 0xB7, 0x9B, 0xC4, | ||
331 | 0x9C, 0xD0, 0x9D, 0xD8, 0x9E, 0xE2, 0x9F, 0xF0, | ||
332 | 0xa0, 0xff}, | ||
333 | {0x90, 0x00, 0x91, 0x1A, 0x92, 0x34, 0x93, 0x52, | ||
334 | 0x94, 0x66, 0x95, 0x7E, 0x96, 0x8D, 0x97, 0x9B, | ||
335 | 0x98, 0xA8, 0x99, 0xB4, 0x9A, 0xC0, 0x9B, 0xCB, | ||
336 | 0x9C, 0xD6, 0x9D, 0xE1, 0x9E, 0xEB, 0x9F, 0xF5, | ||
337 | 0xa0, 0xff}, | ||
338 | {0x90, 0x00, 0x91, 0x3F, 0x92, 0x5A, 0x93, 0x6E, | ||
339 | 0x94, 0x7F, 0x95, 0x8E, 0x96, 0x9C, 0x97, 0xA8, | ||
340 | 0x98, 0xB4, 0x99, 0xBF, 0x9A, 0xC9, 0x9B, 0xD3, | ||
341 | 0x9C, 0xDC, 0x9D, 0xE5, 0x9E, 0xEE, 0x9F, 0xF6, | ||
342 | 0xA0, 0xFF}, | ||
343 | {0x90, 0x00, 0x91, 0x54, 0x92, 0x6F, 0x93, 0x83, | ||
344 | 0x94, 0x93, 0x95, 0xA0, 0x96, 0xAD, 0x97, 0xB7, | ||
345 | 0x98, 0xC2, 0x99, 0xCB, 0x9A, 0xD4, 0x9B, 0xDC, | ||
346 | 0x9C, 0xE4, 0x9D, 0xEB, 0x9E, 0xF2, 0x9F, 0xF9, | ||
347 | 0xa0, 0xff}, | ||
348 | {0x90, 0x00, 0x91, 0x6E, 0x92, 0x88, 0x93, 0x9A, | ||
349 | 0x94, 0xA8, 0x95, 0xB3, 0x96, 0xBD, 0x97, 0xC6, | ||
350 | 0x98, 0xCF, 0x99, 0xD6, 0x9A, 0xDD, 0x9B, 0xE3, | ||
351 | 0x9C, 0xE9, 0x9D, 0xEF, 0x9E, 0xF4, 0x9F, 0xFA, | ||
352 | 0xa0, 0xff}, | ||
353 | {0x90, 0x00, 0x91, 0x93, 0x92, 0xA8, 0x93, 0xB7, | ||
354 | 0x94, 0xC1, 0x95, 0xCA, 0x96, 0xD2, 0x97, 0xD8, | ||
355 | 0x98, 0xDE, 0x99, 0xE3, 0x9A, 0xE8, 0x9B, 0xED, | ||
356 | 0x9C, 0xF1, 0x9D, 0xF5, 0x9E, 0xF8, 0x9F, 0xFC, | ||
357 | 0xA0, 0xFF} | ||
358 | }; | ||
359 | |||
360 | static const __u8 tas5130a_sensor_init[][8] = { | ||
361 | {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09}, | ||
362 | {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09}, | ||
363 | {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}, | ||
364 | {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}, | ||
365 | {}, | ||
366 | }; | ||
367 | |||
368 | /* read 1 byte */ | ||
369 | static int reg_r_1(struct gspca_dev *gspca_dev, | ||
370 | __u16 index) | ||
371 | { | ||
372 | usb_control_msg(gspca_dev->dev, | ||
373 | usb_rcvctrlpipe(gspca_dev->dev, 0), | ||
374 | 0, /* request */ | ||
375 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
376 | 0, /* value */ | ||
377 | index, | ||
378 | gspca_dev->usb_buf, 1, 500); | ||
379 | return gspca_dev->usb_buf[0]; | ||
380 | } | ||
381 | |||
382 | static void reg_w(struct gspca_dev *gspca_dev, | ||
383 | __u16 value, | ||
384 | __u16 index, | ||
385 | const __u8 *buffer, __u16 len) | ||
386 | { | ||
387 | if (buffer == NULL) { | ||
388 | usb_control_msg(gspca_dev->dev, | ||
389 | usb_sndctrlpipe(gspca_dev->dev, 0), | ||
390 | 0, | ||
391 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
392 | value, index, | ||
393 | NULL, 0, 500); | ||
394 | return; | ||
395 | } | ||
396 | if (len <= sizeof gspca_dev->usb_buf) { | ||
397 | memcpy(gspca_dev->usb_buf, buffer, len); | ||
398 | usb_control_msg(gspca_dev->dev, | ||
399 | usb_sndctrlpipe(gspca_dev->dev, 0), | ||
400 | 0, | ||
401 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
402 | value, index, | ||
403 | gspca_dev->usb_buf, len, 500); | ||
404 | } else { | ||
405 | __u8 *tmpbuf; | ||
406 | |||
407 | tmpbuf = kmalloc(len, GFP_KERNEL); | ||
408 | memcpy(tmpbuf, buffer, len); | ||
409 | usb_control_msg(gspca_dev->dev, | ||
410 | usb_sndctrlpipe(gspca_dev->dev, 0), | ||
411 | 0, | ||
412 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | ||
413 | value, index, | ||
414 | tmpbuf, len, 500); | ||
415 | kfree(tmpbuf); | ||
416 | } | ||
417 | } | ||
418 | |||
419 | /* this function is called at probe time */ | ||
420 | static int sd_config(struct gspca_dev *gspca_dev, | ||
421 | const struct usb_device_id *id) | ||
422 | { | ||
423 | struct sd *sd = (struct sd *) gspca_dev; | ||
424 | struct cam *cam; | ||
425 | |||
426 | cam = &gspca_dev->cam; | ||
427 | cam->dev_name = (char *) id->driver_info; | ||
428 | cam->epaddr = 0x01; | ||
429 | |||
430 | cam->cam_mode = vga_mode_t16; | ||
431 | cam->nmodes = ARRAY_SIZE(vga_mode_t16); | ||
432 | |||
433 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
434 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | ||
435 | sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; | ||
436 | sd->gamma = sd_ctrls[SD_GAMMA].qctrl.default_value; | ||
437 | sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value; | ||
438 | sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value; | ||
439 | sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value; | ||
440 | sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value; | ||
441 | sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value; | ||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | static int init_default_parameters(struct gspca_dev *gspca_dev) | ||
446 | { | ||
447 | /* some of this registers are not really neded, because | ||
448 | * they are overriden by setbrigthness, setcontrast, etc, | ||
449 | * but wont hurt anyway, and can help someone with similar webcam | ||
450 | * to see the initial parameters.*/ | ||
451 | int i = 0; | ||
452 | __u8 test_byte; | ||
453 | |||
454 | static const __u8 read_indexs[] = | ||
455 | { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5, | ||
456 | 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 }; | ||
457 | static const __u8 n1[6] = | ||
458 | {0x08, 0x03, 0x09, 0x03, 0x12, 0x04}; | ||
459 | static const __u8 n2[2] = | ||
460 | {0x08, 0x00}; | ||
461 | static const __u8 nset[6] = | ||
462 | { 0x61, 0x68, 0x62, 0xff, 0x60, 0x07 }; | ||
463 | static const __u8 n3[6] = | ||
464 | {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04}; | ||
465 | static const __u8 n4[0x46] = | ||
466 | {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c, | ||
467 | 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68, | ||
468 | 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1, | ||
469 | 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8, | ||
470 | 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48, | ||
471 | 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0, | ||
472 | 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68, | ||
473 | 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40, | ||
474 | 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46}; | ||
475 | static const __u8 nset4[18] = { | ||
476 | 0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, 0xe4, 0xa8, | ||
477 | 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8, | ||
478 | 0xe8, 0xe0 | ||
479 | }; | ||
480 | /* ojo puede ser 0xe6 en vez de 0xe9 */ | ||
481 | static const __u8 nset2[20] = { | ||
482 | 0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, 0xd4, 0xbb, | ||
483 | 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27, | ||
484 | 0xd8, 0xc8, 0xd9, 0xfc | ||
485 | }; | ||
486 | static const __u8 missing[8] = | ||
487 | { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 }; | ||
488 | static const __u8 nset3[18] = { | ||
489 | 0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, 0xcb, 0xa8, | ||
490 | 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8, | ||
491 | 0xcf, 0xe0 | ||
492 | }; | ||
493 | static const __u8 nset5[4] = | ||
494 | { 0x8f, 0x24, 0xc3, 0x00 }; /* bright */ | ||
495 | static const __u8 nset6[34] = { | ||
496 | 0x90, 0x00, 0x91, 0x1c, 0x92, 0x30, 0x93, 0x43, 0x94, 0x54, | ||
497 | 0x95, 0x65, 0x96, 0x75, 0x97, 0x84, | ||
498 | 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd, 0x9c, 0xca, | ||
499 | 0x9d, 0xd8, 0x9e, 0xe5, 0x9f, 0xf2, | ||
500 | 0xa0, 0xff | ||
501 | }; /* Gamma */ | ||
502 | static const __u8 nset7[4] = | ||
503 | { 0x66, 0xca, 0xa8, 0xf8 }; /* 50/60 Hz */ | ||
504 | static const __u8 nset9[4] = | ||
505 | { 0x0b, 0x04, 0x0a, 0x78 }; | ||
506 | static const __u8 nset8[6] = | ||
507 | { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 }; | ||
508 | static const __u8 nset10[6] = | ||
509 | { 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 }; | ||
510 | |||
511 | reg_w(gspca_dev, 0x01, 0x0000, n1, 0x06); | ||
512 | reg_w(gspca_dev, 0x01, 0x0000, nset, 0x06); | ||
513 | reg_r_1(gspca_dev, 0x0063); | ||
514 | reg_w(gspca_dev, 0x01, 0x0000, n2, 0x02); | ||
515 | |||
516 | while (read_indexs[i] != 0x00) { | ||
517 | test_byte = reg_r_1(gspca_dev, read_indexs[i]); | ||
518 | PDEBUG(D_CONF, "Reg 0x%02x => 0x%02x", read_indexs[i], | ||
519 | test_byte); | ||
520 | i++; | ||
521 | } | ||
522 | |||
523 | reg_w(gspca_dev, 0x01, 0x0000, n3, 0x06); | ||
524 | reg_w(gspca_dev, 0x01, 0x0000, n4, 0x46); | ||
525 | reg_r_1(gspca_dev, 0x0080); | ||
526 | reg_w(gspca_dev, 0x00, 0x2c80, NULL, 0); | ||
527 | reg_w(gspca_dev, 0x01, 0x0000, nset2, 0x14); | ||
528 | reg_w(gspca_dev, 0x01, 0x0000, nset3, 0x12); | ||
529 | reg_w(gspca_dev, 0x01, 0x0000, nset4, 0x12); | ||
530 | reg_w(gspca_dev, 0x00, 0x3880, NULL, 0); | ||
531 | reg_w(gspca_dev, 0x00, 0x3880, NULL, 0); | ||
532 | reg_w(gspca_dev, 0x00, 0x338e, NULL, 0); | ||
533 | reg_w(gspca_dev, 0x01, 0x0000, nset5, 0x04); | ||
534 | reg_w(gspca_dev, 0x00, 0x00a9, NULL, 0); | ||
535 | reg_w(gspca_dev, 0x01, 0x0000, nset6, 0x22); | ||
536 | reg_w(gspca_dev, 0x00, 0x86bb, NULL, 0); | ||
537 | reg_w(gspca_dev, 0x00, 0x4aa6, NULL, 0); | ||
538 | |||
539 | reg_w(gspca_dev, 0x01, 0x0000, missing, 0x08); | ||
540 | |||
541 | reg_w(gspca_dev, 0x00, 0x2087, NULL, 0); | ||
542 | reg_w(gspca_dev, 0x00, 0x2088, NULL, 0); | ||
543 | reg_w(gspca_dev, 0x00, 0x2089, NULL, 0); | ||
544 | |||
545 | reg_w(gspca_dev, 0x01, 0x0000, nset7, 0x04); | ||
546 | reg_w(gspca_dev, 0x01, 0x0000, nset10, 0x06); | ||
547 | reg_w(gspca_dev, 0x01, 0x0000, nset8, 0x06); | ||
548 | reg_w(gspca_dev, 0x01, 0x0000, nset9, 0x04); | ||
549 | |||
550 | reg_w(gspca_dev, 0x00, 0x2880, NULL, 0); | ||
551 | reg_w(gspca_dev, 0x01, 0x0000, nset2, 0x14); | ||
552 | reg_w(gspca_dev, 0x01, 0x0000, nset3, 0x12); | ||
553 | reg_w(gspca_dev, 0x01, 0x0000, nset4, 0x12); | ||
554 | |||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
559 | { | ||
560 | struct sd *sd = (struct sd *) gspca_dev; | ||
561 | unsigned int brightness; | ||
562 | __u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x80 }; | ||
563 | brightness = sd->brightness; | ||
564 | |||
565 | if (brightness < 7) { | ||
566 | set6[3] = 0x70 - (brightness * 0xa); | ||
567 | } else { | ||
568 | set6[1] = 0x24; | ||
569 | set6[3] = 0x00 + ((brightness - 7) * 0xa); | ||
570 | } | ||
571 | |||
572 | reg_w(gspca_dev, 0x01, 0x0000, set6, 4); | ||
573 | } | ||
574 | |||
575 | static void setflip(struct gspca_dev *gspca_dev) | ||
576 | { | ||
577 | struct sd *sd = (struct sd *) gspca_dev; | ||
578 | |||
579 | __u8 flipcmd[8] = | ||
580 | { 0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09 }; | ||
581 | |||
582 | if (sd->mirror == 1) | ||
583 | flipcmd[3] = 0x01; | ||
584 | |||
585 | reg_w(gspca_dev, 0x01, 0x0000, flipcmd, 8); | ||
586 | } | ||
587 | |||
588 | static void seteffect(struct gspca_dev *gspca_dev) | ||
589 | { | ||
590 | struct sd *sd = (struct sd *) gspca_dev; | ||
591 | |||
592 | reg_w(gspca_dev, 0x01, 0x0000, effects_table[sd->effect], 0x06); | ||
593 | if (sd->effect == 1 || sd->effect == 5) { | ||
594 | PDEBUG(D_CONF, | ||
595 | "This effect have been disabled for webcam \"safety\""); | ||
596 | return; | ||
597 | } | ||
598 | |||
599 | if (sd->effect == 1 || sd->effect == 4) | ||
600 | reg_w(gspca_dev, 0x00, 0x4aa6, NULL, 0); | ||
601 | else | ||
602 | reg_w(gspca_dev, 0x00, 0xfaa6, NULL, 0); | ||
603 | } | ||
604 | |||
605 | static void setwhitebalance(struct gspca_dev *gspca_dev) | ||
606 | { | ||
607 | struct sd *sd = (struct sd *) gspca_dev; | ||
608 | |||
609 | __u8 white_balance[8] = | ||
610 | { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 }; | ||
611 | |||
612 | if (sd->whitebalance == 1) | ||
613 | white_balance[7] = 0x3c; | ||
614 | |||
615 | reg_w(gspca_dev, 0x01, 0x0000, white_balance, 8); | ||
616 | } | ||
617 | |||
618 | static void setlightfreq(struct gspca_dev *gspca_dev) | ||
619 | { | ||
620 | struct sd *sd = (struct sd *) gspca_dev; | ||
621 | __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 }; | ||
622 | |||
623 | if (sd->freq == 2) /* 60hz */ | ||
624 | freq[1] = 0x00; | ||
625 | |||
626 | reg_w(gspca_dev, 0x1, 0x0000, freq, 0x4); | ||
627 | } | ||
628 | |||
629 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
630 | { | ||
631 | struct sd *sd = (struct sd *) gspca_dev; | ||
632 | unsigned int contrast = sd->contrast; | ||
633 | __u16 reg_to_write = 0x00; | ||
634 | |||
635 | if (contrast < 7) | ||
636 | reg_to_write = 0x8ea9 - (0x200 * contrast); | ||
637 | else | ||
638 | reg_to_write = (0x00a9 + ((contrast - 7) * 0x200)); | ||
639 | |||
640 | reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0); | ||
641 | } | ||
642 | |||
643 | static void setcolors(struct gspca_dev *gspca_dev) | ||
644 | { | ||
645 | struct sd *sd = (struct sd *) gspca_dev; | ||
646 | __u16 reg_to_write; | ||
647 | |||
648 | reg_to_write = 0xc0bb + sd->colors * 0x100; | ||
649 | reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0); | ||
650 | } | ||
651 | |||
652 | static void setgamma(struct gspca_dev *gspca_dev) | ||
653 | { | ||
654 | } | ||
655 | |||
656 | static void setsharpness(struct gspca_dev *gspca_dev) | ||
657 | { | ||
658 | struct sd *sd = (struct sd *) gspca_dev; | ||
659 | __u16 reg_to_write; | ||
660 | |||
661 | reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness; | ||
662 | |||
663 | reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0); | ||
664 | } | ||
665 | |||
666 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
667 | { | ||
668 | struct sd *sd = (struct sd *) gspca_dev; | ||
669 | |||
670 | sd->brightness = val; | ||
671 | if (gspca_dev->streaming) | ||
672 | setbrightness(gspca_dev); | ||
673 | return 0; | ||
674 | } | ||
675 | |||
676 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
677 | { | ||
678 | struct sd *sd = (struct sd *) gspca_dev; | ||
679 | |||
680 | *val = sd->brightness; | ||
681 | return *val; | ||
682 | } | ||
683 | |||
684 | static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val) | ||
685 | { | ||
686 | struct sd *sd = (struct sd *) gspca_dev; | ||
687 | |||
688 | sd->whitebalance = val; | ||
689 | if (gspca_dev->streaming) | ||
690 | setwhitebalance(gspca_dev); | ||
691 | return 0; | ||
692 | } | ||
693 | |||
694 | static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val) | ||
695 | { | ||
696 | struct sd *sd = (struct sd *) gspca_dev; | ||
697 | |||
698 | *val = sd->whitebalance; | ||
699 | return *val; | ||
700 | } | ||
701 | |||
702 | static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val) | ||
703 | { | ||
704 | struct sd *sd = (struct sd *) gspca_dev; | ||
705 | |||
706 | sd->mirror = val; | ||
707 | if (gspca_dev->streaming) | ||
708 | setflip(gspca_dev); | ||
709 | return 0; | ||
710 | } | ||
711 | |||
712 | static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
713 | { | ||
714 | struct sd *sd = (struct sd *) gspca_dev; | ||
715 | |||
716 | *val = sd->mirror; | ||
717 | return *val; | ||
718 | } | ||
719 | |||
720 | static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val) | ||
721 | { | ||
722 | struct sd *sd = (struct sd *) gspca_dev; | ||
723 | |||
724 | sd->effect = val; | ||
725 | if (gspca_dev->streaming) | ||
726 | seteffect(gspca_dev); | ||
727 | return 0; | ||
728 | } | ||
729 | |||
730 | static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val) | ||
731 | { | ||
732 | struct sd *sd = (struct sd *) gspca_dev; | ||
733 | |||
734 | *val = sd->effect; | ||
735 | return *val; | ||
736 | } | ||
737 | |||
738 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
739 | { | ||
740 | struct sd *sd = (struct sd *) gspca_dev; | ||
741 | |||
742 | sd->contrast = val; | ||
743 | if (gspca_dev->streaming) | ||
744 | setcontrast(gspca_dev); | ||
745 | return 0; | ||
746 | } | ||
747 | |||
748 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
749 | { | ||
750 | struct sd *sd = (struct sd *) gspca_dev; | ||
751 | |||
752 | *val = sd->contrast; | ||
753 | return *val; | ||
754 | } | ||
755 | |||
756 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
757 | { | ||
758 | struct sd *sd = (struct sd *) gspca_dev; | ||
759 | |||
760 | sd->colors = val; | ||
761 | if (gspca_dev->streaming) | ||
762 | setcolors(gspca_dev); | ||
763 | return 0; | ||
764 | } | ||
765 | |||
766 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
767 | { | ||
768 | struct sd *sd = (struct sd *) gspca_dev; | ||
769 | |||
770 | *val = sd->colors; | ||
771 | return 0; | ||
772 | } | ||
773 | |||
774 | static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val) | ||
775 | { | ||
776 | struct sd *sd = (struct sd *) gspca_dev; | ||
777 | |||
778 | sd->gamma = val; | ||
779 | if (gspca_dev->streaming) | ||
780 | setgamma(gspca_dev); | ||
781 | return 0; | ||
782 | } | ||
783 | |||
784 | static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) | ||
785 | { | ||
786 | struct sd *sd = (struct sd *) gspca_dev; | ||
787 | *val = sd->gamma; | ||
788 | return 0; | ||
789 | } | ||
790 | |||
791 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | ||
792 | { | ||
793 | struct sd *sd = (struct sd *) gspca_dev; | ||
794 | |||
795 | sd->freq = val; | ||
796 | if (gspca_dev->streaming) | ||
797 | setlightfreq(gspca_dev); | ||
798 | return 0; | ||
799 | } | ||
800 | |||
801 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) | ||
802 | { | ||
803 | struct sd *sd = (struct sd *) gspca_dev; | ||
804 | |||
805 | *val = sd->freq; | ||
806 | return 0; | ||
807 | } | ||
808 | |||
809 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) | ||
810 | { | ||
811 | struct sd *sd = (struct sd *) gspca_dev; | ||
812 | |||
813 | sd->sharpness = val; | ||
814 | if (gspca_dev->streaming) | ||
815 | setsharpness(gspca_dev); | ||
816 | return 0; | ||
817 | } | ||
818 | |||
819 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) | ||
820 | { | ||
821 | struct sd *sd = (struct sd *) gspca_dev; | ||
822 | |||
823 | *val = sd->sharpness; | ||
824 | return 0; | ||
825 | } | ||
826 | |||
827 | /* Low Light set here......*/ | ||
828 | static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val) | ||
829 | { | ||
830 | struct sd *sd = (struct sd *) gspca_dev; | ||
831 | |||
832 | sd->autogain = val; | ||
833 | if (val != 0) | ||
834 | reg_w(gspca_dev, 0x00, 0xf48e, NULL, 0); | ||
835 | else | ||
836 | reg_w(gspca_dev, 0x00, 0xb48e, NULL, 0); | ||
837 | return 0; | ||
838 | } | ||
839 | |||
840 | static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val) | ||
841 | { | ||
842 | struct sd *sd = (struct sd *) gspca_dev; | ||
843 | |||
844 | *val = sd->autogain; | ||
845 | return 0; | ||
846 | } | ||
847 | |||
848 | static void sd_start(struct gspca_dev *gspca_dev) | ||
849 | { | ||
850 | int mode; | ||
851 | |||
852 | static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 }; | ||
853 | __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 }; | ||
854 | static const __u8 t3[] = | ||
855 | { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06, | ||
856 | 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 }; | ||
857 | static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 }; | ||
858 | |||
859 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv; | ||
860 | switch (mode) { | ||
861 | case 1: /* 352x288 */ | ||
862 | t2[1] = 0x40; | ||
863 | break; | ||
864 | case 2: /* 320x240 */ | ||
865 | t2[1] = 0x10; | ||
866 | break; | ||
867 | case 3: /* 176x144 */ | ||
868 | t2[1] = 0x50; | ||
869 | break; | ||
870 | case 4: /* 160x120 */ | ||
871 | t2[1] = 0x20; | ||
872 | break; | ||
873 | default: /* 640x480 (0x00) */ | ||
874 | break; | ||
875 | } | ||
876 | |||
877 | reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[0], 0x8); | ||
878 | reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[1], 0x8); | ||
879 | reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[2], 0x8); | ||
880 | reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8); | ||
881 | reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0); | ||
882 | /* just in case and to keep sync with logs (for mine) */ | ||
883 | reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8); | ||
884 | reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0); | ||
885 | /* just in case and to keep sync with logs (for mine) */ | ||
886 | reg_w(gspca_dev, 0x01, 0x0000, t1, 4); | ||
887 | reg_w(gspca_dev, 0x01, 0x0000, t2, 6); | ||
888 | reg_r_1(gspca_dev, 0x0012); | ||
889 | reg_w(gspca_dev, 0x01, 0x0000, t3, 0x10); | ||
890 | reg_w(gspca_dev, 0x00, 0x0013, NULL, 0); | ||
891 | reg_w(gspca_dev, 0x01, 0x0000, t4, 0x4); | ||
892 | /* restart on each start, just in case, sometimes regs goes wrong | ||
893 | * when using controls from app */ | ||
894 | setbrightness(gspca_dev); | ||
895 | setcontrast(gspca_dev); | ||
896 | setcolors(gspca_dev); | ||
897 | } | ||
898 | |||
899 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
900 | { | ||
901 | } | ||
902 | |||
903 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
904 | { | ||
905 | } | ||
906 | |||
907 | static void sd_close(struct gspca_dev *gspca_dev) | ||
908 | { | ||
909 | } | ||
910 | |||
911 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
912 | struct gspca_frame *frame, /* target */ | ||
913 | __u8 *data, /* isoc packet */ | ||
914 | int len) /* iso packet length */ | ||
915 | { | ||
916 | int sof = 0; | ||
917 | static __u8 ffd9[] = { 0xff, 0xd9 }; | ||
918 | |||
919 | if (data[0] == 0x5a) { | ||
920 | /* Control Packet, after this came the header again, | ||
921 | * but extra bytes came in the packet before this, | ||
922 | * sometimes an EOF arrives, sometimes not... */ | ||
923 | return; | ||
924 | } | ||
925 | |||
926 | if (data[len - 1] == 0xff && data[len] == 0xd9) { | ||
927 | /* Just in case, i have seen packets with the marker, | ||
928 | * other's do not include it... */ | ||
929 | data += 2; | ||
930 | len -= 4; | ||
931 | } else if (data[2] == 0xff && data[3] == 0xd8) { | ||
932 | sof = 1; | ||
933 | data += 2; | ||
934 | len -= 2; | ||
935 | } else { | ||
936 | data += 2; | ||
937 | len -= 2; | ||
938 | } | ||
939 | |||
940 | if (sof) { | ||
941 | /* extra bytes....., could be processed too but would be | ||
942 | * a waste of time, right now leave the application and | ||
943 | * libjpeg do it for ourserlves.. */ | ||
944 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | ||
945 | ffd9, 2); | ||
946 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); | ||
947 | return; | ||
948 | } | ||
949 | |||
950 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
951 | } | ||
952 | |||
953 | static int sd_querymenu(struct gspca_dev *gspca_dev, | ||
954 | struct v4l2_querymenu *menu) | ||
955 | { | ||
956 | switch (menu->id) { | ||
957 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
958 | switch (menu->index) { | ||
959 | case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ | ||
960 | strcpy((char *) menu->name, "50 Hz"); | ||
961 | return 0; | ||
962 | case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ | ||
963 | strcpy((char *) menu->name, "60 Hz"); | ||
964 | return 0; | ||
965 | } | ||
966 | break; | ||
967 | case V4L2_CID_EFFECTS: | ||
968 | if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) { | ||
969 | strncpy((char *) menu->name, | ||
970 | effects_control[menu->index], 32); | ||
971 | return 0; | ||
972 | } | ||
973 | break; | ||
974 | } | ||
975 | return -EINVAL; | ||
976 | } | ||
977 | |||
978 | /* this function is called at open time */ | ||
979 | static int sd_open(struct gspca_dev *gspca_dev) | ||
980 | { | ||
981 | init_default_parameters(gspca_dev); | ||
982 | return 0; | ||
983 | } | ||
984 | |||
985 | /* sub-driver description */ | ||
986 | static const struct sd_desc sd_desc = { | ||
987 | .name = MODULE_NAME, | ||
988 | .ctrls = sd_ctrls, | ||
989 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
990 | .config = sd_config, | ||
991 | .open = sd_open, | ||
992 | .start = sd_start, | ||
993 | .stopN = sd_stopN, | ||
994 | .stop0 = sd_stop0, | ||
995 | .close = sd_close, | ||
996 | .pkt_scan = sd_pkt_scan, | ||
997 | .querymenu = sd_querymenu, | ||
998 | }; | ||
999 | |||
1000 | /* -- module initialisation -- */ | ||
1001 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
1002 | static const __devinitdata struct usb_device_id device_table[] = { | ||
1003 | {USB_DEVICE(0x17a1, 0x0128), DVNM("XPX Webcam")}, | ||
1004 | {} | ||
1005 | }; | ||
1006 | MODULE_DEVICE_TABLE(usb, device_table); | ||
1007 | |||
1008 | /* -- device connect -- */ | ||
1009 | static int sd_probe(struct usb_interface *intf, | ||
1010 | const struct usb_device_id *id) | ||
1011 | { | ||
1012 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
1013 | THIS_MODULE); | ||
1014 | } | ||
1015 | |||
1016 | static struct usb_driver sd_driver = { | ||
1017 | .name = MODULE_NAME, | ||
1018 | .id_table = device_table, | ||
1019 | .probe = sd_probe, | ||
1020 | .disconnect = gspca_disconnect, | ||
1021 | }; | ||
1022 | |||
1023 | /* -- module insert / remove -- */ | ||
1024 | static int __init sd_mod_init(void) | ||
1025 | { | ||
1026 | if (usb_register(&sd_driver) < 0) | ||
1027 | return -1; | ||
1028 | PDEBUG(D_PROBE, "v%s registered", version); | ||
1029 | return 0; | ||
1030 | } | ||
1031 | static void __exit sd_mod_exit(void) | ||
1032 | { | ||
1033 | usb_deregister(&sd_driver); | ||
1034 | PDEBUG(D_PROBE, "deregistered"); | ||
1035 | } | ||
1036 | |||
1037 | module_init(sd_mod_init); | ||
1038 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c new file mode 100644 index 000000000000..0b793899095f --- /dev/null +++ b/drivers/media/video/gspca/tv8532.c | |||
@@ -0,0 +1,670 @@ | |||
1 | /* | ||
2 | * Quickcam cameras initialization data | ||
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 "tv8532" | ||
22 | |||
23 | #include "gspca.h" | ||
24 | |||
25 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) | ||
26 | static const char version[] = "2.1.7"; | ||
27 | |||
28 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
29 | MODULE_DESCRIPTION("TV8532 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 | int buflen; /* current length of tmpbuf */ | ||
37 | __u8 tmpbuf[352 * 288 + 10 * 288]; /* no protection... */ | ||
38 | __u8 tmpbuf2[352 * 288]; /* no protection... */ | ||
39 | |||
40 | unsigned short brightness; | ||
41 | unsigned short contrast; | ||
42 | |||
43 | char packet; | ||
44 | char synchro; | ||
45 | }; | ||
46 | |||
47 | /* V4L2 controls supported by the driver */ | ||
48 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
49 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
50 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
51 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
52 | |||
53 | static struct ctrl sd_ctrls[] = { | ||
54 | #define SD_BRIGHTNESS 0 | ||
55 | { | ||
56 | { | ||
57 | .id = V4L2_CID_BRIGHTNESS, | ||
58 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
59 | .name = "Brightness", | ||
60 | .minimum = 1, | ||
61 | .maximum = 0x2ff, | ||
62 | .step = 1, | ||
63 | .default_value = 0x18f, | ||
64 | }, | ||
65 | .set = sd_setbrightness, | ||
66 | .get = sd_getbrightness, | ||
67 | }, | ||
68 | #define SD_CONTRAST 1 | ||
69 | { | ||
70 | { | ||
71 | .id = V4L2_CID_CONTRAST, | ||
72 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
73 | .name = "Contrast", | ||
74 | .minimum = 0, | ||
75 | .maximum = 0xffff, | ||
76 | .step = 1, | ||
77 | .default_value = 0x7fff, | ||
78 | }, | ||
79 | .set = sd_setcontrast, | ||
80 | .get = sd_getcontrast, | ||
81 | }, | ||
82 | }; | ||
83 | |||
84 | static struct v4l2_pix_format sif_mode[] = { | ||
85 | {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
86 | .bytesperline = 176, | ||
87 | .sizeimage = 176 * 144, | ||
88 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
89 | .priv = 1}, | ||
90 | {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
91 | .bytesperline = 352, | ||
92 | .sizeimage = 352 * 288, | ||
93 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
94 | .priv = 0}, | ||
95 | }; | ||
96 | |||
97 | /* | ||
98 | * Initialization data: this is the first set-up data written to the | ||
99 | * device (before the open data). | ||
100 | */ | ||
101 | #define TESTCLK 0x10 /* reg 0x2c -> 0x12 //10 */ | ||
102 | #define TESTCOMP 0x90 /* reg 0x28 -> 0x80 */ | ||
103 | #define TESTLINE 0x81 /* reg 0x29 -> 0x81 */ | ||
104 | #define QCIFLINE 0x41 /* reg 0x29 -> 0x81 */ | ||
105 | #define TESTPTL 0x14 /* reg 0x2D -> 0x14 */ | ||
106 | #define TESTPTH 0x01 /* reg 0x2E -> 0x01 */ | ||
107 | #define TESTPTBL 0x12 /* reg 0x2F -> 0x0a */ | ||
108 | #define TESTPTBH 0x01 /* reg 0x30 -> 0x01 */ | ||
109 | #define ADWIDTHL 0xe8 /* reg 0x0c -> 0xe8 */ | ||
110 | #define ADWIDTHH 0x03 /* reg 0x0d -> 0x03 */ | ||
111 | #define ADHEIGHL 0x90 /* reg 0x0e -> 0x91 //93 */ | ||
112 | #define ADHEIGHH 0x01 /* reg 0x0f -> 0x01 */ | ||
113 | #define EXPOL 0x8f /* reg 0x1c -> 0x8f */ | ||
114 | #define EXPOH 0x01 /* reg 0x1d -> 0x01 */ | ||
115 | #define ADCBEGINL 0x44 /* reg 0x10 -> 0x46 //47 */ | ||
116 | #define ADCBEGINH 0x00 /* reg 0x11 -> 0x00 */ | ||
117 | #define ADRBEGINL 0x0a /* reg 0x14 -> 0x0b //0x0c */ | ||
118 | #define ADRBEGINH 0x00 /* reg 0x15 -> 0x00 */ | ||
119 | #define TV8532_CMD_UPDATE 0x84 | ||
120 | |||
121 | #define TV8532_EEprom_Add 0x03 | ||
122 | #define TV8532_EEprom_DataL 0x04 | ||
123 | #define TV8532_EEprom_DataM 0x05 | ||
124 | #define TV8532_EEprom_DataH 0x06 | ||
125 | #define TV8532_EEprom_TableLength 0x07 | ||
126 | #define TV8532_EEprom_Write 0x08 | ||
127 | #define TV8532_PART_CTRL 0x00 | ||
128 | #define TV8532_CTRL 0x01 | ||
129 | #define TV8532_CMD_EEprom_Open 0x30 | ||
130 | #define TV8532_CMD_EEprom_Close 0x29 | ||
131 | #define TV8532_UDP_UPDATE 0x31 | ||
132 | #define TV8532_GPIO 0x39 | ||
133 | #define TV8532_GPIO_OE 0x3B | ||
134 | #define TV8532_REQ_RegWrite 0x02 | ||
135 | #define TV8532_REQ_RegRead 0x03 | ||
136 | |||
137 | #define TV8532_ADWIDTH_L 0x0C | ||
138 | #define TV8532_ADWIDTH_H 0x0D | ||
139 | #define TV8532_ADHEIGHT_L 0x0E | ||
140 | #define TV8532_ADHEIGHT_H 0x0F | ||
141 | #define TV8532_EXPOSURE 0x1C | ||
142 | #define TV8532_QUANT_COMP 0x28 | ||
143 | #define TV8532_MODE_PACKET 0x29 | ||
144 | #define TV8532_SETCLK 0x2C | ||
145 | #define TV8532_POINT_L 0x2D | ||
146 | #define TV8532_POINT_H 0x2E | ||
147 | #define TV8532_POINTB_L 0x2F | ||
148 | #define TV8532_POINTB_H 0x30 | ||
149 | #define TV8532_BUDGET_L 0x2A | ||
150 | #define TV8532_BUDGET_H 0x2B | ||
151 | #define TV8532_VID_L 0x34 | ||
152 | #define TV8532_VID_H 0x35 | ||
153 | #define TV8532_PID_L 0x36 | ||
154 | #define TV8532_PID_H 0x37 | ||
155 | #define TV8532_DeviceID 0x83 | ||
156 | #define TV8532_AD_SLOPE 0x91 | ||
157 | #define TV8532_AD_BITCTRL 0x94 | ||
158 | #define TV8532_AD_COLBEGIN_L 0x10 | ||
159 | #define TV8532_AD_COLBEGIN_H 0x11 | ||
160 | #define TV8532_AD_ROWBEGIN_L 0x14 | ||
161 | #define TV8532_AD_ROWBEGIN_H 0x15 | ||
162 | |||
163 | static const __u32 tv_8532_eeprom_data[] = { | ||
164 | /* add dataL dataM dataH */ | ||
165 | 0x00010001, 0x01018011, 0x02050014, 0x0305001c, | ||
166 | 0x040d001e, 0x0505001f, 0x06050519, 0x0705011b, | ||
167 | 0x0805091e, 0x090d892e, 0x0a05892f, 0x0b050dd9, | ||
168 | 0x0c0509f1, 0 | ||
169 | }; | ||
170 | |||
171 | static int reg_r(struct gspca_dev *gspca_dev, | ||
172 | __u16 index) | ||
173 | { | ||
174 | usb_control_msg(gspca_dev->dev, | ||
175 | usb_rcvctrlpipe(gspca_dev->dev, 0), | ||
176 | TV8532_REQ_RegRead, | ||
177 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
178 | 0, /* value */ | ||
179 | index, gspca_dev->usb_buf, 1, | ||
180 | 500); | ||
181 | return gspca_dev->usb_buf[0]; | ||
182 | } | ||
183 | |||
184 | /* write 1 byte */ | ||
185 | static void reg_w_1(struct gspca_dev *gspca_dev, | ||
186 | __u16 index, __u8 value) | ||
187 | { | ||
188 | gspca_dev->usb_buf[0] = value; | ||
189 | usb_control_msg(gspca_dev->dev, | ||
190 | usb_sndctrlpipe(gspca_dev->dev, 0), | ||
191 | TV8532_REQ_RegWrite, | ||
192 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
193 | 0, /* value */ | ||
194 | index, gspca_dev->usb_buf, 1, 500); | ||
195 | } | ||
196 | |||
197 | /* write 2 bytes */ | ||
198 | static void reg_w_2(struct gspca_dev *gspca_dev, | ||
199 | __u16 index, __u8 val1, __u8 val2) | ||
200 | { | ||
201 | gspca_dev->usb_buf[0] = val1; | ||
202 | gspca_dev->usb_buf[1] = val2; | ||
203 | usb_control_msg(gspca_dev->dev, | ||
204 | usb_sndctrlpipe(gspca_dev->dev, 0), | ||
205 | TV8532_REQ_RegWrite, | ||
206 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
207 | 0, /* value */ | ||
208 | index, gspca_dev->usb_buf, 2, 500); | ||
209 | } | ||
210 | |||
211 | static void tv_8532WriteEEprom(struct gspca_dev *gspca_dev) | ||
212 | { | ||
213 | int i = 0; | ||
214 | __u8 reg, data0, data1, data2; | ||
215 | |||
216 | reg_w_1(gspca_dev, TV8532_GPIO, 0xb0); | ||
217 | reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Open); | ||
218 | /* msleep(1); */ | ||
219 | while (tv_8532_eeprom_data[i]) { | ||
220 | reg = (tv_8532_eeprom_data[i] & 0xff000000) >> 24; | ||
221 | reg_w_1(gspca_dev, TV8532_EEprom_Add, reg); | ||
222 | /* msleep(1); */ | ||
223 | data0 = (tv_8532_eeprom_data[i] & 0x000000ff); | ||
224 | reg_w_1(gspca_dev, TV8532_EEprom_DataL, data0); | ||
225 | /* msleep(1); */ | ||
226 | data1 = (tv_8532_eeprom_data[i] & 0x0000ff00) >> 8; | ||
227 | reg_w_1(gspca_dev, TV8532_EEprom_DataM, data1); | ||
228 | /* msleep(1); */ | ||
229 | data2 = (tv_8532_eeprom_data[i] & 0x00ff0000) >> 16; | ||
230 | reg_w_1(gspca_dev, TV8532_EEprom_DataH, data2); | ||
231 | /* msleep(1); */ | ||
232 | reg_w_1(gspca_dev, TV8532_EEprom_Write, 0); | ||
233 | /* msleep(10); */ | ||
234 | i++; | ||
235 | } | ||
236 | reg_w_1(gspca_dev, TV8532_EEprom_TableLength, i); | ||
237 | /* msleep(1); */ | ||
238 | reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Close); | ||
239 | msleep(10); | ||
240 | } | ||
241 | |||
242 | /* this function is called at probe time */ | ||
243 | static int sd_config(struct gspca_dev *gspca_dev, | ||
244 | const struct usb_device_id *id) | ||
245 | { | ||
246 | struct sd *sd = (struct sd *) gspca_dev; | ||
247 | struct cam *cam; | ||
248 | |||
249 | tv_8532WriteEEprom(gspca_dev); | ||
250 | |||
251 | cam = &gspca_dev->cam; | ||
252 | cam->dev_name = (char *) id->driver_info; | ||
253 | cam->epaddr = 1; | ||
254 | cam->cam_mode = sif_mode; | ||
255 | cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; | ||
256 | |||
257 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
258 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | ||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | static void tv_8532ReadRegisters(struct gspca_dev *gspca_dev) | ||
263 | { | ||
264 | __u8 data; | ||
265 | |||
266 | data = reg_r(gspca_dev, 0x0001); | ||
267 | PDEBUG(D_USBI, "register 0x01-> %x", data); | ||
268 | data = reg_r(gspca_dev, 0x0002); | ||
269 | PDEBUG(D_USBI, "register 0x02-> %x", data); | ||
270 | reg_r(gspca_dev, TV8532_ADWIDTH_L); | ||
271 | reg_r(gspca_dev, TV8532_ADWIDTH_H); | ||
272 | reg_r(gspca_dev, TV8532_QUANT_COMP); | ||
273 | reg_r(gspca_dev, TV8532_MODE_PACKET); | ||
274 | reg_r(gspca_dev, TV8532_SETCLK); | ||
275 | reg_r(gspca_dev, TV8532_POINT_L); | ||
276 | reg_r(gspca_dev, TV8532_POINT_H); | ||
277 | reg_r(gspca_dev, TV8532_POINTB_L); | ||
278 | reg_r(gspca_dev, TV8532_POINTB_H); | ||
279 | reg_r(gspca_dev, TV8532_BUDGET_L); | ||
280 | reg_r(gspca_dev, TV8532_BUDGET_H); | ||
281 | reg_r(gspca_dev, TV8532_VID_L); | ||
282 | reg_r(gspca_dev, TV8532_VID_H); | ||
283 | reg_r(gspca_dev, TV8532_PID_L); | ||
284 | reg_r(gspca_dev, TV8532_PID_H); | ||
285 | reg_r(gspca_dev, TV8532_DeviceID); | ||
286 | reg_r(gspca_dev, TV8532_AD_COLBEGIN_L); | ||
287 | reg_r(gspca_dev, TV8532_AD_COLBEGIN_H); | ||
288 | reg_r(gspca_dev, TV8532_AD_ROWBEGIN_L); | ||
289 | reg_r(gspca_dev, TV8532_AD_ROWBEGIN_H); | ||
290 | } | ||
291 | |||
292 | static void tv_8532_setReg(struct gspca_dev *gspca_dev) | ||
293 | { | ||
294 | reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L, | ||
295 | ADCBEGINL); /* 0x10 */ | ||
296 | reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H, | ||
297 | ADCBEGINH); /* also digital gain */ | ||
298 | reg_w_1(gspca_dev, TV8532_PART_CTRL, | ||
299 | TV8532_CMD_UPDATE); /* 0x00<-0x84 */ | ||
300 | |||
301 | reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0a); | ||
302 | /******************************************************/ | ||
303 | reg_w_1(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL); /* 0e */ | ||
304 | reg_w_1(gspca_dev, TV8532_ADHEIGHT_H, ADHEIGHH); /* 0f */ | ||
305 | reg_w_2(gspca_dev, TV8532_EXPOSURE, | ||
306 | EXPOL, EXPOH); /* 350d 0x014c; 1c */ | ||
307 | reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L, | ||
308 | ADCBEGINL); /* 0x10 */ | ||
309 | reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H, | ||
310 | ADCBEGINH); /* also digital gain */ | ||
311 | reg_w_1(gspca_dev, TV8532_AD_ROWBEGIN_L, | ||
312 | ADRBEGINL); /* 0x14 */ | ||
313 | |||
314 | reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00); /* 0x91 */ | ||
315 | reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x02); /* 0x94 */ | ||
316 | |||
317 | reg_w_1(gspca_dev, TV8532_CTRL, | ||
318 | TV8532_CMD_EEprom_Close); /* 0x01 */ | ||
319 | |||
320 | reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00); /* 0x91 */ | ||
321 | reg_w_1(gspca_dev, TV8532_PART_CTRL, | ||
322 | TV8532_CMD_UPDATE); /* 0x00<-0x84 */ | ||
323 | } | ||
324 | |||
325 | static void tv_8532_PollReg(struct gspca_dev *gspca_dev) | ||
326 | { | ||
327 | int i; | ||
328 | |||
329 | /* strange polling from tgc */ | ||
330 | for (i = 0; i < 10; i++) { | ||
331 | reg_w_1(gspca_dev, TV8532_SETCLK, | ||
332 | TESTCLK); /* 0x48; //0x08; 0x2c */ | ||
333 | reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE); | ||
334 | reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */ | ||
335 | } | ||
336 | } | ||
337 | |||
338 | /* this function is called at open time */ | ||
339 | static int sd_open(struct gspca_dev *gspca_dev) | ||
340 | { | ||
341 | reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32); | ||
342 | reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00); | ||
343 | tv_8532ReadRegisters(gspca_dev); | ||
344 | reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); | ||
345 | reg_w_2(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL, | ||
346 | ADHEIGHH); /* 401d 0x0169; 0e */ | ||
347 | reg_w_2(gspca_dev, TV8532_EXPOSURE, EXPOL, | ||
348 | EXPOH); /* 350d 0x014c; 1c */ | ||
349 | reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL); /* 0x20; 0x0c */ | ||
350 | reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH); /* 0x0d */ | ||
351 | |||
352 | /*******************************************************************/ | ||
353 | reg_w_1(gspca_dev, TV8532_QUANT_COMP, | ||
354 | TESTCOMP); /* 0x72 compressed mode 0x28 */ | ||
355 | reg_w_1(gspca_dev, TV8532_MODE_PACKET, | ||
356 | TESTLINE); /* 0x84; // CIF | 4 packet 0x29 */ | ||
357 | |||
358 | /************************************************/ | ||
359 | reg_w_1(gspca_dev, TV8532_SETCLK, | ||
360 | TESTCLK); /* 0x48; //0x08; 0x2c */ | ||
361 | reg_w_1(gspca_dev, TV8532_POINT_L, | ||
362 | TESTPTL); /* 0x38; 0x2d */ | ||
363 | reg_w_1(gspca_dev, TV8532_POINT_H, | ||
364 | TESTPTH); /* 0x04; 0x2e */ | ||
365 | reg_w_1(gspca_dev, TV8532_POINTB_L, | ||
366 | TESTPTBL); /* 0x04; 0x2f */ | ||
367 | reg_w_1(gspca_dev, TV8532_POINTB_H, | ||
368 | TESTPTBH); /* 0x04; 0x30 */ | ||
369 | reg_w_1(gspca_dev, TV8532_PART_CTRL, | ||
370 | TV8532_CMD_UPDATE); /* 0x00<-0x84 */ | ||
371 | /*************************************************/ | ||
372 | reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */ | ||
373 | msleep(200); | ||
374 | reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */ | ||
375 | /*************************************************/ | ||
376 | tv_8532_setReg(gspca_dev); | ||
377 | /*************************************************/ | ||
378 | reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); | ||
379 | /*************************************************/ | ||
380 | tv_8532_setReg(gspca_dev); | ||
381 | /*************************************************/ | ||
382 | tv_8532_PollReg(gspca_dev); | ||
383 | return 0; | ||
384 | } | ||
385 | |||
386 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
387 | { | ||
388 | struct sd *sd = (struct sd *) gspca_dev; | ||
389 | int brightness = sd->brightness; | ||
390 | |||
391 | reg_w_2(gspca_dev, TV8532_EXPOSURE, | ||
392 | brightness >> 8, brightness); /* 1c */ | ||
393 | reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE); | ||
394 | } | ||
395 | |||
396 | /* -- start the camera -- */ | ||
397 | static void sd_start(struct gspca_dev *gspca_dev) | ||
398 | { | ||
399 | reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32); | ||
400 | reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00); | ||
401 | tv_8532ReadRegisters(gspca_dev); | ||
402 | reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); | ||
403 | reg_w_2(gspca_dev, TV8532_ADHEIGHT_L, | ||
404 | ADHEIGHL, ADHEIGHH); /* 401d 0x0169; 0e */ | ||
405 | /* reg_w_2(gspca_dev, TV8532_EXPOSURE, | ||
406 | EXPOL, EXPOH); * 350d 0x014c; 1c */ | ||
407 | setbrightness(gspca_dev); | ||
408 | |||
409 | reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL); /* 0x20; 0x0c */ | ||
410 | reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH); /* 0x0d */ | ||
411 | |||
412 | /************************************************/ | ||
413 | reg_w_1(gspca_dev, TV8532_QUANT_COMP, | ||
414 | TESTCOMP); /* 0x72 compressed mode 0x28 */ | ||
415 | if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { | ||
416 | /* 176x144 */ | ||
417 | reg_w_1(gspca_dev, TV8532_MODE_PACKET, | ||
418 | QCIFLINE); /* 0x84; // CIF | 4 packet 0x29 */ | ||
419 | } else { | ||
420 | /* 352x288 */ | ||
421 | reg_w_1(gspca_dev, TV8532_MODE_PACKET, | ||
422 | TESTLINE); /* 0x84; // CIF | 4 packet 0x29 */ | ||
423 | } | ||
424 | /************************************************/ | ||
425 | reg_w_1(gspca_dev, TV8532_SETCLK, | ||
426 | TESTCLK); /* 0x48; //0x08; 0x2c */ | ||
427 | reg_w_1(gspca_dev, TV8532_POINT_L, | ||
428 | TESTPTL); /* 0x38; 0x2d */ | ||
429 | reg_w_1(gspca_dev, TV8532_POINT_H, | ||
430 | TESTPTH); /* 0x04; 0x2e */ | ||
431 | reg_w_1(gspca_dev, TV8532_POINTB_L, | ||
432 | TESTPTBL); /* 0x04; 0x2f */ | ||
433 | reg_w_1(gspca_dev, TV8532_POINTB_H, | ||
434 | TESTPTBH); /* 0x04; 0x30 */ | ||
435 | reg_w_1(gspca_dev, TV8532_PART_CTRL, | ||
436 | TV8532_CMD_UPDATE); /* 0x00<-0x84 */ | ||
437 | /************************************************/ | ||
438 | reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */ | ||
439 | msleep(200); | ||
440 | reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */ | ||
441 | /************************************************/ | ||
442 | tv_8532_setReg(gspca_dev); | ||
443 | /************************************************/ | ||
444 | reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); | ||
445 | /************************************************/ | ||
446 | tv_8532_setReg(gspca_dev); | ||
447 | /************************************************/ | ||
448 | tv_8532_PollReg(gspca_dev); | ||
449 | reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */ | ||
450 | } | ||
451 | |||
452 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
453 | { | ||
454 | reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); | ||
455 | } | ||
456 | |||
457 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
458 | { | ||
459 | } | ||
460 | |||
461 | static void sd_close(struct gspca_dev *gspca_dev) | ||
462 | { | ||
463 | } | ||
464 | |||
465 | static void tv8532_preprocess(struct gspca_dev *gspca_dev) | ||
466 | { | ||
467 | struct sd *sd = (struct sd *) gspca_dev; | ||
468 | /* we should received a whole frame with header and EOL marker | ||
469 | * in gspca_dev->tmpbuf and return a GBRG pattern in gspca_dev->tmpbuf2 | ||
470 | * sequence 2bytes header the Alternate pixels bayer GB 4 bytes | ||
471 | * Alternate pixels bayer RG 4 bytes EOL */ | ||
472 | int width = gspca_dev->width; | ||
473 | int height = gspca_dev->height; | ||
474 | unsigned char *dst = sd->tmpbuf2; | ||
475 | unsigned char *data = sd->tmpbuf; | ||
476 | int i; | ||
477 | |||
478 | /* precompute where is the good bayer line */ | ||
479 | if (((data[3] + data[width + 7]) >> 1) | ||
480 | + (data[4] >> 2) | ||
481 | + (data[width + 6] >> 1) >= ((data[2] + data[width + 6]) >> 1) | ||
482 | + (data[3] >> 2) | ||
483 | + (data[width + 5] >> 1)) | ||
484 | data += 3; | ||
485 | else | ||
486 | data += 2; | ||
487 | for (i = 0; i < height / 2; i++) { | ||
488 | memcpy(dst, data, width); | ||
489 | data += width + 3; | ||
490 | dst += width; | ||
491 | memcpy(dst, data, width); | ||
492 | data += width + 7; | ||
493 | dst += width; | ||
494 | } | ||
495 | } | ||
496 | |||
497 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
498 | struct gspca_frame *frame, /* target */ | ||
499 | __u8 *data, /* isoc packet */ | ||
500 | int len) /* iso packet length */ | ||
501 | { | ||
502 | struct sd *sd = (struct sd *) gspca_dev; | ||
503 | |||
504 | if (data[0] != 0x80) { | ||
505 | sd->packet++; | ||
506 | if (sd->buflen + len > sizeof sd->tmpbuf) { | ||
507 | if (gspca_dev->last_packet_type != DISCARD_PACKET) { | ||
508 | PDEBUG(D_PACK, "buffer overflow"); | ||
509 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
510 | } | ||
511 | return; | ||
512 | } | ||
513 | memcpy(&sd->tmpbuf[sd->buflen], data, len); | ||
514 | sd->buflen += len; | ||
515 | return; | ||
516 | } | ||
517 | |||
518 | /* here we detect 0x80 */ | ||
519 | /* counter is limited so we need few header for a frame :) */ | ||
520 | |||
521 | /* header 0x80 0x80 0x80 0x80 0x80 */ | ||
522 | /* packet 00 63 127 145 00 */ | ||
523 | /* sof 0 1 1 0 0 */ | ||
524 | |||
525 | /* update sequence */ | ||
526 | if (sd->packet == 63 || sd->packet == 127) | ||
527 | sd->synchro = 1; | ||
528 | |||
529 | /* is there a frame start ? */ | ||
530 | if (sd->packet >= (gspca_dev->height >> 1) - 1) { | ||
531 | PDEBUG(D_PACK, "SOF > %d packet %d", sd->synchro, | ||
532 | sd->packet); | ||
533 | if (!sd->synchro) { /* start of frame */ | ||
534 | if (gspca_dev->last_packet_type == FIRST_PACKET) { | ||
535 | tv8532_preprocess(gspca_dev); | ||
536 | frame = gspca_frame_add(gspca_dev, | ||
537 | LAST_PACKET, | ||
538 | frame, sd->tmpbuf2, | ||
539 | gspca_dev->width * | ||
540 | gspca_dev->width); | ||
541 | } | ||
542 | gspca_frame_add(gspca_dev, FIRST_PACKET, | ||
543 | frame, data, 0); | ||
544 | memcpy(sd->tmpbuf, data, len); | ||
545 | sd->buflen = len; | ||
546 | sd->packet = 0; | ||
547 | return; | ||
548 | } | ||
549 | if (gspca_dev->last_packet_type != DISCARD_PACKET) { | ||
550 | PDEBUG(D_PACK, | ||
551 | "Warning wrong TV8532 frame detection %d", | ||
552 | sd->packet); | ||
553 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
554 | } | ||
555 | return; | ||
556 | } | ||
557 | |||
558 | if (!sd->synchro) { | ||
559 | /* Drop packet frame corrupt */ | ||
560 | PDEBUG(D_PACK, "DROP SOF %d packet %d", | ||
561 | sd->synchro, sd->packet); | ||
562 | sd->packet = 0; | ||
563 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
564 | return; | ||
565 | } | ||
566 | sd->synchro = 1; | ||
567 | sd->packet++; | ||
568 | memcpy(&sd->tmpbuf[sd->buflen], data, len); | ||
569 | sd->buflen += len; | ||
570 | } | ||
571 | |||
572 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
573 | { | ||
574 | } | ||
575 | |||
576 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
577 | { | ||
578 | struct sd *sd = (struct sd *) gspca_dev; | ||
579 | |||
580 | sd->brightness = val; | ||
581 | if (gspca_dev->streaming) | ||
582 | setbrightness(gspca_dev); | ||
583 | return 0; | ||
584 | } | ||
585 | |||
586 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
587 | { | ||
588 | struct sd *sd = (struct sd *) gspca_dev; | ||
589 | |||
590 | *val = sd->brightness; | ||
591 | return 0; | ||
592 | } | ||
593 | |||
594 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
595 | { | ||
596 | struct sd *sd = (struct sd *) gspca_dev; | ||
597 | |||
598 | sd->contrast = val; | ||
599 | if (gspca_dev->streaming) | ||
600 | setcontrast(gspca_dev); | ||
601 | return 0; | ||
602 | } | ||
603 | |||
604 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
605 | { | ||
606 | struct sd *sd = (struct sd *) gspca_dev; | ||
607 | |||
608 | *val = sd->contrast; | ||
609 | return 0; | ||
610 | } | ||
611 | |||
612 | /* sub-driver description */ | ||
613 | static const struct sd_desc sd_desc = { | ||
614 | .name = MODULE_NAME, | ||
615 | .ctrls = sd_ctrls, | ||
616 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
617 | .config = sd_config, | ||
618 | .open = sd_open, | ||
619 | .start = sd_start, | ||
620 | .stopN = sd_stopN, | ||
621 | .stop0 = sd_stop0, | ||
622 | .close = sd_close, | ||
623 | .pkt_scan = sd_pkt_scan, | ||
624 | }; | ||
625 | |||
626 | /* -- module initialisation -- */ | ||
627 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
628 | static const __devinitdata struct usb_device_id device_table[] = { | ||
629 | {USB_DEVICE(0x046d, 0x0920), DVNM("QC Express")}, | ||
630 | {USB_DEVICE(0x046d, 0x0921), DVNM("Labtec Webcam")}, | ||
631 | {USB_DEVICE(0x0545, 0x808b), DVNM("Veo Stingray")}, | ||
632 | {USB_DEVICE(0x0545, 0x8333), DVNM("Veo Stingray")}, | ||
633 | {USB_DEVICE(0x0923, 0x010f), DVNM("ICM532 cams")}, | ||
634 | {} | ||
635 | }; | ||
636 | |||
637 | MODULE_DEVICE_TABLE(usb, device_table); | ||
638 | |||
639 | /* -- device connect -- */ | ||
640 | static int sd_probe(struct usb_interface *intf, | ||
641 | const struct usb_device_id *id) | ||
642 | { | ||
643 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
644 | THIS_MODULE); | ||
645 | } | ||
646 | |||
647 | static struct usb_driver sd_driver = { | ||
648 | .name = MODULE_NAME, | ||
649 | .id_table = device_table, | ||
650 | .probe = sd_probe, | ||
651 | .disconnect = gspca_disconnect, | ||
652 | }; | ||
653 | |||
654 | /* -- module insert / remove -- */ | ||
655 | static int __init sd_mod_init(void) | ||
656 | { | ||
657 | if (usb_register(&sd_driver) < 0) | ||
658 | return -1; | ||
659 | PDEBUG(D_PROBE, "v%s registered", version); | ||
660 | return 0; | ||
661 | } | ||
662 | |||
663 | static void __exit sd_mod_exit(void) | ||
664 | { | ||
665 | usb_deregister(&sd_driver); | ||
666 | PDEBUG(D_PROBE, "deregistered"); | ||
667 | } | ||
668 | |||
669 | module_init(sd_mod_init); | ||
670 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c new file mode 100644 index 000000000000..fcf2c9e32573 --- /dev/null +++ b/drivers/media/video/gspca/vc032x.c | |||
@@ -0,0 +1,1818 @@ | |||
1 | /* | ||
2 | * Z-star vc0321 library | ||
3 | * Copyright (C) 2006 Koninski Artur takeshi87@o2.pl | ||
4 | * Copyright (C) 2006 Michel Xhaard | ||
5 | * | ||
6 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #define MODULE_NAME "vc032x" | ||
24 | |||
25 | #include "gspca.h" | ||
26 | |||
27 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) | ||
28 | static const char version[] = "2.1.7"; | ||
29 | |||
30 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | ||
31 | MODULE_DESCRIPTION("GSPCA/VC032X USB Camera Driver"); | ||
32 | MODULE_LICENSE("GPL"); | ||
33 | |||
34 | /* specific webcam descriptor */ | ||
35 | struct sd { | ||
36 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
37 | |||
38 | unsigned char autogain; | ||
39 | unsigned char lightfreq; | ||
40 | |||
41 | char qindex; | ||
42 | char bridge; | ||
43 | #define BRIDGE_VC0321 0 | ||
44 | #define BRIDGE_VC0323 1 | ||
45 | char sensor; | ||
46 | #define SENSOR_HV7131R 0 | ||
47 | #define SENSOR_MI1320 1 | ||
48 | #define SENSOR_MI1310_SOC 2 | ||
49 | #define SENSOR_OV7660 3 | ||
50 | #define SENSOR_OV7670 4 | ||
51 | #define SENSOR_PO3130NC 5 | ||
52 | }; | ||
53 | |||
54 | /* V4L2 controls supported by the driver */ | ||
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 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | ||
58 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | ||
59 | |||
60 | static struct ctrl sd_ctrls[] = { | ||
61 | { | ||
62 | { | ||
63 | .id = V4L2_CID_AUTOGAIN, | ||
64 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
65 | .name = "Auto Gain", | ||
66 | .minimum = 0, | ||
67 | .maximum = 1, | ||
68 | .step = 1, | ||
69 | #define AUTOGAIN_DEF 1 | ||
70 | .default_value = AUTOGAIN_DEF, | ||
71 | }, | ||
72 | .set = sd_setautogain, | ||
73 | .get = sd_getautogain, | ||
74 | }, | ||
75 | { | ||
76 | { | ||
77 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | ||
78 | .type = V4L2_CTRL_TYPE_MENU, | ||
79 | .name = "Light frequency filter", | ||
80 | .minimum = 0, | ||
81 | .maximum = 2, /* 0: No, 1: 50Hz, 2:60Hz */ | ||
82 | .step = 1, | ||
83 | #define FREQ_DEF 1 | ||
84 | .default_value = FREQ_DEF, | ||
85 | .default_value = 1, | ||
86 | }, | ||
87 | .set = sd_setfreq, | ||
88 | .get = sd_getfreq, | ||
89 | }, | ||
90 | }; | ||
91 | |||
92 | static struct v4l2_pix_format vc0321_mode[] = { | ||
93 | {320, 240, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE, | ||
94 | .bytesperline = 320 * 2, | ||
95 | .sizeimage = 320 * 240 * 2, | ||
96 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
97 | .priv = 1}, | ||
98 | {640, 480, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE, | ||
99 | .bytesperline = 640 * 2, | ||
100 | .sizeimage = 640 * 480 * 2, | ||
101 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
102 | .priv = 0}, | ||
103 | }; | ||
104 | static struct v4l2_pix_format vc0323_mode[] = { | ||
105 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
106 | .bytesperline = 320, | ||
107 | .sizeimage = 320 * 240 * 3 / 8 + 590, | ||
108 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
109 | .priv = 1}, | ||
110 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
111 | .bytesperline = 640, | ||
112 | .sizeimage = 640 * 480 * 3 / 8 + 590, | ||
113 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
114 | .priv = 0}, | ||
115 | }; | ||
116 | |||
117 | static const __u8 mi1310_socinitVGA_JPG[][4] = { | ||
118 | {0xb0, 0x03, 0x19, 0xcc}, | ||
119 | {0xb0, 0x04, 0x02, 0xcc}, | ||
120 | {0xb3, 0x00, 0x64, 0xcc}, | ||
121 | {0xb3, 0x00, 0x65, 0xcc}, | ||
122 | {0xb3, 0x05, 0x00, 0xcc}, | ||
123 | {0xb3, 0x06, 0x00, 0xcc}, | ||
124 | {0xb3, 0x08, 0x01, 0xcc}, | ||
125 | {0xb3, 0x09, 0x0c, 0xcc}, | ||
126 | {0xb3, 0x34, 0x02, 0xcc}, | ||
127 | {0xb3, 0x35, 0xdd, 0xcc}, | ||
128 | {0xb3, 0x02, 0x00, 0xcc}, | ||
129 | {0xb3, 0x03, 0x0a, 0xcc}, | ||
130 | {0xb3, 0x04, 0x05, 0xcc}, | ||
131 | {0xb3, 0x20, 0x00, 0xcc}, | ||
132 | {0xb3, 0x21, 0x00, 0xcc}, | ||
133 | {0xb3, 0x22, 0x03, 0xcc}, | ||
134 | {0xb3, 0x23, 0xc0, 0xcc}, | ||
135 | {0xb3, 0x14, 0x00, 0xcc}, | ||
136 | {0xb3, 0x15, 0x00, 0xcc}, | ||
137 | {0xb3, 0x16, 0x04, 0xcc}, | ||
138 | {0xb3, 0x17, 0xff, 0xcc}, | ||
139 | {0xb3, 0x00, 0x65, 0xcc}, | ||
140 | {0xb8, 0x00, 0x00, 0xcc}, | ||
141 | {0xbc, 0x00, 0xd0, 0xcc}, | ||
142 | {0xbc, 0x01, 0x01, 0xcc}, | ||
143 | {0xf0, 0x00, 0x02, 0xbb}, | ||
144 | {0xc8, 0x9f, 0x0b, 0xbb}, | ||
145 | {0x5b, 0x00, 0x01, 0xbb}, | ||
146 | {0x2f, 0xde, 0x20, 0xbb}, | ||
147 | {0xf0, 0x00, 0x00, 0xbb}, | ||
148 | {0x20, 0x03, 0x02, 0xbb}, | ||
149 | {0xf0, 0x00, 0x01, 0xbb}, | ||
150 | {0x05, 0x00, 0x07, 0xbb}, | ||
151 | {0x34, 0x00, 0x00, 0xbb}, | ||
152 | {0x35, 0xff, 0x00, 0xbb}, | ||
153 | {0xdc, 0x07, 0x02, 0xbb}, | ||
154 | {0xdd, 0x3c, 0x18, 0xbb}, | ||
155 | {0xde, 0x92, 0x6d, 0xbb}, | ||
156 | {0xdf, 0xcd, 0xb1, 0xbb}, | ||
157 | {0xe0, 0xff, 0xe7, 0xbb}, | ||
158 | {0x06, 0xf0, 0x0d, 0xbb}, | ||
159 | {0x06, 0x70, 0x0e, 0xbb}, | ||
160 | {0x4c, 0x00, 0x01, 0xbb}, | ||
161 | {0x4d, 0x00, 0x01, 0xbb}, | ||
162 | {0xf0, 0x00, 0x02, 0xbb}, | ||
163 | {0x2e, 0x0c, 0x55, 0xbb}, | ||
164 | {0x21, 0xb6, 0x6e, 0xbb}, | ||
165 | {0x36, 0x30, 0x10, 0xbb}, | ||
166 | {0x37, 0x00, 0xc1, 0xbb}, | ||
167 | {0xf0, 0x00, 0x00, 0xbb}, | ||
168 | {0x07, 0x00, 0x84, 0xbb}, | ||
169 | {0x08, 0x02, 0x4a, 0xbb}, | ||
170 | {0x05, 0x01, 0x10, 0xbb}, | ||
171 | {0x06, 0x00, 0x39, 0xbb}, | ||
172 | {0xf0, 0x00, 0x02, 0xbb}, | ||
173 | {0x58, 0x02, 0x67, 0xbb}, | ||
174 | {0x57, 0x02, 0x00, 0xbb}, | ||
175 | {0x5a, 0x02, 0x67, 0xbb}, | ||
176 | {0x59, 0x02, 0x00, 0xbb}, | ||
177 | {0x5c, 0x12, 0x0d, 0xbb}, | ||
178 | {0x5d, 0x16, 0x11, 0xbb}, | ||
179 | {0x39, 0x06, 0x18, 0xbb}, | ||
180 | {0x3a, 0x06, 0x18, 0xbb}, | ||
181 | {0x3b, 0x06, 0x18, 0xbb}, | ||
182 | {0x3c, 0x06, 0x18, 0xbb}, | ||
183 | {0x64, 0x7b, 0x5b, 0xbb}, | ||
184 | {0xf0, 0x00, 0x02, 0xbb}, | ||
185 | {0x36, 0x30, 0x10, 0xbb}, | ||
186 | {0x37, 0x00, 0xc0, 0xbb}, | ||
187 | {0xbc, 0x0e, 0x00, 0xcc}, | ||
188 | {0xbc, 0x0f, 0x05, 0xcc}, | ||
189 | {0xbc, 0x10, 0xc0, 0xcc}, | ||
190 | {0xbc, 0x11, 0x03, 0xcc}, | ||
191 | {0xb6, 0x00, 0x00, 0xcc}, | ||
192 | {0xb6, 0x03, 0x02, 0xcc}, | ||
193 | {0xb6, 0x02, 0x80, 0xcc}, | ||
194 | {0xb6, 0x05, 0x01, 0xcc}, | ||
195 | {0xb6, 0x04, 0xe0, 0xcc}, | ||
196 | {0xb6, 0x12, 0xf8, 0xcc}, | ||
197 | {0xb6, 0x13, 0x25, 0xcc}, | ||
198 | {0xb6, 0x18, 0x02, 0xcc}, | ||
199 | {0xb6, 0x17, 0x58, 0xcc}, | ||
200 | {0xb6, 0x16, 0x00, 0xcc}, | ||
201 | {0xb6, 0x22, 0x12, 0xcc}, | ||
202 | {0xb6, 0x23, 0x0b, 0xcc}, | ||
203 | {0xbf, 0xc0, 0x39, 0xcc}, | ||
204 | {0xbf, 0xc1, 0x04, 0xcc}, | ||
205 | {0xbf, 0xcc, 0x00, 0xcc}, | ||
206 | {0xbc, 0x02, 0x18, 0xcc}, | ||
207 | {0xbc, 0x03, 0x50, 0xcc}, | ||
208 | {0xbc, 0x04, 0x18, 0xcc}, | ||
209 | {0xbc, 0x05, 0x00, 0xcc}, | ||
210 | {0xbc, 0x06, 0x00, 0xcc}, | ||
211 | {0xbc, 0x08, 0x30, 0xcc}, | ||
212 | {0xbc, 0x09, 0x40, 0xcc}, | ||
213 | {0xbc, 0x0a, 0x10, 0xcc}, | ||
214 | {0xbc, 0x0b, 0x00, 0xcc}, | ||
215 | {0xbc, 0x0c, 0x00, 0xcc}, | ||
216 | {0xb3, 0x5c, 0x01, 0xcc}, | ||
217 | {0xf0, 0x00, 0x01, 0xbb}, | ||
218 | {0x80, 0x00, 0x03, 0xbb}, | ||
219 | {0x81, 0xc7, 0x14, 0xbb}, | ||
220 | {0x82, 0xeb, 0xe8, 0xbb}, | ||
221 | {0x83, 0xfe, 0xf4, 0xbb}, | ||
222 | {0x84, 0xcd, 0x10, 0xbb}, | ||
223 | {0x85, 0xf3, 0xee, 0xbb}, | ||
224 | {0x86, 0xff, 0xf1, 0xbb}, | ||
225 | {0x87, 0xcd, 0x10, 0xbb}, | ||
226 | {0x88, 0xf3, 0xee, 0xbb}, | ||
227 | {0x89, 0x01, 0xf1, 0xbb}, | ||
228 | {0x8a, 0xe5, 0x17, 0xbb}, | ||
229 | {0x8b, 0xe8, 0xe2, 0xbb}, | ||
230 | {0x8c, 0xf7, 0xed, 0xbb}, | ||
231 | {0x8d, 0x00, 0xff, 0xbb}, | ||
232 | {0x8e, 0xec, 0x10, 0xbb}, | ||
233 | {0x8f, 0xf0, 0xed, 0xbb}, | ||
234 | {0x90, 0xf9, 0xf2, 0xbb}, | ||
235 | {0x91, 0x00, 0x00, 0xbb}, | ||
236 | {0x92, 0xe9, 0x0d, 0xbb}, | ||
237 | {0x93, 0xf4, 0xf2, 0xbb}, | ||
238 | {0x94, 0xfb, 0xf5, 0xbb}, | ||
239 | {0x95, 0x00, 0xff, 0xbb}, | ||
240 | {0xb6, 0x0f, 0x08, 0xbb}, | ||
241 | {0xb7, 0x3d, 0x16, 0xbb}, | ||
242 | {0xb8, 0x0c, 0x04, 0xbb}, | ||
243 | {0xb9, 0x1c, 0x07, 0xbb}, | ||
244 | {0xba, 0x0a, 0x03, 0xbb}, | ||
245 | {0xbb, 0x1b, 0x09, 0xbb}, | ||
246 | {0xbc, 0x17, 0x0d, 0xbb}, | ||
247 | {0xbd, 0x23, 0x1d, 0xbb}, | ||
248 | {0xbe, 0x00, 0x28, 0xbb}, | ||
249 | {0xbf, 0x11, 0x09, 0xbb}, | ||
250 | {0xc0, 0x16, 0x15, 0xbb}, | ||
251 | {0xc1, 0x00, 0x1b, 0xbb}, | ||
252 | {0xc2, 0x0e, 0x07, 0xbb}, | ||
253 | {0xc3, 0x14, 0x10, 0xbb}, | ||
254 | {0xc4, 0x00, 0x17, 0xbb}, | ||
255 | {0x06, 0x74, 0x8e, 0xbb}, | ||
256 | {0xf0, 0x00, 0x01, 0xbb}, | ||
257 | {0x06, 0xf4, 0x8e, 0xbb}, | ||
258 | {0x00, 0x00, 0x50, 0xdd}, | ||
259 | {0x06, 0x74, 0x8e, 0xbb}, | ||
260 | {0xf0, 0x00, 0x02, 0xbb}, | ||
261 | {0x24, 0x50, 0x20, 0xbb}, | ||
262 | {0xf0, 0x00, 0x02, 0xbb}, | ||
263 | {0x34, 0x0c, 0x50, 0xbb}, | ||
264 | {0xb3, 0x01, 0x41, 0xcc}, | ||
265 | {0xf0, 0x00, 0x00, 0xbb}, | ||
266 | {0x03, 0x03, 0xc0, 0xbb}, | ||
267 | {}, | ||
268 | }; | ||
269 | static const __u8 mi1310_socinitQVGA_JPG[][4] = { | ||
270 | {0xb0, 0x03, 0x19, 0xcc}, {0xb0, 0x04, 0x02, 0xcc}, | ||
271 | {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, | ||
272 | {0xb3, 0x05, 0x00, 0xcc}, {0xb3, 0x06, 0x00, 0xcc}, | ||
273 | {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc}, | ||
274 | {0xb3, 0x34, 0x02, 0xcc}, {0xb3, 0x35, 0xdd, 0xcc}, | ||
275 | {0xb3, 0x02, 0x00, 0xcc}, {0xb3, 0x03, 0x0a, 0xcc}, | ||
276 | {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, | ||
277 | {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x03, 0xcc}, | ||
278 | {0xb3, 0x23, 0xc0, 0xcc}, {0xb3, 0x14, 0x00, 0xcc}, | ||
279 | {0xb3, 0x15, 0x00, 0xcc}, {0xb3, 0x16, 0x04, 0xcc}, | ||
280 | {0xb3, 0x17, 0xff, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, | ||
281 | {0xb8, 0x00, 0x00, 0xcc}, {0xbc, 0x00, 0xf0, 0xcc}, | ||
282 | {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x02, 0xbb}, | ||
283 | {0xc8, 0x9f, 0x0b, 0xbb}, {0x5b, 0x00, 0x01, 0xbb}, | ||
284 | {0x2f, 0xde, 0x20, 0xbb}, {0xf0, 0x00, 0x00, 0xbb}, | ||
285 | {0x20, 0x03, 0x02, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, | ||
286 | {0x05, 0x00, 0x07, 0xbb}, {0x34, 0x00, 0x00, 0xbb}, | ||
287 | {0x35, 0xff, 0x00, 0xbb}, {0xdc, 0x07, 0x02, 0xbb}, | ||
288 | {0xdd, 0x3c, 0x18, 0xbb}, {0xde, 0x92, 0x6d, 0xbb}, | ||
289 | {0xdf, 0xcd, 0xb1, 0xbb}, {0xe0, 0xff, 0xe7, 0xbb}, | ||
290 | {0x06, 0xf0, 0x0d, 0xbb}, {0x06, 0x70, 0x0e, 0xbb}, | ||
291 | {0x4c, 0x00, 0x01, 0xbb}, {0x4d, 0x00, 0x01, 0xbb}, | ||
292 | {0xf0, 0x00, 0x02, 0xbb}, {0x2e, 0x0c, 0x55, 0xbb}, | ||
293 | {0x21, 0xb6, 0x6e, 0xbb}, {0x36, 0x30, 0x10, 0xbb}, | ||
294 | {0x37, 0x00, 0xc1, 0xbb}, {0xf0, 0x00, 0x00, 0xbb}, | ||
295 | {0x07, 0x00, 0x84, 0xbb}, {0x08, 0x02, 0x4a, 0xbb}, | ||
296 | {0x05, 0x01, 0x10, 0xbb}, {0x06, 0x00, 0x39, 0xbb}, | ||
297 | {0xf0, 0x00, 0x02, 0xbb}, {0x58, 0x02, 0x67, 0xbb}, | ||
298 | {0x57, 0x02, 0x00, 0xbb}, {0x5a, 0x02, 0x67, 0xbb}, | ||
299 | {0x59, 0x02, 0x00, 0xbb}, {0x5c, 0x12, 0x0d, 0xbb}, | ||
300 | {0x5d, 0x16, 0x11, 0xbb}, {0x39, 0x06, 0x18, 0xbb}, | ||
301 | {0x3a, 0x06, 0x18, 0xbb}, {0x3b, 0x06, 0x18, 0xbb}, | ||
302 | {0x3c, 0x06, 0x18, 0xbb}, {0x64, 0x7b, 0x5b, 0xbb}, | ||
303 | {0xf0, 0x00, 0x02, 0xbb}, {0x36, 0x30, 0x10, 0xbb}, | ||
304 | {0x37, 0x00, 0xc0, 0xbb}, {0xbc, 0x0e, 0x00, 0xcc}, | ||
305 | {0xbc, 0x0f, 0x05, 0xcc}, {0xbc, 0x10, 0xc0, 0xcc}, | ||
306 | {0xbc, 0x11, 0x03, 0xcc}, {0xb6, 0x00, 0x00, 0xcc}, | ||
307 | {0xb6, 0x03, 0x01, 0xcc}, {0xb6, 0x02, 0x40, 0xcc}, | ||
308 | {0xb6, 0x05, 0x00, 0xcc}, {0xb6, 0x04, 0xf0, 0xcc}, | ||
309 | {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x25, 0xcc}, | ||
310 | {0xb6, 0x18, 0x00, 0xcc}, {0xb6, 0x17, 0x96, 0xcc}, | ||
311 | {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc}, | ||
312 | {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc}, | ||
313 | {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc}, | ||
314 | {0xb3, 0x5c, 0x01, 0xcc}, {0xf0, 0x00, 0x01, 0xbb}, | ||
315 | {0x80, 0x00, 0x03, 0xbb}, {0x81, 0xc7, 0x14, 0xbb}, | ||
316 | {0x82, 0xeb, 0xe8, 0xbb}, {0x83, 0xfe, 0xf4, 0xbb}, | ||
317 | {0x84, 0xcd, 0x10, 0xbb}, {0x85, 0xf3, 0xee, 0xbb}, | ||
318 | {0x86, 0xff, 0xf1, 0xbb}, {0x87, 0xcd, 0x10, 0xbb}, | ||
319 | {0x88, 0xf3, 0xee, 0xbb}, {0x89, 0x01, 0xf1, 0xbb}, | ||
320 | {0x8a, 0xe5, 0x17, 0xbb}, {0x8b, 0xe8, 0xe2, 0xbb}, | ||
321 | {0x8c, 0xf7, 0xed, 0xbb}, {0x8d, 0x00, 0xff, 0xbb}, | ||
322 | {0x8e, 0xec, 0x10, 0xbb}, {0x8f, 0xf0, 0xed, 0xbb}, | ||
323 | {0x90, 0xf9, 0xf2, 0xbb}, {0x91, 0x00, 0x00, 0xbb}, | ||
324 | {0x92, 0xe9, 0x0d, 0xbb}, {0x93, 0xf4, 0xf2, 0xbb}, | ||
325 | {0x94, 0xfb, 0xf5, 0xbb}, {0x95, 0x00, 0xff, 0xbb}, | ||
326 | {0xb6, 0x0f, 0x08, 0xbb}, {0xb7, 0x3d, 0x16, 0xbb}, | ||
327 | {0xb8, 0x0c, 0x04, 0xbb}, {0xb9, 0x1c, 0x07, 0xbb}, | ||
328 | {0xba, 0x0a, 0x03, 0xbb}, {0xbb, 0x1b, 0x09, 0xbb}, | ||
329 | {0xbc, 0x17, 0x0d, 0xbb}, {0xbd, 0x23, 0x1d, 0xbb}, | ||
330 | {0xbe, 0x00, 0x28, 0xbb}, {0xbf, 0x11, 0x09, 0xbb}, | ||
331 | {0xc0, 0x16, 0x15, 0xbb}, {0xc1, 0x00, 0x1b, 0xbb}, | ||
332 | {0xc2, 0x0e, 0x07, 0xbb}, {0xc3, 0x14, 0x10, 0xbb}, | ||
333 | {0xc4, 0x00, 0x17, 0xbb}, {0x06, 0x74, 0x8e, 0xbb}, | ||
334 | {0xf0, 0x00, 0x01, 0xbb}, {0x06, 0xf4, 0x8e, 0xbb}, | ||
335 | {0x00, 0x00, 0x50, 0xdd}, {0x06, 0x74, 0x8e, 0xbb}, | ||
336 | {0xf0, 0x00, 0x02, 0xbb}, {0x24, 0x50, 0x20, 0xbb}, | ||
337 | {0xf0, 0x00, 0x02, 0xbb}, {0x34, 0x0c, 0x50, 0xbb}, | ||
338 | {0xb3, 0x01, 0x41, 0xcc}, {0xf0, 0x00, 0x00, 0xbb}, | ||
339 | {0x03, 0x03, 0xc0, 0xbb}, | ||
340 | {}, | ||
341 | }; | ||
342 | |||
343 | static const __u8 mi1320_gamma[17] = { | ||
344 | 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, | ||
345 | 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff | ||
346 | }; | ||
347 | static const __u8 mi1320_matrix[9] = { | ||
348 | 0x54, 0xda, 0x06, 0xf1, 0x50, 0xf4, 0xf7, 0xea, 0x52 | ||
349 | }; | ||
350 | static const __u8 mi1320_initVGA_data[][4] = { | ||
351 | {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, | ||
352 | {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, | ||
353 | {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, | ||
354 | {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, | ||
355 | {0xb0, 0x16, 0x03, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, | ||
356 | {0xb3, 0x06, 0x00, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, | ||
357 | {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x34, 0x02, 0xcc}, | ||
358 | {0xb3, 0x35, 0xc8, 0xcc}, {0xb3, 0x02, 0x00, 0xcc}, | ||
359 | {0xb3, 0x03, 0x0a, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, | ||
360 | {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc}, | ||
361 | {0xb3, 0x22, 0x03, 0xcc}, {0xb3, 0x23, 0xc0, 0xcc}, | ||
362 | {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, | ||
363 | {0xb3, 0x16, 0x04, 0xcc}, {0xb3, 0x17, 0xff, 0xcc}, | ||
364 | {0xb3, 0x00, 0x67, 0xcc}, {0xbc, 0x00, 0xd0, 0xcc}, | ||
365 | {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x00, 0xbb}, | ||
366 | {0x0d, 0x00, 0x09, 0xbb}, {0x00, 0x01, 0x00, 0xdd}, | ||
367 | {0x0d, 0x00, 0x08, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, | ||
368 | {0xa1, 0x05, 0x00, 0xbb}, {0xa4, 0x03, 0xc0, 0xbb}, | ||
369 | {0xf0, 0x00, 0x02, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, | ||
370 | {0xc8, 0x9f, 0x0b, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, | ||
371 | {0xf0, 0x00, 0x00, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, | ||
372 | {0x20, 0x01, 0x00, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, | ||
373 | {0xf0, 0x00, 0x01, 0xbb}, {0x9d, 0x3c, 0xa0, 0xbb}, | ||
374 | {0x47, 0x30, 0x30, 0xbb}, {0xf0, 0x00, 0x00, 0xbb}, | ||
375 | {0x0a, 0x80, 0x11, 0xbb}, {0x35, 0x00, 0x22, 0xbb}, | ||
376 | {0xf0, 0x00, 0x02, 0xbb}, {0x9d, 0xc5, 0x05, 0xbb}, | ||
377 | {0xdc, 0x0f, 0xfc, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, | ||
378 | {0x06, 0x74, 0x0e, 0xbb}, {0x80, 0x00, 0x06, 0xbb}, | ||
379 | {0x81, 0x04, 0x00, 0xbb}, {0x82, 0x01, 0x02, 0xbb}, | ||
380 | {0x83, 0x03, 0x02, 0xbb}, {0x84, 0x05, 0x00, 0xbb}, | ||
381 | {0x85, 0x01, 0x00, 0xbb}, {0x86, 0x03, 0x02, 0xbb}, | ||
382 | {0x87, 0x05, 0x00, 0xbb}, {0x88, 0x01, 0x00, 0xbb}, | ||
383 | {0x89, 0x02, 0x02, 0xbb}, {0x8a, 0xfd, 0x04, 0xbb}, | ||
384 | {0x8b, 0xfc, 0xfd, 0xbb}, {0x8c, 0xff, 0xfd, 0xbb}, | ||
385 | {0x8d, 0x00, 0x00, 0xbb}, {0x8e, 0xfe, 0x05, 0xbb}, | ||
386 | {0x8f, 0xfc, 0xfd, 0xbb}, {0x90, 0xfe, 0xfd, 0xbb}, | ||
387 | {0x91, 0x00, 0x00, 0xbb}, {0x92, 0xfe, 0x03, 0xbb}, | ||
388 | {0x93, 0xfd, 0xfe, 0xbb}, {0x94, 0xff, 0xfd, 0xbb}, | ||
389 | {0x95, 0x00, 0x00, 0xbb}, {0xb6, 0x07, 0x05, 0xbb}, | ||
390 | {0xb7, 0x13, 0x06, 0xbb}, {0xb8, 0x08, 0x06, 0xbb}, | ||
391 | {0xb9, 0x14, 0x08, 0xbb}, {0xba, 0x06, 0x05, 0xbb}, | ||
392 | {0xbb, 0x13, 0x06, 0xbb}, {0xbc, 0x03, 0x01, 0xbb}, | ||
393 | {0xbd, 0x03, 0x04, 0xbb}, {0xbe, 0x00, 0x02, 0xbb}, | ||
394 | {0xbf, 0x03, 0x01, 0xbb}, {0xc0, 0x02, 0x04, 0xbb}, | ||
395 | {0xc1, 0x00, 0x04, 0xbb}, {0xc2, 0x02, 0x01, 0xbb}, | ||
396 | {0xc3, 0x01, 0x03, 0xbb}, {0xc4, 0x00, 0x04, 0xbb}, | ||
397 | {0xf0, 0x00, 0x00, 0xbb}, {0x05, 0x01, 0x13, 0xbb}, | ||
398 | {0x06, 0x00, 0x11, 0xbb}, {0x07, 0x00, 0x85, 0xbb}, | ||
399 | {0x08, 0x00, 0x27, 0xbb}, {0x20, 0x01, 0x03, 0xbb}, | ||
400 | {0x21, 0x80, 0x00, 0xbb}, {0x22, 0x0d, 0x0f, 0xbb}, | ||
401 | {0x24, 0x80, 0x00, 0xbb}, {0x59, 0x00, 0xff, 0xbb}, | ||
402 | {0xf0, 0x00, 0x02, 0xbb}, {0x39, 0x03, 0x0d, 0xbb}, | ||
403 | {0x3a, 0x06, 0x1b, 0xbb}, {0x3b, 0x00, 0x95, 0xbb}, | ||
404 | {0x3c, 0x04, 0xdb, 0xbb}, {0x57, 0x02, 0x00, 0xbb}, | ||
405 | {0x58, 0x02, 0x66, 0xbb}, {0x59, 0x00, 0xff, 0xbb}, | ||
406 | {0x5a, 0x01, 0x33, 0xbb}, {0x5c, 0x12, 0x0d, 0xbb}, | ||
407 | {0x5d, 0x16, 0x11, 0xbb}, {0x64, 0x5e, 0x1c, 0xbb}, | ||
408 | {0xf0, 0x00, 0x02, 0xbb}, {0x2f, 0xd1, 0x00, 0xbb}, | ||
409 | {0x5b, 0x00, 0x01, 0xbb}, {0xf0, 0x00, 0x02, 0xbb}, | ||
410 | {0x36, 0x68, 0x10, 0xbb}, {0x00, 0x00, 0x30, 0xdd}, | ||
411 | {0x37, 0x82, 0x00, 0xbb}, {0xbc, 0x0e, 0x00, 0xcc}, | ||
412 | {0xbc, 0x0f, 0x05, 0xcc}, {0xbc, 0x10, 0xc0, 0xcc}, | ||
413 | {0xbc, 0x11, 0x03, 0xcc}, {0xb6, 0x00, 0x00, 0xcc}, | ||
414 | {0xb6, 0x03, 0x05, 0xcc}, {0xb6, 0x02, 0x00, 0xcc}, | ||
415 | {0xb6, 0x05, 0x04, 0xcc}, {0xb6, 0x04, 0x00, 0xcc}, | ||
416 | {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x29, 0xcc}, | ||
417 | {0xb6, 0x18, 0x0a, 0xcc}, {0xb6, 0x17, 0x00, 0xcc}, | ||
418 | {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc}, | ||
419 | {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x26, 0xcc}, | ||
420 | {0xbf, 0xc1, 0x02, 0xcc}, {0xbf, 0xcc, 0x04, 0xcc}, | ||
421 | {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc}, | ||
422 | {0xbc, 0x04, 0x18, 0xcc}, {0xbc, 0x05, 0x00, 0xcc}, | ||
423 | {0xbc, 0x06, 0x00, 0xcc}, {0xbc, 0x08, 0x30, 0xcc}, | ||
424 | {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x10, 0xcc}, | ||
425 | {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc}, | ||
426 | {0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x01, 0x41, 0xcc}, | ||
427 | {} | ||
428 | }; | ||
429 | static const __u8 mi1320_initQVGA_data[][4] = { | ||
430 | {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, | ||
431 | {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, | ||
432 | {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, | ||
433 | {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, | ||
434 | {0xb0, 0x16, 0x03, 0xcc}, {0xb3, 0x05, 0x01, 0xcc}, | ||
435 | {0xb3, 0x06, 0x01, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, | ||
436 | {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x34, 0x02, 0xcc}, | ||
437 | {0xb3, 0x35, 0xc8, 0xcc}, {0xb3, 0x02, 0x00, 0xcc}, | ||
438 | {0xb3, 0x03, 0x0a, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, | ||
439 | {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc}, | ||
440 | {0xb3, 0x22, 0x01, 0xcc}, {0xb3, 0x23, 0xe0, 0xcc}, | ||
441 | {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, | ||
442 | {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, | ||
443 | {0xb3, 0x00, 0x65, 0xcc}, {0xb8, 0x00, 0x00, 0xcc}, | ||
444 | {0xbc, 0x00, 0xd0, 0xcc}, {0xbc, 0x01, 0x01, 0xcc}, | ||
445 | {0xf0, 0x00, 0x00, 0xbb}, {0x0d, 0x00, 0x09, 0xbb}, | ||
446 | {0x00, 0x01, 0x00, 0xdd}, {0x0d, 0x00, 0x08, 0xbb}, | ||
447 | {0xf0, 0x00, 0x00, 0xbb}, {0x02, 0x00, 0x64, 0xbb}, | ||
448 | {0x05, 0x01, 0x78, 0xbb}, {0x06, 0x00, 0x11, 0xbb}, | ||
449 | {0x07, 0x01, 0x42, 0xbb}, {0x08, 0x00, 0x11, 0xbb}, | ||
450 | {0x20, 0x01, 0x00, 0xbb}, {0x21, 0x80, 0x00, 0xbb}, | ||
451 | {0x22, 0x0d, 0x0f, 0xbb}, {0x24, 0x80, 0x00, 0xbb}, | ||
452 | {0x59, 0x00, 0xff, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, | ||
453 | {0x9d, 0x3c, 0xa0, 0xbb}, {0x47, 0x30, 0x30, 0xbb}, | ||
454 | {0xf0, 0x00, 0x00, 0xbb}, {0x0a, 0x80, 0x11, 0xbb}, | ||
455 | {0x35, 0x00, 0x22, 0xbb}, {0xf0, 0x00, 0x02, 0xbb}, | ||
456 | {0x9d, 0xc5, 0x05, 0xbb}, {0xdc, 0x0f, 0xfc, 0xbb}, | ||
457 | {0xf0, 0x00, 0x01, 0xbb}, {0x06, 0x74, 0x0e, 0xbb}, | ||
458 | {0x80, 0x00, 0x06, 0xbb}, {0x81, 0x04, 0x00, 0xbb}, | ||
459 | {0x82, 0x01, 0x02, 0xbb}, {0x83, 0x03, 0x02, 0xbb}, | ||
460 | {0x84, 0x05, 0x00, 0xbb}, {0x85, 0x01, 0x00, 0xbb}, | ||
461 | {0x86, 0x03, 0x02, 0xbb}, {0x87, 0x05, 0x00, 0xbb}, | ||
462 | {0x88, 0x01, 0x00, 0xbb}, {0x89, 0x02, 0x02, 0xbb}, | ||
463 | {0x8a, 0xfd, 0x04, 0xbb}, {0x8b, 0xfc, 0xfd, 0xbb}, | ||
464 | {0x8c, 0xff, 0xfd, 0xbb}, {0x8d, 0x00, 0x00, 0xbb}, | ||
465 | {0x8e, 0xfe, 0x05, 0xbb}, {0x8f, 0xfc, 0xfd, 0xbb}, | ||
466 | {0x90, 0xfe, 0xfd, 0xbb}, {0x91, 0x00, 0x00, 0xbb}, | ||
467 | {0x92, 0xfe, 0x03, 0xbb}, {0x93, 0xfd, 0xfe, 0xbb}, | ||
468 | {0x94, 0xff, 0xfd, 0xbb}, {0x95, 0x00, 0x00, 0xbb}, | ||
469 | {0xb6, 0x07, 0x05, 0xbb}, {0xb7, 0x13, 0x06, 0xbb}, | ||
470 | {0xb8, 0x08, 0x06, 0xbb}, {0xb9, 0x14, 0x08, 0xbb}, | ||
471 | {0xba, 0x06, 0x05, 0xbb}, {0xbb, 0x13, 0x06, 0xbb}, | ||
472 | {0xbc, 0x03, 0x01, 0xbb}, {0xbd, 0x03, 0x04, 0xbb}, | ||
473 | {0xbe, 0x00, 0x02, 0xbb}, {0xbf, 0x03, 0x01, 0xbb}, | ||
474 | {0xc0, 0x02, 0x04, 0xbb}, {0xc1, 0x00, 0x04, 0xbb}, | ||
475 | {0xc2, 0x02, 0x01, 0xbb}, {0xc3, 0x01, 0x03, 0xbb}, | ||
476 | {0xc4, 0x00, 0x04, 0xbb}, {0xf0, 0x00, 0x02, 0xbb}, | ||
477 | {0xc8, 0x00, 0x00, 0xbb}, {0x2e, 0x00, 0x00, 0xbb}, | ||
478 | {0x2e, 0x0c, 0x5b, 0xbb}, {0x2f, 0xd1, 0x00, 0xbb}, | ||
479 | {0x39, 0x03, 0xca, 0xbb}, {0x3a, 0x06, 0x80, 0xbb}, | ||
480 | {0x3b, 0x01, 0x52, 0xbb}, {0x3c, 0x05, 0x40, 0xbb}, | ||
481 | {0x57, 0x01, 0x9c, 0xbb}, {0x58, 0x01, 0xee, 0xbb}, | ||
482 | {0x59, 0x00, 0xf0, 0xbb}, {0x5a, 0x01, 0x20, 0xbb}, | ||
483 | {0x5c, 0x1d, 0x17, 0xbb}, {0x5d, 0x22, 0x1c, 0xbb}, | ||
484 | {0x64, 0x1e, 0x1c, 0xbb}, {0x5b, 0x00, 0x01, 0xbb}, | ||
485 | {0xf0, 0x00, 0x02, 0xbb}, {0x36, 0x68, 0x10, 0xbb}, | ||
486 | {0x00, 0x00, 0x30, 0xdd}, {0x37, 0x81, 0x00, 0xbb}, | ||
487 | {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc}, | ||
488 | {0xbc, 0x04, 0x18, 0xcc}, {0xbc, 0x05, 0x00, 0xcc}, | ||
489 | {0xbc, 0x06, 0x00, 0xcc}, {0xbc, 0x08, 0x30, 0xcc}, | ||
490 | {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x10, 0xcc}, | ||
491 | {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc}, | ||
492 | {0xbf, 0xc0, 0x26, 0xcc}, {0xbf, 0xc1, 0x02, 0xcc}, | ||
493 | {0xbf, 0xcc, 0x04, 0xcc}, {0xb3, 0x5c, 0x01, 0xcc}, | ||
494 | {0xb3, 0x01, 0x41, 0xcc}, | ||
495 | {} | ||
496 | }; | ||
497 | |||
498 | static const __u8 po3130_gamma[17] = { | ||
499 | 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, | ||
500 | 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff | ||
501 | }; | ||
502 | static const __u8 po3130_matrix[9] = { | ||
503 | 0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63 | ||
504 | }; | ||
505 | |||
506 | static const __u8 po3130_initVGA_data[][4] = { | ||
507 | {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, | ||
508 | {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, | ||
509 | {0xb3, 0x00, 0x04, 0xcc}, {0xb3, 0x00, 0x24, 0xcc}, | ||
510 | {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, | ||
511 | {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, | ||
512 | {0xb3, 0x06, 0x01, 0xcc}, {0xb3, 0x03, 0x1a, 0xcc}, | ||
513 | {0xb3, 0x04, 0x15, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, | ||
514 | {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x01, 0xcc}, | ||
515 | {0xb3, 0x23, 0xe8, 0xcc}, {0xb8, 0x08, 0xe8, 0xcc}, | ||
516 | {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, | ||
517 | {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, | ||
518 | {0xb3, 0x34, 0x01, 0xcc}, {0xb3, 0x35, 0xf6, 0xcc}, | ||
519 | {0xb3, 0x00, 0x27, 0xcc}, {0xbc, 0x00, 0x71, 0xcc}, | ||
520 | {0xb8, 0x00, 0x21, 0xcc}, {0xb8, 0x27, 0x20, 0xcc}, | ||
521 | {0xb8, 0x01, 0x79, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, | ||
522 | {0xb8, 0x2c, 0x50, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc}, | ||
523 | {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc}, | ||
524 | {0xb8, 0x30, 0x50, 0xcc}, {0xb8, 0x31, 0xf8, 0xcc}, | ||
525 | {0xb8, 0x32, 0xf8, 0xcc}, {0xb8, 0x33, 0xf8, 0xcc}, | ||
526 | {0xb8, 0x34, 0x50, 0xcc}, {0xb8, 0x35, 0x00, 0xcc}, | ||
527 | {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc}, | ||
528 | {0x00, 0x1e, 0xc6, 0xaa}, {0x00, 0x20, 0x44, 0xaa}, | ||
529 | {0x00, 0xad, 0x02, 0xaa}, {0x00, 0xae, 0x2c, 0xaa}, | ||
530 | {0x00, 0x12, 0x08, 0xaa}, {0x00, 0x17, 0x41, 0xaa}, | ||
531 | {0x00, 0x19, 0x41, 0xaa}, {0x00, 0x1e, 0x06, 0xaa}, | ||
532 | {0x00, 0x21, 0x00, 0xaa}, {0x00, 0x36, 0xc0, 0xaa}, | ||
533 | {0x00, 0x37, 0xc8, 0xaa}, {0x00, 0x3b, 0x36, 0xaa}, | ||
534 | {0x00, 0x4b, 0xfe, 0xaa}, {0x00, 0x51, 0x1c, 0xaa}, | ||
535 | {0x00, 0x52, 0x01, 0xaa}, {0x00, 0x55, 0x0a, 0xaa}, | ||
536 | {0x00, 0x59, 0x02, 0xaa}, {0x00, 0x5a, 0x04, 0xaa}, | ||
537 | {0x00, 0x5c, 0x10, 0xaa}, {0x00, 0x5d, 0x10, 0xaa}, | ||
538 | {0x00, 0x5e, 0x10, 0xaa}, {0x00, 0x5f, 0x10, 0xaa}, | ||
539 | {0x00, 0x61, 0x00, 0xaa}, {0x00, 0x62, 0x18, 0xaa}, | ||
540 | {0x00, 0x63, 0x30, 0xaa}, {0x00, 0x70, 0x68, 0xaa}, | ||
541 | {0x00, 0x80, 0x71, 0xaa}, {0x00, 0x81, 0x08, 0xaa}, | ||
542 | {0x00, 0x82, 0x00, 0xaa}, {0x00, 0x83, 0x55, 0xaa}, | ||
543 | {0x00, 0x84, 0x06, 0xaa}, {0x00, 0x85, 0x06, 0xaa}, | ||
544 | {0x00, 0x86, 0x13, 0xaa}, {0x00, 0x87, 0x18, 0xaa}, | ||
545 | {0x00, 0xaa, 0x3f, 0xaa}, {0x00, 0xab, 0x44, 0xaa}, | ||
546 | {0x00, 0xb0, 0x68, 0xaa}, {0x00, 0xb5, 0x10, 0xaa}, | ||
547 | {0x00, 0xb8, 0x20, 0xaa}, {0x00, 0xb9, 0xa0, 0xaa}, | ||
548 | {0x00, 0xbc, 0x04, 0xaa}, {0x00, 0x8b, 0x40, 0xaa}, | ||
549 | {0x00, 0x8c, 0x91, 0xaa}, {0x00, 0x8d, 0x8f, 0xaa}, | ||
550 | {0x00, 0x8e, 0x91, 0xaa}, {0x00, 0x8f, 0x43, 0xaa}, | ||
551 | {0x00, 0x90, 0x92, 0xaa}, {0x00, 0x91, 0x89, 0xaa}, | ||
552 | {0x00, 0x92, 0x9d, 0xaa}, {0x00, 0x93, 0x46, 0xaa}, | ||
553 | {0x00, 0xd6, 0x22, 0xaa}, {0x00, 0x73, 0x00, 0xaa}, | ||
554 | {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa}, | ||
555 | {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa}, | ||
556 | {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa}, | ||
557 | {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa}, | ||
558 | {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa}, | ||
559 | {0x00, 0x7e, 0xea, 0xaa}, {0x00, 0xd6, 0x62, 0xaa}, | ||
560 | {0x00, 0x73, 0x00, 0xaa}, {0x00, 0x74, 0x10, 0xaa}, | ||
561 | {0x00, 0x75, 0x20, 0xaa}, {0x00, 0x76, 0x2b, 0xaa}, | ||
562 | {0x00, 0x77, 0x36, 0xaa}, {0x00, 0x78, 0x49, 0xaa}, | ||
563 | {0x00, 0x79, 0x5a, 0xaa}, {0x00, 0x7a, 0x7f, 0xaa}, | ||
564 | {0x00, 0x7b, 0x9b, 0xaa}, {0x00, 0x7c, 0xba, 0xaa}, | ||
565 | {0x00, 0x7d, 0xd4, 0xaa}, {0x00, 0x7e, 0xea, 0xaa}, | ||
566 | {0x00, 0xd6, 0xa2, 0xaa}, {0x00, 0x73, 0x00, 0xaa}, | ||
567 | {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa}, | ||
568 | {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa}, | ||
569 | {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa}, | ||
570 | {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa}, | ||
571 | {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa}, | ||
572 | {0x00, 0x7e, 0xea, 0xaa}, | ||
573 | {0x00, 0x4c, 0x07, 0xaa}, | ||
574 | {0x00, 0x4b, 0xe0, 0xaa}, {0x00, 0x4e, 0x77, 0xaa}, | ||
575 | {0x00, 0x59, 0x02, 0xaa}, {0x00, 0x4d, 0x0a, 0xaa}, | ||
576 | /* {0x00, 0xd1, 0x00, 0xaa}, {0x00, 0x20, 0xc4, 0xaa}, | ||
577 | {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc}, */ | ||
578 | {0x00, 0xd1, 0x3c, 0xaa}, {0x00, 0x20, 0xc4, 0xaa}, | ||
579 | {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc}, | ||
580 | {0xb8, 0xfe, 0x00, 0xcc}, {0xb8, 0xff, 0x28, 0xcc}, | ||
581 | {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc}, | ||
582 | {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc}, | ||
583 | {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc}, | ||
584 | {0xb9, 0x06, 0x3c, 0xcc}, {0xb9, 0x07, 0x3c, 0xcc}, | ||
585 | {0xb9, 0x08, 0x3c, 0xcc}, {0x00, 0x05, 0x00, 0xaa}, | ||
586 | {0xb3, 0x5c, 0x00, 0xcc}, {0xb3, 0x01, 0x41, 0xcc}, | ||
587 | {} | ||
588 | }; | ||
589 | static const __u8 po3130_rundata[][4] = { | ||
590 | {0x00, 0x47, 0x45, 0xaa}, {0x00, 0x48, 0x9b, 0xaa}, | ||
591 | {0x00, 0x49, 0x3a, 0xaa}, {0x00, 0x4a, 0x01, 0xaa}, | ||
592 | {0x00, 0x44, 0x40, 0xaa}, | ||
593 | /* {0x00, 0xd5, 0x7c, 0xaa}, */ | ||
594 | {0x00, 0xad, 0x04, 0xaa}, {0x00, 0xae, 0x00, 0xaa}, | ||
595 | {0x00, 0xb0, 0x78, 0xaa}, {0x00, 0x98, 0x02, 0xaa}, | ||
596 | {0x00, 0x94, 0x25, 0xaa}, {0x00, 0x95, 0x25, 0xaa}, | ||
597 | {0x00, 0x59, 0x68, 0xaa}, {0x00, 0x44, 0x20, 0xaa}, | ||
598 | {0x00, 0x17, 0x50, 0xaa}, {0x00, 0x19, 0x50, 0xaa}, | ||
599 | {0x00, 0xd1, 0x3c, 0xaa}, {0x00, 0xd1, 0x3c, 0xaa}, | ||
600 | {0x00, 0x1e, 0x06, 0xaa}, {0x00, 0x1e, 0x06, 0xaa}, | ||
601 | {} | ||
602 | }; | ||
603 | |||
604 | static const __u8 po3130_initQVGA_data[][4] = { | ||
605 | {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, | ||
606 | {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x09, 0xcc}, | ||
607 | {0xb3, 0x00, 0x04, 0xcc}, {0xb3, 0x00, 0x24, 0xcc}, | ||
608 | {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, | ||
609 | {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, | ||
610 | {0xb3, 0x06, 0x01, 0xcc}, {0xb3, 0x03, 0x1a, 0xcc}, | ||
611 | {0xb3, 0x04, 0x15, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, | ||
612 | {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x01, 0xcc}, | ||
613 | {0xb3, 0x23, 0xe0, 0xcc}, {0xb8, 0x08, 0xe0, 0xcc}, | ||
614 | {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, | ||
615 | {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, | ||
616 | {0xb3, 0x34, 0x01, 0xcc}, {0xb3, 0x35, 0xf6, 0xcc}, | ||
617 | {0xb3, 0x00, 0x27, 0xcc}, {0xbc, 0x00, 0xd1, 0xcc}, | ||
618 | {0xb8, 0x00, 0x21, 0xcc}, {0xb8, 0x27, 0x20, 0xcc}, | ||
619 | {0xb8, 0x01, 0x79, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, | ||
620 | {0xb8, 0x2c, 0x50, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc}, | ||
621 | {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc}, | ||
622 | {0xb8, 0x30, 0x50, 0xcc}, {0xb8, 0x31, 0xf8, 0xcc}, | ||
623 | {0xb8, 0x32, 0xf8, 0xcc}, {0xb8, 0x33, 0xf8, 0xcc}, | ||
624 | {0xb8, 0x34, 0x50, 0xcc}, {0xb8, 0x35, 0x00, 0xcc}, | ||
625 | {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc}, | ||
626 | {0x00, 0x1e, 0xc6, 0xaa}, {0x00, 0x20, 0x44, 0xaa}, | ||
627 | {0x00, 0xad, 0x02, 0xaa}, {0x00, 0xae, 0x2c, 0xaa}, | ||
628 | {0x00, 0x12, 0x08, 0xaa}, {0x00, 0x17, 0x41, 0xaa}, | ||
629 | {0x00, 0x19, 0x41, 0xaa}, {0x00, 0x1e, 0x06, 0xaa}, | ||
630 | {0x00, 0x21, 0x00, 0xaa}, {0x00, 0x36, 0xc0, 0xaa}, | ||
631 | {0x00, 0x37, 0xc8, 0xaa}, {0x00, 0x3b, 0x36, 0xaa}, | ||
632 | {0x00, 0x4b, 0xfe, 0xaa}, {0x00, 0x51, 0x1c, 0xaa}, | ||
633 | {0x00, 0x52, 0x01, 0xaa}, {0x00, 0x55, 0x0a, 0xaa}, | ||
634 | {0x00, 0x59, 0x6f, 0xaa}, {0x00, 0x5a, 0x04, 0xaa}, | ||
635 | {0x00, 0x5c, 0x10, 0xaa}, {0x00, 0x5d, 0x10, 0xaa}, | ||
636 | {0x00, 0x5e, 0x10, 0xaa}, {0x00, 0x5f, 0x10, 0xaa}, | ||
637 | {0x00, 0x61, 0x00, 0xaa}, {0x00, 0x62, 0x18, 0xaa}, | ||
638 | {0x00, 0x63, 0x30, 0xaa}, {0x00, 0x70, 0x68, 0xaa}, | ||
639 | {0x00, 0x80, 0x71, 0xaa}, {0x00, 0x81, 0x08, 0xaa}, | ||
640 | {0x00, 0x82, 0x00, 0xaa}, {0x00, 0x83, 0x55, 0xaa}, | ||
641 | {0x00, 0x84, 0x06, 0xaa}, {0x00, 0x85, 0x06, 0xaa}, | ||
642 | {0x00, 0x86, 0x13, 0xaa}, {0x00, 0x87, 0x18, 0xaa}, | ||
643 | {0x00, 0xaa, 0x3f, 0xaa}, {0x00, 0xab, 0x44, 0xaa}, | ||
644 | {0x00, 0xb0, 0x68, 0xaa}, {0x00, 0xb5, 0x10, 0xaa}, | ||
645 | {0x00, 0xb8, 0x20, 0xaa}, {0x00, 0xb9, 0xa0, 0xaa}, | ||
646 | {0x00, 0xbc, 0x04, 0xaa}, {0x00, 0x8b, 0x40, 0xaa}, | ||
647 | {0x00, 0x8c, 0x91, 0xaa}, {0x00, 0x8d, 0x8f, 0xaa}, | ||
648 | {0x00, 0x8e, 0x91, 0xaa}, {0x00, 0x8f, 0x43, 0xaa}, | ||
649 | {0x00, 0x90, 0x92, 0xaa}, {0x00, 0x91, 0x89, 0xaa}, | ||
650 | {0x00, 0x92, 0x9d, 0xaa}, {0x00, 0x93, 0x46, 0xaa}, | ||
651 | {0x00, 0xd6, 0x22, 0xaa}, {0x00, 0x73, 0x00, 0xaa}, | ||
652 | {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa}, | ||
653 | {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa}, | ||
654 | {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa}, | ||
655 | {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa}, | ||
656 | {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa}, | ||
657 | {0x00, 0x7e, 0xea, 0xaa}, {0x00, 0xd6, 0x62, 0xaa}, | ||
658 | {0x00, 0x73, 0x00, 0xaa}, {0x00, 0x74, 0x10, 0xaa}, | ||
659 | {0x00, 0x75, 0x20, 0xaa}, {0x00, 0x76, 0x2b, 0xaa}, | ||
660 | {0x00, 0x77, 0x36, 0xaa}, {0x00, 0x78, 0x49, 0xaa}, | ||
661 | {0x00, 0x79, 0x5a, 0xaa}, {0x00, 0x7a, 0x7f, 0xaa}, | ||
662 | {0x00, 0x7b, 0x9b, 0xaa}, {0x00, 0x7c, 0xba, 0xaa}, | ||
663 | {0x00, 0x7d, 0xd4, 0xaa}, {0x00, 0x7e, 0xea, 0xaa}, | ||
664 | {0x00, 0xd6, 0xa2, 0xaa}, {0x00, 0x73, 0x00, 0xaa}, | ||
665 | {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa}, | ||
666 | {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa}, | ||
667 | {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa}, | ||
668 | {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa}, | ||
669 | {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa}, | ||
670 | {0x00, 0x7e, 0xea, 0xaa}, {0x00, 0x4c, 0x07, 0xaa}, | ||
671 | {0x00, 0x4b, 0xe0, 0xaa}, {0x00, 0x4e, 0x77, 0xaa}, | ||
672 | {0x00, 0x59, 0x66, 0xaa}, {0x00, 0x4d, 0x0a, 0xaa}, | ||
673 | {0x00, 0xd1, 0x00, 0xaa}, {0x00, 0x20, 0xc4, 0xaa}, | ||
674 | {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc}, | ||
675 | {0xb8, 0xfe, 0x00, 0xcc}, {0xb8, 0xff, 0x28, 0xcc}, | ||
676 | {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc}, | ||
677 | {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc}, | ||
678 | {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc}, | ||
679 | {0xb9, 0x06, 0x3c, 0xcc}, {0xb9, 0x07, 0x3c, 0xcc}, | ||
680 | {0xb9, 0x08, 0x3c, 0xcc}, {0xbc, 0x02, 0x18, 0xcc}, | ||
681 | {0xbc, 0x03, 0x50, 0xcc}, {0xbc, 0x04, 0x18, 0xcc}, | ||
682 | {0xbc, 0x05, 0x00, 0xcc}, {0xbc, 0x06, 0x00, 0xcc}, | ||
683 | {0xbc, 0x08, 0x30, 0xcc}, {0xbc, 0x09, 0x40, 0xcc}, | ||
684 | {0xbc, 0x0a, 0x10, 0xcc}, {0xbc, 0x0b, 0x00, 0xcc}, | ||
685 | {0xbc, 0x0c, 0x00, 0xcc}, {0x00, 0x05, 0x00, 0xaa}, | ||
686 | {0xb3, 0x5c, 0x00, 0xcc}, {0xb3, 0x01, 0x41, 0xcc}, | ||
687 | {} | ||
688 | }; | ||
689 | |||
690 | static const __u8 hv7131r_gamma[17] = { | ||
691 | /* 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, | ||
692 | * 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff */ | ||
693 | 0x04, 0x1a, 0x36, 0x55, 0x6f, 0x87, 0x9d, 0xb0, 0xc1, | ||
694 | 0xcf, 0xda, 0xe4, 0xec, 0xf3, 0xf8, 0xfd, 0xff | ||
695 | }; | ||
696 | static const __u8 hv7131r_matrix[9] = { | ||
697 | 0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63 | ||
698 | }; | ||
699 | static const __u8 hv7131r_initVGA_data[][4] = { | ||
700 | {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, | ||
701 | {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, | ||
702 | {0xb3, 0x00, 0x24, 0xcc}, | ||
703 | {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, | ||
704 | {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, | ||
705 | {0xb3, 0x06, 0x01, 0xcc}, | ||
706 | {0xb3, 0x01, 0x45, 0xcc}, {0xb3, 0x03, 0x0b, 0xcc}, | ||
707 | {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, | ||
708 | {0xb3, 0x21, 0x00, 0xcc}, | ||
709 | {0xb3, 0x22, 0x01, 0xcc}, {0xb3, 0x23, 0xe0, 0xcc}, | ||
710 | {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, | ||
711 | {0xb3, 0x16, 0x02, 0xcc}, | ||
712 | {0xb3, 0x17, 0x7f, 0xcc}, {0xb3, 0x34, 0x01, 0xcc}, | ||
713 | {0xb3, 0x35, 0x91, 0xcc}, {0xb3, 0x00, 0x27, 0xcc}, | ||
714 | {0xbc, 0x00, 0x73, 0xcc}, | ||
715 | {0xb8, 0x00, 0x23, 0xcc}, {0x00, 0x01, 0x0c, 0xaa}, | ||
716 | {0x00, 0x14, 0x01, 0xaa}, {0x00, 0x15, 0xe6, 0xaa}, | ||
717 | {0x00, 0x16, 0x02, 0xaa}, | ||
718 | {0x00, 0x17, 0x86, 0xaa}, {0x00, 0x23, 0x00, 0xaa}, | ||
719 | {0x00, 0x25, 0x09, 0xaa}, {0x00, 0x26, 0x27, 0xaa}, | ||
720 | {0x00, 0x27, 0xc0, 0xaa}, | ||
721 | {0xb8, 0x2c, 0x60, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc}, | ||
722 | {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc}, | ||
723 | {0xb8, 0x30, 0x50, 0xcc}, | ||
724 | {0xb8, 0x31, 0xf8, 0xcc}, {0xb8, 0x32, 0xf8, 0xcc}, | ||
725 | {0xb8, 0x33, 0xf8, 0xcc}, {0xb8, 0x34, 0x65, 0xcc}, | ||
726 | {0xb8, 0x35, 0x00, 0xcc}, | ||
727 | {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc}, | ||
728 | {0xb8, 0x27, 0x20, 0xcc}, {0xb8, 0x01, 0x7d, 0xcc}, | ||
729 | {0xb8, 0x81, 0x09, 0xcc}, | ||
730 | {0xb3, 0x01, 0x41, 0xcc}, {0xb8, 0xfe, 0x00, 0xcc}, | ||
731 | {0xb8, 0xff, 0x28, 0xcc}, {0xb9, 0x00, 0x28, 0xcc}, | ||
732 | {0xb9, 0x01, 0x28, 0xcc}, | ||
733 | {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc}, | ||
734 | {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc}, | ||
735 | {0xb9, 0x06, 0x3c, 0xcc}, | ||
736 | {0xb9, 0x07, 0x3c, 0xcc}, {0xb9, 0x08, 0x3c, 0xcc}, | ||
737 | {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc}, | ||
738 | {0x00, 0x30, 0x18, 0xaa}, | ||
739 | {} | ||
740 | }; | ||
741 | |||
742 | static const __u8 hv7131r_initQVGA_data[][4] = { | ||
743 | {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, | ||
744 | {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, | ||
745 | {0xb3, 0x00, 0x24, 0xcc}, | ||
746 | {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, | ||
747 | {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, | ||
748 | {0xb3, 0x06, 0x01, 0xcc}, | ||
749 | {0xb3, 0x03, 0x0b, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, | ||
750 | {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc}, | ||
751 | {0xb3, 0x22, 0x01, 0xcc}, | ||
752 | {0xb3, 0x23, 0xe0, 0xcc}, {0xb3, 0x14, 0x00, 0xcc}, | ||
753 | {0xb3, 0x15, 0x00, 0xcc}, {0xb3, 0x16, 0x02, 0xcc}, | ||
754 | {0xb3, 0x17, 0x7f, 0xcc}, | ||
755 | {0xb3, 0x34, 0x01, 0xcc}, {0xb3, 0x35, 0x91, 0xcc}, | ||
756 | {0xb3, 0x00, 0x27, 0xcc}, {0xbc, 0x00, 0xd1, 0xcc}, | ||
757 | {0xb8, 0x00, 0x21, 0xcc}, | ||
758 | {0x00, 0x01, 0x0c, 0xaa}, {0x00, 0x14, 0x01, 0xaa}, | ||
759 | {0x00, 0x15, 0xe6, 0xaa}, {0x00, 0x16, 0x02, 0xaa}, | ||
760 | {0x00, 0x17, 0x86, 0xaa}, | ||
761 | {0x00, 0x23, 0x00, 0xaa}, {0x00, 0x25, 0x01, 0xaa}, | ||
762 | {0x00, 0x26, 0xd4, 0xaa}, {0x00, 0x27, 0xc0, 0xaa}, | ||
763 | {0xbc, 0x02, 0x08, 0xcc}, | ||
764 | {0xbc, 0x03, 0x70, 0xcc}, {0xbc, 0x04, 0x08, 0xcc}, | ||
765 | {0xbc, 0x05, 0x00, 0xcc}, {0xbc, 0x06, 0x00, 0xcc}, | ||
766 | {0xbc, 0x08, 0x3c, 0xcc}, | ||
767 | {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x04, 0xcc}, | ||
768 | {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc}, | ||
769 | {0xb8, 0xfe, 0x02, 0xcc}, | ||
770 | {0xb8, 0xff, 0x07, 0xcc}, {0xb9, 0x00, 0x14, 0xcc}, | ||
771 | {0xb9, 0x01, 0x14, 0xcc}, {0xb9, 0x02, 0x14, 0xcc}, | ||
772 | {0xb9, 0x03, 0x00, 0xcc}, | ||
773 | {0xb9, 0x04, 0x02, 0xcc}, {0xb9, 0x05, 0x05, 0xcc}, | ||
774 | {0xb9, 0x06, 0x0f, 0xcc}, {0xb9, 0x07, 0x0f, 0xcc}, | ||
775 | {0xb9, 0x08, 0x0f, 0xcc}, | ||
776 | {0xb8, 0x2c, 0x60, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc}, | ||
777 | {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc}, | ||
778 | {0xb8, 0x30, 0x50, 0xcc}, | ||
779 | {0xb8, 0x31, 0xf8, 0xcc}, {0xb8, 0x32, 0xf8, 0xcc}, | ||
780 | {0xb8, 0x33, 0xf8, 0xcc}, | ||
781 | {0xb8, 0x34, 0x65, 0xcc}, {0xb8, 0x35, 0x00, 0xcc}, | ||
782 | {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc}, | ||
783 | {0xb8, 0x27, 0x20, 0xcc}, | ||
784 | {0xb8, 0x01, 0x7d, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, | ||
785 | {0xb3, 0x01, 0x41, 0xcc}, {0xb8, 0xfe, 0x00, 0xcc}, | ||
786 | {0xb8, 0xff, 0x28, 0xcc}, | ||
787 | {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc}, | ||
788 | {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc}, | ||
789 | {0xb9, 0x04, 0x00, 0xcc}, | ||
790 | {0xb9, 0x05, 0x3c, 0xcc}, {0xb9, 0x06, 0x3c, 0xcc}, | ||
791 | {0xb9, 0x07, 0x3c, 0xcc}, {0xb9, 0x08, 0x3c, 0xcc}, | ||
792 | {0xb8, 0x8e, 0x00, 0xcc}, | ||
793 | {0xb8, 0x8f, 0xff, 0xcc}, {0x00, 0x30, 0x18, 0xaa}, | ||
794 | {} | ||
795 | }; | ||
796 | |||
797 | static const __u8 ov7660_gamma[17] = { | ||
798 | 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, | ||
799 | 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff | ||
800 | }; | ||
801 | static const __u8 ov7660_matrix[9] = { | ||
802 | 0x5a, 0xf0, 0xf6, 0xf3, 0x57, 0xf6, 0xf3, 0xef, 0x62 | ||
803 | }; | ||
804 | static const __u8 ov7660_initVGA_data[][4] = { | ||
805 | {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, | ||
806 | {0x00, 0x00, 0x50, 0xdd}, | ||
807 | {0xb0, 0x03, 0x01, 0xcc}, | ||
808 | {0xb3, 0x00, 0x21, 0xcc}, {0xb3, 0x00, 0x26, 0xcc}, | ||
809 | {0xb3, 0x05, 0x01, 0xcc}, | ||
810 | {0xb3, 0x06, 0x03, 0xcc}, | ||
811 | {0xb3, 0x03, 0x1f, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, | ||
812 | {0xb3, 0x05, 0x00, 0xcc}, | ||
813 | {0xb3, 0x06, 0x01, 0xcc}, | ||
814 | {0xb3, 0x15, 0x00, 0xcc},/* 0xb315 <-0 href startl */ | ||
815 | {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, | ||
816 | {0xb3, 0x21, 0x00, 0xcc}, | ||
817 | {0xb3, 0x23, 0xe0, 0xcc}, {0xb3, 0x1d, 0x01, 0xcc}, | ||
818 | {0xb3, 0x1f, 0x02, 0xcc}, | ||
819 | {0xb3, 0x34, 0x01, 0xcc}, | ||
820 | {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x00, 0x26, 0xcc}, | ||
821 | {0xb8, 0x00, 0x33, 0xcc}, /* 13 */ | ||
822 | {0xb8, 0x01, 0x7d, 0xcc}, | ||
823 | {0xbc, 0x00, 0x73, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, | ||
824 | {0xb8, 0x27, 0x20, 0xcc}, | ||
825 | {0xb8, 0x8f, 0x50, 0xcc}, | ||
826 | {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa}, | ||
827 | {0x00, 0x12, 0x80, 0xaa}, | ||
828 | {0x00, 0x12, 0x05, 0xaa}, | ||
829 | {0x00, 0x1e, 0x01, 0xaa}, | ||
830 | {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */ | ||
831 | {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */ | ||
832 | {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa}, | ||
833 | {0x00, 0x13, 0xa7, 0xaa}, | ||
834 | {0x00, 0x40, 0xc1, 0xaa}, {0x00, 0x35, 0x00, 0xaa}, | ||
835 | {0x00, 0x36, 0x00, 0xaa}, | ||
836 | {0x00, 0x3c, 0x68, 0xaa}, {0x00, 0x1b, 0x05, 0xaa}, | ||
837 | {0x00, 0x39, 0x43, 0xaa}, | ||
838 | {0x00, 0x8d, 0xcf, 0xaa}, | ||
839 | {0x00, 0x8b, 0xcc, 0xaa}, {0x00, 0x8c, 0xcc, 0xaa}, | ||
840 | {0x00, 0x0f, 0x62, 0xaa}, | ||
841 | {0x00, 0x35, 0x84, 0xaa}, | ||
842 | {0x00, 0x3b, 0x08, 0xaa}, /* 0 * Nightframe 1/4 + 50Hz -> 0xC8 */ | ||
843 | {0x00, 0x3a, 0x00, 0xaa}, /* mx change yuyv format 00, 04, 01; 08, 0c*/ | ||
844 | {0x00, 0x14, 0x2a, 0xaa}, /* agc ampli */ | ||
845 | {0x00, 0x9e, 0x40, 0xaa}, {0xb8, 0x8f, 0x50, 0xcc}, | ||
846 | {0x00, 0x01, 0x80, 0xaa}, | ||
847 | {0x00, 0x02, 0x80, 0xaa}, | ||
848 | {0xb8, 0xfe, 0x00, 0xcc}, {0xb8, 0xff, 0x28, 0xcc}, | ||
849 | {0xb9, 0x00, 0x28, 0xcc}, | ||
850 | {0xb9, 0x01, 0x28, 0xcc}, {0xb9, 0x02, 0x28, 0xcc}, | ||
851 | {0xb9, 0x03, 0x00, 0xcc}, | ||
852 | {0xb9, 0x04, 0x00, 0xcc}, | ||
853 | {0xb9, 0x05, 0x3c, 0xcc}, {0xb9, 0x06, 0x3c, 0xcc}, | ||
854 | {0xb9, 0x07, 0x3c, 0xcc}, | ||
855 | {0xb9, 0x08, 0x3c, 0xcc}, | ||
856 | |||
857 | {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc}, | ||
858 | |||
859 | {0x00, 0x29, 0x3c, 0xaa}, {0xb3, 0x01, 0x45, 0xcc}, | ||
860 | {} | ||
861 | }; | ||
862 | static const __u8 ov7660_initQVGA_data[][4] = { | ||
863 | {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, | ||
864 | {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, | ||
865 | {0xb3, 0x00, 0x21, 0xcc}, {0xb3, 0x00, 0x26, 0xcc}, | ||
866 | {0xb3, 0x05, 0x01, 0xcc}, {0xb3, 0x06, 0x03, 0xcc}, | ||
867 | {0xb3, 0x03, 0x1f, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, | ||
868 | {0xb3, 0x05, 0x00, 0xcc}, {0xb3, 0x06, 0x01, 0xcc}, | ||
869 | {0xb3, 0x15, 0x00, 0xcc},/* 0xb315 <-0 href startl */ | ||
870 | {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, | ||
871 | {0xb3, 0x21, 0x00, 0xcc}, | ||
872 | {0xb3, 0x23, 0xe0, 0xcc}, {0xb3, 0x1d, 0x01, 0xcc}, | ||
873 | {0xb3, 0x1f, 0x02, 0xcc}, {0xb3, 0x34, 0x01, 0xcc}, | ||
874 | {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x00, 0x26, 0xcc}, | ||
875 | {0xb8, 0x00, 0x33, 0xcc}, /* 13 */ | ||
876 | {0xb8, 0x01, 0x7d, 0xcc}, | ||
877 | /* sizer */ | ||
878 | {0xbc, 0x00, 0xd3, 0xcc}, | ||
879 | {0xb8, 0x81, 0x09, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, | ||
880 | {0xb8, 0x27, 0x20, 0xcc}, {0xb8, 0x8f, 0x50, 0xcc}, | ||
881 | {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa}, | ||
882 | {0x00, 0x12, 0x80, 0xaa}, {0x00, 0x12, 0x05, 0xaa}, | ||
883 | {0x00, 0x1e, 0x01, 0xaa}, | ||
884 | {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */ | ||
885 | {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */ | ||
886 | {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa}, | ||
887 | {0x00, 0x13, 0xa7, 0xaa}, | ||
888 | {0x00, 0x40, 0xc1, 0xaa}, {0x00, 0x35, 0x00, 0xaa}, | ||
889 | {0x00, 0x36, 0x00, 0xaa}, | ||
890 | {0x00, 0x3c, 0x68, 0xaa}, {0x00, 0x1b, 0x05, 0xaa}, | ||
891 | {0x00, 0x39, 0x43, 0xaa}, {0x00, 0x8d, 0xcf, 0xaa}, | ||
892 | {0x00, 0x8b, 0xcc, 0xaa}, {0x00, 0x8c, 0xcc, 0xaa}, | ||
893 | {0x00, 0x0f, 0x62, 0xaa}, {0x00, 0x35, 0x84, 0xaa}, | ||
894 | {0x00, 0x3b, 0x08, 0xaa}, /* 0 * Nightframe 1/4 + 50Hz -> 0xC8 */ | ||
895 | {0x00, 0x3a, 0x00, 0xaa}, /* mx change yuyv format 00, 04, 01; 08, 0c*/ | ||
896 | {0x00, 0x14, 0x2a, 0xaa}, /* agc ampli */ | ||
897 | {0x00, 0x9e, 0x40, 0xaa}, {0xb8, 0x8f, 0x50, 0xcc}, | ||
898 | {0x00, 0x01, 0x80, 0xaa}, | ||
899 | {0x00, 0x02, 0x80, 0xaa}, | ||
900 | /* sizer filters */ | ||
901 | {0xbc, 0x02, 0x08, 0xcc}, | ||
902 | {0xbc, 0x03, 0x70, 0xcc}, | ||
903 | {0xb8, 0x35, 0x00, 0xcc}, | ||
904 | {0xb8, 0x36, 0x00, 0xcc}, | ||
905 | {0xb8, 0x37, 0x00, 0xcc}, | ||
906 | {0xbc, 0x04, 0x08, 0xcc}, | ||
907 | {0xbc, 0x05, 0x00, 0xcc}, | ||
908 | {0xbc, 0x06, 0x00, 0xcc}, | ||
909 | {0xbc, 0x08, 0x3c, 0xcc}, | ||
910 | {0xbc, 0x09, 0x40, 0xcc}, | ||
911 | {0xbc, 0x0a, 0x04, 0xcc}, | ||
912 | {0xbc, 0x0b, 0x00, 0xcc}, | ||
913 | {0xbc, 0x0c, 0x00, 0xcc}, | ||
914 | /* */ | ||
915 | {0xb8, 0xfe, 0x00, 0xcc}, | ||
916 | {0xb8, 0xff, 0x28, 0xcc}, | ||
917 | /* */ | ||
918 | {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc}, | ||
919 | {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc}, | ||
920 | {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc}, | ||
921 | {0xb9, 0x06, 0x3c, 0xcc}, {0xb9, 0x07, 0x3c, 0xcc}, | ||
922 | {0xb9, 0x08, 0x3c, 0xcc}, | ||
923 | /* */ | ||
924 | {0xb8, 0x8e, 0x00, 0xcc}, | ||
925 | {0xb8, 0x8f, 0xff, 0xcc}, /* ff */ | ||
926 | {0x00, 0x29, 0x3c, 0xaa}, | ||
927 | {0xb3, 0x01, 0x45, 0xcc}, /* 45 */ | ||
928 | {} | ||
929 | }; | ||
930 | |||
931 | static const __u8 ov7660_50HZ[][4] = { | ||
932 | {0x00, 0x3b, 0x08, 0xaa}, | ||
933 | {0x00, 0x9d, 0x40, 0xaa}, | ||
934 | {0x00, 0x13, 0xa7, 0xaa}, | ||
935 | {} | ||
936 | }; | ||
937 | |||
938 | static const __u8 ov7660_60HZ[][4] = { | ||
939 | {0x00, 0x3b, 0x00, 0xaa}, | ||
940 | {0x00, 0x9e, 0x40, 0xaa}, | ||
941 | {0x00, 0x13, 0xa7, 0xaa}, | ||
942 | {} | ||
943 | }; | ||
944 | |||
945 | static const __u8 ov7660_NoFliker[][4] = { | ||
946 | {0x00, 0x13, 0x87, 0xaa}, | ||
947 | {} | ||
948 | }; | ||
949 | |||
950 | static const __u8 ov7670_initVGA_JPG[][4] = { | ||
951 | {0xb3, 0x01, 0x05, 0xcc}, | ||
952 | {0x00, 0x00, 0x30, 0xdd}, {0xb0, 0x03, 0x19, 0xcc}, | ||
953 | {0x00, 0x00, 0x10, 0xdd}, | ||
954 | {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x10, 0xdd}, | ||
955 | {0xb3, 0x00, 0x66, 0xcc}, {0xb3, 0x00, 0x67, 0xcc}, | ||
956 | {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x34, 0x01, 0xcc}, | ||
957 | {0xb3, 0x05, 0x01, 0xcc}, {0xb3, 0x06, 0x01, 0xcc}, | ||
958 | {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc}, | ||
959 | {0xb3, 0x02, 0x02, 0xcc}, {0xb3, 0x03, 0x1f, 0xcc}, | ||
960 | {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, | ||
961 | {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, | ||
962 | {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, | ||
963 | {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x01, 0xcc}, | ||
964 | {0xb3, 0x23, 0xe0, 0xcc}, {0xbc, 0x00, 0x41, 0xcc}, | ||
965 | {0xbc, 0x01, 0x01, 0xcc}, {0x00, 0x12, 0x80, 0xaa}, | ||
966 | {0x00, 0x00, 0x20, 0xdd}, {0x00, 0x12, 0x00, 0xaa}, | ||
967 | {0x00, 0x11, 0x40, 0xaa}, {0x00, 0x6b, 0x0a, 0xaa}, | ||
968 | {0x00, 0x3a, 0x04, 0xaa}, {0x00, 0x40, 0xc0, 0xaa}, | ||
969 | {0x00, 0x8c, 0x00, 0xaa}, {0x00, 0x7a, 0x29, 0xaa}, | ||
970 | {0x00, 0x7b, 0x0e, 0xaa}, {0x00, 0x7c, 0x1a, 0xaa}, | ||
971 | {0x00, 0x7d, 0x31, 0xaa}, {0x00, 0x7e, 0x53, 0xaa}, | ||
972 | {0x00, 0x7f, 0x60, 0xaa}, {0x00, 0x80, 0x6b, 0xaa}, | ||
973 | {0x00, 0x81, 0x73, 0xaa}, {0x00, 0x82, 0x7b, 0xaa}, | ||
974 | {0x00, 0x83, 0x82, 0xaa}, {0x00, 0x84, 0x89, 0xaa}, | ||
975 | {0x00, 0x85, 0x96, 0xaa}, {0x00, 0x86, 0xa1, 0xaa}, | ||
976 | {0x00, 0x87, 0xb7, 0xaa}, {0x00, 0x88, 0xcc, 0xaa}, | ||
977 | {0x00, 0x89, 0xe1, 0xaa}, {0x00, 0x13, 0xe0, 0xaa}, | ||
978 | {0x00, 0x00, 0x00, 0xaa}, {0x00, 0x10, 0x00, 0xaa}, | ||
979 | {0x00, 0x0d, 0x40, 0xaa}, {0x00, 0x14, 0x28, 0xaa}, | ||
980 | {0x00, 0xa5, 0x05, 0xaa}, {0x00, 0xab, 0x07, 0xaa}, | ||
981 | {0x00, 0x24, 0x95, 0xaa}, {0x00, 0x25, 0x33, 0xaa}, | ||
982 | {0x00, 0x26, 0xe3, 0xaa}, {0x00, 0x9f, 0x88, 0xaa}, | ||
983 | {0x00, 0xa0, 0x78, 0xaa}, {0x00, 0x55, 0x90, 0xaa}, | ||
984 | {0x00, 0xa1, 0x03, 0xaa}, {0x00, 0xa6, 0xe0, 0xaa}, | ||
985 | {0x00, 0xa7, 0xd8, 0xaa}, {0x00, 0xa8, 0xf0, 0xaa}, | ||
986 | {0x00, 0xa9, 0x90, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, | ||
987 | {0x00, 0x13, 0xe5, 0xaa}, {0x00, 0x0e, 0x61, 0xaa}, | ||
988 | {0x00, 0x0f, 0x4b, 0xaa}, {0x00, 0x16, 0x02, 0xaa}, | ||
989 | {0x00, 0x1e, 0x07, 0xaa}, {0x00, 0x21, 0x02, 0xaa}, | ||
990 | {0x00, 0x22, 0x91, 0xaa}, {0x00, 0x29, 0x07, 0xaa}, | ||
991 | {0x00, 0x33, 0x0b, 0xaa}, {0x00, 0x35, 0x0b, 0xaa}, | ||
992 | {0x00, 0x37, 0x1d, 0xaa}, {0x00, 0x38, 0x71, 0xaa}, | ||
993 | {0x00, 0x39, 0x2a, 0xaa}, {0x00, 0x3c, 0x78, 0xaa}, | ||
994 | {0x00, 0x4d, 0x40, 0xaa}, {0x00, 0x4e, 0x20, 0xaa}, | ||
995 | {0x00, 0x74, 0x19, 0xaa}, {0x00, 0x8d, 0x4f, 0xaa}, | ||
996 | {0x00, 0x8e, 0x00, 0xaa}, {0x00, 0x8f, 0x00, 0xaa}, | ||
997 | {0x00, 0x90, 0x00, 0xaa}, {0x00, 0x91, 0x00, 0xaa}, | ||
998 | {0x00, 0x96, 0x00, 0xaa}, {0x00, 0x9a, 0x80, 0xaa}, | ||
999 | {0x00, 0xb0, 0x84, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, | ||
1000 | {0x00, 0xb2, 0x0e, 0xaa}, {0x00, 0xb3, 0x82, 0xaa}, | ||
1001 | {0x00, 0xb8, 0x0a, 0xaa}, {0x00, 0x43, 0x14, 0xaa}, | ||
1002 | {0x00, 0x44, 0xf0, 0xaa}, {0x00, 0x45, 0x45, 0xaa}, | ||
1003 | {0x00, 0x46, 0x63, 0xaa}, {0x00, 0x47, 0x2d, 0xaa}, | ||
1004 | {0x00, 0x48, 0x46, 0xaa}, {0x00, 0x59, 0x88, 0xaa}, | ||
1005 | {0x00, 0x5a, 0xa0, 0xaa}, {0x00, 0x5b, 0xc6, 0xaa}, | ||
1006 | {0x00, 0x5c, 0x7d, 0xaa}, {0x00, 0x5d, 0x5f, 0xaa}, | ||
1007 | {0x00, 0x5e, 0x19, 0xaa}, {0x00, 0x6c, 0x0a, 0xaa}, | ||
1008 | {0x00, 0x6d, 0x55, 0xaa}, {0x00, 0x6e, 0x11, 0xaa}, | ||
1009 | {0x00, 0x6f, 0x9e, 0xaa}, {0x00, 0x69, 0x00, 0xaa}, | ||
1010 | {0x00, 0x6a, 0x40, 0xaa}, {0x00, 0x01, 0x40, 0xaa}, | ||
1011 | {0x00, 0x02, 0x40, 0xaa}, {0x00, 0x13, 0xe7, 0xaa}, | ||
1012 | {0x00, 0x5f, 0xf0, 0xaa}, {0x00, 0x60, 0xf0, 0xaa}, | ||
1013 | {0x00, 0x61, 0xf0, 0xaa}, {0x00, 0x27, 0xa0, 0xaa}, | ||
1014 | {0x00, 0x28, 0x80, 0xaa}, {0x00, 0x2c, 0x90, 0xaa}, | ||
1015 | {0x00, 0x4f, 0x66, 0xaa}, {0x00, 0x50, 0x66, 0xaa}, | ||
1016 | {0x00, 0x51, 0x00, 0xaa}, {0x00, 0x52, 0x22, 0xaa}, | ||
1017 | {0x00, 0x53, 0x5e, 0xaa}, {0x00, 0x54, 0x80, 0xaa}, | ||
1018 | {0x00, 0x58, 0x9e, 0xaa}, {0x00, 0x41, 0x08, 0xaa}, | ||
1019 | {0x00, 0x3f, 0x00, 0xaa}, {0x00, 0x75, 0x85, 0xaa}, | ||
1020 | {0x00, 0x76, 0xe1, 0xaa}, {0x00, 0x4c, 0x00, 0xaa}, | ||
1021 | {0x00, 0x77, 0x0a, 0xaa}, {0x00, 0x3d, 0x88, 0xaa}, | ||
1022 | {0x00, 0x4b, 0x09, 0xaa}, {0x00, 0xc9, 0x60, 0xaa}, | ||
1023 | {0x00, 0x41, 0x38, 0xaa}, {0x00, 0x62, 0x30, 0xaa}, | ||
1024 | {0x00, 0x63, 0x30, 0xaa}, {0x00, 0x64, 0x08, 0xaa}, | ||
1025 | {0x00, 0x94, 0x07, 0xaa}, {0x00, 0x95, 0x0b, 0xaa}, | ||
1026 | {0x00, 0x65, 0x00, 0xaa}, {0x00, 0x66, 0x05, 0xaa}, | ||
1027 | {0x00, 0x56, 0x50, 0xaa}, {0x00, 0x34, 0x11, 0xaa}, | ||
1028 | {0x00, 0xa4, 0x88, 0xaa}, {0x00, 0x96, 0x00, 0xaa}, | ||
1029 | {0x00, 0x97, 0x30, 0xaa}, {0x00, 0x98, 0x20, 0xaa}, | ||
1030 | {0x00, 0x99, 0x30, 0xaa}, {0x00, 0x9a, 0x84, 0xaa}, | ||
1031 | {0x00, 0x9b, 0x29, 0xaa}, {0x00, 0x9c, 0x03, 0xaa}, | ||
1032 | {0x00, 0x78, 0x04, 0xaa}, {0x00, 0x79, 0x01, 0xaa}, | ||
1033 | {0x00, 0xc8, 0xf0, 0xaa}, {0x00, 0x79, 0x0f, 0xaa}, | ||
1034 | {0x00, 0xc8, 0x00, 0xaa}, {0x00, 0x79, 0x10, 0xaa}, | ||
1035 | {0x00, 0xc8, 0x7e, 0xaa}, {0x00, 0x79, 0x0a, 0xaa}, | ||
1036 | {0x00, 0xc8, 0x80, 0xaa}, {0x00, 0x79, 0x0b, 0xaa}, | ||
1037 | {0x00, 0xc8, 0x01, 0xaa}, {0x00, 0x79, 0x0c, 0xaa}, | ||
1038 | {0x00, 0xc8, 0x0f, 0xaa}, {0x00, 0x79, 0x0d, 0xaa}, | ||
1039 | {0x00, 0xc8, 0x20, 0xaa}, {0x00, 0x79, 0x09, 0xaa}, | ||
1040 | {0x00, 0xc8, 0x80, 0xaa}, {0x00, 0x79, 0x02, 0xaa}, | ||
1041 | {0x00, 0xc8, 0xc0, 0xaa}, {0x00, 0x79, 0x03, 0xaa}, | ||
1042 | {0x00, 0xc8, 0x40, 0xaa}, {0x00, 0x79, 0x05, 0xaa}, | ||
1043 | {0x00, 0xc8, 0x30, 0xaa}, {0x00, 0x79, 0x26, 0xaa}, | ||
1044 | {0x00, 0x11, 0x40, 0xaa}, {0x00, 0x3a, 0x04, 0xaa}, | ||
1045 | {0x00, 0x12, 0x00, 0xaa}, {0x00, 0x40, 0xc0, 0xaa}, | ||
1046 | {0x00, 0x8c, 0x00, 0xaa}, {0x00, 0x17, 0x14, 0xaa}, | ||
1047 | {0x00, 0x18, 0x02, 0xaa}, {0x00, 0x32, 0x92, 0xaa}, | ||
1048 | {0x00, 0x19, 0x02, 0xaa}, {0x00, 0x1a, 0x7a, 0xaa}, | ||
1049 | {0x00, 0x03, 0x0a, 0xaa}, {0x00, 0x0c, 0x00, 0xaa}, | ||
1050 | {0x00, 0x3e, 0x00, 0xaa}, {0x00, 0x70, 0x3a, 0xaa}, | ||
1051 | {0x00, 0x71, 0x35, 0xaa}, {0x00, 0x72, 0x11, 0xaa}, | ||
1052 | {0x00, 0x73, 0xf0, 0xaa}, {0x00, 0xa2, 0x02, 0xaa}, | ||
1053 | {0x00, 0xb1, 0x00, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, | ||
1054 | {0x00, 0x1e, 0x37, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, | ||
1055 | {0x00, 0x24, 0x80, 0xaa}, {0x00, 0x25, 0x74, 0xaa}, | ||
1056 | {0x00, 0x26, 0xd3, 0xaa}, {0x00, 0x0d, 0x00, 0xaa}, | ||
1057 | {0x00, 0x14, 0x18, 0xaa}, {0x00, 0x9d, 0x99, 0xaa}, | ||
1058 | {0x00, 0x9e, 0x7f, 0xaa}, {0x00, 0x64, 0x08, 0xaa}, | ||
1059 | {0x00, 0x94, 0x07, 0xaa}, {0x00, 0x95, 0x06, 0xaa}, | ||
1060 | {0x00, 0x66, 0x05, 0xaa}, {0x00, 0x41, 0x08, 0xaa}, | ||
1061 | {0x00, 0x3f, 0x00, 0xaa}, {0x00, 0x75, 0x07, 0xaa}, | ||
1062 | {0x00, 0x76, 0xe1, 0xaa}, {0x00, 0x4c, 0x00, 0xaa}, | ||
1063 | {0x00, 0x77, 0x00, 0xaa}, {0x00, 0x3d, 0xc2, 0xaa}, | ||
1064 | {0x00, 0x4b, 0x09, 0xaa}, {0x00, 0xc9, 0x60, 0xaa}, | ||
1065 | {0x00, 0x41, 0x38, 0xaa}, {0xb6, 0x00, 0x00, 0xcc}, | ||
1066 | {0xb6, 0x03, 0x02, 0xcc}, {0xb6, 0x02, 0x80, 0xcc}, | ||
1067 | {0xb6, 0x05, 0x01, 0xcc}, {0xb6, 0x04, 0xe0, 0xcc}, | ||
1068 | {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x13, 0xcc}, | ||
1069 | {0xb6, 0x18, 0x02, 0xcc}, {0xb6, 0x17, 0x58, 0xcc}, | ||
1070 | {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc}, | ||
1071 | {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc}, | ||
1072 | {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc}, | ||
1073 | {0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x01, 0x45, 0xcc}, | ||
1074 | {0x00, 0x77, 0x05, 0xaa}, | ||
1075 | {}, | ||
1076 | }; | ||
1077 | |||
1078 | static const __u8 ov7670_initQVGA_JPG[][4] = { | ||
1079 | {0xb3, 0x01, 0x05, 0xcc}, {0x00, 0x00, 0x30, 0xdd}, | ||
1080 | {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x10, 0xdd}, | ||
1081 | {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x10, 0xdd}, | ||
1082 | {0xb3, 0x00, 0x66, 0xcc}, {0xb3, 0x00, 0x67, 0xcc}, | ||
1083 | {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x34, 0x01, 0xcc}, | ||
1084 | {0xb3, 0x05, 0x01, 0xcc}, {0xb3, 0x06, 0x01, 0xcc}, | ||
1085 | {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc}, | ||
1086 | {0xb3, 0x02, 0x02, 0xcc}, {0xb3, 0x03, 0x1f, 0xcc}, | ||
1087 | {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, | ||
1088 | {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, | ||
1089 | {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, | ||
1090 | {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x01, 0xcc}, | ||
1091 | {0xb3, 0x23, 0xe0, 0xcc}, {0xbc, 0x00, 0xd1, 0xcc}, | ||
1092 | {0xbc, 0x01, 0x01, 0xcc}, {0x00, 0x12, 0x80, 0xaa}, | ||
1093 | {0x00, 0x00, 0x20, 0xdd}, {0x00, 0x12, 0x00, 0xaa}, | ||
1094 | {0x00, 0x11, 0x40, 0xaa}, {0x00, 0x6b, 0x0a, 0xaa}, | ||
1095 | {0x00, 0x3a, 0x04, 0xaa}, {0x00, 0x40, 0xc0, 0xaa}, | ||
1096 | {0x00, 0x8c, 0x00, 0xaa}, {0x00, 0x7a, 0x29, 0xaa}, | ||
1097 | {0x00, 0x7b, 0x0e, 0xaa}, {0x00, 0x7c, 0x1a, 0xaa}, | ||
1098 | {0x00, 0x7d, 0x31, 0xaa}, {0x00, 0x7e, 0x53, 0xaa}, | ||
1099 | {0x00, 0x7f, 0x60, 0xaa}, {0x00, 0x80, 0x6b, 0xaa}, | ||
1100 | {0x00, 0x81, 0x73, 0xaa}, {0x00, 0x82, 0x7b, 0xaa}, | ||
1101 | {0x00, 0x83, 0x82, 0xaa}, {0x00, 0x84, 0x89, 0xaa}, | ||
1102 | {0x00, 0x85, 0x96, 0xaa}, {0x00, 0x86, 0xa1, 0xaa}, | ||
1103 | {0x00, 0x87, 0xb7, 0xaa}, {0x00, 0x88, 0xcc, 0xaa}, | ||
1104 | {0x00, 0x89, 0xe1, 0xaa}, {0x00, 0x13, 0xe0, 0xaa}, | ||
1105 | {0x00, 0x00, 0x00, 0xaa}, {0x00, 0x10, 0x00, 0xaa}, | ||
1106 | {0x00, 0x0d, 0x40, 0xaa}, {0x00, 0x14, 0x28, 0xaa}, | ||
1107 | {0x00, 0xa5, 0x05, 0xaa}, {0x00, 0xab, 0x07, 0xaa}, | ||
1108 | {0x00, 0x24, 0x95, 0xaa}, {0x00, 0x25, 0x33, 0xaa}, | ||
1109 | {0x00, 0x26, 0xe3, 0xaa}, {0x00, 0x9f, 0x88, 0xaa}, | ||
1110 | {0x00, 0xa0, 0x78, 0xaa}, {0x00, 0x55, 0x90, 0xaa}, | ||
1111 | {0x00, 0xa1, 0x03, 0xaa}, {0x00, 0xa6, 0xe0, 0xaa}, | ||
1112 | {0x00, 0xa7, 0xd8, 0xaa}, {0x00, 0xa8, 0xf0, 0xaa}, | ||
1113 | {0x00, 0xa9, 0x90, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, | ||
1114 | {0x00, 0x13, 0xe5, 0xaa}, {0x00, 0x0e, 0x61, 0xaa}, | ||
1115 | {0x00, 0x0f, 0x4b, 0xaa}, {0x00, 0x16, 0x02, 0xaa}, | ||
1116 | {0x00, 0x1e, 0x07, 0xaa}, {0x00, 0x21, 0x02, 0xaa}, | ||
1117 | {0x00, 0x22, 0x91, 0xaa}, {0x00, 0x29, 0x07, 0xaa}, | ||
1118 | {0x00, 0x33, 0x0b, 0xaa}, {0x00, 0x35, 0x0b, 0xaa}, | ||
1119 | {0x00, 0x37, 0x1d, 0xaa}, {0x00, 0x38, 0x71, 0xaa}, | ||
1120 | {0x00, 0x39, 0x2a, 0xaa}, {0x00, 0x3c, 0x78, 0xaa}, | ||
1121 | {0x00, 0x4d, 0x40, 0xaa}, {0x00, 0x4e, 0x20, 0xaa}, | ||
1122 | {0x00, 0x74, 0x19, 0xaa}, {0x00, 0x8d, 0x4f, 0xaa}, | ||
1123 | {0x00, 0x8e, 0x00, 0xaa}, {0x00, 0x8f, 0x00, 0xaa}, | ||
1124 | {0x00, 0x90, 0x00, 0xaa}, {0x00, 0x91, 0x00, 0xaa}, | ||
1125 | {0x00, 0x96, 0x00, 0xaa}, {0x00, 0x9a, 0x80, 0xaa}, | ||
1126 | {0x00, 0xb0, 0x84, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, | ||
1127 | {0x00, 0xb2, 0x0e, 0xaa}, {0x00, 0xb3, 0x82, 0xaa}, | ||
1128 | {0x00, 0xb8, 0x0a, 0xaa}, {0x00, 0x43, 0x14, 0xaa}, | ||
1129 | {0x00, 0x44, 0xf0, 0xaa}, {0x00, 0x45, 0x45, 0xaa}, | ||
1130 | {0x00, 0x46, 0x63, 0xaa}, {0x00, 0x47, 0x2d, 0xaa}, | ||
1131 | {0x00, 0x48, 0x46, 0xaa}, {0x00, 0x59, 0x88, 0xaa}, | ||
1132 | {0x00, 0x5a, 0xa0, 0xaa}, {0x00, 0x5b, 0xc6, 0xaa}, | ||
1133 | {0x00, 0x5c, 0x7d, 0xaa}, {0x00, 0x5d, 0x5f, 0xaa}, | ||
1134 | {0x00, 0x5e, 0x19, 0xaa}, {0x00, 0x6c, 0x0a, 0xaa}, | ||
1135 | {0x00, 0x6d, 0x55, 0xaa}, {0x00, 0x6e, 0x11, 0xaa}, | ||
1136 | {0x00, 0x6f, 0x9e, 0xaa}, {0x00, 0x69, 0x00, 0xaa}, | ||
1137 | {0x00, 0x6a, 0x40, 0xaa}, {0x00, 0x01, 0x40, 0xaa}, | ||
1138 | {0x00, 0x02, 0x40, 0xaa}, {0x00, 0x13, 0xe7, 0xaa}, | ||
1139 | {0x00, 0x5f, 0xf0, 0xaa}, {0x00, 0x60, 0xf0, 0xaa}, | ||
1140 | {0x00, 0x61, 0xf0, 0xaa}, {0x00, 0x27, 0xa0, 0xaa}, | ||
1141 | {0x00, 0x28, 0x80, 0xaa}, {0x00, 0x2c, 0x90, 0xaa}, | ||
1142 | {0x00, 0x4f, 0x66, 0xaa}, {0x00, 0x50, 0x66, 0xaa}, | ||
1143 | {0x00, 0x51, 0x00, 0xaa}, {0x00, 0x52, 0x22, 0xaa}, | ||
1144 | {0x00, 0x53, 0x5e, 0xaa}, {0x00, 0x54, 0x80, 0xaa}, | ||
1145 | {0x00, 0x58, 0x9e, 0xaa}, {0x00, 0x41, 0x08, 0xaa}, | ||
1146 | {0x00, 0x3f, 0x00, 0xaa}, {0x00, 0x75, 0x85, 0xaa}, | ||
1147 | {0x00, 0x76, 0xe1, 0xaa}, {0x00, 0x4c, 0x00, 0xaa}, | ||
1148 | {0x00, 0x77, 0x0a, 0xaa}, {0x00, 0x3d, 0x88, 0xaa}, | ||
1149 | {0x00, 0x4b, 0x09, 0xaa}, {0x00, 0xc9, 0x60, 0xaa}, | ||
1150 | {0x00, 0x41, 0x38, 0xaa}, {0x00, 0x62, 0x30, 0xaa}, | ||
1151 | {0x00, 0x63, 0x30, 0xaa}, {0x00, 0x64, 0x08, 0xaa}, | ||
1152 | {0x00, 0x94, 0x07, 0xaa}, {0x00, 0x95, 0x0b, 0xaa}, | ||
1153 | {0x00, 0x65, 0x00, 0xaa}, {0x00, 0x66, 0x05, 0xaa}, | ||
1154 | {0x00, 0x56, 0x50, 0xaa}, {0x00, 0x34, 0x11, 0xaa}, | ||
1155 | {0x00, 0xa4, 0x88, 0xaa}, {0x00, 0x96, 0x00, 0xaa}, | ||
1156 | {0x00, 0x97, 0x30, 0xaa}, {0x00, 0x98, 0x20, 0xaa}, | ||
1157 | {0x00, 0x99, 0x30, 0xaa}, {0x00, 0x9a, 0x84, 0xaa}, | ||
1158 | {0x00, 0x9b, 0x29, 0xaa}, {0x00, 0x9c, 0x03, 0xaa}, | ||
1159 | {0x00, 0x78, 0x04, 0xaa}, {0x00, 0x79, 0x01, 0xaa}, | ||
1160 | {0x00, 0xc8, 0xf0, 0xaa}, {0x00, 0x79, 0x0f, 0xaa}, | ||
1161 | {0x00, 0xc8, 0x00, 0xaa}, {0x00, 0x79, 0x10, 0xaa}, | ||
1162 | {0x00, 0xc8, 0x7e, 0xaa}, {0x00, 0x79, 0x0a, 0xaa}, | ||
1163 | {0x00, 0xc8, 0x80, 0xaa}, {0x00, 0x79, 0x0b, 0xaa}, | ||
1164 | {0x00, 0xc8, 0x01, 0xaa}, {0x00, 0x79, 0x0c, 0xaa}, | ||
1165 | {0x00, 0xc8, 0x0f, 0xaa}, {0x00, 0x79, 0x0d, 0xaa}, | ||
1166 | {0x00, 0xc8, 0x20, 0xaa}, {0x00, 0x79, 0x09, 0xaa}, | ||
1167 | {0x00, 0xc8, 0x80, 0xaa}, {0x00, 0x79, 0x02, 0xaa}, | ||
1168 | {0x00, 0xc8, 0xc0, 0xaa}, {0x00, 0x79, 0x03, 0xaa}, | ||
1169 | {0x00, 0xc8, 0x40, 0xaa}, {0x00, 0x79, 0x05, 0xaa}, | ||
1170 | {0x00, 0xc8, 0x30, 0xaa}, {0x00, 0x79, 0x26, 0xaa}, | ||
1171 | {0x00, 0x11, 0x40, 0xaa}, {0x00, 0x3a, 0x04, 0xaa}, | ||
1172 | {0x00, 0x12, 0x00, 0xaa}, {0x00, 0x40, 0xc0, 0xaa}, | ||
1173 | {0x00, 0x8c, 0x00, 0xaa}, {0x00, 0x17, 0x14, 0xaa}, | ||
1174 | {0x00, 0x18, 0x02, 0xaa}, {0x00, 0x32, 0x92, 0xaa}, | ||
1175 | {0x00, 0x19, 0x02, 0xaa}, {0x00, 0x1a, 0x7a, 0xaa}, | ||
1176 | {0x00, 0x03, 0x0a, 0xaa}, {0x00, 0x0c, 0x00, 0xaa}, | ||
1177 | {0x00, 0x3e, 0x00, 0xaa}, {0x00, 0x70, 0x3a, 0xaa}, | ||
1178 | {0x00, 0x71, 0x35, 0xaa}, {0x00, 0x72, 0x11, 0xaa}, | ||
1179 | {0x00, 0x73, 0xf0, 0xaa}, {0x00, 0xa2, 0x02, 0xaa}, | ||
1180 | {0x00, 0xb1, 0x00, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, | ||
1181 | {0x00, 0x1e, 0x37, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, | ||
1182 | {0x00, 0x24, 0x80, 0xaa}, {0x00, 0x25, 0x74, 0xaa}, | ||
1183 | {0x00, 0x26, 0xd3, 0xaa}, {0x00, 0x0d, 0x00, 0xaa}, | ||
1184 | {0x00, 0x14, 0x18, 0xaa}, {0x00, 0x9d, 0x99, 0xaa}, | ||
1185 | {0x00, 0x9e, 0x7f, 0xaa}, {0x00, 0x64, 0x08, 0xaa}, | ||
1186 | {0x00, 0x94, 0x07, 0xaa}, {0x00, 0x95, 0x06, 0xaa}, | ||
1187 | {0x00, 0x66, 0x05, 0xaa}, {0x00, 0x41, 0x08, 0xaa}, | ||
1188 | {0x00, 0x3f, 0x00, 0xaa}, {0x00, 0x75, 0x07, 0xaa}, | ||
1189 | {0x00, 0x76, 0xe1, 0xaa}, {0x00, 0x4c, 0x00, 0xaa}, | ||
1190 | {0x00, 0x77, 0x00, 0xaa}, {0x00, 0x3d, 0xc2, 0xaa}, | ||
1191 | {0x00, 0x4b, 0x09, 0xaa}, {0x00, 0xc9, 0x60, 0xaa}, | ||
1192 | {0x00, 0x41, 0x38, 0xaa}, {0xb6, 0x00, 0x00, 0xcc}, | ||
1193 | {0xb6, 0x03, 0x01, 0xcc}, {0xb6, 0x02, 0x40, 0xcc}, | ||
1194 | {0xb6, 0x05, 0x00, 0xcc}, {0xb6, 0x04, 0xf0, 0xcc}, | ||
1195 | {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x21, 0xcc}, | ||
1196 | {0xb6, 0x18, 0x00, 0xcc}, {0xb6, 0x17, 0x96, 0xcc}, | ||
1197 | {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc}, | ||
1198 | {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc}, | ||
1199 | {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc}, | ||
1200 | {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc}, | ||
1201 | {0xbc, 0x04, 0x18, 0xcc}, {0xbc, 0x05, 0x00, 0xcc}, | ||
1202 | {0xbc, 0x06, 0x00, 0xcc}, {0xbc, 0x08, 0x30, 0xcc}, | ||
1203 | {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x10, 0xcc}, | ||
1204 | {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc}, | ||
1205 | {0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x01, 0x45, 0xcc}, | ||
1206 | {0x00, 0x77, 0x05, 0xaa }, | ||
1207 | {}, | ||
1208 | }; | ||
1209 | |||
1210 | struct sensor_info { | ||
1211 | int sensorId; | ||
1212 | __u8 I2cAdd; | ||
1213 | __u8 IdAdd; | ||
1214 | __u16 VpId; | ||
1215 | __u8 m1; | ||
1216 | __u8 m2; | ||
1217 | __u8 op; | ||
1218 | }; | ||
1219 | |||
1220 | static const struct sensor_info sensor_info_data[] = { | ||
1221 | /* sensorId, I2cAdd, IdAdd, VpId, m1, m2, op */ | ||
1222 | {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01}, | ||
1223 | {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05}, | ||
1224 | {SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x3130, 0x24, 0x25, 0x01}, | ||
1225 | {SENSOR_MI1320, 0x80 | 0xc8, 0x00, 0x148c, 0x64, 0x65, 0x01}, | ||
1226 | {SENSOR_OV7670, 0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05}, | ||
1227 | {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01}, | ||
1228 | }; | ||
1229 | |||
1230 | /* read 'len' bytes in gspca_dev->usb_buf */ | ||
1231 | static void reg_r(struct gspca_dev *gspca_dev, | ||
1232 | __u16 req, | ||
1233 | __u16 index, | ||
1234 | __u16 len) | ||
1235 | { | ||
1236 | usb_control_msg(gspca_dev->dev, | ||
1237 | usb_rcvctrlpipe(gspca_dev->dev, 0), | ||
1238 | req, | ||
1239 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
1240 | 1, /* value */ | ||
1241 | index, gspca_dev->usb_buf, len, | ||
1242 | 500); | ||
1243 | } | ||
1244 | |||
1245 | static void reg_w(struct usb_device *dev, | ||
1246 | __u16 req, | ||
1247 | __u16 value, | ||
1248 | __u16 index) | ||
1249 | { | ||
1250 | usb_control_msg(dev, | ||
1251 | usb_sndctrlpipe(dev, 0), | ||
1252 | req, | ||
1253 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
1254 | value, index, NULL, 0, | ||
1255 | 500); | ||
1256 | } | ||
1257 | |||
1258 | static void read_sensor_register(struct gspca_dev *gspca_dev, | ||
1259 | __u16 address, __u16 *value) | ||
1260 | { | ||
1261 | struct usb_device *dev = gspca_dev->dev; | ||
1262 | __u8 ldata, mdata, hdata; | ||
1263 | int retry = 50; | ||
1264 | |||
1265 | *value = 0; | ||
1266 | |||
1267 | reg_r(gspca_dev, 0xa1, 0xb33f, 1); | ||
1268 | /*PDEBUG(D_PROBE, " I2c Bus Busy Wait 0x%02X ", tmpvalue); */ | ||
1269 | if (!(gspca_dev->usb_buf[0] & 0x02)) { | ||
1270 | PDEBUG(D_ERR, "I2c Bus Busy Wait %d", | ||
1271 | gspca_dev->usb_buf[0] & 0x02); | ||
1272 | return; | ||
1273 | } | ||
1274 | reg_w(dev, 0xa0, address, 0xb33a); | ||
1275 | reg_w(dev, 0xa0, 0x02, 0xb339); | ||
1276 | |||
1277 | reg_r(gspca_dev, 0xa1, 0xb33b, 1); | ||
1278 | while (retry-- && gspca_dev->usb_buf[0]) { | ||
1279 | reg_r(gspca_dev, 0xa1, 0xb33b, 1); | ||
1280 | /* PDEBUG(D_PROBE, "Read again 0xb33b %d", tmpvalue); */ | ||
1281 | msleep(1); | ||
1282 | } | ||
1283 | reg_r(gspca_dev, 0xa1, 0xb33e, 1); | ||
1284 | hdata = gspca_dev->usb_buf[0]; | ||
1285 | reg_r(gspca_dev, 0xa1, 0xb33d, 1); | ||
1286 | mdata = gspca_dev->usb_buf[0]; | ||
1287 | reg_r(gspca_dev, 0xa1, 0xb33c, 1); | ||
1288 | ldata = gspca_dev->usb_buf[0]; | ||
1289 | PDEBUG(D_PROBE, "Read Sensor h (0x%02X) m (0x%02X) l (0x%02X)", | ||
1290 | hdata, mdata, ldata); | ||
1291 | reg_r(gspca_dev, 0xa1, 0xb334, 1); | ||
1292 | if (gspca_dev->usb_buf[0] == 0x02) | ||
1293 | *value = (ldata << 8) + mdata; | ||
1294 | else | ||
1295 | *value = ldata; | ||
1296 | } | ||
1297 | |||
1298 | static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) | ||
1299 | { | ||
1300 | struct usb_device *dev = gspca_dev->dev; | ||
1301 | int i; | ||
1302 | __u16 value; | ||
1303 | const struct sensor_info *ptsensor_info; | ||
1304 | |||
1305 | reg_r(gspca_dev, 0xa1, 0xbfcf, 1); | ||
1306 | PDEBUG(D_PROBE, "check sensor header %d", gspca_dev->usb_buf[0]); | ||
1307 | for (i = 0; i < ARRAY_SIZE(sensor_info_data); i++) { | ||
1308 | ptsensor_info = &sensor_info_data[i]; | ||
1309 | reg_w(dev, 0xa0, 0x02, 0xb334); | ||
1310 | reg_w(dev, 0xa0, ptsensor_info->m1, 0xb300); | ||
1311 | reg_w(dev, 0xa0, ptsensor_info->m2, 0xb300); | ||
1312 | reg_w(dev, 0xa0, 0x01, 0xb308); | ||
1313 | reg_w(dev, 0xa0, 0x0c, 0xb309); | ||
1314 | reg_w(dev, 0xa0, ptsensor_info->I2cAdd, 0xb335); | ||
1315 | /* PDEBUG(D_PROBE, | ||
1316 | "check sensor VC032X -> %d Add -> ox%02X!", | ||
1317 | i, ptsensor_info->I2cAdd); */ | ||
1318 | reg_w(dev, 0xa0, ptsensor_info->op, 0xb301); | ||
1319 | read_sensor_register(gspca_dev, ptsensor_info->IdAdd, &value); | ||
1320 | if (value == ptsensor_info->VpId) { | ||
1321 | /* PDEBUG(D_PROBE, "find sensor VC032X -> ox%04X!", | ||
1322 | ptsensor_info->VpId); */ | ||
1323 | return ptsensor_info->sensorId; | ||
1324 | } | ||
1325 | } | ||
1326 | return -1; | ||
1327 | } | ||
1328 | |||
1329 | static __u8 i2c_write(struct gspca_dev *gspca_dev, | ||
1330 | __u8 reg, const __u8 *val, __u8 size) | ||
1331 | { | ||
1332 | struct usb_device *dev = gspca_dev->dev; | ||
1333 | |||
1334 | if (size > 3 || size < 1) | ||
1335 | return -EINVAL; | ||
1336 | reg_r(gspca_dev, 0xa1, 0xb33f, 1); | ||
1337 | reg_w(dev, 0xa0, size, 0xb334); | ||
1338 | reg_w(dev, 0xa0, reg, 0xb33a); | ||
1339 | switch (size) { | ||
1340 | case 1: | ||
1341 | reg_w(dev, 0xa0, val[0], 0xb336); | ||
1342 | break; | ||
1343 | case 2: | ||
1344 | reg_w(dev, 0xa0, val[0], 0xb336); | ||
1345 | reg_w(dev, 0xa0, val[1], 0xb337); | ||
1346 | break; | ||
1347 | case 3: | ||
1348 | reg_w(dev, 0xa0, val[0], 0xb336); | ||
1349 | reg_w(dev, 0xa0, val[1], 0xb337); | ||
1350 | reg_w(dev, 0xa0, val[2], 0xb338); | ||
1351 | break; | ||
1352 | default: | ||
1353 | reg_w(dev, 0xa0, 0x01, 0xb334); | ||
1354 | return -EINVAL; | ||
1355 | } | ||
1356 | reg_w(dev, 0xa0, 0x01, 0xb339); | ||
1357 | reg_r(gspca_dev, 0xa1, 0xb33b, 1); | ||
1358 | return gspca_dev->usb_buf[0] == 0; | ||
1359 | } | ||
1360 | |||
1361 | static void put_tab_to_reg(struct gspca_dev *gspca_dev, | ||
1362 | const __u8 *tab, __u8 tabsize, __u16 addr) | ||
1363 | { | ||
1364 | int j; | ||
1365 | __u16 ad = addr; | ||
1366 | |||
1367 | for (j = 0; j < tabsize; j++) | ||
1368 | reg_w(gspca_dev->dev, 0xa0, tab[j], ad++); | ||
1369 | } | ||
1370 | |||
1371 | static void usb_exchange(struct gspca_dev *gspca_dev, | ||
1372 | const __u8 data[][4]) | ||
1373 | { | ||
1374 | struct usb_device *dev = gspca_dev->dev; | ||
1375 | int i = 0; | ||
1376 | |||
1377 | for (;;) { | ||
1378 | switch (data[i][3]) { | ||
1379 | default: | ||
1380 | return; | ||
1381 | case 0xcc: /* normal write */ | ||
1382 | reg_w(dev, 0xa0, data[i][2], | ||
1383 | ((data[i][0])<<8) | data[i][1]); | ||
1384 | break; | ||
1385 | case 0xaa: /* i2c op */ | ||
1386 | i2c_write(gspca_dev, data[i][1], &data[i][2], 1); | ||
1387 | break; | ||
1388 | case 0xbb: /* i2c op */ | ||
1389 | i2c_write(gspca_dev, data[i][0], &data[i][1], 2); | ||
1390 | break; | ||
1391 | case 0xdd: | ||
1392 | msleep(data[i][2] + 10); | ||
1393 | break; | ||
1394 | } | ||
1395 | i++; | ||
1396 | } | ||
1397 | /*not reached*/ | ||
1398 | } | ||
1399 | |||
1400 | /* | ||
1401 | "GammaT"=hex:04,17,31,4f,6a,83,99,ad,bf,ce,da,e5,ee,f5,fb,ff,ff | ||
1402 | "MatrixT"=hex:60,f9,e5,e7,50,05,f3,e6,66 | ||
1403 | */ | ||
1404 | |||
1405 | static void vc0321_reset(struct gspca_dev *gspca_dev) | ||
1406 | { | ||
1407 | reg_w(gspca_dev->dev, 0xa0, 0x00, 0xb04d); | ||
1408 | reg_w(gspca_dev->dev, 0xa0, 0x01, 0xb301); | ||
1409 | msleep(100); | ||
1410 | reg_w(gspca_dev->dev, 0xa0, 0x01, 0xb003); | ||
1411 | msleep(100); | ||
1412 | } | ||
1413 | |||
1414 | /* this function is called at probe time */ | ||
1415 | static int sd_config(struct gspca_dev *gspca_dev, | ||
1416 | const struct usb_device_id *id) | ||
1417 | { | ||
1418 | struct sd *sd = (struct sd *) gspca_dev; | ||
1419 | struct usb_device *dev = gspca_dev->dev; | ||
1420 | struct cam *cam; | ||
1421 | int sensor; | ||
1422 | __u16 product; | ||
1423 | |||
1424 | product = id->idProduct; | ||
1425 | sd->bridge = BRIDGE_VC0321; | ||
1426 | switch (id->idVendor) { | ||
1427 | case 0x0ac8: /* Vimicro z-star */ | ||
1428 | switch (product) { | ||
1429 | case 0x0323: | ||
1430 | sd->bridge = BRIDGE_VC0323; | ||
1431 | break; | ||
1432 | } | ||
1433 | break; | ||
1434 | case 0x17ef: /* Lenovo */ | ||
1435 | /* switch (product) { */ | ||
1436 | /* case 0x4802: * Lenovo MI1310_SOC */ | ||
1437 | sd->bridge = BRIDGE_VC0323; | ||
1438 | /* break; */ | ||
1439 | /* } */ | ||
1440 | break; | ||
1441 | } | ||
1442 | |||
1443 | cam = &gspca_dev->cam; | ||
1444 | cam->dev_name = (char *) id->driver_info; | ||
1445 | cam->epaddr = 0x02; | ||
1446 | if (sd->bridge == BRIDGE_VC0321) { | ||
1447 | cam->cam_mode = vc0321_mode; | ||
1448 | cam->nmodes = ARRAY_SIZE(vc0321_mode); | ||
1449 | } else { | ||
1450 | cam->cam_mode = vc0323_mode; | ||
1451 | cam->nmodes = ARRAY_SIZE(vc0323_mode); | ||
1452 | } | ||
1453 | |||
1454 | vc0321_reset(gspca_dev); | ||
1455 | sensor = vc032x_probe_sensor(gspca_dev); | ||
1456 | switch (sensor) { | ||
1457 | case -1: | ||
1458 | PDEBUG(D_PROBE, "Unknown sensor..."); | ||
1459 | return -EINVAL; | ||
1460 | case SENSOR_HV7131R: | ||
1461 | PDEBUG(D_PROBE, "Find Sensor HV7131R"); | ||
1462 | sd->sensor = SENSOR_HV7131R; | ||
1463 | break; | ||
1464 | case SENSOR_MI1310_SOC: | ||
1465 | PDEBUG(D_PROBE, "Find Sensor MI1310_SOC"); | ||
1466 | sd->sensor = SENSOR_MI1310_SOC; | ||
1467 | break; | ||
1468 | case SENSOR_MI1320: | ||
1469 | PDEBUG(D_PROBE, "Find Sensor MI1320"); | ||
1470 | sd->sensor = SENSOR_MI1320; | ||
1471 | break; | ||
1472 | case SENSOR_OV7660: | ||
1473 | PDEBUG(D_PROBE, "Find Sensor OV7660"); | ||
1474 | sd->sensor = SENSOR_OV7660; | ||
1475 | break; | ||
1476 | case SENSOR_OV7670: | ||
1477 | PDEBUG(D_PROBE, "Find Sensor OV7670"); | ||
1478 | sd->sensor = SENSOR_OV7670; | ||
1479 | break; | ||
1480 | case SENSOR_PO3130NC: | ||
1481 | PDEBUG(D_PROBE, "Find Sensor PO3130NC"); | ||
1482 | sd->sensor = SENSOR_PO3130NC; | ||
1483 | break; | ||
1484 | } | ||
1485 | |||
1486 | sd->qindex = 7; | ||
1487 | sd->autogain = AUTOGAIN_DEF; | ||
1488 | sd->lightfreq = FREQ_DEF; | ||
1489 | |||
1490 | if (sd->bridge == BRIDGE_VC0321) { | ||
1491 | reg_r(gspca_dev, 0x8a, 0, 3); | ||
1492 | reg_w(dev, 0x87, 0x00, 0x0f0f); | ||
1493 | |||
1494 | reg_r(gspca_dev, 0x8b, 0, 3); | ||
1495 | reg_w(dev, 0x88, 0x00, 0x0202); | ||
1496 | } | ||
1497 | return 0; | ||
1498 | } | ||
1499 | |||
1500 | /* this function is called at open time */ | ||
1501 | static int sd_open(struct gspca_dev *gspca_dev) | ||
1502 | { | ||
1503 | return 0; | ||
1504 | } | ||
1505 | |||
1506 | static void setquality(struct gspca_dev *gspca_dev) | ||
1507 | { | ||
1508 | } | ||
1509 | |||
1510 | static void setautogain(struct gspca_dev *gspca_dev) | ||
1511 | { | ||
1512 | } | ||
1513 | |||
1514 | static void setlightfreq(struct gspca_dev *gspca_dev) | ||
1515 | { | ||
1516 | struct sd *sd = (struct sd *) gspca_dev; | ||
1517 | static const __u8 (*ov7660_freq_tb[3])[4] = | ||
1518 | {ov7660_NoFliker, ov7660_50HZ, ov7660_60HZ}; | ||
1519 | |||
1520 | if (sd->sensor != SENSOR_OV7660) | ||
1521 | return; | ||
1522 | usb_exchange(gspca_dev, ov7660_freq_tb[sd->lightfreq]); | ||
1523 | } | ||
1524 | |||
1525 | static void sd_start(struct gspca_dev *gspca_dev) | ||
1526 | { | ||
1527 | struct sd *sd = (struct sd *) gspca_dev; | ||
1528 | const __u8 *GammaT = NULL; | ||
1529 | const __u8 *MatrixT = NULL; | ||
1530 | int mode; | ||
1531 | |||
1532 | /* Assume start use the good resolution from gspca_dev->mode */ | ||
1533 | if (sd->bridge == BRIDGE_VC0321) { | ||
1534 | reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfec); | ||
1535 | reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfed); | ||
1536 | reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfee); | ||
1537 | reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfef); | ||
1538 | } | ||
1539 | |||
1540 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | ||
1541 | switch (sd->sensor) { | ||
1542 | case SENSOR_HV7131R: | ||
1543 | GammaT = hv7131r_gamma; | ||
1544 | MatrixT = hv7131r_matrix; | ||
1545 | if (mode) { | ||
1546 | /* 320x240 */ | ||
1547 | usb_exchange(gspca_dev, hv7131r_initQVGA_data); | ||
1548 | } else { | ||
1549 | /* 640x480 */ | ||
1550 | usb_exchange(gspca_dev, hv7131r_initVGA_data); | ||
1551 | } | ||
1552 | break; | ||
1553 | case SENSOR_OV7660: | ||
1554 | GammaT = ov7660_gamma; | ||
1555 | MatrixT = ov7660_matrix; | ||
1556 | if (mode) { | ||
1557 | /* 320x240 */ | ||
1558 | usb_exchange(gspca_dev, ov7660_initQVGA_data); | ||
1559 | } else { | ||
1560 | /* 640x480 */ | ||
1561 | usb_exchange(gspca_dev, ov7660_initVGA_data); | ||
1562 | } | ||
1563 | break; | ||
1564 | case SENSOR_OV7670: | ||
1565 | /*GammaT = ov7660_gamma; */ | ||
1566 | /*MatrixT = ov7660_matrix; */ | ||
1567 | if (mode) { | ||
1568 | /* 320x240 */ | ||
1569 | usb_exchange(gspca_dev, ov7670_initQVGA_JPG); | ||
1570 | } else { | ||
1571 | /* 640x480 */ | ||
1572 | usb_exchange(gspca_dev, ov7670_initVGA_JPG); | ||
1573 | } | ||
1574 | break; | ||
1575 | case SENSOR_MI1310_SOC: | ||
1576 | if (mode) { | ||
1577 | /* 320x240 */ | ||
1578 | usb_exchange(gspca_dev, mi1310_socinitQVGA_JPG); | ||
1579 | } else { | ||
1580 | /* 640x480 */ | ||
1581 | usb_exchange(gspca_dev, mi1310_socinitVGA_JPG); | ||
1582 | } | ||
1583 | break; | ||
1584 | case SENSOR_MI1320: | ||
1585 | GammaT = mi1320_gamma; | ||
1586 | MatrixT = mi1320_matrix; | ||
1587 | if (mode) { | ||
1588 | /* 320x240 */ | ||
1589 | usb_exchange(gspca_dev, mi1320_initQVGA_data); | ||
1590 | } else { | ||
1591 | /* 640x480 */ | ||
1592 | usb_exchange(gspca_dev, mi1320_initVGA_data); | ||
1593 | } | ||
1594 | break; | ||
1595 | case SENSOR_PO3130NC: | ||
1596 | GammaT = po3130_gamma; | ||
1597 | MatrixT = po3130_matrix; | ||
1598 | if (mode) { | ||
1599 | /* 320x240 */ | ||
1600 | usb_exchange(gspca_dev, po3130_initQVGA_data); | ||
1601 | } else { | ||
1602 | /* 640x480 */ | ||
1603 | usb_exchange(gspca_dev, po3130_initVGA_data); | ||
1604 | } | ||
1605 | usb_exchange(gspca_dev, po3130_rundata); | ||
1606 | break; | ||
1607 | default: | ||
1608 | PDEBUG(D_PROBE, "Damned !! no sensor found Bye"); | ||
1609 | return; | ||
1610 | } | ||
1611 | if (GammaT && MatrixT) { | ||
1612 | put_tab_to_reg(gspca_dev, GammaT, 17, 0xb84a); | ||
1613 | put_tab_to_reg(gspca_dev, GammaT, 17, 0xb85b); | ||
1614 | put_tab_to_reg(gspca_dev, GammaT, 17, 0xb86c); | ||
1615 | put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c); | ||
1616 | |||
1617 | /* Seem SHARPNESS */ | ||
1618 | /* | ||
1619 | reg_w(gspca_dev->dev, 0xa0, 0x80, 0xb80a); | ||
1620 | reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb80b); | ||
1621 | reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb80e); | ||
1622 | */ | ||
1623 | /* all 0x40 ??? do nothing | ||
1624 | reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb822); | ||
1625 | reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb823); | ||
1626 | reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb824); | ||
1627 | */ | ||
1628 | /* Only works for HV7131R ?? | ||
1629 | reg_r (gspca_dev, 0xa1, 0xb881, 1); | ||
1630 | reg_w(gspca_dev->dev, 0xa0, 0xfe01, 0xb881); | ||
1631 | reg_w(gspca_dev->dev, 0xa0, 0x79, 0xb801); | ||
1632 | */ | ||
1633 | /* only hv7131r et ov7660 | ||
1634 | reg_w(gspca_dev->dev, 0xa0, 0x20, 0xb827); | ||
1635 | reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb826); * ISP_GAIN 80 | ||
1636 | reg_w(gspca_dev->dev, 0xa0, 0x23, 0xb800); * ISP CTRL_BAS | ||
1637 | */ | ||
1638 | /* set the led on 0x0892 0x0896 */ | ||
1639 | reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff); | ||
1640 | msleep(100); | ||
1641 | setquality(gspca_dev); | ||
1642 | setautogain(gspca_dev); | ||
1643 | setlightfreq(gspca_dev); | ||
1644 | } | ||
1645 | } | ||
1646 | |||
1647 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
1648 | { | ||
1649 | struct usb_device *dev = gspca_dev->dev; | ||
1650 | |||
1651 | reg_w(dev, 0x89, 0xffff, 0xffff); | ||
1652 | reg_w(dev, 0xa0, 0x01, 0xb301); | ||
1653 | reg_w(dev, 0xa0, 0x09, 0xb003); | ||
1654 | } | ||
1655 | |||
1656 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
1657 | { | ||
1658 | struct usb_device *dev = gspca_dev->dev; | ||
1659 | |||
1660 | reg_w(dev, 0x89, 0xffff, 0xffff); | ||
1661 | } | ||
1662 | |||
1663 | /* this function is called at close time */ | ||
1664 | static void sd_close(struct gspca_dev *gspca_dev) | ||
1665 | { | ||
1666 | /* struct usb_device *dev = gspca_dev->dev; | ||
1667 | __u8 buffread; | ||
1668 | |||
1669 | reg_w(dev, 0x89, 0xffff, 0xffff); | ||
1670 | reg_w(dev, 0xa0, 0x01, 0xb301); | ||
1671 | reg_w(dev, 0xa0, 0x09, 0xb303); | ||
1672 | reg_w(dev, 0x89, 0xffff, 0xffff); | ||
1673 | */ | ||
1674 | } | ||
1675 | |||
1676 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
1677 | struct gspca_frame *frame, /* target */ | ||
1678 | __u8 *data, /* isoc packet */ | ||
1679 | int len) /* iso pkt length */ | ||
1680 | { | ||
1681 | struct sd *sd = (struct sd *) gspca_dev; | ||
1682 | |||
1683 | if (data[0] == 0xff && data[1] == 0xd8) { | ||
1684 | PDEBUG(D_PACK, | ||
1685 | "vc032x header packet found len %d", len); | ||
1686 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | ||
1687 | data, 0); | ||
1688 | if (sd->bridge == BRIDGE_VC0321) { | ||
1689 | #define VCHDRSZ 46 | ||
1690 | data += VCHDRSZ; | ||
1691 | len -= VCHDRSZ; | ||
1692 | #undef VCHDRSZ | ||
1693 | } | ||
1694 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | ||
1695 | data, len); | ||
1696 | return; | ||
1697 | } | ||
1698 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
1699 | } | ||
1700 | |||
1701 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
1702 | { | ||
1703 | struct sd *sd = (struct sd *) gspca_dev; | ||
1704 | |||
1705 | sd->autogain = val; | ||
1706 | if (gspca_dev->streaming) | ||
1707 | setautogain(gspca_dev); | ||
1708 | return 0; | ||
1709 | } | ||
1710 | |||
1711 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | ||
1712 | { | ||
1713 | struct sd *sd = (struct sd *) gspca_dev; | ||
1714 | |||
1715 | *val = sd->autogain; | ||
1716 | return 0; | ||
1717 | } | ||
1718 | |||
1719 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | ||
1720 | { | ||
1721 | struct sd *sd = (struct sd *) gspca_dev; | ||
1722 | |||
1723 | sd->lightfreq = val; | ||
1724 | if (gspca_dev->streaming) | ||
1725 | setlightfreq(gspca_dev); | ||
1726 | return 0; | ||
1727 | } | ||
1728 | |||
1729 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) | ||
1730 | { | ||
1731 | struct sd *sd = (struct sd *) gspca_dev; | ||
1732 | |||
1733 | *val = sd->lightfreq; | ||
1734 | return 0; | ||
1735 | } | ||
1736 | |||
1737 | static int sd_querymenu(struct gspca_dev *gspca_dev, | ||
1738 | struct v4l2_querymenu *menu) | ||
1739 | { | ||
1740 | switch (menu->id) { | ||
1741 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
1742 | switch (menu->index) { | ||
1743 | case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ | ||
1744 | strcpy((char *) menu->name, "NoFliker"); | ||
1745 | return 0; | ||
1746 | case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ | ||
1747 | strcpy((char *) menu->name, "50 Hz"); | ||
1748 | return 0; | ||
1749 | case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ | ||
1750 | strcpy((char *) menu->name, "60 Hz"); | ||
1751 | return 0; | ||
1752 | } | ||
1753 | break; | ||
1754 | } | ||
1755 | return -EINVAL; | ||
1756 | } | ||
1757 | |||
1758 | /* sub-driver description */ | ||
1759 | static const struct sd_desc sd_desc = { | ||
1760 | .name = MODULE_NAME, | ||
1761 | .ctrls = sd_ctrls, | ||
1762 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
1763 | .config = sd_config, | ||
1764 | .open = sd_open, | ||
1765 | .start = sd_start, | ||
1766 | .stopN = sd_stopN, | ||
1767 | .stop0 = sd_stop0, | ||
1768 | .close = sd_close, | ||
1769 | .pkt_scan = sd_pkt_scan, | ||
1770 | .querymenu = sd_querymenu, | ||
1771 | }; | ||
1772 | |||
1773 | /* -- module initialisation -- */ | ||
1774 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
1775 | static const __devinitdata struct usb_device_id device_table[] = { | ||
1776 | {USB_DEVICE(0x046d, 0x0892), DVNM("Logitech Orbicam")}, | ||
1777 | {USB_DEVICE(0x046d, 0x0896), DVNM("Logitech Orbicam")}, | ||
1778 | {USB_DEVICE(0x0ac8, 0x0321), DVNM("Vimicro generic vc0321")}, | ||
1779 | {USB_DEVICE(0x0ac8, 0x0323), DVNM("Vimicro Vc0323")}, | ||
1780 | {USB_DEVICE(0x0ac8, 0x0328), DVNM("A4Tech PK-130MG")}, | ||
1781 | {USB_DEVICE(0x0ac8, 0xc001), DVNM("Sony embedded vimicro")}, | ||
1782 | {USB_DEVICE(0x0ac8, 0xc002), DVNM("Sony embedded vimicro")}, | ||
1783 | {USB_DEVICE(0x17ef, 0x4802), DVNM("Lenovo Vc0323+MI1310_SOC")}, | ||
1784 | {} | ||
1785 | }; | ||
1786 | MODULE_DEVICE_TABLE(usb, device_table); | ||
1787 | |||
1788 | /* -- device connect -- */ | ||
1789 | static int sd_probe(struct usb_interface *intf, | ||
1790 | const struct usb_device_id *id) | ||
1791 | { | ||
1792 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
1793 | THIS_MODULE); | ||
1794 | } | ||
1795 | |||
1796 | static struct usb_driver sd_driver = { | ||
1797 | .name = MODULE_NAME, | ||
1798 | .id_table = device_table, | ||
1799 | .probe = sd_probe, | ||
1800 | .disconnect = gspca_disconnect, | ||
1801 | }; | ||
1802 | |||
1803 | /* -- module insert / remove -- */ | ||
1804 | static int __init sd_mod_init(void) | ||
1805 | { | ||
1806 | if (usb_register(&sd_driver) < 0) | ||
1807 | return -1; | ||
1808 | PDEBUG(D_PROBE, "v%s registered", version); | ||
1809 | return 0; | ||
1810 | } | ||
1811 | static void __exit sd_mod_exit(void) | ||
1812 | { | ||
1813 | usb_deregister(&sd_driver); | ||
1814 | PDEBUG(D_PROBE, "deregistered"); | ||
1815 | } | ||
1816 | |||
1817 | module_init(sd_mod_init); | ||
1818 | module_exit(sd_mod_exit); | ||
diff --git a/drivers/media/video/gspca/zc3xx-reg.h b/drivers/media/video/gspca/zc3xx-reg.h new file mode 100644 index 000000000000..f52e09c2cc19 --- /dev/null +++ b/drivers/media/video/gspca/zc3xx-reg.h | |||
@@ -0,0 +1,261 @@ | |||
1 | /* | ||
2 | * zc030x registers | ||
3 | * | ||
4 | * Copyright (c) 2008 Mauro Carvalho Chehab <mchehab@infradead.org> | ||
5 | * | ||
6 | * The register aliases used here came from this driver: | ||
7 | * http://zc0302.sourceforge.net/zc0302.php | ||
8 | * | ||
9 | * This code is placed under the terms of the GNU General Public License v2 | ||
10 | */ | ||
11 | |||
12 | /* Define the register map */ | ||
13 | #define ZC3XX_R000_SYSTEMCONTROL 0x0000 | ||
14 | #define ZC3XX_R001_SYSTEMOPERATING 0x0001 | ||
15 | |||
16 | /* Picture size */ | ||
17 | #define ZC3XX_R002_CLOCKSELECT 0x0002 | ||
18 | #define ZC3XX_R003_FRAMEWIDTHHIGH 0x0003 | ||
19 | #define ZC3XX_R004_FRAMEWIDTHLOW 0x0004 | ||
20 | #define ZC3XX_R005_FRAMEHEIGHTHIGH 0x0005 | ||
21 | #define ZC3XX_R006_FRAMEHEIGHTLOW 0x0006 | ||
22 | |||
23 | /* JPEG control */ | ||
24 | #define ZC3XX_R008_CLOCKSETTING 0x0008 | ||
25 | |||
26 | /* Test mode */ | ||
27 | #define ZC3XX_R00B_TESTMODECONTROL 0x000b | ||
28 | |||
29 | /* Frame retreiving */ | ||
30 | #define ZC3XX_R00C_LASTACQTIME 0x000c | ||
31 | #define ZC3XX_R00D_MONITORRES 0x000d | ||
32 | #define ZC3XX_R00E_TIMESTAMPHIGH 0x000e | ||
33 | #define ZC3XX_R00F_TIMESTAMPLOW 0x000f | ||
34 | #define ZC3XX_R018_FRAMELOST 0x0018 | ||
35 | #define ZC3XX_R019_AUTOADJUSTFPS 0x0019 | ||
36 | #define ZC3XX_R01A_LASTFRAMESTATE 0x001a | ||
37 | #define ZC3XX_R025_DATACOUNTER 0x0025 | ||
38 | |||
39 | /* Stream and sensor specific */ | ||
40 | #define ZC3XX_R010_CMOSSENSORSELECT 0x0010 | ||
41 | #define ZC3XX_R011_VIDEOSTATUS 0x0011 | ||
42 | #define ZC3XX_R012_VIDEOCONTROLFUNC 0x0012 | ||
43 | |||
44 | /* Horizontal and vertical synchros */ | ||
45 | #define ZC3XX_R01D_HSYNC_0 0x001d | ||
46 | #define ZC3XX_R01E_HSYNC_1 0x001e | ||
47 | #define ZC3XX_R01F_HSYNC_2 0x001f | ||
48 | #define ZC3XX_R020_HSYNC_3 0x0020 | ||
49 | |||
50 | /* Target picture size in byte */ | ||
51 | #define ZC3XX_R022_TARGETPICTSIZE_0 0x0022 | ||
52 | #define ZC3XX_R023_TARGETPICTSIZE_1 0x0023 | ||
53 | #define ZC3XX_R024_TARGETPICTSIZE_2 0x0024 | ||
54 | |||
55 | /* Audio registers */ | ||
56 | #define ZC3XX_R030_AUDIOADC 0x0030 | ||
57 | #define ZC3XX_R031_AUDIOSTREAMSTATUS 0x0031 | ||
58 | #define ZC3XX_R032_AUDIOSTATUS 0x0032 | ||
59 | |||
60 | /* Sensor interface */ | ||
61 | #define ZC3XX_R080_HBLANKHIGH 0x0080 | ||
62 | #define ZC3XX_R081_HBLANKLOW 0x0081 | ||
63 | #define ZC3XX_R082_RESETLEVELADDR 0x0082 | ||
64 | #define ZC3XX_R083_RGAINADDR 0x0083 | ||
65 | #define ZC3XX_R084_GGAINADDR 0x0084 | ||
66 | #define ZC3XX_R085_BGAINADDR 0x0085 | ||
67 | #define ZC3XX_R086_EXPTIMEHIGH 0x0086 | ||
68 | #define ZC3XX_R087_EXPTIMEMID 0x0087 | ||
69 | #define ZC3XX_R088_EXPTIMELOW 0x0088 | ||
70 | #define ZC3XX_R089_RESETBLACKHIGH 0x0089 | ||
71 | #define ZC3XX_R08A_RESETWHITEHIGH 0x008a | ||
72 | #define ZC3XX_R08B_I2CDEVICEADDR 0x008b | ||
73 | #define ZC3XX_R08C_I2CIDLEANDNACK 0x008c | ||
74 | #define ZC3XX_R08D_COMPABILITYMODE 0x008d | ||
75 | #define ZC3XX_R08E_COMPABILITYMODE2 0x008e | ||
76 | |||
77 | /* I2C control */ | ||
78 | #define ZC3XX_R090_I2CCOMMAND 0x0090 | ||
79 | #define ZC3XX_R091_I2CSTATUS 0x0091 | ||
80 | #define ZC3XX_R092_I2CADDRESSSELECT 0x0092 | ||
81 | #define ZC3XX_R093_I2CSETVALUE 0x0093 | ||
82 | #define ZC3XX_R094_I2CWRITEACK 0x0094 | ||
83 | #define ZC3XX_R095_I2CREAD 0x0095 | ||
84 | #define ZC3XX_R096_I2CREADACK 0x0096 | ||
85 | |||
86 | /* Window inside the sensor array */ | ||
87 | #define ZC3XX_R097_WINYSTARTHIGH 0x0097 | ||
88 | #define ZC3XX_R098_WINYSTARTLOW 0x0098 | ||
89 | #define ZC3XX_R099_WINXSTARTHIGH 0x0099 | ||
90 | #define ZC3XX_R09A_WINXSTARTLOW 0x009a | ||
91 | #define ZC3XX_R09B_WINHEIGHTHIGH 0x009b | ||
92 | #define ZC3XX_R09C_WINHEIGHTLOW 0x009c | ||
93 | #define ZC3XX_R09D_WINWIDTHHIGH 0x009d | ||
94 | #define ZC3XX_R09E_WINWIDTHLOW 0x009e | ||
95 | #define ZC3XX_R119_FIRSTYHIGH 0x0119 | ||
96 | #define ZC3XX_R11A_FIRSTYLOW 0x011a | ||
97 | #define ZC3XX_R11B_FIRSTXHIGH 0x011b | ||
98 | #define ZC3XX_R11C_FIRSTXLOW 0x011c | ||
99 | |||
100 | /* Max sensor array size */ | ||
101 | #define ZC3XX_R09F_MAXXHIGH 0x009f | ||
102 | #define ZC3XX_R0A0_MAXXLOW 0x00a0 | ||
103 | #define ZC3XX_R0A1_MAXYHIGH 0x00a1 | ||
104 | #define ZC3XX_R0A2_MAXYLOW 0x00a2 | ||
105 | #define ZC3XX_R0A3_EXPOSURETIMEHIGH 0x00a3 | ||
106 | #define ZC3XX_R0A4_EXPOSURETIMELOW 0x00a4 | ||
107 | #define ZC3XX_R0A5_EXPOSUREGAIN 0x00a5 | ||
108 | #define ZC3XX_R0A6_EXPOSUREBLACKLVL 0x00a6 | ||
109 | |||
110 | /* Other registers */ | ||
111 | #define ZC3XX_R100_OPERATIONMODE 0x0100 | ||
112 | #define ZC3XX_R101_SENSORCORRECTION 0x0101 | ||
113 | |||
114 | /* Gains */ | ||
115 | #define ZC3XX_R116_RGAIN 0x0116 | ||
116 | #define ZC3XX_R117_GGAIN 0x0117 | ||
117 | #define ZC3XX_R118_BGAIN 0x0118 | ||
118 | #define ZC3XX_R11D_GLOBALGAIN 0x011d | ||
119 | #define ZC3XX_R1A8_DIGITALGAIN 0x01a8 | ||
120 | #define ZC3XX_R1A9_DIGITALLIMITDIFF 0x01a9 | ||
121 | #define ZC3XX_R1AA_DIGITALGAINSTEP 0x01aa | ||
122 | |||
123 | /* Auto correction */ | ||
124 | #define ZC3XX_R180_AUTOCORRECTENABLE 0x0180 | ||
125 | #define ZC3XX_R181_WINXSTART 0x0181 | ||
126 | #define ZC3XX_R182_WINXWIDTH 0x0182 | ||
127 | #define ZC3XX_R183_WINXCENTER 0x0183 | ||
128 | #define ZC3XX_R184_WINYSTART 0x0184 | ||
129 | #define ZC3XX_R185_WINYWIDTH 0x0185 | ||
130 | #define ZC3XX_R186_WINYCENTER 0x0186 | ||
131 | |||
132 | /* Gain range */ | ||
133 | #define ZC3XX_R187_MAXGAIN 0x0187 | ||
134 | #define ZC3XX_R188_MINGAIN 0x0188 | ||
135 | |||
136 | /* Auto exposure and white balance */ | ||
137 | #define ZC3XX_R189_AWBSTATUS 0x0189 | ||
138 | #define ZC3XX_R18A_AWBFREEZE 0x018a | ||
139 | #define ZC3XX_R18B_AESTATUS 0x018b | ||
140 | #define ZC3XX_R18C_AEFREEZE 0x018c | ||
141 | #define ZC3XX_R18F_AEUNFREEZE 0x018f | ||
142 | #define ZC3XX_R190_EXPOSURELIMITHIGH 0x0190 | ||
143 | #define ZC3XX_R191_EXPOSURELIMITMID 0x0191 | ||
144 | #define ZC3XX_R192_EXPOSURELIMITLOW 0x0192 | ||
145 | #define ZC3XX_R195_ANTIFLICKERHIGH 0x0195 | ||
146 | #define ZC3XX_R196_ANTIFLICKERMID 0x0196 | ||
147 | #define ZC3XX_R197_ANTIFLICKERLOW 0x0197 | ||
148 | |||
149 | /* What is this ? */ | ||
150 | #define ZC3XX_R18D_YTARGET 0x018d | ||
151 | #define ZC3XX_R18E_RESETLVL 0x018e | ||
152 | |||
153 | /* Color */ | ||
154 | #define ZC3XX_R1A0_REDMEANAFTERAGC 0x01a0 | ||
155 | #define ZC3XX_R1A1_GREENMEANAFTERAGC 0x01a1 | ||
156 | #define ZC3XX_R1A2_BLUEMEANAFTERAGC 0x01a2 | ||
157 | #define ZC3XX_R1A3_REDMEANAFTERAWB 0x01a3 | ||
158 | #define ZC3XX_R1A4_GREENMEANAFTERAWB 0x01a4 | ||
159 | #define ZC3XX_R1A5_BLUEMEANAFTERAWB 0x01a5 | ||
160 | #define ZC3XX_R1A6_YMEANAFTERAE 0x01a6 | ||
161 | #define ZC3XX_R1A7_CALCGLOBALMEAN 0x01a7 | ||
162 | |||
163 | #define ZC3XX_R1A2_BLUEMEANAFTERAGC 0x01a2 | ||
164 | |||
165 | /* Matrixes */ | ||
166 | |||
167 | /* Color matrix is like : | ||
168 | R' = R * RGB00 + G * RGB01 + B * RGB02 + RGB03 | ||
169 | G' = R * RGB10 + G * RGB11 + B * RGB22 + RGB13 | ||
170 | B' = R * RGB20 + G * RGB21 + B * RGB12 + RGB23 | ||
171 | */ | ||
172 | #define ZC3XX_R10A_RGB00 0x010a | ||
173 | #define ZC3XX_R10B_RGB01 0x010b | ||
174 | #define ZC3XX_R10C_RGB02 0x010c | ||
175 | #define ZC3XX_R113_RGB03 0x0113 | ||
176 | #define ZC3XX_R10D_RGB10 0x010d | ||
177 | #define ZC3XX_R10E_RGB11 0x010e | ||
178 | #define ZC3XX_R10F_RGB12 0x010f | ||
179 | #define ZC3XX_R114_RGB13 0x0114 | ||
180 | #define ZC3XX_R110_RGB20 0x0110 | ||
181 | #define ZC3XX_R111_RGB21 0x0111 | ||
182 | #define ZC3XX_R112_RGB22 0x0112 | ||
183 | #define ZC3XX_R115_RGB23 0x0115 | ||
184 | |||
185 | /* Gamma matrix */ | ||
186 | #define ZC3XX_R120_GAMMA00 0x0120 | ||
187 | #define ZC3XX_R121_GAMMA01 0x0121 | ||
188 | #define ZC3XX_R122_GAMMA02 0x0122 | ||
189 | #define ZC3XX_R123_GAMMA03 0x0123 | ||
190 | #define ZC3XX_R124_GAMMA04 0x0124 | ||
191 | #define ZC3XX_R125_GAMMA05 0x0125 | ||
192 | #define ZC3XX_R126_GAMMA06 0x0126 | ||
193 | #define ZC3XX_R127_GAMMA07 0x0127 | ||
194 | #define ZC3XX_R128_GAMMA08 0x0128 | ||
195 | #define ZC3XX_R129_GAMMA09 0x0129 | ||
196 | #define ZC3XX_R12A_GAMMA0A 0x012a | ||
197 | #define ZC3XX_R12B_GAMMA0B 0x012b | ||
198 | #define ZC3XX_R12C_GAMMA0C 0x012c | ||
199 | #define ZC3XX_R12D_GAMMA0D 0x012d | ||
200 | #define ZC3XX_R12E_GAMMA0E 0x012e | ||
201 | #define ZC3XX_R12F_GAMMA0F 0x012f | ||
202 | #define ZC3XX_R130_GAMMA10 0x0130 | ||
203 | #define ZC3XX_R131_GAMMA11 0x0131 | ||
204 | #define ZC3XX_R132_GAMMA12 0x0132 | ||
205 | #define ZC3XX_R133_GAMMA13 0x0133 | ||
206 | #define ZC3XX_R134_GAMMA14 0x0134 | ||
207 | #define ZC3XX_R135_GAMMA15 0x0135 | ||
208 | #define ZC3XX_R136_GAMMA16 0x0136 | ||
209 | #define ZC3XX_R137_GAMMA17 0x0137 | ||
210 | #define ZC3XX_R138_GAMMA18 0x0138 | ||
211 | #define ZC3XX_R139_GAMMA19 0x0139 | ||
212 | #define ZC3XX_R13A_GAMMA1A 0x013a | ||
213 | #define ZC3XX_R13B_GAMMA1B 0x013b | ||
214 | #define ZC3XX_R13C_GAMMA1C 0x013c | ||
215 | #define ZC3XX_R13D_GAMMA1D 0x013d | ||
216 | #define ZC3XX_R13E_GAMMA1E 0x013e | ||
217 | #define ZC3XX_R13F_GAMMA1F 0x013f | ||
218 | |||
219 | /* Luminance gamma */ | ||
220 | #define ZC3XX_R140_YGAMMA00 0x0140 | ||
221 | #define ZC3XX_R141_YGAMMA01 0x0141 | ||
222 | #define ZC3XX_R142_YGAMMA02 0x0142 | ||
223 | #define ZC3XX_R143_YGAMMA03 0x0143 | ||
224 | #define ZC3XX_R144_YGAMMA04 0x0144 | ||
225 | #define ZC3XX_R145_YGAMMA05 0x0145 | ||
226 | #define ZC3XX_R146_YGAMMA06 0x0146 | ||
227 | #define ZC3XX_R147_YGAMMA07 0x0147 | ||
228 | #define ZC3XX_R148_YGAMMA08 0x0148 | ||
229 | #define ZC3XX_R149_YGAMMA09 0x0149 | ||
230 | #define ZC3XX_R14A_YGAMMA0A 0x014a | ||
231 | #define ZC3XX_R14B_YGAMMA0B 0x014b | ||
232 | #define ZC3XX_R14C_YGAMMA0C 0x014c | ||
233 | #define ZC3XX_R14D_YGAMMA0D 0x014d | ||
234 | #define ZC3XX_R14E_YGAMMA0E 0x014e | ||
235 | #define ZC3XX_R14F_YGAMMA0F 0x014f | ||
236 | #define ZC3XX_R150_YGAMMA10 0x0150 | ||
237 | #define ZC3XX_R151_YGAMMA11 0x0151 | ||
238 | |||
239 | #define ZC3XX_R1C5_SHARPNESSMODE 0x01c5 | ||
240 | #define ZC3XX_R1C6_SHARPNESS00 0x01c6 | ||
241 | #define ZC3XX_R1C7_SHARPNESS01 0x01c7 | ||
242 | #define ZC3XX_R1C8_SHARPNESS02 0x01c8 | ||
243 | #define ZC3XX_R1C9_SHARPNESS03 0x01c9 | ||
244 | #define ZC3XX_R1CA_SHARPNESS04 0x01ca | ||
245 | #define ZC3XX_R1CB_SHARPNESS05 0x01cb | ||
246 | |||
247 | /* Synchronization */ | ||
248 | #define ZC3XX_R190_SYNC00LOW 0x0190 | ||
249 | #define ZC3XX_R191_SYNC00MID 0x0191 | ||
250 | #define ZC3XX_R192_SYNC00HIGH 0x0192 | ||
251 | #define ZC3XX_R195_SYNC01LOW 0x0195 | ||
252 | #define ZC3XX_R196_SYNC01MID 0x0196 | ||
253 | #define ZC3XX_R197_SYNC01HIGH 0x0197 | ||
254 | |||
255 | /* Dead pixels */ | ||
256 | #define ZC3XX_R250_DEADPIXELSMODE 0x0250 | ||
257 | |||
258 | /* EEPROM */ | ||
259 | #define ZC3XX_R300_EEPROMCONFIG 0x0300 | ||
260 | #define ZC3XX_R301_EEPROMACCESS 0x0301 | ||
261 | #define ZC3XX_R302_EEPROMSTATUS 0x0302 | ||
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c new file mode 100644 index 000000000000..b761b11c5c6a --- /dev/null +++ b/drivers/media/video/gspca/zc3xx.c | |||
@@ -0,0 +1,7623 @@ | |||
1 | /* | ||
2 | * Z-Star/Vimicro zc301/zc302p/vc30x library | ||
3 | * Copyright (C) 2004 2005 2006 Michel Xhaard | ||
4 | * mxhaard@magic.fr | ||
5 | * | ||
6 | * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | #define MODULE_NAME "zc3xx" | ||
24 | |||
25 | #include "gspca.h" | ||
26 | |||
27 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) | ||
28 | static const char version[] = "2.1.7"; | ||
29 | |||
30 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>, " | ||
31 | "Serge A. Suchkov <Serge.A.S@tochka.ru>"); | ||
32 | MODULE_DESCRIPTION("GSPCA ZC03xx/VC3xx USB Camera Driver"); | ||
33 | MODULE_LICENSE("GPL"); | ||
34 | |||
35 | static int force_sensor = -1; | ||
36 | |||
37 | #include "jpeg.h" | ||
38 | #include "zc3xx-reg.h" | ||
39 | |||
40 | /* specific webcam descriptor */ | ||
41 | struct sd { | ||
42 | struct gspca_dev gspca_dev; /* !! must be the first item */ | ||
43 | |||
44 | __u8 brightness; | ||
45 | __u8 contrast; | ||
46 | __u8 gamma; | ||
47 | __u8 autogain; | ||
48 | __u8 lightfreq; | ||
49 | __u8 sharpness; | ||
50 | |||
51 | char qindex; | ||
52 | char sensor; /* Type of image sensor chip */ | ||
53 | /* !! values used in different tables */ | ||
54 | #define SENSOR_CS2102 0 | ||
55 | #define SENSOR_CS2102K 1 | ||
56 | #define SENSOR_GC0305 2 | ||
57 | #define SENSOR_HDCS2020 3 | ||
58 | #define SENSOR_HDCS2020b 4 | ||
59 | #define SENSOR_HV7131B 5 | ||
60 | #define SENSOR_HV7131C 6 | ||
61 | #define SENSOR_ICM105A 7 | ||
62 | #define SENSOR_MC501CB 8 | ||
63 | #define SENSOR_OV7620 9 | ||
64 | /*#define SENSOR_OV7648 9 - same values */ | ||
65 | #define SENSOR_OV7630C 10 | ||
66 | #define SENSOR_PAS106 11 | ||
67 | #define SENSOR_PB0330 12 | ||
68 | #define SENSOR_PO2030 13 | ||
69 | #define SENSOR_TAS5130CK 14 | ||
70 | #define SENSOR_TAS5130CXX 15 | ||
71 | #define SENSOR_TAS5130C_VF0250 16 | ||
72 | #define SENSOR_MAX 17 | ||
73 | unsigned short chip_revision; | ||
74 | }; | ||
75 | |||
76 | /* V4L2 controls supported by the driver */ | ||
77 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
78 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
79 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
80 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
81 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
82 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
83 | static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val); | ||
84 | static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val); | ||
85 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | ||
86 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | ||
87 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); | ||
88 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | ||
89 | |||
90 | static struct ctrl sd_ctrls[] = { | ||
91 | #define SD_BRIGHTNESS 0 | ||
92 | { | ||
93 | { | ||
94 | .id = V4L2_CID_BRIGHTNESS, | ||
95 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
96 | .name = "Brightness", | ||
97 | .minimum = 0, | ||
98 | .maximum = 255, | ||
99 | .step = 1, | ||
100 | .default_value = 128, | ||
101 | }, | ||
102 | .set = sd_setbrightness, | ||
103 | .get = sd_getbrightness, | ||
104 | }, | ||
105 | #define SD_CONTRAST 1 | ||
106 | { | ||
107 | { | ||
108 | .id = V4L2_CID_CONTRAST, | ||
109 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
110 | .name = "Contrast", | ||
111 | .minimum = 0, | ||
112 | .maximum = 256, | ||
113 | .step = 1, | ||
114 | .default_value = 128, | ||
115 | }, | ||
116 | .set = sd_setcontrast, | ||
117 | .get = sd_getcontrast, | ||
118 | }, | ||
119 | #define SD_GAMMA 2 | ||
120 | { | ||
121 | { | ||
122 | .id = V4L2_CID_GAMMA, | ||
123 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
124 | .name = "Gamma", | ||
125 | .minimum = 1, | ||
126 | .maximum = 6, | ||
127 | .step = 1, | ||
128 | .default_value = 4, | ||
129 | }, | ||
130 | .set = sd_setgamma, | ||
131 | .get = sd_getgamma, | ||
132 | }, | ||
133 | #define SD_AUTOGAIN 3 | ||
134 | { | ||
135 | { | ||
136 | .id = V4L2_CID_AUTOGAIN, | ||
137 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
138 | .name = "Auto Gain", | ||
139 | .minimum = 0, | ||
140 | .maximum = 1, | ||
141 | .step = 1, | ||
142 | .default_value = 1, | ||
143 | }, | ||
144 | .set = sd_setautogain, | ||
145 | .get = sd_getautogain, | ||
146 | }, | ||
147 | #define SD_FREQ 4 | ||
148 | { | ||
149 | { | ||
150 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | ||
151 | .type = V4L2_CTRL_TYPE_MENU, | ||
152 | .name = "Light frequency filter", | ||
153 | .minimum = 0, | ||
154 | .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ | ||
155 | .step = 1, | ||
156 | .default_value = 1, | ||
157 | }, | ||
158 | .set = sd_setfreq, | ||
159 | .get = sd_getfreq, | ||
160 | }, | ||
161 | #define SD_SHARPNESS 5 | ||
162 | { | ||
163 | { | ||
164 | .id = V4L2_CID_SHARPNESS, | ||
165 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
166 | .name = "Sharpness", | ||
167 | .minimum = 0, | ||
168 | .maximum = 3, | ||
169 | .step = 1, | ||
170 | .default_value = 2, | ||
171 | }, | ||
172 | .set = sd_setsharpness, | ||
173 | .get = sd_getsharpness, | ||
174 | }, | ||
175 | }; | ||
176 | |||
177 | static struct v4l2_pix_format vga_mode[] = { | ||
178 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
179 | .bytesperline = 320, | ||
180 | .sizeimage = 320 * 240 * 3 / 8 + 590, | ||
181 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
182 | .priv = 1}, | ||
183 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
184 | .bytesperline = 640, | ||
185 | .sizeimage = 640 * 480 * 3 / 8 + 590, | ||
186 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
187 | .priv = 0}, | ||
188 | }; | ||
189 | |||
190 | static struct v4l2_pix_format sif_mode[] = { | ||
191 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
192 | .bytesperline = 176, | ||
193 | .sizeimage = 176 * 144 * 3 / 8 + 590, | ||
194 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
195 | .priv = 1}, | ||
196 | {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
197 | .bytesperline = 352, | ||
198 | .sizeimage = 352 * 288 * 3 / 8 + 590, | ||
199 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
200 | .priv = 0}, | ||
201 | }; | ||
202 | |||
203 | /* usb exchanges */ | ||
204 | struct usb_action { | ||
205 | __u8 req; | ||
206 | __u8 val; | ||
207 | __u16 idx; | ||
208 | }; | ||
209 | |||
210 | static const struct usb_action cs2102_Initial[] = { | ||
211 | {0xa1, 0x01, 0x0008}, | ||
212 | {0xa1, 0x01, 0x0008}, | ||
213 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
214 | {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, | ||
215 | {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, | ||
216 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
217 | {0xa0, 0x20, ZC3XX_R080_HBLANKHIGH}, | ||
218 | {0xa0, 0x21, ZC3XX_R081_HBLANKLOW}, | ||
219 | {0xa0, 0x30, ZC3XX_R083_RGAINADDR}, | ||
220 | {0xa0, 0x31, ZC3XX_R084_GGAINADDR}, | ||
221 | {0xa0, 0x32, ZC3XX_R085_BGAINADDR}, | ||
222 | {0xa0, 0x23, ZC3XX_R086_EXPTIMEHIGH}, | ||
223 | {0xa0, 0x24, ZC3XX_R087_EXPTIMEMID}, | ||
224 | {0xa0, 0x25, ZC3XX_R088_EXPTIMELOW}, | ||
225 | {0xa0, 0xb3, ZC3XX_R08B_I2CDEVICEADDR}, | ||
226 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ | ||
227 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
228 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
229 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
230 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
231 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
232 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
233 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, | ||
234 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, | ||
235 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, | ||
236 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, | ||
237 | {0xaa, 0x02, 0x0008}, | ||
238 | {0xaa, 0x03, 0x0000}, | ||
239 | {0xaa, 0x11, 0x0000}, | ||
240 | {0xaa, 0x12, 0x0089}, | ||
241 | {0xaa, 0x13, 0x0000}, | ||
242 | {0xaa, 0x14, 0x00e9}, | ||
243 | {0xaa, 0x20, 0x0000}, | ||
244 | {0xaa, 0x22, 0x0000}, | ||
245 | {0xaa, 0x0b, 0x0004}, | ||
246 | {0xaa, 0x30, 0x0030}, | ||
247 | {0xaa, 0x31, 0x0030}, | ||
248 | {0xaa, 0x32, 0x0030}, | ||
249 | {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, | ||
250 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
251 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
252 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
253 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
254 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
255 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
256 | {0xa0, 0x10, 0x01ae}, | ||
257 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
258 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
259 | {0xa0, 0x68, ZC3XX_R18D_YTARGET}, | ||
260 | {0xa0, 0x00, 0x01ad}, | ||
261 | {0xa1, 0x01, 0x0002}, | ||
262 | {0xa1, 0x01, 0x0008}, | ||
263 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ | ||
264 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
265 | {0xa1, 0x01, 0x01c8}, | ||
266 | {0xa1, 0x01, 0x01c9}, | ||
267 | {0xa1, 0x01, 0x01ca}, | ||
268 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
269 | {0xa0, 0x24, ZC3XX_R120_GAMMA00}, /* gamma 5 */ | ||
270 | {0xa0, 0x44, ZC3XX_R121_GAMMA01}, | ||
271 | {0xa0, 0x64, ZC3XX_R122_GAMMA02}, | ||
272 | {0xa0, 0x84, ZC3XX_R123_GAMMA03}, | ||
273 | {0xa0, 0x9d, ZC3XX_R124_GAMMA04}, | ||
274 | {0xa0, 0xb2, ZC3XX_R125_GAMMA05}, | ||
275 | {0xa0, 0xc4, ZC3XX_R126_GAMMA06}, | ||
276 | {0xa0, 0xd3, ZC3XX_R127_GAMMA07}, | ||
277 | {0xa0, 0xe0, ZC3XX_R128_GAMMA08}, | ||
278 | {0xa0, 0xeb, ZC3XX_R129_GAMMA09}, | ||
279 | {0xa0, 0xf4, ZC3XX_R12A_GAMMA0A}, | ||
280 | {0xa0, 0xfb, ZC3XX_R12B_GAMMA0B}, | ||
281 | {0xa0, 0xff, ZC3XX_R12C_GAMMA0C}, | ||
282 | {0xa0, 0xff, ZC3XX_R12D_GAMMA0D}, | ||
283 | {0xa0, 0xff, ZC3XX_R12E_GAMMA0E}, | ||
284 | {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, | ||
285 | {0xa0, 0x18, ZC3XX_R130_GAMMA10}, | ||
286 | {0xa0, 0x20, ZC3XX_R131_GAMMA11}, | ||
287 | {0xa0, 0x20, ZC3XX_R132_GAMMA12}, | ||
288 | {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, | ||
289 | {0xa0, 0x16, ZC3XX_R134_GAMMA14}, | ||
290 | {0xa0, 0x13, ZC3XX_R135_GAMMA15}, | ||
291 | {0xa0, 0x10, ZC3XX_R136_GAMMA16}, | ||
292 | {0xa0, 0x0e, ZC3XX_R137_GAMMA17}, | ||
293 | {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, | ||
294 | {0xa0, 0x09, ZC3XX_R139_GAMMA19}, | ||
295 | {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, | ||
296 | {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, | ||
297 | {0xa0, 0x00, ZC3XX_R13C_GAMMA1C}, | ||
298 | {0xa0, 0x00, ZC3XX_R13D_GAMMA1D}, | ||
299 | {0xa0, 0x00, ZC3XX_R13E_GAMMA1E}, | ||
300 | {0xa0, 0x01, ZC3XX_R13F_GAMMA1F}, | ||
301 | {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ | ||
302 | {0xa0, 0xf4, ZC3XX_R10B_RGB01}, | ||
303 | {0xa0, 0xf4, ZC3XX_R10C_RGB02}, | ||
304 | {0xa0, 0xf4, ZC3XX_R10D_RGB10}, | ||
305 | {0xa0, 0x58, ZC3XX_R10E_RGB11}, | ||
306 | {0xa0, 0xf4, ZC3XX_R10F_RGB12}, | ||
307 | {0xa0, 0xf4, ZC3XX_R110_RGB20}, | ||
308 | {0xa0, 0xf4, ZC3XX_R111_RGB21}, | ||
309 | {0xa0, 0x58, ZC3XX_R112_RGB22}, | ||
310 | {0xa1, 0x01, 0x0180}, | ||
311 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
312 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
313 | {0xaa, 0x23, 0x0001}, | ||
314 | {0xaa, 0x24, 0x0055}, | ||
315 | {0xaa, 0x25, 0x00cc}, | ||
316 | {0xaa, 0x21, 0x003f}, | ||
317 | {0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH}, | ||
318 | {0xa0, 0xab, ZC3XX_R191_EXPOSURELIMITMID}, | ||
319 | {0xa0, 0x98, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
320 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
321 | {0xa0, 0x30, ZC3XX_R196_ANTIFLICKERMID}, | ||
322 | {0xa0, 0xd4, ZC3XX_R197_ANTIFLICKERLOW}, | ||
323 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, | ||
324 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, | ||
325 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
326 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
327 | {0xa0, 0x39, ZC3XX_R01D_HSYNC_0}, | ||
328 | {0xa0, 0x70, ZC3XX_R01E_HSYNC_1}, | ||
329 | {0xa0, 0xb0, ZC3XX_R01F_HSYNC_2}, | ||
330 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, | ||
331 | {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
332 | {0xa1, 0x01, 0x0180}, | ||
333 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
334 | {0xa0, 0x40, ZC3XX_R116_RGAIN}, | ||
335 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, | ||
336 | {0xa0, 0x40, ZC3XX_R118_BGAIN}, | ||
337 | {} | ||
338 | }; | ||
339 | |||
340 | static const struct usb_action cs2102_InitialScale[] = { | ||
341 | {0xa1, 0x01, 0x0008}, | ||
342 | {0xa1, 0x01, 0x0008}, | ||
343 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
344 | {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, | ||
345 | {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, | ||
346 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
347 | {0xa0, 0x20, ZC3XX_R080_HBLANKHIGH}, | ||
348 | {0xa0, 0x21, ZC3XX_R081_HBLANKLOW}, | ||
349 | {0xa0, 0x30, ZC3XX_R083_RGAINADDR}, | ||
350 | {0xa0, 0x31, ZC3XX_R084_GGAINADDR}, | ||
351 | {0xa0, 0x32, ZC3XX_R085_BGAINADDR}, | ||
352 | {0xa0, 0x23, ZC3XX_R086_EXPTIMEHIGH}, | ||
353 | {0xa0, 0x24, ZC3XX_R087_EXPTIMEMID}, | ||
354 | {0xa0, 0x25, ZC3XX_R088_EXPTIMELOW}, | ||
355 | {0xa0, 0xb3, ZC3XX_R08B_I2CDEVICEADDR}, | ||
356 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ | ||
357 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
358 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
359 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
360 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
361 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
362 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
363 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, | ||
364 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, | ||
365 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, | ||
366 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, | ||
367 | {0xaa, 0x02, 0x0008}, | ||
368 | {0xaa, 0x03, 0x0000}, | ||
369 | {0xaa, 0x11, 0x0001}, | ||
370 | {0xaa, 0x12, 0x0087}, | ||
371 | {0xaa, 0x13, 0x0001}, | ||
372 | {0xaa, 0x14, 0x00e7}, | ||
373 | {0xaa, 0x20, 0x0000}, | ||
374 | {0xaa, 0x22, 0x0000}, | ||
375 | {0xaa, 0x0b, 0x0004}, | ||
376 | {0xaa, 0x30, 0x0030}, | ||
377 | {0xaa, 0x31, 0x0030}, | ||
378 | {0xaa, 0x32, 0x0030}, | ||
379 | {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, | ||
380 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
381 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
382 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
383 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
384 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
385 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
386 | {0xa0, 0x15, 0x01ae}, | ||
387 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
388 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
389 | {0xa0, 0x68, ZC3XX_R18D_YTARGET}, | ||
390 | {0xa0, 0x00, 0x01ad}, | ||
391 | {0xa1, 0x01, 0x0002}, | ||
392 | {0xa1, 0x01, 0x0008}, | ||
393 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ | ||
394 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
395 | {0xa1, 0x01, 0x01c8}, | ||
396 | {0xa1, 0x01, 0x01c9}, | ||
397 | {0xa1, 0x01, 0x01ca}, | ||
398 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
399 | {0xa0, 0x24, ZC3XX_R120_GAMMA00}, /* gamma 5 */ | ||
400 | {0xa0, 0x44, ZC3XX_R121_GAMMA01}, | ||
401 | {0xa0, 0x64, ZC3XX_R122_GAMMA02}, | ||
402 | {0xa0, 0x84, ZC3XX_R123_GAMMA03}, | ||
403 | {0xa0, 0x9d, ZC3XX_R124_GAMMA04}, | ||
404 | {0xa0, 0xb2, ZC3XX_R125_GAMMA05}, | ||
405 | {0xa0, 0xc4, ZC3XX_R126_GAMMA06}, | ||
406 | {0xa0, 0xd3, ZC3XX_R127_GAMMA07}, | ||
407 | {0xa0, 0xe0, ZC3XX_R128_GAMMA08}, | ||
408 | {0xa0, 0xeb, ZC3XX_R129_GAMMA09}, | ||
409 | {0xa0, 0xf4, ZC3XX_R12A_GAMMA0A}, | ||
410 | {0xa0, 0xfb, ZC3XX_R12B_GAMMA0B}, | ||
411 | {0xa0, 0xff, ZC3XX_R12C_GAMMA0C}, | ||
412 | {0xa0, 0xff, ZC3XX_R12D_GAMMA0D}, | ||
413 | {0xa0, 0xff, ZC3XX_R12E_GAMMA0E}, | ||
414 | {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, | ||
415 | {0xa0, 0x18, ZC3XX_R130_GAMMA10}, | ||
416 | {0xa0, 0x20, ZC3XX_R131_GAMMA11}, | ||
417 | {0xa0, 0x20, ZC3XX_R132_GAMMA12}, | ||
418 | {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, | ||
419 | {0xa0, 0x16, ZC3XX_R134_GAMMA14}, | ||
420 | {0xa0, 0x13, ZC3XX_R135_GAMMA15}, | ||
421 | {0xa0, 0x10, ZC3XX_R136_GAMMA16}, | ||
422 | {0xa0, 0x0e, ZC3XX_R137_GAMMA17}, | ||
423 | {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, | ||
424 | {0xa0, 0x09, ZC3XX_R139_GAMMA19}, | ||
425 | {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, | ||
426 | {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, | ||
427 | {0xa0, 0x00, ZC3XX_R13C_GAMMA1C}, | ||
428 | {0xa0, 0x00, ZC3XX_R13D_GAMMA1D}, | ||
429 | {0xa0, 0x00, ZC3XX_R13E_GAMMA1E}, | ||
430 | {0xa0, 0x01, ZC3XX_R13F_GAMMA1F}, | ||
431 | {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ | ||
432 | {0xa0, 0xf4, ZC3XX_R10B_RGB01}, | ||
433 | {0xa0, 0xf4, ZC3XX_R10C_RGB02}, | ||
434 | {0xa0, 0xf4, ZC3XX_R10D_RGB10}, | ||
435 | {0xa0, 0x58, ZC3XX_R10E_RGB11}, | ||
436 | {0xa0, 0xf4, ZC3XX_R10F_RGB12}, | ||
437 | {0xa0, 0xf4, ZC3XX_R110_RGB20}, | ||
438 | {0xa0, 0xf4, ZC3XX_R111_RGB21}, | ||
439 | {0xa0, 0x58, ZC3XX_R112_RGB22}, | ||
440 | {0xa1, 0x01, 0x0180}, | ||
441 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
442 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
443 | {0xaa, 0x23, 0x0000}, | ||
444 | {0xaa, 0x24, 0x00aa}, | ||
445 | {0xaa, 0x25, 0x00e6}, | ||
446 | {0xaa, 0x21, 0x003f}, | ||
447 | {0xa0, 0x01, ZC3XX_R190_EXPOSURELIMITHIGH}, | ||
448 | {0xa0, 0x55, ZC3XX_R191_EXPOSURELIMITMID}, | ||
449 | {0xa0, 0xcc, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
450 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
451 | {0xa0, 0x18, ZC3XX_R196_ANTIFLICKERMID}, | ||
452 | {0xa0, 0x6a, ZC3XX_R197_ANTIFLICKERLOW}, | ||
453 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, | ||
454 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, | ||
455 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
456 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
457 | {0xa0, 0x3f, ZC3XX_R01D_HSYNC_0}, | ||
458 | {0xa0, 0xa5, ZC3XX_R01E_HSYNC_1}, | ||
459 | {0xa0, 0xf0, ZC3XX_R01F_HSYNC_2}, | ||
460 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, | ||
461 | {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
462 | {0xa1, 0x01, 0x0180}, | ||
463 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
464 | {0xa0, 0x40, ZC3XX_R116_RGAIN}, | ||
465 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, | ||
466 | {0xa0, 0x40, ZC3XX_R118_BGAIN}, | ||
467 | {} | ||
468 | }; | ||
469 | static const struct usb_action cs2102_50HZ[] = { | ||
470 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
471 | {0xaa, 0x0f, 0x008c}, /* 00,0f,8c,aa */ | ||
472 | {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ | ||
473 | {0xaa, 0x04, 0x00ac}, /* 00,04,ac,aa */ | ||
474 | {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */ | ||
475 | {0xaa, 0x11, 0x00ac}, /* 00,11,ac,aa */ | ||
476 | {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ | ||
477 | {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ | ||
478 | {0xaa, 0x1d, 0x00ac}, /* 00,1d,ac,aa */ | ||
479 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
480 | {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */ | ||
481 | {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ | ||
482 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
483 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
484 | {0xa0, 0x42, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,42,cc */ | ||
485 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
486 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
487 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ | ||
488 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ | ||
489 | {0xa0, 0x8c, ZC3XX_R01D_HSYNC_0}, /* 00,1d,8c,cc */ | ||
490 | {0xa0, 0xb0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,b0,cc */ | ||
491 | {0xa0, 0xd0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,d0,cc */ | ||
492 | {} | ||
493 | }; | ||
494 | static const struct usb_action cs2102_50HZScale[] = { | ||
495 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
496 | {0xaa, 0x0f, 0x0093}, /* 00,0f,93,aa */ | ||
497 | {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ | ||
498 | {0xaa, 0x04, 0x00a1}, /* 00,04,a1,aa */ | ||
499 | {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */ | ||
500 | {0xaa, 0x11, 0x00a1}, /* 00,11,a1,aa */ | ||
501 | {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ | ||
502 | {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ | ||
503 | {0xaa, 0x1d, 0x00a1}, /* 00,1d,a1,aa */ | ||
504 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
505 | {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */ | ||
506 | {0xa0, 0xf7, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f7,cc */ | ||
507 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
508 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
509 | {0xa0, 0x83, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,83,cc */ | ||
510 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
511 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
512 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ | ||
513 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ | ||
514 | {0xa0, 0x93, ZC3XX_R01D_HSYNC_0}, /* 00,1d,93,cc */ | ||
515 | {0xa0, 0xb0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,b0,cc */ | ||
516 | {0xa0, 0xd0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,d0,cc */ | ||
517 | {} | ||
518 | }; | ||
519 | static const struct usb_action cs2102_60HZ[] = { | ||
520 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
521 | {0xaa, 0x0f, 0x005d}, /* 00,0f,5d,aa */ | ||
522 | {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ | ||
523 | {0xaa, 0x04, 0x00aa}, /* 00,04,aa,aa */ | ||
524 | {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */ | ||
525 | {0xaa, 0x11, 0x00aa}, /* 00,11,aa,aa */ | ||
526 | {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ | ||
527 | {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ | ||
528 | {0xaa, 0x1d, 0x00aa}, /* 00,1d,aa,aa */ | ||
529 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
530 | {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */ | ||
531 | {0xa0, 0xe4, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e4,cc */ | ||
532 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
533 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
534 | {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3a,cc */ | ||
535 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
536 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
537 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ | ||
538 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ | ||
539 | {0xa0, 0x5d, ZC3XX_R01D_HSYNC_0}, /* 00,1d,5d,cc */ | ||
540 | {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */ | ||
541 | {0xa0, 0xd0, 0x00c8}, /* 00,c8,d0,cc */ | ||
542 | {} | ||
543 | }; | ||
544 | static const struct usb_action cs2102_60HZScale[] = { | ||
545 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
546 | {0xaa, 0x0f, 0x00b7}, /* 00,0f,b7,aa */ | ||
547 | {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ | ||
548 | {0xaa, 0x04, 0x00be}, /* 00,04,be,aa */ | ||
549 | {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */ | ||
550 | {0xaa, 0x11, 0x00be}, /* 00,11,be,aa */ | ||
551 | {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ | ||
552 | {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ | ||
553 | {0xaa, 0x1d, 0x00be}, /* 00,1d,be,aa */ | ||
554 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
555 | {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */ | ||
556 | {0xa0, 0xfc, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,fc,cc */ | ||
557 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
558 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
559 | {0xa0, 0x69, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,69,cc */ | ||
560 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
561 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
562 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ | ||
563 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ | ||
564 | {0xa0, 0xb7, ZC3XX_R01D_HSYNC_0}, /* 00,1d,b7,cc */ | ||
565 | {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */ | ||
566 | {0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */ | ||
567 | {} | ||
568 | }; | ||
569 | static const struct usb_action cs2102_NoFliker[] = { | ||
570 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
571 | {0xaa, 0x0f, 0x0059}, /* 00,0f,59,aa */ | ||
572 | {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ | ||
573 | {0xaa, 0x04, 0x0080}, /* 00,04,80,aa */ | ||
574 | {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */ | ||
575 | {0xaa, 0x11, 0x0080}, /* 00,11,80,aa */ | ||
576 | {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ | ||
577 | {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ | ||
578 | {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */ | ||
579 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
580 | {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */ | ||
581 | {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ | ||
582 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
583 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
584 | {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ | ||
585 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
586 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
587 | {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ | ||
588 | {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ | ||
589 | {0xa0, 0x59, ZC3XX_R01D_HSYNC_0}, /* 00,1d,59,cc */ | ||
590 | {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */ | ||
591 | {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */ | ||
592 | {} | ||
593 | }; | ||
594 | static const struct usb_action cs2102_NoFlikerScale[] = { | ||
595 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
596 | {0xaa, 0x0f, 0x0059}, /* 00,0f,59,aa */ | ||
597 | {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ | ||
598 | {0xaa, 0x04, 0x0080}, /* 00,04,80,aa */ | ||
599 | {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */ | ||
600 | {0xaa, 0x11, 0x0080}, /* 00,11,80,aa */ | ||
601 | {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ | ||
602 | {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ | ||
603 | {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */ | ||
604 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
605 | {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */ | ||
606 | {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ | ||
607 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
608 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
609 | {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ | ||
610 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
611 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
612 | {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ | ||
613 | {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ | ||
614 | {0xa0, 0x59, ZC3XX_R01D_HSYNC_0}, /* 00,1d,59,cc */ | ||
615 | {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */ | ||
616 | {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */ | ||
617 | {} | ||
618 | }; | ||
619 | |||
620 | /* CS2102_KOCOM */ | ||
621 | static const struct usb_action cs2102K_Initial[] = { | ||
622 | {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT}, | ||
623 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | ||
624 | {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT}, | ||
625 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
626 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
627 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
628 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
629 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
630 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
631 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
632 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, | ||
633 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, | ||
634 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, | ||
635 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, | ||
636 | {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, | ||
637 | {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, | ||
638 | {0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR}, | ||
639 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
640 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
641 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
642 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
643 | {0xa0, 0x0a, ZC3XX_R092_I2CADDRESSSELECT}, | ||
644 | {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, | ||
645 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
646 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
647 | {0xa0, 0x0b, ZC3XX_R092_I2CADDRESSSELECT}, | ||
648 | {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, | ||
649 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
650 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
651 | {0xa0, 0x0c, ZC3XX_R092_I2CADDRESSSELECT}, | ||
652 | {0xa0, 0x7c, ZC3XX_R093_I2CSETVALUE}, | ||
653 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
654 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
655 | {0xa0, 0x0d, ZC3XX_R092_I2CADDRESSSELECT}, | ||
656 | {0xa0, 0xa3, ZC3XX_R093_I2CSETVALUE}, | ||
657 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
658 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
659 | {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT}, | ||
660 | {0xa0, 0xfb, ZC3XX_R093_I2CSETVALUE}, | ||
661 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
662 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
663 | {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT}, | ||
664 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
665 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
666 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
667 | {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT}, | ||
668 | {0xa0, 0x03, ZC3XX_R093_I2CSETVALUE}, | ||
669 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
670 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
671 | {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT}, | ||
672 | {0xa0, 0x08, ZC3XX_R093_I2CSETVALUE}, | ||
673 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
674 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
675 | {0xa0, 0x0e, ZC3XX_R092_I2CADDRESSSELECT}, | ||
676 | {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, | ||
677 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
678 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
679 | {0xa0, 0x0f, ZC3XX_R092_I2CADDRESSSELECT}, | ||
680 | {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, | ||
681 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
682 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
683 | {0xa0, 0x10, ZC3XX_R092_I2CADDRESSSELECT}, | ||
684 | {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, | ||
685 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
686 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
687 | {0xa0, 0x11, ZC3XX_R092_I2CADDRESSSELECT}, | ||
688 | {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, | ||
689 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
690 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
691 | {0xa0, 0x12, ZC3XX_R092_I2CADDRESSSELECT}, | ||
692 | {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, | ||
693 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
694 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
695 | {0xa0, 0x15, ZC3XX_R092_I2CADDRESSSELECT}, | ||
696 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
697 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
698 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
699 | {0xa0, 0x16, ZC3XX_R092_I2CADDRESSSELECT}, | ||
700 | {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE}, | ||
701 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
702 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
703 | {0xa0, 0x17, ZC3XX_R092_I2CADDRESSSELECT}, | ||
704 | {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE}, | ||
705 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
706 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
707 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
708 | {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, | ||
709 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
710 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
711 | {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, | ||
712 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
713 | {0xa0, 0x78, ZC3XX_R18D_YTARGET}, | ||
714 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
715 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
716 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
717 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
718 | {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, | ||
719 | {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, | ||
720 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
721 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
722 | {0xa0, 0x00, 0x01ad}, | ||
723 | {0xa0, 0x01, 0x01b1}, | ||
724 | {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
725 | {0xa0, 0x60, ZC3XX_R116_RGAIN}, | ||
726 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, | ||
727 | {0xa0, 0x4c, ZC3XX_R118_BGAIN}, | ||
728 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ | ||
729 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
730 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
731 | {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */ | ||
732 | {0xa0, 0x38, ZC3XX_R121_GAMMA01}, | ||
733 | {0xa0, 0x59, ZC3XX_R122_GAMMA02}, | ||
734 | {0xa0, 0x79, ZC3XX_R123_GAMMA03}, | ||
735 | {0xa0, 0x92, ZC3XX_R124_GAMMA04}, | ||
736 | {0xa0, 0xa7, ZC3XX_R125_GAMMA05}, | ||
737 | {0xa0, 0xb9, ZC3XX_R126_GAMMA06}, | ||
738 | {0xa0, 0xc8, ZC3XX_R127_GAMMA07}, | ||
739 | {0xa0, 0xd4, ZC3XX_R128_GAMMA08}, | ||
740 | {0xa0, 0xdf, ZC3XX_R129_GAMMA09}, | ||
741 | {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A}, | ||
742 | {0xa0, 0xee, ZC3XX_R12B_GAMMA0B}, | ||
743 | {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C}, | ||
744 | {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D}, | ||
745 | {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E}, | ||
746 | {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, | ||
747 | {0xa0, 0x26, ZC3XX_R130_GAMMA10}, | ||
748 | {0xa0, 0x22, ZC3XX_R131_GAMMA11}, | ||
749 | {0xa0, 0x20, ZC3XX_R132_GAMMA12}, | ||
750 | {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, | ||
751 | {0xa0, 0x16, ZC3XX_R134_GAMMA14}, | ||
752 | {0xa0, 0x13, ZC3XX_R135_GAMMA15}, | ||
753 | {0xa0, 0x10, ZC3XX_R136_GAMMA16}, | ||
754 | {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, | ||
755 | {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, | ||
756 | {0xa0, 0x09, ZC3XX_R139_GAMMA19}, | ||
757 | {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, | ||
758 | {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, | ||
759 | {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, | ||
760 | {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, | ||
761 | {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, | ||
762 | {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, | ||
763 | {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ | ||
764 | {0xa0, 0xf4, ZC3XX_R10B_RGB01}, | ||
765 | {0xa0, 0xf4, ZC3XX_R10C_RGB02}, | ||
766 | {0xa0, 0xf4, ZC3XX_R10D_RGB10}, | ||
767 | {0xa0, 0x58, ZC3XX_R10E_RGB11}, | ||
768 | {0xa0, 0xf4, ZC3XX_R10F_RGB12}, | ||
769 | {0xa0, 0xf4, ZC3XX_R110_RGB20}, | ||
770 | {0xa0, 0xf4, ZC3XX_R111_RGB21}, | ||
771 | {0xa0, 0x58, ZC3XX_R112_RGB22}, | ||
772 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
773 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
774 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
775 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
776 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
777 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
778 | {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, | ||
779 | {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE}, | ||
780 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
781 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
782 | {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, | ||
783 | {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, | ||
784 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
785 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
786 | {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, | ||
787 | {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, | ||
788 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
789 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
790 | {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, | ||
791 | {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE}, | ||
792 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
793 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
794 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
795 | {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, | ||
796 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
797 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
798 | {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, | ||
799 | {0xa0, 0x22, ZC3XX_R0A4_EXPOSURETIMELOW}, | ||
800 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, | ||
801 | {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, | ||
802 | {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
803 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
804 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, | ||
805 | {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW}, | ||
806 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, | ||
807 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, | ||
808 | {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
809 | {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
810 | {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, | ||
811 | {0xa0, 0x0f, ZC3XX_R01E_HSYNC_1}, | ||
812 | {0xa0, 0x19, ZC3XX_R01F_HSYNC_2}, | ||
813 | {0xa0, 0x1f, ZC3XX_R020_HSYNC_3}, | ||
814 | {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, | ||
815 | {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, | ||
816 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
817 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
818 | {0xa0, 0x60, ZC3XX_R116_RGAIN}, | ||
819 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, | ||
820 | {0xa0, 0x4c, ZC3XX_R118_BGAIN}, | ||
821 | {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
822 | {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, | ||
823 | {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, | ||
824 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
825 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
826 | {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, | ||
827 | {0xa0, 0x5c, ZC3XX_R093_I2CSETVALUE}, | ||
828 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
829 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
830 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
831 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
832 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
833 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
834 | {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, | ||
835 | {0xa0, 0x5c, ZC3XX_R093_I2CSETVALUE}, | ||
836 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
837 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
838 | {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, | ||
839 | {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, | ||
840 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
841 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
842 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
843 | {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, | ||
844 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
845 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
846 | {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
847 | {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
848 | {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
849 | {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
850 | {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, | ||
851 | {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, | ||
852 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
853 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
854 | {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, | ||
855 | {0xa0, 0x96, ZC3XX_R093_I2CSETVALUE}, | ||
856 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
857 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
858 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
859 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
860 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
861 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
862 | {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, | ||
863 | {0xa0, 0x96, ZC3XX_R093_I2CSETVALUE}, | ||
864 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
865 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
866 | {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, | ||
867 | {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, | ||
868 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
869 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
870 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
871 | {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, | ||
872 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
873 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
874 | {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
875 | {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
876 | {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
877 | {} | ||
878 | }; | ||
879 | |||
880 | static const struct usb_action cs2102K_InitialScale[] = { | ||
881 | {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT}, | ||
882 | {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, | ||
883 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | ||
884 | {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT}, | ||
885 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
886 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
887 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
888 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
889 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
890 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
891 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
892 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, | ||
893 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, | ||
894 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, | ||
895 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, | ||
896 | {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, | ||
897 | {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, | ||
898 | {0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR}, | ||
899 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
900 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
901 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
902 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
903 | {0xa0, 0x0a, ZC3XX_R092_I2CADDRESSSELECT}, | ||
904 | {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, | ||
905 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
906 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
907 | {0xa0, 0x0b, ZC3XX_R092_I2CADDRESSSELECT}, | ||
908 | {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, | ||
909 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
910 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
911 | {0xa0, 0x0c, ZC3XX_R092_I2CADDRESSSELECT}, | ||
912 | {0xa0, 0x7b, ZC3XX_R093_I2CSETVALUE}, | ||
913 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
914 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
915 | {0xa0, 0x0d, ZC3XX_R092_I2CADDRESSSELECT}, | ||
916 | {0xa0, 0xa3, ZC3XX_R093_I2CSETVALUE}, | ||
917 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
918 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
919 | {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT}, | ||
920 | {0xa0, 0xfb, ZC3XX_R093_I2CSETVALUE}, | ||
921 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
922 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
923 | {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT}, | ||
924 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
925 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
926 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
927 | {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT}, | ||
928 | {0xa0, 0x03, ZC3XX_R093_I2CSETVALUE}, | ||
929 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
930 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
931 | {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT}, | ||
932 | {0xa0, 0x08, ZC3XX_R093_I2CSETVALUE}, | ||
933 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
934 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
935 | {0xa0, 0x0e, ZC3XX_R092_I2CADDRESSSELECT}, | ||
936 | {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, | ||
937 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
938 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
939 | {0xa0, 0x0f, ZC3XX_R092_I2CADDRESSSELECT}, | ||
940 | {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, | ||
941 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
942 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
943 | {0xa0, 0x10, ZC3XX_R092_I2CADDRESSSELECT}, | ||
944 | {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, | ||
945 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
946 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
947 | {0xa0, 0x11, ZC3XX_R092_I2CADDRESSSELECT}, | ||
948 | {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, | ||
949 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
950 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
951 | {0xa0, 0x12, ZC3XX_R092_I2CADDRESSSELECT}, | ||
952 | {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, | ||
953 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
954 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
955 | {0xa0, 0x15, ZC3XX_R092_I2CADDRESSSELECT}, | ||
956 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
957 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
958 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
959 | {0xa0, 0x16, ZC3XX_R092_I2CADDRESSSELECT}, | ||
960 | {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE}, | ||
961 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
962 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
963 | {0xa0, 0x17, ZC3XX_R092_I2CADDRESSSELECT}, | ||
964 | {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE}, | ||
965 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
966 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
967 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
968 | {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, | ||
969 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
970 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
971 | {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, | ||
972 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
973 | {0xa0, 0x78, ZC3XX_R18D_YTARGET}, | ||
974 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
975 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
976 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
977 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
978 | {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, | ||
979 | {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, | ||
980 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
981 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
982 | {0xa0, 0x00, 0x01ad}, | ||
983 | {0xa0, 0x01, 0x01b1}, | ||
984 | {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
985 | {0xa0, 0x60, ZC3XX_R116_RGAIN}, | ||
986 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, | ||
987 | {0xa0, 0x4c, ZC3XX_R118_BGAIN}, | ||
988 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ | ||
989 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
990 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
991 | {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */ | ||
992 | {0xa0, 0x38, ZC3XX_R121_GAMMA01}, | ||
993 | {0xa0, 0x59, ZC3XX_R122_GAMMA02}, | ||
994 | {0xa0, 0x79, ZC3XX_R123_GAMMA03}, | ||
995 | {0xa0, 0x92, ZC3XX_R124_GAMMA04}, | ||
996 | {0xa0, 0xa7, ZC3XX_R125_GAMMA05}, | ||
997 | {0xa0, 0xb9, ZC3XX_R126_GAMMA06}, | ||
998 | {0xa0, 0xc8, ZC3XX_R127_GAMMA07}, | ||
999 | {0xa0, 0xd4, ZC3XX_R128_GAMMA08}, | ||
1000 | {0xa0, 0xdf, ZC3XX_R129_GAMMA09}, | ||
1001 | {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A}, | ||
1002 | {0xa0, 0xee, ZC3XX_R12B_GAMMA0B}, | ||
1003 | {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C}, | ||
1004 | {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D}, | ||
1005 | {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E}, | ||
1006 | {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, | ||
1007 | {0xa0, 0x26, ZC3XX_R130_GAMMA10}, | ||
1008 | {0xa0, 0x22, ZC3XX_R131_GAMMA11}, | ||
1009 | {0xa0, 0x20, ZC3XX_R132_GAMMA12}, | ||
1010 | {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, | ||
1011 | {0xa0, 0x16, ZC3XX_R134_GAMMA14}, | ||
1012 | {0xa0, 0x13, ZC3XX_R135_GAMMA15}, | ||
1013 | {0xa0, 0x10, ZC3XX_R136_GAMMA16}, | ||
1014 | {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, | ||
1015 | {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, | ||
1016 | {0xa0, 0x09, ZC3XX_R139_GAMMA19}, | ||
1017 | {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, | ||
1018 | {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, | ||
1019 | {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, | ||
1020 | {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, | ||
1021 | {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, | ||
1022 | {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, | ||
1023 | {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ | ||
1024 | {0xa0, 0xf4, ZC3XX_R10B_RGB01}, | ||
1025 | {0xa0, 0xf4, ZC3XX_R10C_RGB02}, | ||
1026 | {0xa0, 0xf4, ZC3XX_R10D_RGB10}, | ||
1027 | {0xa0, 0x58, ZC3XX_R10E_RGB11}, | ||
1028 | {0xa0, 0xf4, ZC3XX_R10F_RGB12}, | ||
1029 | {0xa0, 0xf4, ZC3XX_R110_RGB20}, | ||
1030 | {0xa0, 0xf4, ZC3XX_R111_RGB21}, | ||
1031 | {0xa0, 0x58, ZC3XX_R112_RGB22}, | ||
1032 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
1033 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
1034 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1035 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
1036 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1037 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1038 | {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1039 | {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE}, | ||
1040 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1041 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1042 | {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1043 | {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, | ||
1044 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1045 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1046 | {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1047 | {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, | ||
1048 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1049 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1050 | {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1051 | {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE}, | ||
1052 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1053 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1054 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1055 | {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, | ||
1056 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1057 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1058 | {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, | ||
1059 | {0xa0, 0x22, ZC3XX_R0A4_EXPOSURETIMELOW}, | ||
1060 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, | ||
1061 | {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, | ||
1062 | {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
1063 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
1064 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, | ||
1065 | {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW}, | ||
1066 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, | ||
1067 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, | ||
1068 | {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
1069 | {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
1070 | {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, | ||
1071 | {0xa0, 0x0f, ZC3XX_R01E_HSYNC_1}, | ||
1072 | {0xa0, 0x19, ZC3XX_R01F_HSYNC_2}, | ||
1073 | {0xa0, 0x1f, ZC3XX_R020_HSYNC_3}, | ||
1074 | {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, | ||
1075 | {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, | ||
1076 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
1077 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
1078 | {0xa0, 0x60, ZC3XX_R116_RGAIN}, | ||
1079 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, | ||
1080 | {0xa0, 0x4c, ZC3XX_R118_BGAIN}, | ||
1081 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
1082 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
1083 | {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, | ||
1084 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | ||
1085 | {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT}, | ||
1086 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
1087 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
1088 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
1089 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
1090 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
1091 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
1092 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
1093 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, | ||
1094 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, | ||
1095 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, | ||
1096 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, | ||
1097 | {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, | ||
1098 | {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, | ||
1099 | {0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR}, | ||
1100 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1101 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
1102 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1103 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1104 | {0xa0, 0x0A, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1105 | {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, | ||
1106 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1107 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1108 | {0xa0, 0x0B, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1109 | {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, | ||
1110 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1111 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1112 | {0xa0, 0x0C, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1113 | {0xa0, 0x7b, ZC3XX_R093_I2CSETVALUE}, | ||
1114 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1115 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1116 | {0xa0, 0x0D, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1117 | {0xa0, 0xA3, ZC3XX_R093_I2CSETVALUE}, | ||
1118 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1119 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1120 | {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1121 | {0xa0, 0xfb, ZC3XX_R093_I2CSETVALUE}, | ||
1122 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1123 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1124 | {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1125 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
1126 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1127 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1128 | {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1129 | {0xa0, 0x03, ZC3XX_R093_I2CSETVALUE}, | ||
1130 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1131 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1132 | {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1133 | {0xa0, 0x08, ZC3XX_R093_I2CSETVALUE}, | ||
1134 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1135 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1136 | {0xa0, 0x0E, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1137 | {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, | ||
1138 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1139 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1140 | {0xa0, 0x0f, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1141 | {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, | ||
1142 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1143 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1144 | {0xa0, 0x10, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1145 | {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, | ||
1146 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1147 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1148 | {0xa0, 0x11, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1149 | {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, | ||
1150 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1151 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1152 | {0xa0, 0x12, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1153 | {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, | ||
1154 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1155 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1156 | {0xa0, 0x15, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1157 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
1158 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1159 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1160 | {0xa0, 0x16, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1161 | {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE}, | ||
1162 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1163 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1164 | {0xa0, 0x17, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1165 | {0xa0, 0x0C, ZC3XX_R093_I2CSETVALUE}, | ||
1166 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1167 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1168 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1169 | {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, | ||
1170 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1171 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1172 | {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, | ||
1173 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
1174 | {0xa0, 0x78, ZC3XX_R18D_YTARGET}, | ||
1175 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
1176 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
1177 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
1178 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
1179 | {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, | ||
1180 | {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, | ||
1181 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
1182 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
1183 | {0xa0, 0x00, 0x01ad}, | ||
1184 | {0xa0, 0x01, 0x01b1}, | ||
1185 | {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
1186 | {0xa0, 0x60, ZC3XX_R116_RGAIN}, | ||
1187 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, | ||
1188 | {0xa0, 0x4c, ZC3XX_R118_BGAIN}, | ||
1189 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ | ||
1190 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
1191 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
1192 | {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */ | ||
1193 | {0xa0, 0x38, ZC3XX_R121_GAMMA01}, | ||
1194 | {0xa0, 0x59, ZC3XX_R122_GAMMA02}, | ||
1195 | {0xa0, 0x79, ZC3XX_R123_GAMMA03}, | ||
1196 | {0xa0, 0x92, ZC3XX_R124_GAMMA04}, | ||
1197 | {0xa0, 0xa7, ZC3XX_R125_GAMMA05}, | ||
1198 | {0xa0, 0xb9, ZC3XX_R126_GAMMA06}, | ||
1199 | {0xa0, 0xc8, ZC3XX_R127_GAMMA07}, | ||
1200 | {0xa0, 0xd4, ZC3XX_R128_GAMMA08}, | ||
1201 | {0xa0, 0xdf, ZC3XX_R129_GAMMA09}, | ||
1202 | {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A}, | ||
1203 | {0xa0, 0xee, ZC3XX_R12B_GAMMA0B}, | ||
1204 | {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C}, | ||
1205 | {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D}, | ||
1206 | {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E}, | ||
1207 | {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, | ||
1208 | {0xa0, 0x26, ZC3XX_R130_GAMMA10}, | ||
1209 | {0xa0, 0x22, ZC3XX_R131_GAMMA11}, | ||
1210 | {0xa0, 0x20, ZC3XX_R132_GAMMA12}, | ||
1211 | {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, | ||
1212 | {0xa0, 0x16, ZC3XX_R134_GAMMA14}, | ||
1213 | {0xa0, 0x13, ZC3XX_R135_GAMMA15}, | ||
1214 | {0xa0, 0x10, ZC3XX_R136_GAMMA16}, | ||
1215 | {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, | ||
1216 | {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, | ||
1217 | {0xa0, 0x09, ZC3XX_R139_GAMMA19}, | ||
1218 | {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, | ||
1219 | {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, | ||
1220 | {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, | ||
1221 | {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, | ||
1222 | {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, | ||
1223 | {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, | ||
1224 | {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ | ||
1225 | {0xa0, 0xf4, ZC3XX_R10B_RGB01}, | ||
1226 | {0xa0, 0xf4, ZC3XX_R10C_RGB02}, | ||
1227 | {0xa0, 0xf4, ZC3XX_R10D_RGB10}, | ||
1228 | {0xa0, 0x58, ZC3XX_R10E_RGB11}, | ||
1229 | {0xa0, 0xf4, ZC3XX_R10F_RGB12}, | ||
1230 | {0xa0, 0xf4, ZC3XX_R110_RGB20}, | ||
1231 | {0xa0, 0xf4, ZC3XX_R111_RGB21}, | ||
1232 | {0xa0, 0x58, ZC3XX_R112_RGB22}, | ||
1233 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
1234 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
1235 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1236 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
1237 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1238 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1239 | {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1240 | {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE}, | ||
1241 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1242 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1243 | {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1244 | {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, | ||
1245 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1246 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1247 | {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1248 | {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, | ||
1249 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1250 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1251 | {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1252 | {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE}, | ||
1253 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1254 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1255 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1256 | {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, | ||
1257 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1258 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1259 | {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, | ||
1260 | {0xa0, 0x22, ZC3XX_R0A4_EXPOSURETIMELOW}, | ||
1261 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, | ||
1262 | {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, | ||
1263 | {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
1264 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
1265 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, | ||
1266 | {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW}, | ||
1267 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, | ||
1268 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, | ||
1269 | {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
1270 | {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
1271 | {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, | ||
1272 | {0xa0, 0x0f, ZC3XX_R01E_HSYNC_1}, | ||
1273 | {0xa0, 0x19, ZC3XX_R01F_HSYNC_2}, | ||
1274 | {0xa0, 0x1f, ZC3XX_R020_HSYNC_3}, | ||
1275 | {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, | ||
1276 | {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, | ||
1277 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
1278 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
1279 | {0xa0, 0x60, ZC3XX_R116_RGAIN}, | ||
1280 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, | ||
1281 | {0xa0, 0x4c, ZC3XX_R118_BGAIN}, | ||
1282 | {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1283 | {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1284 | {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, | ||
1285 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1286 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1287 | {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1288 | {0xa0, 0x5c, ZC3XX_R093_I2CSETVALUE}, | ||
1289 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1290 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1291 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1292 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
1293 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1294 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1295 | {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1296 | {0xa0, 0x5c, ZC3XX_R093_I2CSETVALUE}, | ||
1297 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1298 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1299 | {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1300 | {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, | ||
1301 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1302 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1303 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1304 | {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, | ||
1305 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1306 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1307 | {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1308 | {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1309 | {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1310 | {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1311 | {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1312 | {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, | ||
1313 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1314 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1315 | {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1316 | {0xa0, 0x96, ZC3XX_R093_I2CSETVALUE}, | ||
1317 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1318 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1319 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1320 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
1321 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1322 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1323 | {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1324 | {0xa0, 0x96, ZC3XX_R093_I2CSETVALUE}, | ||
1325 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1326 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1327 | {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1328 | {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, | ||
1329 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1330 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1331 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1332 | {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, | ||
1333 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1334 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1335 | {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1336 | {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1337 | {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1338 | {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1339 | {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1340 | {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1341 | {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1342 | {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, | ||
1343 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1344 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1345 | {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1346 | {0xa0, 0xd0, ZC3XX_R093_I2CSETVALUE}, | ||
1347 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1348 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1349 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1350 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
1351 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1352 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1353 | {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1354 | {0xa0, 0xd0, ZC3XX_R093_I2CSETVALUE}, | ||
1355 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1356 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1357 | {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1358 | {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, | ||
1359 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1360 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1361 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1362 | {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, | ||
1363 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1364 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1365 | {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1366 | {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, | ||
1367 | {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1368 | {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1369 | {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1370 | {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1371 | {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, | ||
1372 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1373 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1374 | {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1375 | {0xa0, 0x0a, ZC3XX_R093_I2CSETVALUE}, | ||
1376 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1377 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1378 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1379 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
1380 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1381 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1382 | {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1383 | {0xa0, 0x0a, ZC3XX_R093_I2CSETVALUE}, | ||
1384 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1385 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1386 | {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1387 | {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, | ||
1388 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1389 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1390 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1391 | {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, | ||
1392 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1393 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1394 | {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1395 | {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1396 | {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1397 | {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1398 | {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1399 | {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, | ||
1400 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1401 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1402 | {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1403 | {0xa0, 0x44, ZC3XX_R093_I2CSETVALUE}, | ||
1404 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1405 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1406 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1407 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
1408 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1409 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1410 | {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1411 | {0xa0, 0x44, ZC3XX_R093_I2CSETVALUE}, | ||
1412 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1413 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1414 | {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1415 | {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, | ||
1416 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1417 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1418 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1419 | {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, | ||
1420 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1421 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1422 | {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1423 | {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1424 | {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1425 | {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1426 | {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1427 | {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, | ||
1428 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1429 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1430 | {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1431 | {0xa0, 0x7e, ZC3XX_R093_I2CSETVALUE}, | ||
1432 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1433 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1434 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1435 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
1436 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1437 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1438 | {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1439 | {0xa0, 0x7e, ZC3XX_R093_I2CSETVALUE}, | ||
1440 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1441 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1442 | {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1443 | {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, | ||
1444 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1445 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1446 | {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, | ||
1447 | {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, | ||
1448 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
1449 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
1450 | {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1451 | {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1452 | {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1453 | {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
1454 | {} | ||
1455 | }; | ||
1456 | |||
1457 | static const struct usb_action gc0305_Initial[] = { /* 640x480 */ | ||
1458 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ | ||
1459 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ | ||
1460 | {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ | ||
1461 | {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */ | ||
1462 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ | ||
1463 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ | ||
1464 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ | ||
1465 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */ | ||
1466 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ | ||
1467 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ | ||
1468 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ | ||
1469 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ | ||
1470 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ | ||
1471 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ | ||
1472 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ | ||
1473 | {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e6,cc */ | ||
1474 | {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */ | ||
1475 | {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc */ | ||
1476 | {0xaa, 0x13, 0x0002}, /* 00,13,02,aa */ | ||
1477 | {0xaa, 0x15, 0x0003}, /* 00,15,03,aa */ | ||
1478 | {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */ | ||
1479 | {0xaa, 0x02, 0x0000}, /* 00,02,00,aa */ | ||
1480 | {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */ | ||
1481 | {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa */ | ||
1482 | {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */ | ||
1483 | {0xaa, 0x1f, 0x0008}, /* 00,1f,08,aa */ | ||
1484 | {0xaa, 0x21, 0x0012}, /* 00,21,12,aa */ | ||
1485 | {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc */ | ||
1486 | {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc */ | ||
1487 | {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc */ | ||
1488 | {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */ | ||
1489 | {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa */ | ||
1490 | {0xaa, 0x0b, 0x00b0}, /* 00,0b,b0,aa */ | ||
1491 | {0xaa, 0x0c, 0x0000}, /* 00,0c,00,aa */ | ||
1492 | {0xaa, 0x0d, 0x00b0}, /* 00,0d,b0,aa */ | ||
1493 | {0xaa, 0x0e, 0x0000}, /* 00,0e,00,aa */ | ||
1494 | {0xaa, 0x0f, 0x00b0}, /* 00,0f,b0,aa */ | ||
1495 | {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ | ||
1496 | {0xaa, 0x11, 0x00b0}, /* 00,11,b0,aa */ | ||
1497 | {0xaa, 0x16, 0x0001}, /* 00,16,01,aa */ | ||
1498 | {0xaa, 0x17, 0x00e6}, /* 00,17,e6,aa */ | ||
1499 | {0xaa, 0x18, 0x0002}, /* 00,18,02,aa */ | ||
1500 | {0xaa, 0x19, 0x0086}, /* 00,19,86,aa */ | ||
1501 | {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */ | ||
1502 | {0xaa, 0x1b, 0x0020}, /* 00,1b,20,aa */ | ||
1503 | {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc */ | ||
1504 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ | ||
1505 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ | ||
1506 | {0xa0, 0x76, ZC3XX_R189_AWBSTATUS}, /* 01,89,76,cc */ | ||
1507 | {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc */ | ||
1508 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ | ||
1509 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ | ||
1510 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ | ||
1511 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ | ||
1512 | {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc */ | ||
1513 | {0xa0, 0x85, ZC3XX_R18D_YTARGET}, /* 01,8d,85,cc */ | ||
1514 | {0xa0, 0x00, 0x011e}, /* 01,1e,00,cc */ | ||
1515 | {0xa0, 0x52, ZC3XX_R116_RGAIN}, /* 01,16,52,cc */ | ||
1516 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, /* 01,17,40,cc */ | ||
1517 | {0xa0, 0x52, ZC3XX_R118_BGAIN}, /* 01,18,52,cc */ | ||
1518 | {0xa0, 0x03, ZC3XX_R113_RGB03}, /* 01,13,03,cc */ | ||
1519 | {} | ||
1520 | }; | ||
1521 | static const struct usb_action gc0305_InitialScale[] = { /* 320x240 */ | ||
1522 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ | ||
1523 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ | ||
1524 | {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ | ||
1525 | {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */ | ||
1526 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ | ||
1527 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ | ||
1528 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ | ||
1529 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */ | ||
1530 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ | ||
1531 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ | ||
1532 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ | ||
1533 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ | ||
1534 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ | ||
1535 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ | ||
1536 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ | ||
1537 | {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e8,cc */ | ||
1538 | {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */ | ||
1539 | {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc */ | ||
1540 | {0xaa, 0x13, 0x0000}, /* 00,13,00,aa */ | ||
1541 | {0xaa, 0x15, 0x0001}, /* 00,15,01,aa */ | ||
1542 | {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */ | ||
1543 | {0xaa, 0x02, 0x0000}, /* 00,02,00,aa */ | ||
1544 | {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */ | ||
1545 | {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa */ | ||
1546 | {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */ | ||
1547 | {0xaa, 0x1f, 0x0008}, /* 00,1f,08,aa */ | ||
1548 | {0xaa, 0x21, 0x0012}, /* 00,21,12,aa */ | ||
1549 | {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc */ | ||
1550 | {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc */ | ||
1551 | {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc */ | ||
1552 | {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */ | ||
1553 | {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa */ | ||
1554 | {0xaa, 0x0b, 0x00b0}, /* 00,0b,b0,aa */ | ||
1555 | {0xaa, 0x0c, 0x0000}, /* 00,0c,00,aa */ | ||
1556 | {0xaa, 0x0d, 0x00b0}, /* 00,0d,b0,aa */ | ||
1557 | {0xaa, 0x0e, 0x0000}, /* 00,0e,00,aa */ | ||
1558 | {0xaa, 0x0f, 0x00b0}, /* 00,0f,b0,aa */ | ||
1559 | {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ | ||
1560 | {0xaa, 0x11, 0x00b0}, /* 00,11,b0,aa */ | ||
1561 | {0xaa, 0x16, 0x0001}, /* 00,16,01,aa */ | ||
1562 | {0xaa, 0x17, 0x00e8}, /* 00,17,e8,aa */ | ||
1563 | {0xaa, 0x18, 0x0002}, /* 00,18,02,aa */ | ||
1564 | {0xaa, 0x19, 0x0088}, /* 00,19,88,aa */ | ||
1565 | {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */ | ||
1566 | {0xaa, 0x1b, 0x0020}, /* 00,1b,20,aa */ | ||
1567 | {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc */ | ||
1568 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ | ||
1569 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ | ||
1570 | {0xa0, 0x76, ZC3XX_R189_AWBSTATUS}, /* 01,89,76,cc */ | ||
1571 | {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc */ | ||
1572 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ | ||
1573 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ | ||
1574 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ | ||
1575 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ | ||
1576 | {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc */ | ||
1577 | {0xa0, 0x00, 0x011e}, /* 01,1e,00,cc */ | ||
1578 | {0xa0, 0x52, ZC3XX_R116_RGAIN}, /* 01,16,52,cc */ | ||
1579 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, /* 01,17,40,cc */ | ||
1580 | {0xa0, 0x52, ZC3XX_R118_BGAIN}, /* 01,18,52,cc */ | ||
1581 | {0xa0, 0x03, ZC3XX_R113_RGB03}, /* 01,13,03,cc */ | ||
1582 | {} | ||
1583 | }; | ||
1584 | static const struct usb_action gc0305_50HZ[] = { | ||
1585 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | ||
1586 | {0xaa, 0x83, 0x0002}, /* 00,83,02,aa */ | ||
1587 | {0xaa, 0x84, 0x0038}, /* 00,84,38,aa */ /* win: 00,84,ec */ | ||
1588 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
1589 | {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0b,cc */ | ||
1590 | {0xa0, 0x18, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,18,cc */ | ||
1591 | /* win: 01,92,10 */ | ||
1592 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
1593 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
1594 | {0xa0, 0x8e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,8e,cc */ | ||
1595 | /* win: 01,97,ec */ | ||
1596 | {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc */ | ||
1597 | {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc */ | ||
1598 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ | ||
1599 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ | ||
1600 | {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc */ | ||
1601 | {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */ | ||
1602 | {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */ | ||
1603 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ | ||
1604 | {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,60,cc */ | ||
1605 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */ | ||
1606 | /* {0xa0, 0x85, ZC3XX_R18D_YTARGET}, * 01,8d,85,cc * | ||
1607 | * if 640x480 */ | ||
1608 | {} | ||
1609 | }; | ||
1610 | static const struct usb_action gc0305_60HZ[] = { | ||
1611 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | ||
1612 | {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ | ||
1613 | {0xaa, 0x84, 0x00ec}, /* 00,84,ec,aa */ | ||
1614 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
1615 | {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0b,cc */ | ||
1616 | {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,10,cc */ | ||
1617 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
1618 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
1619 | {0xa0, 0xec, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,ec,cc */ | ||
1620 | {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc */ | ||
1621 | {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc */ | ||
1622 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ | ||
1623 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ | ||
1624 | {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc */ | ||
1625 | {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */ | ||
1626 | {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */ | ||
1627 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ | ||
1628 | {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,60,cc */ | ||
1629 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */ | ||
1630 | {0xa0, 0x80, ZC3XX_R18D_YTARGET}, /* 01,8d,80,cc */ | ||
1631 | {} | ||
1632 | }; | ||
1633 | |||
1634 | static const struct usb_action gc0305_NoFliker[] = { | ||
1635 | {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc */ | ||
1636 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | ||
1637 | {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ | ||
1638 | {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */ | ||
1639 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
1640 | {0xa0, 0x00, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,00,cc */ | ||
1641 | {0xa0, 0x48, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,48,cc */ | ||
1642 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
1643 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
1644 | {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ | ||
1645 | {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc */ | ||
1646 | {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc */ | ||
1647 | {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc */ | ||
1648 | {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */ | ||
1649 | {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */ | ||
1650 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ | ||
1651 | {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,60,cc */ | ||
1652 | {0xa0, 0x03, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,03,cc */ | ||
1653 | {0xa0, 0x80, ZC3XX_R18D_YTARGET}, /* 01,8d,80,cc */ | ||
1654 | {} | ||
1655 | }; | ||
1656 | |||
1657 | /* play poker with registers at your own risk !! */ | ||
1658 | static const struct usb_action hdcs2020xx_Initial[] = { | ||
1659 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
1660 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | ||
1661 | {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT}, | ||
1662 | {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, | ||
1663 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
1664 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
1665 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
1666 | {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
1667 | /* D0 ?? E0 did not start */ | ||
1668 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
1669 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
1670 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
1671 | {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, | ||
1672 | {0xa0, 0x08, ZC3XX_R098_WINYSTARTLOW}, | ||
1673 | {0xa0, 0x02, ZC3XX_R09A_WINXSTARTLOW}, | ||
1674 | {0xa0, 0x08, ZC3XX_R11A_FIRSTYLOW}, | ||
1675 | {0xa0, 0x02, ZC3XX_R11C_FIRSTXLOW}, | ||
1676 | {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, | ||
1677 | {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW}, | ||
1678 | {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, | ||
1679 | {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, | ||
1680 | {0xaa, 0x02, 0x0002}, | ||
1681 | {0xaa, 0x07, 0x0006}, | ||
1682 | {0xaa, 0x08, 0x0002}, | ||
1683 | {0xaa, 0x09, 0x0006}, | ||
1684 | {0xaa, 0x0a, 0x0001}, | ||
1685 | {0xaa, 0x0b, 0x0001}, | ||
1686 | {0xaa, 0x0c, 0x0008}, | ||
1687 | {0xaa, 0x0d, 0x0000}, | ||
1688 | {0xaa, 0x10, 0x0000}, | ||
1689 | {0xaa, 0x12, 0x0005}, | ||
1690 | {0xaa, 0x13, 0x0063}, | ||
1691 | {0xaa, 0x15, 0x0070}, | ||
1692 | {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, | ||
1693 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
1694 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
1695 | {0xa0, 0x00, 0x01ad}, | ||
1696 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
1697 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
1698 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
1699 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
1700 | {0xa0, 0x70, ZC3XX_R18D_YTARGET}, | ||
1701 | {0xa1, 0x01, 0x0002}, | ||
1702 | {0xa1, 0x01, 0x0008}, | ||
1703 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ | ||
1704 | {0xa0, 0x04, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
1705 | {0xa1, 0x01, 0x01c8}, | ||
1706 | {0xa1, 0x01, 0x01c9}, | ||
1707 | {0xa1, 0x01, 0x01ca}, | ||
1708 | {0xa0, 0x07, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
1709 | {0xa0, 0x11, ZC3XX_R120_GAMMA00}, /* gamma ~4 */ | ||
1710 | {0xa0, 0x37, ZC3XX_R121_GAMMA01}, | ||
1711 | {0xa0, 0x58, ZC3XX_R122_GAMMA02}, | ||
1712 | {0xa0, 0x79, ZC3XX_R123_GAMMA03}, | ||
1713 | {0xa0, 0x91, ZC3XX_R124_GAMMA04}, | ||
1714 | {0xa0, 0xa6, ZC3XX_R125_GAMMA05}, | ||
1715 | {0xa0, 0xb8, ZC3XX_R126_GAMMA06}, | ||
1716 | {0xa0, 0xc7, ZC3XX_R127_GAMMA07}, | ||
1717 | {0xa0, 0xd3, ZC3XX_R128_GAMMA08}, | ||
1718 | {0xa0, 0xde, ZC3XX_R129_GAMMA09}, | ||
1719 | {0xa0, 0xe6, ZC3XX_R12A_GAMMA0A}, | ||
1720 | {0xa0, 0xed, ZC3XX_R12B_GAMMA0B}, | ||
1721 | {0xa0, 0xf3, ZC3XX_R12C_GAMMA0C}, | ||
1722 | {0xa0, 0xf8, ZC3XX_R12D_GAMMA0D}, | ||
1723 | {0xa0, 0xfb, ZC3XX_R12E_GAMMA0E}, | ||
1724 | {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, | ||
1725 | {0xa0, 0x26, ZC3XX_R130_GAMMA10}, | ||
1726 | {0xa0, 0x23, ZC3XX_R131_GAMMA11}, | ||
1727 | {0xa0, 0x20, ZC3XX_R132_GAMMA12}, | ||
1728 | {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, | ||
1729 | {0xa0, 0x16, ZC3XX_R134_GAMMA14}, | ||
1730 | {0xa0, 0x13, ZC3XX_R135_GAMMA15}, | ||
1731 | {0xa0, 0x10, ZC3XX_R136_GAMMA16}, | ||
1732 | {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, | ||
1733 | {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, | ||
1734 | {0xa0, 0x09, ZC3XX_R139_GAMMA19}, | ||
1735 | {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, | ||
1736 | {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, | ||
1737 | {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, | ||
1738 | {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, | ||
1739 | {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, | ||
1740 | {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, | ||
1741 | |||
1742 | {0xa0, 0x4c, ZC3XX_R10A_RGB00}, /* matrix */ | ||
1743 | {0xa0, 0xf5, ZC3XX_R10B_RGB01}, | ||
1744 | {0xa0, 0xff, ZC3XX_R10C_RGB02}, | ||
1745 | {0xa0, 0xf9, ZC3XX_R10D_RGB10}, | ||
1746 | {0xa0, 0x51, ZC3XX_R10E_RGB11}, | ||
1747 | {0xa0, 0xf5, ZC3XX_R10F_RGB12}, | ||
1748 | {0xa0, 0xfb, ZC3XX_R110_RGB20}, | ||
1749 | {0xa0, 0xed, ZC3XX_R111_RGB21}, | ||
1750 | {0xa0, 0x5f, ZC3XX_R112_RGB22}, | ||
1751 | |||
1752 | {0xa1, 0x01, 0x0180}, | ||
1753 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
1754 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
1755 | {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, | ||
1756 | {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, | ||
1757 | {0xaa, 0x20, 0x0004}, | ||
1758 | {0xaa, 0x21, 0x003d}, | ||
1759 | {0xaa, 0x03, 0x0041}, | ||
1760 | {0xaa, 0x04, 0x0010}, | ||
1761 | {0xaa, 0x05, 0x003d}, | ||
1762 | {0xaa, 0x0e, 0x0001}, | ||
1763 | {0xaa, 0x0f, 0x0000}, | ||
1764 | {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
1765 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
1766 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, | ||
1767 | {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, | ||
1768 | {0xa0, 0x3d, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
1769 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
1770 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, | ||
1771 | {0xa0, 0x9b, ZC3XX_R197_ANTIFLICKERLOW}, | ||
1772 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, | ||
1773 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, | ||
1774 | {0xa0, 0x41, ZC3XX_R01D_HSYNC_0}, | ||
1775 | {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, | ||
1776 | {0xa0, 0xad, ZC3XX_R01F_HSYNC_2}, | ||
1777 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, | ||
1778 | {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, | ||
1779 | {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, | ||
1780 | {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
1781 | {0xa1, 0x01, 0x0195}, | ||
1782 | {0xa1, 0x01, 0x0196}, | ||
1783 | {0xa1, 0x01, 0x0197}, | ||
1784 | {0xa0, 0x3d, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
1785 | {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, | ||
1786 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, | ||
1787 | {0xa0, 0x1d, ZC3XX_R116_RGAIN}, | ||
1788 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, | ||
1789 | {0xa0, 0x85, ZC3XX_R118_BGAIN}, | ||
1790 | {0xa1, 0x01, 0x0116}, | ||
1791 | {0xa1, 0x01, 0x0118}, | ||
1792 | {0xa1, 0x01, 0x0180}, | ||
1793 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
1794 | {0xa0, 0x1d, ZC3XX_R116_RGAIN}, | ||
1795 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, | ||
1796 | {0xa0, 0x85, ZC3XX_R118_BGAIN}, | ||
1797 | {0xa1, 0x01, 0x0116}, | ||
1798 | {0xa1, 0x01, 0x0118}, | ||
1799 | /* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */ | ||
1800 | {0xa0, 0x00, 0x0007}, | ||
1801 | {} | ||
1802 | }; | ||
1803 | |||
1804 | static const struct usb_action hdcs2020xx_InitialScale[] = { | ||
1805 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
1806 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | ||
1807 | {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT}, | ||
1808 | {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, | ||
1809 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
1810 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
1811 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
1812 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
1813 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
1814 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
1815 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
1816 | {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, | ||
1817 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, | ||
1818 | {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW}, | ||
1819 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, | ||
1820 | {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW}, | ||
1821 | {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, | ||
1822 | {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, | ||
1823 | {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, | ||
1824 | {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, | ||
1825 | {0xaa, 0x02, 0x0002}, | ||
1826 | {0xaa, 0x07, 0x0006}, | ||
1827 | {0xaa, 0x08, 0x0002}, | ||
1828 | {0xaa, 0x09, 0x0006}, | ||
1829 | {0xaa, 0x0a, 0x0001}, | ||
1830 | {0xaa, 0x0b, 0x0001}, | ||
1831 | {0xaa, 0x0c, 0x0008}, | ||
1832 | {0xaa, 0x0d, 0x0000}, | ||
1833 | {0xaa, 0x10, 0x0000}, | ||
1834 | {0xaa, 0x12, 0x0005}, | ||
1835 | {0xaa, 0x13, 0x0063}, | ||
1836 | {0xaa, 0x15, 0x0070}, | ||
1837 | {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, | ||
1838 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
1839 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
1840 | {0xa0, 0x00, 0x01ad}, | ||
1841 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
1842 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
1843 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
1844 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
1845 | {0xa0, 0x70, ZC3XX_R18D_YTARGET}, | ||
1846 | {0xa1, 0x01, 0x0002}, | ||
1847 | {0xa1, 0x01, 0x0008}, | ||
1848 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ | ||
1849 | {0xa0, 0x04, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
1850 | {0xa1, 0x01, 0x01c8}, | ||
1851 | {0xa1, 0x01, 0x01c9}, | ||
1852 | {0xa1, 0x01, 0x01ca}, | ||
1853 | {0xa0, 0x07, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
1854 | {0xa0, 0x11, ZC3XX_R120_GAMMA00}, /* gamma ~4*/ | ||
1855 | {0xa0, 0x37, ZC3XX_R121_GAMMA01}, | ||
1856 | {0xa0, 0x58, ZC3XX_R122_GAMMA02}, | ||
1857 | {0xa0, 0x79, ZC3XX_R123_GAMMA03}, | ||
1858 | {0xa0, 0x91, ZC3XX_R124_GAMMA04}, | ||
1859 | {0xa0, 0xa6, ZC3XX_R125_GAMMA05}, | ||
1860 | {0xa0, 0xb8, ZC3XX_R126_GAMMA06}, | ||
1861 | {0xa0, 0xc7, ZC3XX_R127_GAMMA07}, | ||
1862 | {0xa0, 0xd3, ZC3XX_R128_GAMMA08}, | ||
1863 | {0xa0, 0xde, ZC3XX_R129_GAMMA09}, | ||
1864 | {0xa0, 0xe6, ZC3XX_R12A_GAMMA0A}, | ||
1865 | {0xa0, 0xed, ZC3XX_R12B_GAMMA0B}, | ||
1866 | {0xa0, 0xf3, ZC3XX_R12C_GAMMA0C}, | ||
1867 | {0xa0, 0xf8, ZC3XX_R12D_GAMMA0D}, | ||
1868 | {0xa0, 0xfb, ZC3XX_R12E_GAMMA0E}, | ||
1869 | {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, | ||
1870 | {0xa0, 0x26, ZC3XX_R130_GAMMA10}, | ||
1871 | {0xa0, 0x23, ZC3XX_R131_GAMMA11}, | ||
1872 | {0xa0, 0x20, ZC3XX_R132_GAMMA12}, | ||
1873 | {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, | ||
1874 | {0xa0, 0x16, ZC3XX_R134_GAMMA14}, | ||
1875 | {0xa0, 0x13, ZC3XX_R135_GAMMA15}, | ||
1876 | {0xa0, 0x10, ZC3XX_R136_GAMMA16}, | ||
1877 | {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, | ||
1878 | {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, | ||
1879 | {0xa0, 0x09, ZC3XX_R139_GAMMA19}, | ||
1880 | {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, | ||
1881 | {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, | ||
1882 | {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, | ||
1883 | {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, | ||
1884 | {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, | ||
1885 | {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, | ||
1886 | {0xa0, 0x60, ZC3XX_R10A_RGB00}, /* matrix */ | ||
1887 | {0xa0, 0xff, ZC3XX_R10B_RGB01}, | ||
1888 | {0xa0, 0xff, ZC3XX_R10C_RGB02}, | ||
1889 | {0xa0, 0xff, ZC3XX_R10D_RGB10}, | ||
1890 | {0xa0, 0x60, ZC3XX_R10E_RGB11}, | ||
1891 | {0xa0, 0xff, ZC3XX_R10F_RGB12}, | ||
1892 | {0xa0, 0xff, ZC3XX_R110_RGB20}, | ||
1893 | {0xa0, 0xff, ZC3XX_R111_RGB21}, | ||
1894 | {0xa0, 0x60, ZC3XX_R112_RGB22}, | ||
1895 | |||
1896 | {0xa1, 0x01, 0x0180}, | ||
1897 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
1898 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
1899 | {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, | ||
1900 | {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, | ||
1901 | {0xaa, 0x20, 0x0002}, | ||
1902 | {0xaa, 0x21, 0x001b}, | ||
1903 | {0xaa, 0x03, 0x0044}, | ||
1904 | {0xaa, 0x04, 0x0008}, | ||
1905 | {0xaa, 0x05, 0x001b}, | ||
1906 | {0xaa, 0x0e, 0x0001}, | ||
1907 | {0xaa, 0x0f, 0x0000}, | ||
1908 | {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
1909 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
1910 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, | ||
1911 | {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, | ||
1912 | {0xa0, 0x1b, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
1913 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
1914 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, | ||
1915 | {0xa0, 0x4d, ZC3XX_R197_ANTIFLICKERLOW}, | ||
1916 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, | ||
1917 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, | ||
1918 | {0xa0, 0x44, ZC3XX_R01D_HSYNC_0}, | ||
1919 | {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, | ||
1920 | {0xa0, 0xad, ZC3XX_R01F_HSYNC_2}, | ||
1921 | {0xa0, 0xeb, ZC3XX_R020_HSYNC_3}, | ||
1922 | {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, | ||
1923 | {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, | ||
1924 | {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
1925 | {0xa1, 0x01, 0x0195}, | ||
1926 | {0xa1, 0x01, 0x0196}, | ||
1927 | {0xa1, 0x01, 0x0197}, | ||
1928 | {0xa0, 0x1b, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
1929 | {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, | ||
1930 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, | ||
1931 | {0xa0, 0x1d, ZC3XX_R116_RGAIN}, | ||
1932 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, | ||
1933 | {0xa0, 0x99, ZC3XX_R118_BGAIN}, | ||
1934 | {0xa1, 0x01, 0x0116}, | ||
1935 | {0xa1, 0x01, 0x0118}, | ||
1936 | {0xa1, 0x01, 0x0180}, | ||
1937 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
1938 | {0xa0, 0x1d, ZC3XX_R116_RGAIN}, | ||
1939 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, | ||
1940 | {0xa0, 0x99, ZC3XX_R118_BGAIN}, | ||
1941 | /* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */ | ||
1942 | {0xa0, 0x00, 0x0007}, | ||
1943 | /* {0xa0, 0x18, 0x00fe}, */ | ||
1944 | {} | ||
1945 | }; | ||
1946 | static const struct usb_action hdcs2020xb_Initial[] = { | ||
1947 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
1948 | {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT}, | ||
1949 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* qtable 0x05 */ | ||
1950 | {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT}, | ||
1951 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
1952 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
1953 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
1954 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
1955 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
1956 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
1957 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
1958 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, | ||
1959 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, | ||
1960 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, | ||
1961 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, | ||
1962 | {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, | ||
1963 | {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, | ||
1964 | {0xaa, 0x1c, 0x0000}, | ||
1965 | {0xaa, 0x0a, 0x0001}, | ||
1966 | {0xaa, 0x0b, 0x0006}, | ||
1967 | {0xaa, 0x0c, 0x007b}, | ||
1968 | {0xaa, 0x0d, 0x00a7}, | ||
1969 | {0xaa, 0x03, 0x00fb}, | ||
1970 | {0xaa, 0x05, 0x0000}, | ||
1971 | {0xaa, 0x06, 0x0003}, | ||
1972 | {0xaa, 0x09, 0x0008}, | ||
1973 | |||
1974 | {0xaa, 0x0f, 0x0018}, /* set sensor gain */ | ||
1975 | {0xaa, 0x10, 0x0018}, | ||
1976 | {0xaa, 0x11, 0x0018}, | ||
1977 | {0xaa, 0x12, 0x0018}, | ||
1978 | |||
1979 | {0xaa, 0x15, 0x004e}, | ||
1980 | {0xaa, 0x1c, 0x0004}, | ||
1981 | {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, | ||
1982 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
1983 | {0xa0, 0x70, ZC3XX_R18D_YTARGET}, | ||
1984 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
1985 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
1986 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
1987 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
1988 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
1989 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
1990 | {0xa1, 0x01, 0x0002}, | ||
1991 | {0xa1, 0x01, 0x0008}, | ||
1992 | {0xa1, 0x01, 0x0180}, | ||
1993 | {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
1994 | {0xa0, 0x40, ZC3XX_R116_RGAIN}, | ||
1995 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, | ||
1996 | {0xa0, 0x40, ZC3XX_R118_BGAIN}, | ||
1997 | {0xa1, 0x01, 0x0008}, | ||
1998 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ | ||
1999 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
2000 | {0xa1, 0x01, 0x01c8}, | ||
2001 | {0xa1, 0x01, 0x01c9}, | ||
2002 | {0xa1, 0x01, 0x01ca}, | ||
2003 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
2004 | {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */ | ||
2005 | {0xa0, 0x38, ZC3XX_R121_GAMMA01}, | ||
2006 | {0xa0, 0x59, ZC3XX_R122_GAMMA02}, | ||
2007 | {0xa0, 0x79, ZC3XX_R123_GAMMA03}, | ||
2008 | {0xa0, 0x92, ZC3XX_R124_GAMMA04}, | ||
2009 | {0xa0, 0xa7, ZC3XX_R125_GAMMA05}, | ||
2010 | {0xa0, 0xb9, ZC3XX_R126_GAMMA06}, | ||
2011 | {0xa0, 0xc8, ZC3XX_R127_GAMMA07}, | ||
2012 | {0xa0, 0xd4, ZC3XX_R128_GAMMA08}, | ||
2013 | {0xa0, 0xdf, ZC3XX_R129_GAMMA09}, | ||
2014 | {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A}, | ||
2015 | {0xa0, 0xee, ZC3XX_R12B_GAMMA0B}, | ||
2016 | {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C}, | ||
2017 | {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D}, | ||
2018 | {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E}, | ||
2019 | {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, | ||
2020 | {0xa0, 0x26, ZC3XX_R130_GAMMA10}, | ||
2021 | {0xa0, 0x22, ZC3XX_R131_GAMMA11}, | ||
2022 | {0xa0, 0x20, ZC3XX_R132_GAMMA12}, | ||
2023 | {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, | ||
2024 | {0xa0, 0x16, ZC3XX_R134_GAMMA14}, | ||
2025 | {0xa0, 0x13, ZC3XX_R135_GAMMA15}, | ||
2026 | {0xa0, 0x10, ZC3XX_R136_GAMMA16}, | ||
2027 | {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, | ||
2028 | {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, | ||
2029 | {0xa0, 0x09, ZC3XX_R139_GAMMA19}, | ||
2030 | {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, | ||
2031 | {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, | ||
2032 | {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, | ||
2033 | {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, | ||
2034 | {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, | ||
2035 | {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, | ||
2036 | |||
2037 | {0xa0, 0x66, ZC3XX_R10A_RGB00}, /* matrix */ | ||
2038 | {0xa0, 0xed, ZC3XX_R10B_RGB01}, | ||
2039 | {0xa0, 0xed, ZC3XX_R10C_RGB02}, | ||
2040 | {0xa0, 0xed, ZC3XX_R10D_RGB10}, | ||
2041 | {0xa0, 0x66, ZC3XX_R10E_RGB11}, | ||
2042 | {0xa0, 0xed, ZC3XX_R10F_RGB12}, | ||
2043 | {0xa0, 0xed, ZC3XX_R110_RGB20}, | ||
2044 | {0xa0, 0xed, ZC3XX_R111_RGB21}, | ||
2045 | {0xa0, 0x66, ZC3XX_R112_RGB22}, | ||
2046 | |||
2047 | {0xa1, 0x01, 0x0180}, | ||
2048 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2049 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
2050 | {0xaa, 0x13, 0x0031}, | ||
2051 | {0xaa, 0x14, 0x0001}, | ||
2052 | {0xaa, 0x0e, 0x0004}, | ||
2053 | {0xaa, 0x19, 0x00cd}, | ||
2054 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, | ||
2055 | {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, | ||
2056 | {0xa0, 0x62, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
2057 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
2058 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, | ||
2059 | {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW}, | ||
2060 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, | ||
2061 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, | ||
2062 | |||
2063 | {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 0x14 */ | ||
2064 | {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
2065 | {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, | ||
2066 | {0xa0, 0x18, ZC3XX_R01E_HSYNC_1}, | ||
2067 | {0xa0, 0x2c, ZC3XX_R01F_HSYNC_2}, | ||
2068 | {0xa0, 0x41, ZC3XX_R020_HSYNC_3}, | ||
2069 | {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, | ||
2070 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2071 | {0xa1, 0x01, 0x0180}, | ||
2072 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2073 | {0xa0, 0x40, ZC3XX_R116_RGAIN}, | ||
2074 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, | ||
2075 | {0xa0, 0x40, ZC3XX_R118_BGAIN}, | ||
2076 | {} | ||
2077 | }; | ||
2078 | static const struct usb_action hdcs2020xb_InitialScale[] = { | ||
2079 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
2080 | {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, | ||
2081 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | ||
2082 | {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT}, | ||
2083 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
2084 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
2085 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
2086 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
2087 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
2088 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
2089 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
2090 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, | ||
2091 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, | ||
2092 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, | ||
2093 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, | ||
2094 | {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, | ||
2095 | {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, | ||
2096 | {0xaa, 0x1c, 0x0000}, | ||
2097 | {0xaa, 0x0a, 0x0001}, | ||
2098 | {0xaa, 0x0b, 0x0006}, | ||
2099 | {0xaa, 0x0c, 0x007a}, | ||
2100 | {0xaa, 0x0d, 0x00a7}, | ||
2101 | {0xaa, 0x03, 0x00fb}, | ||
2102 | {0xaa, 0x05, 0x0000}, | ||
2103 | {0xaa, 0x06, 0x0003}, | ||
2104 | {0xaa, 0x09, 0x0008}, | ||
2105 | {0xaa, 0x0f, 0x0018}, /* original setting */ | ||
2106 | {0xaa, 0x10, 0x0018}, | ||
2107 | {0xaa, 0x11, 0x0018}, | ||
2108 | {0xaa, 0x12, 0x0018}, | ||
2109 | {0xaa, 0x15, 0x004e}, | ||
2110 | {0xaa, 0x1c, 0x0004}, | ||
2111 | {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, | ||
2112 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
2113 | {0xa0, 0x70, ZC3XX_R18D_YTARGET}, | ||
2114 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
2115 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
2116 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
2117 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
2118 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
2119 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
2120 | {0xa1, 0x01, 0x0002}, | ||
2121 | {0xa1, 0x01, 0x0008}, | ||
2122 | {0xa1, 0x01, 0x0180}, | ||
2123 | {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2124 | {0xa0, 0x40, ZC3XX_R116_RGAIN}, | ||
2125 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, | ||
2126 | {0xa0, 0x40, ZC3XX_R118_BGAIN}, | ||
2127 | {0xa1, 0x01, 0x0008}, | ||
2128 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ | ||
2129 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
2130 | {0xa1, 0x01, 0x01c8}, | ||
2131 | {0xa1, 0x01, 0x01c9}, | ||
2132 | {0xa1, 0x01, 0x01ca}, | ||
2133 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
2134 | {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */ | ||
2135 | {0xa0, 0x38, ZC3XX_R121_GAMMA01}, | ||
2136 | {0xa0, 0x59, ZC3XX_R122_GAMMA02}, | ||
2137 | {0xa0, 0x79, ZC3XX_R123_GAMMA03}, | ||
2138 | {0xa0, 0x92, ZC3XX_R124_GAMMA04}, | ||
2139 | {0xa0, 0xa7, ZC3XX_R125_GAMMA05}, | ||
2140 | {0xa0, 0xb9, ZC3XX_R126_GAMMA06}, | ||
2141 | {0xa0, 0xc8, ZC3XX_R127_GAMMA07}, | ||
2142 | {0xa0, 0xd4, ZC3XX_R128_GAMMA08}, | ||
2143 | {0xa0, 0xdf, ZC3XX_R129_GAMMA09}, | ||
2144 | {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A}, | ||
2145 | {0xa0, 0xee, ZC3XX_R12B_GAMMA0B}, | ||
2146 | {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C}, | ||
2147 | {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D}, | ||
2148 | {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E}, | ||
2149 | {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, | ||
2150 | {0xa0, 0x26, ZC3XX_R130_GAMMA10}, | ||
2151 | {0xa0, 0x22, ZC3XX_R131_GAMMA11}, | ||
2152 | {0xa0, 0x20, ZC3XX_R132_GAMMA12}, | ||
2153 | {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, | ||
2154 | {0xa0, 0x16, ZC3XX_R134_GAMMA14}, | ||
2155 | {0xa0, 0x13, ZC3XX_R135_GAMMA15}, | ||
2156 | {0xa0, 0x10, ZC3XX_R136_GAMMA16}, | ||
2157 | {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, | ||
2158 | {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, | ||
2159 | {0xa0, 0x09, ZC3XX_R139_GAMMA19}, | ||
2160 | {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, | ||
2161 | {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, | ||
2162 | {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, | ||
2163 | {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, | ||
2164 | {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, | ||
2165 | {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, | ||
2166 | {0xa0, 0x66, ZC3XX_R10A_RGB00}, /* matrix */ | ||
2167 | {0xa0, 0xed, ZC3XX_R10B_RGB01}, | ||
2168 | {0xa0, 0xed, ZC3XX_R10C_RGB02}, | ||
2169 | {0xa0, 0xed, ZC3XX_R10D_RGB10}, | ||
2170 | {0xa0, 0x66, ZC3XX_R10E_RGB11}, | ||
2171 | {0xa0, 0xed, ZC3XX_R10F_RGB12}, | ||
2172 | {0xa0, 0xed, ZC3XX_R110_RGB20}, | ||
2173 | {0xa0, 0xed, ZC3XX_R111_RGB21}, | ||
2174 | {0xa0, 0x66, ZC3XX_R112_RGB22}, | ||
2175 | {0xa1, 0x01, 0x0180}, | ||
2176 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2177 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
2178 | /**** set exposure ***/ | ||
2179 | {0xaa, 0x13, 0x0031}, | ||
2180 | {0xaa, 0x14, 0x0001}, | ||
2181 | {0xaa, 0x0e, 0x0004}, | ||
2182 | {0xaa, 0x19, 0x00cd}, | ||
2183 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, | ||
2184 | {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, | ||
2185 | {0xa0, 0x62, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
2186 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
2187 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, | ||
2188 | {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW}, | ||
2189 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, | ||
2190 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, | ||
2191 | {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
2192 | {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
2193 | {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, | ||
2194 | {0xa0, 0x18, ZC3XX_R01E_HSYNC_1}, | ||
2195 | {0xa0, 0x2c, ZC3XX_R01F_HSYNC_2}, | ||
2196 | {0xa0, 0x41, ZC3XX_R020_HSYNC_3}, | ||
2197 | {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, | ||
2198 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2199 | {0xa1, 0x01, 0x0180}, | ||
2200 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2201 | {0xa0, 0x40, ZC3XX_R116_RGAIN}, | ||
2202 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, | ||
2203 | {0xa0, 0x40, ZC3XX_R118_BGAIN}, | ||
2204 | {} | ||
2205 | }; | ||
2206 | static const struct usb_action hdcs2020b_50HZ[] = { | ||
2207 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
2208 | {0xaa, 0x13, 0x0018}, /* 00,13,18,aa */ | ||
2209 | {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ | ||
2210 | {0xaa, 0x0e, 0x0005}, /* 00,0e,05,aa */ | ||
2211 | {0xaa, 0x19, 0x001f}, /* 00,19,1f,aa */ | ||
2212 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
2213 | {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */ | ||
2214 | {0xa0, 0x76, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,76,cc */ | ||
2215 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
2216 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
2217 | {0xa0, 0x46, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,46,cc */ | ||
2218 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
2219 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
2220 | {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ | ||
2221 | {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,28,cc */ | ||
2222 | {0xa0, 0x05, ZC3XX_R01D_HSYNC_0}, /* 00,1d,05,cc */ | ||
2223 | {0xa0, 0x1a, ZC3XX_R01E_HSYNC_1}, /* 00,1e,1a,cc */ | ||
2224 | {0xa0, 0x2f, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2f,cc */ | ||
2225 | {} | ||
2226 | }; | ||
2227 | static const struct usb_action hdcs2020b_60HZ[] = { | ||
2228 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
2229 | {0xaa, 0x13, 0x0031}, /* 00,13,31,aa */ | ||
2230 | {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ | ||
2231 | {0xaa, 0x0e, 0x0004}, /* 00,0e,04,aa */ | ||
2232 | {0xaa, 0x19, 0x00cd}, /* 00,19,cd,aa */ | ||
2233 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
2234 | {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */ | ||
2235 | {0xa0, 0x62, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,62,cc */ | ||
2236 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
2237 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
2238 | {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3d,cc */ | ||
2239 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
2240 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
2241 | {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ | ||
2242 | {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,28,cc */ | ||
2243 | {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, /* 00,1d,04,cc */ | ||
2244 | {0xa0, 0x18, ZC3XX_R01E_HSYNC_1}, /* 00,1e,18,cc */ | ||
2245 | {0xa0, 0x2c, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2c,cc */ | ||
2246 | {} | ||
2247 | }; | ||
2248 | static const struct usb_action hdcs2020b_NoFliker[] = { | ||
2249 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
2250 | {0xaa, 0x13, 0x0010}, /* 00,13,10,aa */ | ||
2251 | {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ | ||
2252 | {0xaa, 0x0e, 0x0004}, /* 00,0e,04,aa */ | ||
2253 | {0xaa, 0x19, 0x0000}, /* 00,19,00,aa */ | ||
2254 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
2255 | {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */ | ||
2256 | {0xa0, 0x70, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,70,cc */ | ||
2257 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
2258 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
2259 | {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ | ||
2260 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
2261 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
2262 | {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ | ||
2263 | {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ | ||
2264 | {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, /* 00,1d,04,cc */ | ||
2265 | {0xa0, 0x17, ZC3XX_R01E_HSYNC_1}, /* 00,1e,17,cc */ | ||
2266 | {0xa0, 0x2a, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2a,cc */ | ||
2267 | {} | ||
2268 | }; | ||
2269 | |||
2270 | static const struct usb_action hv7131bxx_Initial[] = { | ||
2271 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
2272 | {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, | ||
2273 | {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, | ||
2274 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
2275 | {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, | ||
2276 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ | ||
2277 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
2278 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
2279 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
2280 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
2281 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
2282 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
2283 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, | ||
2284 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, | ||
2285 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, | ||
2286 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, | ||
2287 | {0xaa, 0x30, 0x002d}, | ||
2288 | {0xaa, 0x01, 0x0005}, | ||
2289 | {0xaa, 0x11, 0x0000}, | ||
2290 | {0xaa, 0x13, 0x0001}, /* {0xaa, 0x13, 0x0000}, */ | ||
2291 | {0xaa, 0x14, 0x0001}, | ||
2292 | {0xaa, 0x15, 0x00e8}, | ||
2293 | {0xaa, 0x16, 0x0002}, | ||
2294 | {0xaa, 0x17, 0x0086}, | ||
2295 | {0xaa, 0x31, 0x0038}, | ||
2296 | {0xaa, 0x32, 0x0038}, | ||
2297 | {0xaa, 0x33, 0x0038}, | ||
2298 | {0xaa, 0x5b, 0x0001}, | ||
2299 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
2300 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
2301 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
2302 | {0xa0, 0x68, ZC3XX_R18D_YTARGET}, | ||
2303 | {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, | ||
2304 | {0xa0, 0x00, 0x01ad}, | ||
2305 | {0xa0, 0xc0, 0x019b}, | ||
2306 | {0xa0, 0xa0, 0x019c}, | ||
2307 | {0xa0, 0x02, ZC3XX_R188_MINGAIN}, | ||
2308 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
2309 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
2310 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
2311 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
2312 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
2313 | {0xaa, 0x02, 0x0080}, /* {0xaa, 0x02, 0x0090}; */ | ||
2314 | {0xa1, 0x01, 0x0002}, | ||
2315 | {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT}, | ||
2316 | {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND}, | ||
2317 | {0xa1, 0x01, 0x0091}, | ||
2318 | {0xa1, 0x01, 0x0095}, | ||
2319 | {0xa1, 0x01, 0x0096}, | ||
2320 | |||
2321 | {0xa1, 0x01, 0x0008}, | ||
2322 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ | ||
2323 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
2324 | {0xa1, 0x01, 0x01c8}, | ||
2325 | {0xa1, 0x01, 0x01c9}, | ||
2326 | {0xa1, 0x01, 0x01ca}, | ||
2327 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
2328 | |||
2329 | {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ | ||
2330 | {0xa0, 0xf8, ZC3XX_R10B_RGB01}, | ||
2331 | {0xa0, 0xf8, ZC3XX_R10C_RGB02}, | ||
2332 | {0xa0, 0xf8, ZC3XX_R10D_RGB10}, | ||
2333 | {0xa0, 0x50, ZC3XX_R10E_RGB11}, | ||
2334 | {0xa0, 0xf8, ZC3XX_R10F_RGB12}, | ||
2335 | {0xa0, 0xf8, ZC3XX_R110_RGB20}, | ||
2336 | {0xa0, 0xf8, ZC3XX_R111_RGB21}, | ||
2337 | {0xa0, 0x50, ZC3XX_R112_RGB22}, | ||
2338 | {0xa1, 0x01, 0x0180}, | ||
2339 | {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2340 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
2341 | {0xaa, 0x25, 0x0007}, | ||
2342 | {0xaa, 0x26, 0x00a1}, | ||
2343 | {0xaa, 0x27, 0x0020}, | ||
2344 | {0xaa, 0x20, 0x0000}, | ||
2345 | {0xaa, 0x21, 0x00a0}, | ||
2346 | {0xaa, 0x22, 0x0016}, | ||
2347 | {0xaa, 0x23, 0x0040}, | ||
2348 | |||
2349 | {0xa0, 0x10, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 2F */ | ||
2350 | {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 4d */ | ||
2351 | {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
2352 | {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
2353 | {0xa0, 0x86, ZC3XX_R196_ANTIFLICKERMID}, | ||
2354 | {0xa0, 0xa0, ZC3XX_R197_ANTIFLICKERLOW}, | ||
2355 | {0xa0, 0x07, ZC3XX_R18C_AEFREEZE}, | ||
2356 | {0xa0, 0x0f, ZC3XX_R18F_AEUNFREEZE}, | ||
2357 | {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
2358 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
2359 | {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, | ||
2360 | {0xa0, 0xa0, ZC3XX_R01E_HSYNC_1}, | ||
2361 | {0xa0, 0x16, ZC3XX_R01F_HSYNC_2}, | ||
2362 | {0xa0, 0x40, ZC3XX_R020_HSYNC_3}, | ||
2363 | {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, | ||
2364 | {0xa1, 0x01, 0x001d}, | ||
2365 | {0xa1, 0x01, 0x001e}, | ||
2366 | {0xa1, 0x01, 0x001f}, | ||
2367 | {0xa1, 0x01, 0x0020}, | ||
2368 | {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2369 | {0xa1, 0x01, 0x0180}, | ||
2370 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2371 | {0xa0, 0x40, ZC3XX_R116_RGAIN}, | ||
2372 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, | ||
2373 | {0xa0, 0x40, ZC3XX_R118_BGAIN}, | ||
2374 | /* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */ | ||
2375 | {} | ||
2376 | }; | ||
2377 | |||
2378 | static const struct usb_action hv7131bxx_InitialScale[] = { | ||
2379 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
2380 | {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, | ||
2381 | {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, | ||
2382 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
2383 | {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, | ||
2384 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ | ||
2385 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
2386 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
2387 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
2388 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
2389 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
2390 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
2391 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, | ||
2392 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, | ||
2393 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, | ||
2394 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, | ||
2395 | {0xaa, 0x30, 0x002d}, | ||
2396 | {0xaa, 0x01, 0x0005}, | ||
2397 | {0xaa, 0x11, 0x0001}, | ||
2398 | {0xaa, 0x13, 0x0000}, /* {0xaa, 0x13, 0x0001}; */ | ||
2399 | {0xaa, 0x14, 0x0001}, | ||
2400 | {0xaa, 0x15, 0x00e6}, | ||
2401 | {0xaa, 0x16, 0x0002}, | ||
2402 | {0xaa, 0x17, 0x0086}, | ||
2403 | {0xaa, 0x31, 0x0038}, | ||
2404 | {0xaa, 0x32, 0x0038}, | ||
2405 | {0xaa, 0x33, 0x0038}, | ||
2406 | {0xaa, 0x5b, 0x0001}, | ||
2407 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
2408 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
2409 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
2410 | {0xa0, 0x70, ZC3XX_R18D_YTARGET}, | ||
2411 | {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, | ||
2412 | {0xa0, 0x00, 0x01ad}, | ||
2413 | {0xa0, 0xc0, 0x019b}, | ||
2414 | {0xa0, 0xa0, 0x019c}, | ||
2415 | {0xa0, 0x02, ZC3XX_R188_MINGAIN}, | ||
2416 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
2417 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
2418 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
2419 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
2420 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
2421 | {0xaa, 0x02, 0x0090}, /* {0xaa, 0x02, 0x0080}, */ | ||
2422 | {0xa1, 0x01, 0x0002}, | ||
2423 | {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT}, | ||
2424 | {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND}, | ||
2425 | {0xa1, 0x01, 0x0091}, | ||
2426 | {0xa1, 0x01, 0x0095}, | ||
2427 | {0xa1, 0x01, 0x0096}, | ||
2428 | {0xa1, 0x01, 0x0008}, | ||
2429 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ | ||
2430 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
2431 | {0xa1, 0x01, 0x01c8}, | ||
2432 | {0xa1, 0x01, 0x01c9}, | ||
2433 | {0xa1, 0x01, 0x01ca}, | ||
2434 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
2435 | |||
2436 | {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ | ||
2437 | {0xa0, 0xf8, ZC3XX_R10B_RGB01}, | ||
2438 | {0xa0, 0xf8, ZC3XX_R10C_RGB02}, | ||
2439 | {0xa0, 0xf8, ZC3XX_R10D_RGB10}, | ||
2440 | {0xa0, 0x50, ZC3XX_R10E_RGB11}, | ||
2441 | {0xa0, 0xf8, ZC3XX_R10F_RGB12}, | ||
2442 | {0xa0, 0xf8, ZC3XX_R110_RGB20}, | ||
2443 | {0xa0, 0xf8, ZC3XX_R111_RGB21}, | ||
2444 | {0xa0, 0x50, ZC3XX_R112_RGB22}, | ||
2445 | {0xa1, 0x01, 0x0180}, | ||
2446 | {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2447 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
2448 | {0xaa, 0x25, 0x0007}, | ||
2449 | {0xaa, 0x26, 0x00a1}, | ||
2450 | {0xaa, 0x27, 0x0020}, | ||
2451 | {0xaa, 0x20, 0x0000}, | ||
2452 | {0xaa, 0x21, 0x0040}, | ||
2453 | {0xaa, 0x22, 0x0013}, | ||
2454 | {0xaa, 0x23, 0x004c}, | ||
2455 | {0xa0, 0x10, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 2f */ | ||
2456 | {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 4d */ | ||
2457 | {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, /* 60 */ | ||
2458 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
2459 | {0xa0, 0xc3, ZC3XX_R196_ANTIFLICKERMID}, | ||
2460 | {0xa0, 0x50, ZC3XX_R197_ANTIFLICKERLOW}, | ||
2461 | {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, | ||
2462 | {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, | ||
2463 | {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
2464 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
2465 | {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, | ||
2466 | {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, | ||
2467 | {0xa0, 0x13, ZC3XX_R01F_HSYNC_2}, | ||
2468 | {0xa0, 0x4c, ZC3XX_R020_HSYNC_3}, | ||
2469 | {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, | ||
2470 | {0xa1, 0x01, 0x001d}, | ||
2471 | {0xa1, 0x01, 0x001e}, | ||
2472 | {0xa1, 0x01, 0x001f}, | ||
2473 | {0xa1, 0x01, 0x0020}, | ||
2474 | {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2475 | {0xa1, 0x01, 0x0180}, | ||
2476 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2477 | {0xa0, 0x40, ZC3XX_R116_RGAIN}, | ||
2478 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, | ||
2479 | {0xa0, 0x40, ZC3XX_R118_BGAIN}, | ||
2480 | /* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */ | ||
2481 | {} | ||
2482 | }; | ||
2483 | |||
2484 | static const struct usb_action hv7131cxx_Initial[] = { | ||
2485 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
2486 | {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, | ||
2487 | {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, | ||
2488 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
2489 | {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, | ||
2490 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | ||
2491 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
2492 | {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
2493 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
2494 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
2495 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
2496 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
2497 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, | ||
2498 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, | ||
2499 | {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, | ||
2500 | {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, | ||
2501 | {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, | ||
2502 | {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, | ||
2503 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, | ||
2504 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, | ||
2505 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
2506 | {0xaa, 0x01, 0x000c}, | ||
2507 | {0xaa, 0x11, 0x0000}, | ||
2508 | {0xaa, 0x13, 0x0000}, | ||
2509 | {0xaa, 0x14, 0x0001}, | ||
2510 | {0xaa, 0x15, 0x00e8}, | ||
2511 | {0xaa, 0x16, 0x0002}, | ||
2512 | {0xaa, 0x17, 0x0088}, | ||
2513 | |||
2514 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
2515 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
2516 | {0xa0, 0x89, ZC3XX_R18D_YTARGET}, | ||
2517 | {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, | ||
2518 | {0xa0, 0x00, 0x01ad}, | ||
2519 | {0xa0, 0xc0, 0x019b}, | ||
2520 | {0xa0, 0xa0, 0x019c}, | ||
2521 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
2522 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
2523 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
2524 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
2525 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
2526 | {0xa1, 0x01, 0x0002}, | ||
2527 | {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT}, | ||
2528 | {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND}, | ||
2529 | {0xa1, 0x01, 0x0091}, | ||
2530 | {0xa1, 0x01, 0x0095}, | ||
2531 | {0xa1, 0x01, 0x0096}, | ||
2532 | |||
2533 | {0xa1, 0x01, 0x0008}, | ||
2534 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ | ||
2535 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
2536 | {0xa1, 0x01, 0x01c8}, | ||
2537 | {0xa1, 0x01, 0x01c9}, | ||
2538 | {0xa1, 0x01, 0x01ca}, | ||
2539 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
2540 | |||
2541 | {0xa0, 0x60, ZC3XX_R10A_RGB00}, /* matrix */ | ||
2542 | {0xa0, 0xf0, ZC3XX_R10B_RGB01}, | ||
2543 | {0xa0, 0xf0, ZC3XX_R10C_RGB02}, | ||
2544 | {0xa0, 0xf0, ZC3XX_R10D_RGB10}, | ||
2545 | {0xa0, 0x60, ZC3XX_R10E_RGB11}, | ||
2546 | {0xa0, 0xf0, ZC3XX_R10F_RGB12}, | ||
2547 | {0xa0, 0xf0, ZC3XX_R110_RGB20}, | ||
2548 | {0xa0, 0xf0, ZC3XX_R111_RGB21}, | ||
2549 | {0xa0, 0x60, ZC3XX_R112_RGB22}, | ||
2550 | {0xa1, 0x01, 0x0180}, | ||
2551 | {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2552 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
2553 | {0xaa, 0x25, 0x0007}, | ||
2554 | {0xaa, 0x26, 0x0053}, | ||
2555 | {0xaa, 0x27, 0x0000}, | ||
2556 | |||
2557 | {0xa0, 0x10, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 2f */ | ||
2558 | {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 9b */ | ||
2559 | {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, /* 80 */ | ||
2560 | {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
2561 | {0xa0, 0xd4, ZC3XX_R196_ANTIFLICKERMID}, | ||
2562 | {0xa0, 0xc0, ZC3XX_R197_ANTIFLICKERLOW}, | ||
2563 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, | ||
2564 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, | ||
2565 | {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, | ||
2566 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
2567 | {0xa0, 0x13, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
2568 | {0xa1, 0x01, 0x001d}, | ||
2569 | {0xa1, 0x01, 0x001e}, | ||
2570 | {0xa1, 0x01, 0x001f}, | ||
2571 | {0xa1, 0x01, 0x0020}, | ||
2572 | {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2573 | {0xa1, 0x01, 0x0180}, | ||
2574 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2575 | {} | ||
2576 | }; | ||
2577 | |||
2578 | static const struct usb_action hv7131cxx_InitialScale[] = { | ||
2579 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
2580 | |||
2581 | {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* diff */ | ||
2582 | {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, | ||
2583 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
2584 | {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, | ||
2585 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | ||
2586 | |||
2587 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
2588 | {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
2589 | |||
2590 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
2591 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
2592 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
2593 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 1e0 */ | ||
2594 | |||
2595 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, | ||
2596 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, | ||
2597 | {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, | ||
2598 | {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, | ||
2599 | {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, | ||
2600 | {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, | ||
2601 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, | ||
2602 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, | ||
2603 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
2604 | {0xaa, 0x01, 0x000c}, | ||
2605 | {0xaa, 0x11, 0x0000}, | ||
2606 | {0xaa, 0x13, 0x0000}, | ||
2607 | {0xaa, 0x14, 0x0001}, | ||
2608 | {0xaa, 0x15, 0x00e8}, | ||
2609 | {0xaa, 0x16, 0x0002}, | ||
2610 | {0xaa, 0x17, 0x0088}, | ||
2611 | |||
2612 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00 */ | ||
2613 | |||
2614 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
2615 | {0xa0, 0x89, ZC3XX_R18D_YTARGET}, | ||
2616 | {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, | ||
2617 | {0xa0, 0x00, 0x01ad}, | ||
2618 | {0xa0, 0xc0, 0x019b}, | ||
2619 | {0xa0, 0xa0, 0x019c}, | ||
2620 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
2621 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
2622 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
2623 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
2624 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
2625 | {0xa1, 0x01, 0x0002}, | ||
2626 | {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT}, | ||
2627 | /* read the i2c chips ident */ | ||
2628 | {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND}, | ||
2629 | {0xa1, 0x01, 0x0091}, | ||
2630 | {0xa1, 0x01, 0x0095}, | ||
2631 | {0xa1, 0x01, 0x0096}, | ||
2632 | |||
2633 | {0xa1, 0x01, 0x0008}, | ||
2634 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ | ||
2635 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
2636 | {0xa1, 0x01, 0x01c8}, | ||
2637 | {0xa1, 0x01, 0x01c9}, | ||
2638 | {0xa1, 0x01, 0x01ca}, | ||
2639 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
2640 | |||
2641 | {0xa0, 0x60, ZC3XX_R10A_RGB00}, /* matrix */ | ||
2642 | {0xa0, 0xf0, ZC3XX_R10B_RGB01}, | ||
2643 | {0xa0, 0xf0, ZC3XX_R10C_RGB02}, | ||
2644 | {0xa0, 0xf0, ZC3XX_R10D_RGB10}, | ||
2645 | {0xa0, 0x60, ZC3XX_R10E_RGB11}, | ||
2646 | {0xa0, 0xf0, ZC3XX_R10F_RGB12}, | ||
2647 | {0xa0, 0xf0, ZC3XX_R110_RGB20}, | ||
2648 | {0xa0, 0xf0, ZC3XX_R111_RGB21}, | ||
2649 | {0xa0, 0x60, ZC3XX_R112_RGB22}, | ||
2650 | {0xa1, 0x01, 0x0180}, | ||
2651 | {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2652 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
2653 | {0xaa, 0x25, 0x0007}, | ||
2654 | {0xaa, 0x26, 0x0053}, | ||
2655 | {0xaa, 0x27, 0x0000}, | ||
2656 | |||
2657 | {0xa0, 0x10, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 2f */ | ||
2658 | {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 9b */ | ||
2659 | {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, /* 80 */ | ||
2660 | |||
2661 | {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
2662 | {0xa0, 0xd4, ZC3XX_R196_ANTIFLICKERMID}, | ||
2663 | {0xa0, 0xc0, ZC3XX_R197_ANTIFLICKERLOW}, | ||
2664 | |||
2665 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, | ||
2666 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, | ||
2667 | {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, | ||
2668 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
2669 | {0xa0, 0x13, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
2670 | {0xa1, 0x01, 0x001d}, | ||
2671 | {0xa1, 0x01, 0x001e}, | ||
2672 | {0xa1, 0x01, 0x001f}, | ||
2673 | {0xa1, 0x01, 0x0020}, | ||
2674 | {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2675 | {0xa1, 0x01, 0x0180}, | ||
2676 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2677 | {} | ||
2678 | }; | ||
2679 | |||
2680 | static const struct usb_action icm105axx_Initial[] = { | ||
2681 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
2682 | {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, | ||
2683 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | ||
2684 | {0xa0, 0x0c, ZC3XX_R010_CMOSSENSORSELECT}, | ||
2685 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
2686 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
2687 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
2688 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
2689 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
2690 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
2691 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
2692 | {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR}, | ||
2693 | {0xa0, 0x00, ZC3XX_R097_WINYSTARTHIGH}, | ||
2694 | {0xa0, 0x01, ZC3XX_R098_WINYSTARTLOW}, | ||
2695 | {0xa0, 0x00, ZC3XX_R099_WINXSTARTHIGH}, | ||
2696 | {0xa0, 0x01, ZC3XX_R09A_WINXSTARTLOW}, | ||
2697 | {0xa0, 0x01, ZC3XX_R11A_FIRSTYLOW}, | ||
2698 | {0xa0, 0x01, ZC3XX_R11C_FIRSTXLOW}, | ||
2699 | {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, | ||
2700 | {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, | ||
2701 | {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, | ||
2702 | {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, | ||
2703 | {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, | ||
2704 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
2705 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
2706 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
2707 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
2708 | {0xaa, 0x01, 0x0010}, | ||
2709 | {0xaa, 0x03, 0x0000}, | ||
2710 | {0xaa, 0x04, 0x0001}, | ||
2711 | {0xaa, 0x05, 0x0020}, | ||
2712 | {0xaa, 0x06, 0x0001}, | ||
2713 | {0xaa, 0x08, 0x0000}, | ||
2714 | {0xaa, 0x03, 0x0001}, | ||
2715 | {0xaa, 0x04, 0x0011}, | ||
2716 | {0xaa, 0x05, 0x00a0}, | ||
2717 | {0xaa, 0x06, 0x0001}, | ||
2718 | {0xaa, 0x08, 0x0000}, | ||
2719 | {0xaa, 0x03, 0x0002}, | ||
2720 | {0xaa, 0x04, 0x0013}, | ||
2721 | {0xaa, 0x05, 0x0020}, | ||
2722 | {0xaa, 0x06, 0x0001}, | ||
2723 | {0xaa, 0x08, 0x0000}, | ||
2724 | {0xaa, 0x03, 0x0003}, | ||
2725 | {0xaa, 0x04, 0x0015}, | ||
2726 | {0xaa, 0x05, 0x0020}, | ||
2727 | {0xaa, 0x06, 0x0005}, | ||
2728 | {0xaa, 0x08, 0x0000}, | ||
2729 | {0xaa, 0x03, 0x0004}, | ||
2730 | {0xaa, 0x04, 0x0017}, | ||
2731 | {0xaa, 0x05, 0x0020}, | ||
2732 | {0xaa, 0x06, 0x000d}, | ||
2733 | {0xaa, 0x08, 0x0000}, | ||
2734 | {0xaa, 0x03, 0x0005}, | ||
2735 | {0xaa, 0x04, 0x0019}, | ||
2736 | {0xaa, 0x05, 0x0020}, | ||
2737 | {0xaa, 0x06, 0x0005}, | ||
2738 | {0xaa, 0x08, 0x0000}, | ||
2739 | {0xaa, 0x03, 0x0006}, | ||
2740 | {0xaa, 0x04, 0x0017}, | ||
2741 | {0xaa, 0x05, 0x0026}, | ||
2742 | {0xaa, 0x06, 0x0005}, | ||
2743 | {0xaa, 0x08, 0x0000}, | ||
2744 | {0xaa, 0x03, 0x0007}, | ||
2745 | {0xaa, 0x04, 0x0019}, | ||
2746 | {0xaa, 0x05, 0x0022}, | ||
2747 | {0xaa, 0x06, 0x0005}, | ||
2748 | {0xaa, 0x08, 0x0000}, | ||
2749 | {0xaa, 0x03, 0x0008}, | ||
2750 | {0xaa, 0x04, 0x0021}, | ||
2751 | {0xaa, 0x05, 0x00aa}, | ||
2752 | {0xaa, 0x06, 0x0005}, | ||
2753 | {0xaa, 0x08, 0x0000}, | ||
2754 | {0xaa, 0x03, 0x0009}, | ||
2755 | {0xaa, 0x04, 0x0023}, | ||
2756 | {0xaa, 0x05, 0x00aa}, | ||
2757 | {0xaa, 0x06, 0x000d}, | ||
2758 | {0xaa, 0x08, 0x0000}, | ||
2759 | {0xaa, 0x03, 0x000a}, | ||
2760 | {0xaa, 0x04, 0x0025}, | ||
2761 | {0xaa, 0x05, 0x00aa}, | ||
2762 | {0xaa, 0x06, 0x0005}, | ||
2763 | {0xaa, 0x08, 0x0000}, | ||
2764 | {0xaa, 0x03, 0x000b}, | ||
2765 | {0xaa, 0x04, 0x00ec}, | ||
2766 | {0xaa, 0x05, 0x002e}, | ||
2767 | {0xaa, 0x06, 0x0005}, | ||
2768 | {0xaa, 0x08, 0x0000}, | ||
2769 | {0xaa, 0x03, 0x000c}, | ||
2770 | {0xaa, 0x04, 0x00fa}, | ||
2771 | {0xaa, 0x05, 0x002a}, | ||
2772 | {0xaa, 0x06, 0x0005}, | ||
2773 | {0xaa, 0x08, 0x0000}, | ||
2774 | {0xaa, 0x07, 0x000d}, | ||
2775 | {0xaa, 0x01, 0x0005}, | ||
2776 | {0xaa, 0x94, 0x0002}, | ||
2777 | {0xaa, 0x90, 0x0000}, | ||
2778 | {0xaa, 0x91, 0x001f}, | ||
2779 | {0xaa, 0x10, 0x0064}, | ||
2780 | {0xaa, 0x9b, 0x00f0}, | ||
2781 | {0xaa, 0x9c, 0x0002}, | ||
2782 | {0xaa, 0x14, 0x001a}, | ||
2783 | {0xaa, 0x20, 0x0080}, | ||
2784 | {0xaa, 0x22, 0x0080}, | ||
2785 | {0xaa, 0x24, 0x0080}, | ||
2786 | {0xaa, 0x26, 0x0080}, | ||
2787 | {0xaa, 0x00, 0x0084}, | ||
2788 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
2789 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
2790 | {0xaa, 0xa8, 0x00c0}, | ||
2791 | {0xa1, 0x01, 0x0002}, | ||
2792 | {0xa1, 0x01, 0x0008}, | ||
2793 | {0xa1, 0x01, 0x0180}, | ||
2794 | {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2795 | {0xa0, 0x40, ZC3XX_R116_RGAIN}, | ||
2796 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, | ||
2797 | {0xa0, 0x40, ZC3XX_R118_BGAIN}, | ||
2798 | {0xa1, 0x01, 0x0008}, | ||
2799 | |||
2800 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ | ||
2801 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
2802 | {0xa1, 0x01, 0x01c8}, | ||
2803 | {0xa1, 0x01, 0x01c9}, | ||
2804 | {0xa1, 0x01, 0x01ca}, | ||
2805 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
2806 | {0xa0, 0x52, ZC3XX_R10A_RGB00}, /* matrix */ | ||
2807 | {0xa0, 0xf7, ZC3XX_R10B_RGB01}, | ||
2808 | {0xa0, 0xf7, ZC3XX_R10C_RGB02}, | ||
2809 | {0xa0, 0xf7, ZC3XX_R10D_RGB10}, | ||
2810 | {0xa0, 0x52, ZC3XX_R10E_RGB11}, | ||
2811 | {0xa0, 0xf7, ZC3XX_R10F_RGB12}, | ||
2812 | {0xa0, 0xf7, ZC3XX_R110_RGB20}, | ||
2813 | {0xa0, 0xf7, ZC3XX_R111_RGB21}, | ||
2814 | {0xa0, 0x52, ZC3XX_R112_RGB22}, | ||
2815 | {0xa1, 0x01, 0x0180}, | ||
2816 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2817 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
2818 | {0xaa, 0x0d, 0x0003}, | ||
2819 | {0xaa, 0x0c, 0x008c}, | ||
2820 | {0xaa, 0x0e, 0x0095}, | ||
2821 | {0xaa, 0x0f, 0x0002}, | ||
2822 | {0xaa, 0x1c, 0x0094}, | ||
2823 | {0xaa, 0x1d, 0x0002}, | ||
2824 | {0xaa, 0x20, 0x0080}, | ||
2825 | {0xaa, 0x22, 0x0080}, | ||
2826 | {0xaa, 0x24, 0x0080}, | ||
2827 | {0xaa, 0x26, 0x0080}, | ||
2828 | {0xaa, 0x00, 0x0084}, | ||
2829 | {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, | ||
2830 | {0xa0, 0x94, ZC3XX_R0A4_EXPOSURETIMELOW}, | ||
2831 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, | ||
2832 | {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, | ||
2833 | {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
2834 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
2835 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, | ||
2836 | {0xa0, 0x84, ZC3XX_R197_ANTIFLICKERLOW}, | ||
2837 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, | ||
2838 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, | ||
2839 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
2840 | {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
2841 | {0xa0, 0xe3, ZC3XX_R01D_HSYNC_0}, | ||
2842 | {0xa0, 0xec, ZC3XX_R01E_HSYNC_1}, | ||
2843 | {0xa0, 0xf5, ZC3XX_R01F_HSYNC_2}, | ||
2844 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, | ||
2845 | {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
2846 | {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, | ||
2847 | {0xa0, 0xc0, ZC3XX_R11D_GLOBALGAIN}, | ||
2848 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2849 | {0xa1, 0x01, 0x0180}, | ||
2850 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2851 | {0xa0, 0x40, ZC3XX_R116_RGAIN}, | ||
2852 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, | ||
2853 | {0xa0, 0x40, ZC3XX_R118_BGAIN}, | ||
2854 | {} | ||
2855 | }; | ||
2856 | |||
2857 | static const struct usb_action icm105axx_InitialScale[] = { | ||
2858 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
2859 | {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, | ||
2860 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | ||
2861 | {0xa0, 0x0c, ZC3XX_R010_CMOSSENSORSELECT}, | ||
2862 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
2863 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
2864 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
2865 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
2866 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
2867 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
2868 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
2869 | {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR}, | ||
2870 | {0xa0, 0x00, ZC3XX_R097_WINYSTARTHIGH}, | ||
2871 | {0xa0, 0x02, ZC3XX_R098_WINYSTARTLOW}, | ||
2872 | {0xa0, 0x00, ZC3XX_R099_WINXSTARTHIGH}, | ||
2873 | {0xa0, 0x02, ZC3XX_R09A_WINXSTARTLOW}, | ||
2874 | {0xa0, 0x02, ZC3XX_R11A_FIRSTYLOW}, | ||
2875 | {0xa0, 0x02, ZC3XX_R11C_FIRSTXLOW}, | ||
2876 | {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, | ||
2877 | {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, | ||
2878 | {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, | ||
2879 | {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, | ||
2880 | {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, | ||
2881 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
2882 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
2883 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
2884 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
2885 | {0xaa, 0x01, 0x0010}, | ||
2886 | {0xaa, 0x03, 0x0000}, | ||
2887 | {0xaa, 0x04, 0x0001}, | ||
2888 | {0xaa, 0x05, 0x0020}, | ||
2889 | {0xaa, 0x06, 0x0001}, | ||
2890 | {0xaa, 0x08, 0x0000}, | ||
2891 | {0xaa, 0x03, 0x0001}, | ||
2892 | {0xaa, 0x04, 0x0011}, | ||
2893 | {0xaa, 0x05, 0x00a0}, | ||
2894 | {0xaa, 0x06, 0x0001}, | ||
2895 | {0xaa, 0x08, 0x0000}, | ||
2896 | {0xaa, 0x03, 0x0002}, | ||
2897 | {0xaa, 0x04, 0x0013}, | ||
2898 | {0xaa, 0x05, 0x0020}, | ||
2899 | {0xaa, 0x06, 0x0001}, | ||
2900 | {0xaa, 0x08, 0x0000}, | ||
2901 | {0xaa, 0x03, 0x0003}, | ||
2902 | {0xaa, 0x04, 0x0015}, | ||
2903 | {0xaa, 0x05, 0x0020}, | ||
2904 | {0xaa, 0x06, 0x0005}, | ||
2905 | {0xaa, 0x08, 0x0000}, | ||
2906 | {0xaa, 0x03, 0x0004}, | ||
2907 | {0xaa, 0x04, 0x0017}, | ||
2908 | {0xaa, 0x05, 0x0020}, | ||
2909 | {0xaa, 0x06, 0x000d}, | ||
2910 | {0xaa, 0x08, 0x0000}, | ||
2911 | {0xaa, 0x03, 0x0005}, | ||
2912 | {0xa0, 0x04, ZC3XX_R092_I2CADDRESSSELECT}, | ||
2913 | {0xa0, 0x19, ZC3XX_R093_I2CSETVALUE}, | ||
2914 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
2915 | {0xa1, 0x01, 0x0091}, | ||
2916 | {0xaa, 0x05, 0x0020}, | ||
2917 | {0xaa, 0x06, 0x0005}, | ||
2918 | {0xaa, 0x08, 0x0000}, | ||
2919 | {0xaa, 0x03, 0x0006}, | ||
2920 | {0xaa, 0x04, 0x0017}, | ||
2921 | {0xaa, 0x05, 0x0026}, | ||
2922 | {0xaa, 0x06, 0x0005}, | ||
2923 | {0xaa, 0x08, 0x0000}, | ||
2924 | {0xaa, 0x03, 0x0007}, | ||
2925 | {0xaa, 0x04, 0x0019}, | ||
2926 | {0xaa, 0x05, 0x0022}, | ||
2927 | {0xaa, 0x06, 0x0005}, | ||
2928 | {0xaa, 0x08, 0x0000}, | ||
2929 | {0xaa, 0x03, 0x0008}, | ||
2930 | {0xaa, 0x04, 0x0021}, | ||
2931 | {0xaa, 0x05, 0x00aa}, | ||
2932 | {0xaa, 0x06, 0x0005}, | ||
2933 | {0xaa, 0x08, 0x0000}, | ||
2934 | {0xaa, 0x03, 0x0009}, | ||
2935 | {0xaa, 0x04, 0x0023}, | ||
2936 | {0xaa, 0x05, 0x00aa}, | ||
2937 | {0xaa, 0x06, 0x000d}, | ||
2938 | {0xaa, 0x08, 0x0000}, | ||
2939 | {0xaa, 0x03, 0x000a}, | ||
2940 | {0xaa, 0x04, 0x0025}, | ||
2941 | {0xaa, 0x05, 0x00aa}, | ||
2942 | {0xaa, 0x06, 0x0005}, | ||
2943 | {0xaa, 0x08, 0x0000}, | ||
2944 | {0xaa, 0x03, 0x000b}, | ||
2945 | {0xaa, 0x04, 0x00ec}, | ||
2946 | {0xaa, 0x05, 0x002e}, | ||
2947 | {0xaa, 0x06, 0x0005}, | ||
2948 | {0xaa, 0x08, 0x0000}, | ||
2949 | {0xaa, 0x03, 0x000c}, | ||
2950 | {0xaa, 0x04, 0x00fa}, | ||
2951 | {0xaa, 0x05, 0x002a}, | ||
2952 | {0xaa, 0x06, 0x0005}, | ||
2953 | {0xaa, 0x08, 0x0000}, | ||
2954 | {0xaa, 0x07, 0x000d}, | ||
2955 | {0xaa, 0x01, 0x0005}, | ||
2956 | {0xaa, 0x94, 0x0002}, | ||
2957 | {0xaa, 0x90, 0x0000}, | ||
2958 | {0xaa, 0x91, 0x0010}, | ||
2959 | {0xaa, 0x10, 0x0064}, | ||
2960 | {0xaa, 0x9b, 0x00f0}, | ||
2961 | {0xaa, 0x9c, 0x0002}, | ||
2962 | {0xaa, 0x14, 0x001a}, | ||
2963 | {0xaa, 0x20, 0x0080}, | ||
2964 | {0xaa, 0x22, 0x0080}, | ||
2965 | {0xaa, 0x24, 0x0080}, | ||
2966 | {0xaa, 0x26, 0x0080}, | ||
2967 | {0xaa, 0x00, 0x0084}, | ||
2968 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
2969 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
2970 | {0xaa, 0xa8, 0x0080}, | ||
2971 | {0xa0, 0x78, ZC3XX_R18D_YTARGET}, | ||
2972 | {0xa1, 0x01, 0x0002}, | ||
2973 | {0xa1, 0x01, 0x0008}, | ||
2974 | {0xa1, 0x01, 0x0180}, | ||
2975 | {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2976 | {0xa0, 0x40, ZC3XX_R116_RGAIN}, | ||
2977 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, | ||
2978 | {0xa0, 0x40, ZC3XX_R118_BGAIN}, | ||
2979 | {0xa1, 0x01, 0x0008}, | ||
2980 | |||
2981 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ | ||
2982 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
2983 | {0xa1, 0x01, 0x01c8}, | ||
2984 | {0xa1, 0x01, 0x01c9}, | ||
2985 | {0xa1, 0x01, 0x01ca}, | ||
2986 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
2987 | |||
2988 | {0xa0, 0x52, ZC3XX_R10A_RGB00}, /* matrix */ | ||
2989 | {0xa0, 0xf7, ZC3XX_R10B_RGB01}, | ||
2990 | {0xa0, 0xf7, ZC3XX_R10C_RGB02}, | ||
2991 | {0xa0, 0xf7, ZC3XX_R10D_RGB10}, | ||
2992 | {0xa0, 0x52, ZC3XX_R10E_RGB11}, | ||
2993 | {0xa0, 0xf7, ZC3XX_R10F_RGB12}, | ||
2994 | {0xa0, 0xf7, ZC3XX_R110_RGB20}, | ||
2995 | {0xa0, 0xf7, ZC3XX_R111_RGB21}, | ||
2996 | {0xa0, 0x52, ZC3XX_R112_RGB22}, | ||
2997 | {0xa1, 0x01, 0x0180}, | ||
2998 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
2999 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
3000 | {0xaa, 0x0d, 0x0003}, | ||
3001 | {0xaa, 0x0c, 0x0020}, | ||
3002 | {0xaa, 0x0e, 0x000e}, | ||
3003 | {0xaa, 0x0f, 0x0002}, | ||
3004 | {0xaa, 0x1c, 0x000d}, | ||
3005 | {0xaa, 0x1d, 0x0002}, | ||
3006 | {0xaa, 0x20, 0x0080}, | ||
3007 | {0xaa, 0x22, 0x0080}, | ||
3008 | {0xaa, 0x24, 0x0080}, | ||
3009 | {0xaa, 0x26, 0x0080}, | ||
3010 | {0xaa, 0x00, 0x0084}, | ||
3011 | {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, | ||
3012 | {0xa0, 0x0d, ZC3XX_R0A4_EXPOSURETIMELOW}, | ||
3013 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, | ||
3014 | {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, | ||
3015 | {0xa0, 0x1a, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
3016 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
3017 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, | ||
3018 | {0xa0, 0x4b, ZC3XX_R197_ANTIFLICKERLOW}, | ||
3019 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, | ||
3020 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, | ||
3021 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
3022 | {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
3023 | {0xa0, 0xc8, ZC3XX_R01D_HSYNC_0}, | ||
3024 | {0xa0, 0xd8, ZC3XX_R01E_HSYNC_1}, | ||
3025 | {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, | ||
3026 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, | ||
3027 | {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
3028 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
3029 | {0xa1, 0x01, 0x0180}, | ||
3030 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
3031 | {0xa0, 0x40, ZC3XX_R116_RGAIN}, | ||
3032 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, | ||
3033 | {0xa0, 0x40, ZC3XX_R118_BGAIN}, | ||
3034 | {} | ||
3035 | }; | ||
3036 | static const struct usb_action icm105a_50HZ[] = { | ||
3037 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
3038 | {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ | ||
3039 | {0xaa, 0x0c, 0x0020}, /* 00,0c,20,aa */ | ||
3040 | {0xaa, 0x0e, 0x000e}, /* 00,0e,0e,aa */ | ||
3041 | {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */ | ||
3042 | {0xaa, 0x1c, 0x000d}, /* 00,1c,0d,aa */ | ||
3043 | {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ | ||
3044 | {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */ | ||
3045 | {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */ | ||
3046 | {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ | ||
3047 | {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ | ||
3048 | {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ | ||
3049 | {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */ | ||
3050 | {0xa0, 0x0d, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,0d,cc */ | ||
3051 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
3052 | {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ | ||
3053 | {0xa0, 0x1a, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,1a,cc */ | ||
3054 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
3055 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
3056 | {0xa0, 0x4b, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,4b,cc */ | ||
3057 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
3058 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
3059 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ | ||
3060 | {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,12,cc */ | ||
3061 | {0xa0, 0xc8, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c8,cc */ | ||
3062 | {0xa0, 0xd8, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d8,cc */ | ||
3063 | {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ea,cc */ | ||
3064 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ | ||
3065 | {} | ||
3066 | }; | ||
3067 | static const struct usb_action icm105a_50HZScale[] = { | ||
3068 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
3069 | {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ | ||
3070 | {0xaa, 0x0c, 0x008c}, /* 00,0c,8c,aa */ | ||
3071 | {0xaa, 0x0e, 0x0095}, /* 00,0e,95,aa */ | ||
3072 | {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */ | ||
3073 | {0xaa, 0x1c, 0x0094}, /* 00,1c,94,aa */ | ||
3074 | {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ | ||
3075 | {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */ | ||
3076 | {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */ | ||
3077 | {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ | ||
3078 | {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ | ||
3079 | {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ | ||
3080 | {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */ | ||
3081 | {0xa0, 0x94, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,94,cc */ | ||
3082 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
3083 | {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ | ||
3084 | {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,20,cc */ | ||
3085 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
3086 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
3087 | {0xa0, 0x84, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,84,cc */ | ||
3088 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
3089 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
3090 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ | ||
3091 | {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,12,cc */ | ||
3092 | {0xa0, 0xe3, ZC3XX_R01D_HSYNC_0}, /* 00,1d,e3,cc */ | ||
3093 | {0xa0, 0xec, ZC3XX_R01E_HSYNC_1}, /* 00,1e,ec,cc */ | ||
3094 | {0xa0, 0xf5, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f5,cc */ | ||
3095 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ | ||
3096 | {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, /* 01,a7,00,cc */ | ||
3097 | {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */ | ||
3098 | {} | ||
3099 | }; | ||
3100 | static const struct usb_action icm105a_60HZ[] = { | ||
3101 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
3102 | {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ | ||
3103 | {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */ | ||
3104 | {0xaa, 0x0e, 0x000d}, /* 00,0e,0d,aa */ | ||
3105 | {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */ | ||
3106 | {0xaa, 0x1c, 0x0008}, /* 00,1c,08,aa */ | ||
3107 | {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ | ||
3108 | {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */ | ||
3109 | {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */ | ||
3110 | {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ | ||
3111 | {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ | ||
3112 | {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ | ||
3113 | {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */ | ||
3114 | {0xa0, 0x08, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,08,cc */ | ||
3115 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
3116 | {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ | ||
3117 | {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,10,cc */ | ||
3118 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
3119 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
3120 | {0xa0, 0x41, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,41,cc */ | ||
3121 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
3122 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
3123 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ | ||
3124 | {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,12,cc */ | ||
3125 | {0xa0, 0xc1, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c1,cc */ | ||
3126 | {0xa0, 0xd4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d4,cc */ | ||
3127 | {0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */ | ||
3128 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ | ||
3129 | {} | ||
3130 | }; | ||
3131 | static const struct usb_action icm105a_60HZScale[] = { | ||
3132 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
3133 | {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ | ||
3134 | {0xaa, 0x0c, 0x0008}, /* 00,0c,08,aa */ | ||
3135 | {0xaa, 0x0e, 0x0086}, /* 00,0e,86,aa */ | ||
3136 | {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */ | ||
3137 | {0xaa, 0x1c, 0x0085}, /* 00,1c,85,aa */ | ||
3138 | {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ | ||
3139 | {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */ | ||
3140 | {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */ | ||
3141 | {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ | ||
3142 | {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ | ||
3143 | {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ | ||
3144 | {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */ | ||
3145 | {0xa0, 0x85, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,85,cc */ | ||
3146 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
3147 | {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ | ||
3148 | {0xa0, 0x08, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,08,cc */ | ||
3149 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
3150 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
3151 | {0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,81,cc */ | ||
3152 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
3153 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
3154 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ | ||
3155 | {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,12,cc */ | ||
3156 | {0xa0, 0xc2, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c2,cc */ | ||
3157 | {0xa0, 0xd6, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d6,cc */ | ||
3158 | {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ea,cc */ | ||
3159 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ | ||
3160 | {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, /* 01,a7,00,cc */ | ||
3161 | {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */ | ||
3162 | {} | ||
3163 | }; | ||
3164 | static const struct usb_action icm105a_NoFliker[] = { | ||
3165 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
3166 | {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ | ||
3167 | {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */ | ||
3168 | {0xaa, 0x0e, 0x000d}, /* 00,0e,0d,aa */ | ||
3169 | {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */ | ||
3170 | {0xaa, 0x1c, 0x0000}, /* 00,1c,00,aa */ | ||
3171 | {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ | ||
3172 | {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */ | ||
3173 | {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */ | ||
3174 | {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ | ||
3175 | {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ | ||
3176 | {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ | ||
3177 | {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */ | ||
3178 | {0xa0, 0x00, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,00,cc */ | ||
3179 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
3180 | {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ | ||
3181 | {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,20,cc */ | ||
3182 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
3183 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
3184 | {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ | ||
3185 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
3186 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
3187 | {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ | ||
3188 | {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ | ||
3189 | {0xa0, 0xc1, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c1,cc */ | ||
3190 | {0xa0, 0xd4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d4,cc */ | ||
3191 | {0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */ | ||
3192 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ | ||
3193 | {} | ||
3194 | }; | ||
3195 | static const struct usb_action icm105a_NoFlikerScale[] = { | ||
3196 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
3197 | {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ | ||
3198 | {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */ | ||
3199 | {0xaa, 0x0e, 0x0081}, /* 00,0e,81,aa */ | ||
3200 | {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */ | ||
3201 | {0xaa, 0x1c, 0x0080}, /* 00,1c,80,aa */ | ||
3202 | {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ | ||
3203 | {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */ | ||
3204 | {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */ | ||
3205 | {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ | ||
3206 | {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ | ||
3207 | {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ | ||
3208 | {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */ | ||
3209 | {0xa0, 0x80, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,80,cc */ | ||
3210 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
3211 | {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ | ||
3212 | {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,20,cc */ | ||
3213 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
3214 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
3215 | {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ | ||
3216 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
3217 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
3218 | {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ | ||
3219 | {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ | ||
3220 | {0xa0, 0xc1, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c1,cc */ | ||
3221 | {0xa0, 0xd4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d4,cc */ | ||
3222 | {0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */ | ||
3223 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ | ||
3224 | {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, /* 01,a7,00,cc */ | ||
3225 | {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */ | ||
3226 | {} | ||
3227 | }; | ||
3228 | |||
3229 | static const struct usb_action MC501CB_InitialScale[] = { | ||
3230 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ | ||
3231 | {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc */ | ||
3232 | {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ | ||
3233 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ | ||
3234 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ | ||
3235 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ | ||
3236 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ | ||
3237 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ | ||
3238 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ | ||
3239 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ | ||
3240 | {0xa0, 0xd8, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d8,cc */ | ||
3241 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ | ||
3242 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ | ||
3243 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ | ||
3244 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ | ||
3245 | {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, /* 00,9b,01,cc */ | ||
3246 | {0xa0, 0xde, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,de,cc */ | ||
3247 | {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, /* 00,9d,02,cc */ | ||
3248 | {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */ | ||
3249 | {0xa0, 0x33, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,33,cc */ | ||
3250 | {0xa0, 0x34, ZC3XX_R087_EXPTIMEMID}, /* 00,87,34,cc */ | ||
3251 | {0xa0, 0x35, ZC3XX_R088_EXPTIMELOW}, /* 00,88,35,cc */ | ||
3252 | {0xa0, 0xb0, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,b0,cc */ | ||
3253 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ | ||
3254 | {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */ | ||
3255 | {0xaa, 0x01, 0x0003}, /* 00,01,03,aa */ | ||
3256 | {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */ | ||
3257 | {0xaa, 0x03, 0x0000}, /* 00,03,00,aa */ | ||
3258 | {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ | ||
3259 | {0xaa, 0x11, 0x0080}, /* 00,11,80,aa */ | ||
3260 | {0xaa, 0x12, 0x0000}, /* 00,12,00,aa */ | ||
3261 | {0xaa, 0x13, 0x0000}, /* 00,13,00,aa */ | ||
3262 | {0xaa, 0x14, 0x0000}, /* 00,14,00,aa */ | ||
3263 | {0xaa, 0x15, 0x0000}, /* 00,15,00,aa */ | ||
3264 | {0xaa, 0x16, 0x0000}, /* 00,16,00,aa */ | ||
3265 | {0xaa, 0x17, 0x0001}, /* 00,17,01,aa */ | ||
3266 | {0xaa, 0x18, 0x00de}, /* 00,18,de,aa */ | ||
3267 | {0xaa, 0x19, 0x0002}, /* 00,19,02,aa */ | ||
3268 | {0xaa, 0x1a, 0x0086}, /* 00,1a,86,aa */ | ||
3269 | {0xaa, 0x20, 0x00a8}, /* 00,20,a8,aa */ | ||
3270 | {0xaa, 0x22, 0x0000}, /* 00,22,00,aa */ | ||
3271 | {0xaa, 0x23, 0x0000}, /* 00,23,00,aa */ | ||
3272 | {0xaa, 0x24, 0x0000}, /* 00,24,00,aa */ | ||
3273 | {0xaa, 0x40, 0x0033}, /* 00,40,33,aa */ | ||
3274 | {0xaa, 0x41, 0x0077}, /* 00,41,77,aa */ | ||
3275 | {0xaa, 0x42, 0x0053}, /* 00,42,53,aa */ | ||
3276 | {0xaa, 0x43, 0x00b0}, /* 00,43,b0,aa */ | ||
3277 | {0xaa, 0x4b, 0x0001}, /* 00,4b,01,aa */ | ||
3278 | {0xaa, 0x72, 0x0020}, /* 00,72,20,aa */ | ||
3279 | {0xaa, 0x73, 0x0000}, /* 00,73,00,aa */ | ||
3280 | {0xaa, 0x80, 0x0000}, /* 00,80,00,aa */ | ||
3281 | {0xaa, 0x85, 0x0050}, /* 00,85,50,aa */ | ||
3282 | {0xaa, 0x91, 0x0070}, /* 00,91,70,aa */ | ||
3283 | {0xaa, 0x92, 0x0072}, /* 00,92,72,aa */ | ||
3284 | {0xaa, 0x03, 0x0001}, /* 00,03,01,aa */ | ||
3285 | {0xaa, 0x10, 0x00a0}, /* 00,10,a0,aa */ | ||
3286 | {0xaa, 0x11, 0x0001}, /* 00,11,01,aa */ | ||
3287 | {0xaa, 0x30, 0x0000}, /* 00,30,00,aa */ | ||
3288 | {0xaa, 0x60, 0x0000}, /* 00,60,00,aa */ | ||
3289 | {0xaa, 0xa0, ZC3XX_R01A_LASTFRAMESTATE}, /* 00,a0,1a,aa */ | ||
3290 | {0xaa, 0xa1, 0x0000}, /* 00,a1,00,aa */ | ||
3291 | {0xaa, 0xa2, 0x003f}, /* 00,a2,3f,aa */ | ||
3292 | {0xaa, 0xa3, 0x0028}, /* 00,a3,28,aa */ | ||
3293 | {0xaa, 0xa4, 0x0010}, /* 00,a4,10,aa */ | ||
3294 | {0xaa, 0xa5, 0x0020}, /* 00,a5,20,aa */ | ||
3295 | {0xaa, 0xb1, 0x0044}, /* 00,b1,44,aa */ | ||
3296 | {0xaa, 0xd0, 0x0001}, /* 00,d0,01,aa */ | ||
3297 | {0xaa, 0xd1, 0x0085}, /* 00,d1,85,aa */ | ||
3298 | {0xaa, 0xd2, 0x0080}, /* 00,d2,80,aa */ | ||
3299 | {0xaa, 0xd3, 0x0080}, /* 00,d3,80,aa */ | ||
3300 | {0xaa, 0xd4, 0x0080}, /* 00,d4,80,aa */ | ||
3301 | {0xaa, 0xd5, 0x0080}, /* 00,d5,80,aa */ | ||
3302 | {0xaa, 0xc0, 0x00c3}, /* 00,c0,c3,aa */ | ||
3303 | {0xaa, 0xc2, 0x0044}, /* 00,c2,44,aa */ | ||
3304 | {0xaa, 0xc4, 0x0040}, /* 00,c4,40,aa */ | ||
3305 | {0xaa, 0xc5, 0x0020}, /* 00,c5,20,aa */ | ||
3306 | {0xaa, 0xc6, 0x0008}, /* 00,c6,08,aa */ | ||
3307 | {0xaa, 0x03, 0x0004}, /* 00,03,04,aa */ | ||
3308 | {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ | ||
3309 | {0xaa, 0x40, 0x0030}, /* 00,40,30,aa */ | ||
3310 | {0xaa, 0x41, 0x0020}, /* 00,41,20,aa */ | ||
3311 | {0xaa, 0x42, 0x002d}, /* 00,42,2d,aa */ | ||
3312 | {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ | ||
3313 | {0xaa, 0x1c, 0x0050}, /* 00,1C,50,aa */ | ||
3314 | {0xaa, 0x11, 0x0081}, /* 00,11,81,aa */ | ||
3315 | {0xaa, 0x3b, 0x001d}, /* 00,3b,1D,aa */ | ||
3316 | {0xaa, 0x3c, 0x004c}, /* 00,3c,4C,aa */ | ||
3317 | {0xaa, 0x3d, 0x0018}, /* 00,3d,18,aa */ | ||
3318 | {0xaa, 0x3e, 0x006a}, /* 00,3e,6A,aa */ | ||
3319 | {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */ | ||
3320 | {0xaa, 0x52, 0x00ff}, /* 00,52,FF,aa */ | ||
3321 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
3322 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ | ||
3323 | {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */ | ||
3324 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ | ||
3325 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ | ||
3326 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ | ||
3327 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ | ||
3328 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ | ||
3329 | {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ | ||
3330 | {0xaa, 0x03, 0x0002}, /* 00,03,02,aa */ | ||
3331 | {0xaa, 0x51, 0x0027}, /* 00,51,27,aa */ | ||
3332 | {0xaa, 0x52, 0x0020}, /* 00,52,20,aa */ | ||
3333 | {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ | ||
3334 | {0xaa, 0x50, 0x0010}, /* 00,50,10,aa */ | ||
3335 | {0xaa, 0x51, 0x0010}, /* 00,51,10,aa */ | ||
3336 | {0xaa, 0x54, 0x0010}, /* 00,54,10,aa */ | ||
3337 | {0xaa, 0x55, 0x0010}, /* 00,55,10,aa */ | ||
3338 | {0xa0, 0xf0, 0x0199}, /* 01,99,F0,cc */ | ||
3339 | {0xa0, 0x80, 0x019a}, /* 01,9A,80,cc */ | ||
3340 | |||
3341 | {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ | ||
3342 | {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ | ||
3343 | {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */ | ||
3344 | {0xaa, 0x37, 0x004c}, /* 00,37,4C,aa */ | ||
3345 | {0xaa, 0x3b, 0x001d}, /* 00,3B,1D,aa */ | ||
3346 | {} | ||
3347 | }; | ||
3348 | |||
3349 | static const struct usb_action MC501CB_Initial[] = { /* 320x240 */ | ||
3350 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ | ||
3351 | {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */ | ||
3352 | {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ | ||
3353 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ | ||
3354 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ | ||
3355 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ | ||
3356 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ | ||
3357 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ | ||
3358 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ | ||
3359 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ | ||
3360 | {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d0,cc */ | ||
3361 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ | ||
3362 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ | ||
3363 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ | ||
3364 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ | ||
3365 | {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, /* 00,9b,01,cc */ | ||
3366 | {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,d8,cc */ | ||
3367 | {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, /* 00,9d,02,cc */ | ||
3368 | {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */ | ||
3369 | {0xa0, 0x33, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,33,cc */ | ||
3370 | {0xa0, 0x34, ZC3XX_R087_EXPTIMEMID}, /* 00,87,34,cc */ | ||
3371 | {0xa0, 0x35, ZC3XX_R088_EXPTIMELOW}, /* 00,88,35,cc */ | ||
3372 | {0xa0, 0xb0, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,b0,cc */ | ||
3373 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ | ||
3374 | {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */ | ||
3375 | {0xaa, 0x01, 0x0003}, /* 00,01,03,aa */ | ||
3376 | {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */ | ||
3377 | {0xaa, 0x03, 0x0000}, /* 00,03,00,aa */ | ||
3378 | {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ | ||
3379 | {0xaa, 0x11, 0x0080}, /* 00,11,80,aa */ | ||
3380 | {0xaa, 0x12, 0x0000}, /* 00,12,00,aa */ | ||
3381 | {0xaa, 0x13, 0x0000}, /* 00,13,00,aa */ | ||
3382 | {0xaa, 0x14, 0x0000}, /* 00,14,00,aa */ | ||
3383 | {0xaa, 0x15, 0x0000}, /* 00,15,00,aa */ | ||
3384 | {0xaa, 0x16, 0x0000}, /* 00,16,00,aa */ | ||
3385 | {0xaa, 0x17, 0x0001}, /* 00,17,01,aa */ | ||
3386 | {0xaa, 0x18, 0x00d8}, /* 00,18,d8,aa */ | ||
3387 | {0xaa, 0x19, 0x0002}, /* 00,19,02,aa */ | ||
3388 | {0xaa, 0x1a, 0x0088}, /* 00,1a,88,aa */ | ||
3389 | {0xaa, 0x20, 0x00a8}, /* 00,20,a8,aa */ | ||
3390 | {0xaa, 0x22, 0x0000}, /* 00,22,00,aa */ | ||
3391 | {0xaa, 0x23, 0x0000}, /* 00,23,00,aa */ | ||
3392 | {0xaa, 0x24, 0x0000}, /* 00,24,00,aa */ | ||
3393 | {0xaa, 0x40, 0x0033}, /* 00,40,33,aa */ | ||
3394 | {0xaa, 0x41, 0x0077}, /* 00,41,77,aa */ | ||
3395 | {0xaa, 0x42, 0x0053}, /* 00,42,53,aa */ | ||
3396 | {0xaa, 0x43, 0x00b0}, /* 00,43,b0,aa */ | ||
3397 | {0xaa, 0x4b, 0x0001}, /* 00,4b,01,aa */ | ||
3398 | {0xaa, 0x72, 0x0020}, /* 00,72,20,aa */ | ||
3399 | {0xaa, 0x73, 0x0000}, /* 00,73,00,aa */ | ||
3400 | {0xaa, 0x80, 0x0000}, /* 00,80,00,aa */ | ||
3401 | {0xaa, 0x85, 0x0050}, /* 00,85,50,aa */ | ||
3402 | {0xaa, 0x91, 0x0070}, /* 00,91,70,aa */ | ||
3403 | {0xaa, 0x92, 0x0072}, /* 00,92,72,aa */ | ||
3404 | {0xaa, 0x03, 0x0001}, /* 00,03,01,aa */ | ||
3405 | {0xaa, 0x10, 0x00a0}, /* 00,10,a0,aa */ | ||
3406 | {0xaa, 0x11, 0x0001}, /* 00,11,01,aa */ | ||
3407 | {0xaa, 0x30, 0x0000}, /* 00,30,00,aa */ | ||
3408 | {0xaa, 0x60, 0x0000}, /* 00,60,00,aa */ | ||
3409 | {0xaa, 0xa0, ZC3XX_R01A_LASTFRAMESTATE}, /* 00,a0,1a,aa */ | ||
3410 | {0xaa, 0xa1, 0x0000}, /* 00,a1,00,aa */ | ||
3411 | {0xaa, 0xa2, 0x003f}, /* 00,a2,3f,aa */ | ||
3412 | {0xaa, 0xa3, 0x0028}, /* 00,a3,28,aa */ | ||
3413 | {0xaa, 0xa4, 0x0010}, /* 00,a4,10,aa */ | ||
3414 | {0xaa, 0xa5, 0x0020}, /* 00,a5,20,aa */ | ||
3415 | {0xaa, 0xb1, 0x0044}, /* 00,b1,44,aa */ | ||
3416 | {0xaa, 0xd0, 0x0001}, /* 00,d0,01,aa */ | ||
3417 | {0xaa, 0xd1, 0x0085}, /* 00,d1,85,aa */ | ||
3418 | {0xaa, 0xd2, 0x0080}, /* 00,d2,80,aa */ | ||
3419 | {0xaa, 0xd3, 0x0080}, /* 00,d3,80,aa */ | ||
3420 | {0xaa, 0xd4, 0x0080}, /* 00,d4,80,aa */ | ||
3421 | {0xaa, 0xd5, 0x0080}, /* 00,d5,80,aa */ | ||
3422 | {0xaa, 0xc0, 0x00c3}, /* 00,c0,c3,aa */ | ||
3423 | {0xaa, 0xc2, 0x0044}, /* 00,c2,44,aa */ | ||
3424 | {0xaa, 0xc4, 0x0040}, /* 00,c4,40,aa */ | ||
3425 | {0xaa, 0xc5, 0x0020}, /* 00,c5,20,aa */ | ||
3426 | {0xaa, 0xc6, 0x0008}, /* 00,c6,08,aa */ | ||
3427 | {0xaa, 0x03, 0x0004}, /* 00,03,04,aa */ | ||
3428 | {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ | ||
3429 | {0xaa, 0x40, 0x0030}, /* 00,40,30,aa */ | ||
3430 | {0xaa, 0x41, 0x0020}, /* 00,41,20,aa */ | ||
3431 | {0xaa, 0x42, 0x002d}, /* 00,42,2d,aa */ | ||
3432 | {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ | ||
3433 | {0xaa, 0x1c, 0x0050}, /* 00,1c,50,aa */ | ||
3434 | {0xaa, 0x11, 0x0081}, /* 00,11,81,aa */ | ||
3435 | {0xaa, 0x3b, 0x003a}, /* 00,3b,3A,aa */ | ||
3436 | {0xaa, 0x3c, 0x0098}, /* 00,3c,98,aa */ | ||
3437 | {0xaa, 0x3d, 0x0030}, /* 00,3d,30,aa */ | ||
3438 | {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */ | ||
3439 | {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */ | ||
3440 | {0xaa, 0x52, 0x00ff}, /* 00,52,FF,aa */ | ||
3441 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
3442 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ | ||
3443 | {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */ | ||
3444 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ | ||
3445 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ | ||
3446 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ | ||
3447 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ | ||
3448 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ | ||
3449 | {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ | ||
3450 | {0xaa, 0x03, 0x0002}, /* 00,03,02,aa */ | ||
3451 | {0xaa, 0x51, 0x004e}, /* 00,51,4E,aa */ | ||
3452 | {0xaa, 0x52, 0x0041}, /* 00,52,41,aa */ | ||
3453 | {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ | ||
3454 | {0xaa, 0x50, 0x0010}, /* 00,50,10,aa */ | ||
3455 | {0xaa, 0x51, 0x0010}, /* 00,51,10,aa */ | ||
3456 | {0xaa, 0x54, 0x0010}, /* 00,54,10,aa */ | ||
3457 | {0xaa, 0x55, 0x0010}, /* 00,55,10,aa */ | ||
3458 | {0xa0, 0xf0, 0x0199}, /* 01,99,F0,cc */ | ||
3459 | {0xa0, 0x80, 0x019a}, /* 01,9A,80,cc */ | ||
3460 | {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ | ||
3461 | {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ | ||
3462 | {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */ | ||
3463 | {0xaa, 0x37, 0x004c}, /* 00,37,4C,aa */ | ||
3464 | {0xaa, 0x3b, 0x001d}, /* 00,3B,1D,aa */ | ||
3465 | {} | ||
3466 | }; | ||
3467 | |||
3468 | static const struct usb_action MC501CB_50HZ[] = { | ||
3469 | {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ | ||
3470 | {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ | ||
3471 | {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */ | ||
3472 | {0xaa, 0x37, 0x004c}, /* 00,37,4C,aa */ | ||
3473 | {0xaa, 0x3b, 0x001d}, /* 00,3B,1D,aa */ | ||
3474 | {0xaa, 0x3c, 0x004c}, /* 00,3C,4C,aa */ | ||
3475 | {0xaa, 0x3d, 0x001d}, /* 00,3D,1D,aa */ | ||
3476 | {0xaa, 0x3e, 0x004c}, /* 00,3E,4C,aa */ | ||
3477 | {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ | ||
3478 | {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ | ||
3479 | {0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */ | ||
3480 | {0xaa, 0x37, 0x0098}, /* 00,37,98,aa */ | ||
3481 | {0xaa, 0x3b, 0x003a}, /* 00,3B,3A,aa */ | ||
3482 | {} | ||
3483 | }; | ||
3484 | |||
3485 | static const struct usb_action MC501CB_50HZScale[] = { | ||
3486 | {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ | ||
3487 | {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ | ||
3488 | {0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */ | ||
3489 | {0xaa, 0x37, 0x0098}, /* 00,37,98,aa */ | ||
3490 | {0xaa, 0x3b, 0x003a}, /* 00,3B,3A,aa */ | ||
3491 | {0xaa, 0x3c, 0x0098}, /* 00,3C,98,aa */ | ||
3492 | {0xaa, 0x3d, 0x003a}, /* 00,3D,3A,aa */ | ||
3493 | {0xaa, 0x3e, 0x0098}, /* 00,3E,98,aa */ | ||
3494 | {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ | ||
3495 | {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ | ||
3496 | {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ | ||
3497 | {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */ | ||
3498 | {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */ | ||
3499 | {} | ||
3500 | }; | ||
3501 | |||
3502 | static const struct usb_action MC501CB_60HZ[] = { | ||
3503 | {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ | ||
3504 | {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ | ||
3505 | {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ | ||
3506 | {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */ | ||
3507 | {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */ | ||
3508 | {0xaa, 0x3e, 0x006a}, /* 00,3E,6A,aa */ | ||
3509 | {0xaa, 0x3b, 0x0018}, /* 00,3B,18,aa */ | ||
3510 | {0xaa, 0x3c, 0x006a}, /* 00,3C,6A,aa */ | ||
3511 | {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ | ||
3512 | {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ | ||
3513 | {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ | ||
3514 | {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */ | ||
3515 | {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */ | ||
3516 | {} | ||
3517 | }; | ||
3518 | |||
3519 | static const struct usb_action MC501CB_60HZScale[] = { | ||
3520 | {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ | ||
3521 | {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ | ||
3522 | {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ | ||
3523 | {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */ | ||
3524 | {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */ | ||
3525 | {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */ | ||
3526 | {0xaa, 0x3b, 0x0030}, /* 00,3B,30,aa */ | ||
3527 | {0xaa, 0x3c, 0x00d4}, /* 00,3C,D4,aa */ | ||
3528 | {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ | ||
3529 | {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ | ||
3530 | {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ | ||
3531 | {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */ | ||
3532 | {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */ | ||
3533 | {} | ||
3534 | }; | ||
3535 | |||
3536 | static const struct usb_action MC501CB_NoFliker[] = { | ||
3537 | {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ | ||
3538 | {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ | ||
3539 | {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ | ||
3540 | {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */ | ||
3541 | {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */ | ||
3542 | {0xaa, 0x3e, 0x006a}, /* 00,3E,6A,aa */ | ||
3543 | {0xaa, 0x3b, 0x0018}, /* 00,3B,18,aa */ | ||
3544 | {0xaa, 0x3c, 0x006a}, /* 00,3C,6A,aa */ | ||
3545 | {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ | ||
3546 | {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ | ||
3547 | {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ | ||
3548 | {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */ | ||
3549 | {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */ | ||
3550 | {} | ||
3551 | }; | ||
3552 | |||
3553 | static const struct usb_action MC501CB_NoFlikerScale[] = { | ||
3554 | {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ | ||
3555 | {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ | ||
3556 | {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ | ||
3557 | {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */ | ||
3558 | {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */ | ||
3559 | {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */ | ||
3560 | {0xaa, 0x3b, 0x0030}, /* 00,3B,30,aa */ | ||
3561 | {0xaa, 0x3c, 0x00d4}, /* 00,3C,D4,aa */ | ||
3562 | {} | ||
3563 | }; | ||
3564 | |||
3565 | /* from zs211.inf - HKR,%OV7620%,Initial - 640x480 */ | ||
3566 | static const struct usb_action OV7620_mode0[] = { | ||
3567 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ | ||
3568 | {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, /* 00,02,40,cc */ | ||
3569 | {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */ | ||
3570 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ | ||
3571 | {0xa0, 0x06, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,06,cc */ | ||
3572 | {0xa0, 0x02, ZC3XX_R083_RGAINADDR}, /* 00,83,02,cc */ | ||
3573 | {0xa0, 0x01, ZC3XX_R085_BGAINADDR}, /* 00,85,01,cc */ | ||
3574 | {0xa0, 0x80, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,80,cc */ | ||
3575 | {0xa0, 0x81, ZC3XX_R087_EXPTIMEMID}, /* 00,87,81,cc */ | ||
3576 | {0xa0, 0x10, ZC3XX_R088_EXPTIMELOW}, /* 00,88,10,cc */ | ||
3577 | {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,a1,cc */ | ||
3578 | {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* 00,8d,08,cc */ | ||
3579 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ | ||
3580 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ | ||
3581 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ | ||
3582 | {0xa0, 0xd8, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d8,cc */ | ||
3583 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ | ||
3584 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ | ||
3585 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ | ||
3586 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ | ||
3587 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ | ||
3588 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ | ||
3589 | {0xa0, 0xde, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,de,cc */ | ||
3590 | {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */ | ||
3591 | {0xaa, 0x12, 0x0088}, /* 00,12,88,aa */ | ||
3592 | {0xaa, 0x12, 0x0048}, /* 00,12,48,aa */ | ||
3593 | {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */ | ||
3594 | {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ | ||
3595 | {0xaa, 0x04, 0x0000}, /* 00,04,00,aa */ | ||
3596 | {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */ | ||
3597 | {0xaa, 0x14, 0x0000}, /* 00,14,00,aa */ | ||
3598 | {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */ | ||
3599 | {0xaa, 0x17, 0x0018}, /* 00,17,18,aa */ | ||
3600 | {0xaa, 0x18, 0x00ba}, /* 00,18,ba,aa */ | ||
3601 | {0xaa, 0x19, 0x0002}, /* 00,19,02,aa */ | ||
3602 | {0xaa, 0x1a, 0x00f1}, /* 00,1a,f1,aa */ | ||
3603 | {0xaa, 0x20, 0x0040}, /* 00,20,40,aa */ | ||
3604 | {0xaa, 0x24, 0x0088}, /* 00,24,88,aa */ | ||
3605 | {0xaa, 0x25, 0x0078}, /* 00,25,78,aa */ | ||
3606 | {0xaa, 0x27, 0x00f6}, /* 00,27,f6,aa */ | ||
3607 | {0xaa, 0x28, 0x00a0}, /* 00,28,a0,aa */ | ||
3608 | {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */ | ||
3609 | {0xaa, 0x2a, 0x0083}, /* 00,2a,83,aa */ | ||
3610 | {0xaa, 0x2b, 0x0096}, /* 00,2b,96,aa */ | ||
3611 | {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */ | ||
3612 | {0xaa, 0x74, 0x0020}, /* 00,74,20,aa */ | ||
3613 | {0xaa, 0x61, 0x0068}, /* 00,61,68,aa */ | ||
3614 | {0xaa, 0x64, 0x0088}, /* 00,64,88,aa */ | ||
3615 | {0xaa, 0x00, 0x0000}, /* 00,00,00,aa */ | ||
3616 | {0xaa, 0x06, 0x0080}, /* 00,06,80,aa */ | ||
3617 | {0xaa, 0x01, 0x0090}, /* 00,01,90,aa */ | ||
3618 | {0xaa, 0x02, 0x0030}, /* 00,02,30,aa */ | ||
3619 | {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,77,cc */ | ||
3620 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ | ||
3621 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ | ||
3622 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ | ||
3623 | {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */ | ||
3624 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ | ||
3625 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ | ||
3626 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ | ||
3627 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ | ||
3628 | {0xa0, 0x68, ZC3XX_R116_RGAIN}, /* 01,16,68,cc */ | ||
3629 | {0xa0, 0x52, ZC3XX_R118_BGAIN}, /* 01,18,52,cc */ | ||
3630 | {0xa0, 0x40, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,40,cc */ | ||
3631 | {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ | ||
3632 | {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,50,cc */ | ||
3633 | {} | ||
3634 | }; | ||
3635 | |||
3636 | /* from zs211.inf - HKR,%OV7620%,InitialScale - 320x240 */ | ||
3637 | static const struct usb_action OV7620_mode1[] = { | ||
3638 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ | ||
3639 | {0xa0, 0x50, ZC3XX_R002_CLOCKSELECT}, /* 00,02,50,cc */ | ||
3640 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */ | ||
3641 | /* mx change? */ | ||
3642 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ | ||
3643 | {0xa0, 0x06, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,06,cc */ | ||
3644 | {0xa0, 0x02, ZC3XX_R083_RGAINADDR}, /* 00,83,02,cc */ | ||
3645 | {0xa0, 0x01, ZC3XX_R085_BGAINADDR}, /* 00,85,01,cc */ | ||
3646 | {0xa0, 0x80, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,80,cc */ | ||
3647 | {0xa0, 0x81, ZC3XX_R087_EXPTIMEMID}, /* 00,87,81,cc */ | ||
3648 | {0xa0, 0x10, ZC3XX_R088_EXPTIMELOW}, /* 00,88,10,cc */ | ||
3649 | {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,a1,cc */ | ||
3650 | {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* 00,8d,08,cc */ | ||
3651 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ | ||
3652 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ | ||
3653 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ | ||
3654 | {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d0,cc */ | ||
3655 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ | ||
3656 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ | ||
3657 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ | ||
3658 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ | ||
3659 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ | ||
3660 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ | ||
3661 | {0xa0, 0xd6, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,d6,cc */ | ||
3662 | /* OV7648 00,9c,d8,cc */ | ||
3663 | {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */ | ||
3664 | {0xaa, 0x12, 0x0088}, /* 00,12,88,aa */ | ||
3665 | {0xaa, 0x12, 0x0048}, /* 00,12,48,aa */ | ||
3666 | {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */ | ||
3667 | {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ | ||
3668 | {0xaa, 0x04, 0x0000}, /* 00,04,00,aa */ | ||
3669 | {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */ | ||
3670 | {0xaa, 0x14, 0x0000}, /* 00,14,00,aa */ | ||
3671 | {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */ | ||
3672 | {0xaa, 0x24, 0x0088}, /* 00,24,88,aa */ | ||
3673 | {0xaa, 0x25, 0x0078}, /* 00,25,78,aa */ | ||
3674 | {0xaa, 0x17, 0x0018}, /* 00,17,18,aa */ | ||
3675 | {0xaa, 0x18, 0x00ba}, /* 00,18,ba,aa */ | ||
3676 | {0xaa, 0x19, 0x0002}, /* 00,19,02,aa */ | ||
3677 | {0xaa, 0x1a, 0x00f2}, /* 00,1a,f2,aa */ | ||
3678 | {0xaa, 0x20, 0x0040}, /* 00,20,40,aa */ | ||
3679 | {0xaa, 0x27, 0x00f6}, /* 00,27,f6,aa */ | ||
3680 | {0xaa, 0x28, 0x00a0}, /* 00,28,a0,aa */ | ||
3681 | {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */ | ||
3682 | {0xaa, 0x2a, 0x0083}, /* 00,2a,83,aa */ | ||
3683 | {0xaa, 0x2b, 0x0096}, /* 00,2b,96,aa */ | ||
3684 | {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */ | ||
3685 | {0xaa, 0x74, 0x0020}, /* 00,74,20,aa */ | ||
3686 | {0xaa, 0x61, 0x0068}, /* 00,61,68,aa */ | ||
3687 | {0xaa, 0x64, 0x0088}, /* 00,64,88,aa */ | ||
3688 | {0xaa, 0x00, 0x0000}, /* 00,00,00,aa */ | ||
3689 | {0xaa, 0x06, 0x0080}, /* 00,06,80,aa */ | ||
3690 | {0xaa, 0x01, 0x0090}, /* 00,01,90,aa */ | ||
3691 | {0xaa, 0x02, 0x0030}, /* 00,02,30,aa */ | ||
3692 | {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,77,cc */ | ||
3693 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ | ||
3694 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ | ||
3695 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ | ||
3696 | {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */ | ||
3697 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ | ||
3698 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ | ||
3699 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ | ||
3700 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ | ||
3701 | {0xa0, 0x68, ZC3XX_R116_RGAIN}, /* 01,16,68,cc */ | ||
3702 | {0xa0, 0x52, ZC3XX_R118_BGAIN}, /* 01,18,52,cc */ | ||
3703 | {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,50,cc */ | ||
3704 | {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ | ||
3705 | {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,50,cc */ | ||
3706 | {} | ||
3707 | }; | ||
3708 | |||
3709 | /* from zs211.inf - HKR,%OV7620%\AE,50HZ */ | ||
3710 | static const struct usb_action OV7620_50HZ[] = { | ||
3711 | {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ | ||
3712 | {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ | ||
3713 | {0xaa, 0x2b, 0x0096}, /* 00,2b,96,aa */ | ||
3714 | {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */ | ||
3715 | {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */ | ||
3716 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
3717 | {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ | ||
3718 | {0xa0, 0x18, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,18,cc */ | ||
3719 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
3720 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
3721 | {0xa0, 0x83, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,83,cc */ | ||
3722 | {0xaa, 0x10, 0x0082}, /* 00,10,82,aa */ | ||
3723 | {0xaa, 0x76, 0x0003}, /* 00,76,03,aa */ | ||
3724 | /* {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, * 00,02,40,cc | ||
3725 | if mode0 (640x480) */ | ||
3726 | {} | ||
3727 | }; | ||
3728 | |||
3729 | /* from zs211.inf - HKR,%OV7620%\AE,60HZ */ | ||
3730 | static const struct usb_action OV7620_60HZ[] = { | ||
3731 | {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ | ||
3732 | /* (bug in zs211.inf) */ | ||
3733 | {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ | ||
3734 | {0xaa, 0x2b, 0x0000}, /* 00,2b,00,aa */ | ||
3735 | {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */ | ||
3736 | {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */ | ||
3737 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
3738 | {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ | ||
3739 | {0xa0, 0x18, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,18,cc */ | ||
3740 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
3741 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
3742 | {0xa0, 0x83, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,83,cc */ | ||
3743 | {0xaa, 0x10, 0x0020}, /* 00,10,20,aa */ | ||
3744 | {0xaa, 0x76, 0x0003}, /* 00,76,03,aa */ | ||
3745 | /* {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, * 00,02,40,cc | ||
3746 | * if mode0 (640x480) */ | ||
3747 | /* ?? in gspca v1, it was | ||
3748 | {0xa0, 0x00, 0x0039}, * 00,00,00,dd * | ||
3749 | {0xa1, 0x01, 0x0037}, */ | ||
3750 | {} | ||
3751 | }; | ||
3752 | |||
3753 | /* from zs211.inf - HKR,%OV7620%\AE,NoFliker */ | ||
3754 | static const struct usb_action OV7620_NoFliker[] = { | ||
3755 | {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ | ||
3756 | /* (bug in zs211.inf) */ | ||
3757 | {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ | ||
3758 | {0xaa, 0x2b, 0x0000}, /* 00,2b,00,aa */ | ||
3759 | {0xaa, 0x75, 0x008e}, /* 00,75,8e,aa */ | ||
3760 | {0xaa, 0x2d, 0x0001}, /* 00,2d,01,aa */ | ||
3761 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
3762 | {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ | ||
3763 | {0xa0, 0x18, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,18,cc */ | ||
3764 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
3765 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
3766 | {0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,01,cc */ | ||
3767 | /* {0xa0, 0x44, ZC3XX_R002_CLOCKSELECT}, * 00,02,44,cc | ||
3768 | - if mode1 (320x240) */ | ||
3769 | /* ?? was | ||
3770 | {0xa0, 0x00, 0x0039}, * 00,00,00,dd * | ||
3771 | {0xa1, 0x01, 0x0037}, */ | ||
3772 | {} | ||
3773 | }; | ||
3774 | |||
3775 | static const struct usb_action ov7630c_Initial[] = { | ||
3776 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
3777 | {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, | ||
3778 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
3779 | {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, | ||
3780 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | ||
3781 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
3782 | {0xa0, 0x06, ZC3XX_R010_CMOSSENSORSELECT}, | ||
3783 | {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR}, | ||
3784 | {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, | ||
3785 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
3786 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
3787 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
3788 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
3789 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
3790 | {0xaa, 0x12, 0x0080}, | ||
3791 | {0xa0, 0x02, ZC3XX_R083_RGAINADDR}, | ||
3792 | {0xa0, 0x01, ZC3XX_R085_BGAINADDR}, | ||
3793 | {0xa0, 0x90, ZC3XX_R086_EXPTIMEHIGH}, | ||
3794 | {0xa0, 0x91, ZC3XX_R087_EXPTIMEMID}, | ||
3795 | {0xa0, 0x10, ZC3XX_R088_EXPTIMELOW}, | ||
3796 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, | ||
3797 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, | ||
3798 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, | ||
3799 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, | ||
3800 | {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW}, | ||
3801 | {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, | ||
3802 | {0xaa, 0x12, 0x0069}, | ||
3803 | {0xaa, 0x04, 0x0020}, | ||
3804 | {0xaa, 0x06, 0x0050}, | ||
3805 | {0xaa, 0x13, 0x0083}, | ||
3806 | {0xaa, 0x14, 0x0000}, | ||
3807 | {0xaa, 0x15, 0x0024}, | ||
3808 | {0xaa, 0x17, 0x0018}, | ||
3809 | {0xaa, 0x18, 0x00ba}, | ||
3810 | {0xaa, 0x19, 0x0002}, | ||
3811 | {0xaa, 0x1a, 0x00f6}, | ||
3812 | {0xaa, 0x1b, 0x0002}, | ||
3813 | {0xaa, 0x20, 0x00c2}, | ||
3814 | {0xaa, 0x24, 0x0060}, | ||
3815 | {0xaa, 0x25, 0x0040}, | ||
3816 | {0xaa, 0x26, 0x0030}, | ||
3817 | {0xaa, 0x27, 0x00ea}, | ||
3818 | {0xaa, 0x28, 0x00a0}, | ||
3819 | {0xaa, 0x21, 0x0000}, | ||
3820 | {0xaa, 0x2a, 0x0081}, | ||
3821 | {0xaa, 0x2b, 0x0096}, | ||
3822 | {0xaa, 0x2d, 0x0094}, | ||
3823 | {0xaa, 0x2f, 0x003d}, | ||
3824 | {0xaa, 0x30, 0x0024}, | ||
3825 | {0xaa, 0x60, 0x0000}, | ||
3826 | {0xaa, 0x61, 0x0040}, | ||
3827 | {0xaa, 0x68, 0x007c}, | ||
3828 | {0xaa, 0x6f, 0x0015}, | ||
3829 | {0xaa, 0x75, 0x0088}, | ||
3830 | {0xaa, 0x77, 0x00b5}, | ||
3831 | {0xaa, 0x01, 0x0060}, | ||
3832 | {0xaa, 0x02, 0x0060}, | ||
3833 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
3834 | {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, | ||
3835 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
3836 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
3837 | {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
3838 | {0xa0, 0x00, 0x01ad}, | ||
3839 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
3840 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
3841 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
3842 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
3843 | {0xa0, 0x60, ZC3XX_R116_RGAIN}, | ||
3844 | {0xa0, 0x46, ZC3XX_R118_BGAIN}, | ||
3845 | {0xa0, 0x04, ZC3XX_R113_RGB03}, | ||
3846 | /* 0x10, */ | ||
3847 | {0xa1, 0x01, 0x0002}, | ||
3848 | {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ | ||
3849 | {0xa0, 0xf8, ZC3XX_R10B_RGB01}, | ||
3850 | {0xa0, 0xf8, ZC3XX_R10C_RGB02}, | ||
3851 | {0xa0, 0xf8, ZC3XX_R10D_RGB10}, | ||
3852 | {0xa0, 0x50, ZC3XX_R10E_RGB11}, | ||
3853 | {0xa0, 0xf8, ZC3XX_R10F_RGB12}, | ||
3854 | {0xa0, 0xf8, ZC3XX_R110_RGB20}, | ||
3855 | {0xa0, 0xf8, ZC3XX_R111_RGB21}, | ||
3856 | {0xa0, 0x50, ZC3XX_R112_RGB22}, | ||
3857 | /* 0x03, */ | ||
3858 | {0xa1, 0x01, 0x0008}, | ||
3859 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ | ||
3860 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
3861 | {0xa1, 0x01, 0x01c8}, | ||
3862 | {0xa1, 0x01, 0x01c9}, | ||
3863 | {0xa1, 0x01, 0x01ca}, | ||
3864 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
3865 | {0xa0, 0x01, ZC3XX_R120_GAMMA00}, /* gamma 2 ?*/ | ||
3866 | {0xa0, 0x0c, ZC3XX_R121_GAMMA01}, | ||
3867 | {0xa0, 0x1f, ZC3XX_R122_GAMMA02}, | ||
3868 | {0xa0, 0x3a, ZC3XX_R123_GAMMA03}, | ||
3869 | {0xa0, 0x53, ZC3XX_R124_GAMMA04}, | ||
3870 | {0xa0, 0x6d, ZC3XX_R125_GAMMA05}, | ||
3871 | {0xa0, 0x85, ZC3XX_R126_GAMMA06}, | ||
3872 | {0xa0, 0x9c, ZC3XX_R127_GAMMA07}, | ||
3873 | {0xa0, 0xb0, ZC3XX_R128_GAMMA08}, | ||
3874 | {0xa0, 0xc2, ZC3XX_R129_GAMMA09}, | ||
3875 | {0xa0, 0xd1, ZC3XX_R12A_GAMMA0A}, | ||
3876 | {0xa0, 0xde, ZC3XX_R12B_GAMMA0B}, | ||
3877 | {0xa0, 0xe9, ZC3XX_R12C_GAMMA0C}, | ||
3878 | {0xa0, 0xf2, ZC3XX_R12D_GAMMA0D}, | ||
3879 | {0xa0, 0xf9, ZC3XX_R12E_GAMMA0E}, | ||
3880 | {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, | ||
3881 | {0xa0, 0x05, ZC3XX_R130_GAMMA10}, | ||
3882 | {0xa0, 0x0f, ZC3XX_R131_GAMMA11}, | ||
3883 | {0xa0, 0x16, ZC3XX_R132_GAMMA12}, | ||
3884 | {0xa0, 0x1a, ZC3XX_R133_GAMMA13}, | ||
3885 | {0xa0, 0x19, ZC3XX_R134_GAMMA14}, | ||
3886 | {0xa0, 0x19, ZC3XX_R135_GAMMA15}, | ||
3887 | {0xa0, 0x17, ZC3XX_R136_GAMMA16}, | ||
3888 | {0xa0, 0x15, ZC3XX_R137_GAMMA17}, | ||
3889 | {0xa0, 0x12, ZC3XX_R138_GAMMA18}, | ||
3890 | {0xa0, 0x10, ZC3XX_R139_GAMMA19}, | ||
3891 | {0xa0, 0x0e, ZC3XX_R13A_GAMMA1A}, | ||
3892 | {0xa0, 0x0b, ZC3XX_R13B_GAMMA1B}, | ||
3893 | {0xa0, 0x09, ZC3XX_R13C_GAMMA1C}, | ||
3894 | {0xa0, 0x08, ZC3XX_R13D_GAMMA1D}, | ||
3895 | {0xa0, 0x06, ZC3XX_R13E_GAMMA1E}, | ||
3896 | {0xa0, 0x03, ZC3XX_R13F_GAMMA1F}, | ||
3897 | {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ | ||
3898 | {0xa0, 0xf8, ZC3XX_R10B_RGB01}, | ||
3899 | {0xa0, 0xf8, ZC3XX_R10C_RGB02}, | ||
3900 | {0xa0, 0xf8, ZC3XX_R10D_RGB10}, | ||
3901 | {0xa0, 0x50, ZC3XX_R10E_RGB11}, | ||
3902 | {0xa0, 0xf8, ZC3XX_R10F_RGB12}, | ||
3903 | {0xa0, 0xf8, ZC3XX_R110_RGB20}, | ||
3904 | {0xa0, 0xf8, ZC3XX_R111_RGB21}, | ||
3905 | {0xa0, 0x50, ZC3XX_R112_RGB22}, | ||
3906 | |||
3907 | {0xa1, 0x01, 0x0180}, | ||
3908 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
3909 | {0xaa, 0x10, 0x001b}, | ||
3910 | {0xaa, 0x76, 0x0002}, | ||
3911 | {0xaa, 0x2a, 0x0081}, | ||
3912 | {0xaa, 0x2b, 0x0000}, | ||
3913 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, | ||
3914 | {0xa0, 0x01, ZC3XX_R191_EXPOSURELIMITMID}, | ||
3915 | {0xa0, 0xb8, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
3916 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
3917 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, | ||
3918 | {0xa0, 0x37, ZC3XX_R197_ANTIFLICKERLOW}, | ||
3919 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, | ||
3920 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, | ||
3921 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
3922 | {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
3923 | {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, | ||
3924 | {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
3925 | {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
3926 | {0xaa, 0x13, 0x0083}, /* 40 */ | ||
3927 | {0xa1, 0x01, 0x0180}, | ||
3928 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
3929 | {} | ||
3930 | }; | ||
3931 | |||
3932 | static const struct usb_action ov7630c_InitialScale[] = { | ||
3933 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
3934 | {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, | ||
3935 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | ||
3936 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
3937 | {0xa0, 0x06, ZC3XX_R010_CMOSSENSORSELECT}, | ||
3938 | {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR}, | ||
3939 | {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, | ||
3940 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
3941 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
3942 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
3943 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
3944 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
3945 | |||
3946 | {0xaa, 0x12, 0x0080}, | ||
3947 | {0xa0, 0x02, ZC3XX_R083_RGAINADDR}, | ||
3948 | {0xa0, 0x01, ZC3XX_R085_BGAINADDR}, | ||
3949 | {0xa0, 0x90, ZC3XX_R086_EXPTIMEHIGH}, | ||
3950 | {0xa0, 0x91, ZC3XX_R087_EXPTIMEMID}, | ||
3951 | {0xa0, 0x10, ZC3XX_R088_EXPTIMELOW}, | ||
3952 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, | ||
3953 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, | ||
3954 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, | ||
3955 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, | ||
3956 | {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, | ||
3957 | {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, | ||
3958 | {0xaa, 0x12, 0x0069}, /* i2c */ | ||
3959 | {0xaa, 0x04, 0x0020}, | ||
3960 | {0xaa, 0x06, 0x0050}, | ||
3961 | {0xaa, 0x13, 0x00c3}, | ||
3962 | {0xaa, 0x14, 0x0000}, | ||
3963 | {0xaa, 0x15, 0x0024}, | ||
3964 | {0xaa, 0x19, 0x0003}, | ||
3965 | {0xaa, 0x1a, 0x00f6}, | ||
3966 | {0xaa, 0x1b, 0x0002}, | ||
3967 | {0xaa, 0x20, 0x00c2}, | ||
3968 | {0xaa, 0x24, 0x0060}, | ||
3969 | {0xaa, 0x25, 0x0040}, | ||
3970 | {0xaa, 0x26, 0x0030}, | ||
3971 | {0xaa, 0x27, 0x00ea}, | ||
3972 | {0xaa, 0x28, 0x00a0}, | ||
3973 | {0xaa, 0x21, 0x0000}, | ||
3974 | {0xaa, 0x2a, 0x0081}, | ||
3975 | {0xaa, 0x2b, 0x0096}, | ||
3976 | {0xaa, 0x2d, 0x0084}, | ||
3977 | {0xaa, 0x2f, 0x003d}, | ||
3978 | {0xaa, 0x30, 0x0024}, | ||
3979 | {0xaa, 0x60, 0x0000}, | ||
3980 | {0xaa, 0x61, 0x0040}, | ||
3981 | {0xaa, 0x68, 0x007c}, | ||
3982 | {0xaa, 0x6f, 0x0015}, | ||
3983 | {0xaa, 0x75, 0x0088}, | ||
3984 | {0xaa, 0x77, 0x00b5}, | ||
3985 | {0xaa, 0x01, 0x0060}, | ||
3986 | {0xaa, 0x02, 0x0060}, | ||
3987 | {0xaa, 0x17, 0x0018}, | ||
3988 | {0xaa, 0x18, 0x00ba}, | ||
3989 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
3990 | {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, | ||
3991 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
3992 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
3993 | {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, | ||
3994 | {0xa0, 0x00, 0x01ad}, | ||
3995 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
3996 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
3997 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
3998 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
3999 | {0xa0, 0x60, ZC3XX_R116_RGAIN}, | ||
4000 | {0xa0, 0x46, ZC3XX_R118_BGAIN}, | ||
4001 | {0xa0, 0x04, ZC3XX_R113_RGB03}, | ||
4002 | |||
4003 | {0xa1, 0x01, 0x0002}, | ||
4004 | {0xa0, 0x4e, ZC3XX_R10A_RGB00}, /* matrix */ | ||
4005 | {0xa0, 0xfe, ZC3XX_R10B_RGB01}, | ||
4006 | {0xa0, 0xf4, ZC3XX_R10C_RGB02}, | ||
4007 | {0xa0, 0xf7, ZC3XX_R10D_RGB10}, | ||
4008 | {0xa0, 0x4d, ZC3XX_R10E_RGB11}, | ||
4009 | {0xa0, 0xfc, ZC3XX_R10F_RGB12}, | ||
4010 | {0xa0, 0x00, ZC3XX_R110_RGB20}, | ||
4011 | {0xa0, 0xf6, ZC3XX_R111_RGB21}, | ||
4012 | {0xa0, 0x4a, ZC3XX_R112_RGB22}, | ||
4013 | |||
4014 | {0xa1, 0x01, 0x0008}, | ||
4015 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ | ||
4016 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
4017 | {0xa1, 0x01, 0x01c8}, | ||
4018 | {0xa1, 0x01, 0x01c9}, | ||
4019 | {0xa1, 0x01, 0x01ca}, | ||
4020 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
4021 | {0xa0, 0x16, ZC3XX_R120_GAMMA00}, /* gamma ~4 */ | ||
4022 | {0xa0, 0x3a, ZC3XX_R121_GAMMA01}, | ||
4023 | {0xa0, 0x5b, ZC3XX_R122_GAMMA02}, | ||
4024 | {0xa0, 0x7c, ZC3XX_R123_GAMMA03}, | ||
4025 | {0xa0, 0x94, ZC3XX_R124_GAMMA04}, | ||
4026 | {0xa0, 0xa9, ZC3XX_R125_GAMMA05}, | ||
4027 | {0xa0, 0xbb, ZC3XX_R126_GAMMA06}, | ||
4028 | {0xa0, 0xca, ZC3XX_R127_GAMMA07}, | ||
4029 | {0xa0, 0xd7, ZC3XX_R128_GAMMA08}, | ||
4030 | {0xa0, 0xe1, ZC3XX_R129_GAMMA09}, | ||
4031 | {0xa0, 0xea, ZC3XX_R12A_GAMMA0A}, | ||
4032 | {0xa0, 0xf1, ZC3XX_R12B_GAMMA0B}, | ||
4033 | {0xa0, 0xf7, ZC3XX_R12C_GAMMA0C}, | ||
4034 | {0xa0, 0xfc, ZC3XX_R12D_GAMMA0D}, | ||
4035 | {0xa0, 0xff, ZC3XX_R12E_GAMMA0E}, | ||
4036 | {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, | ||
4037 | {0xa0, 0x20, ZC3XX_R130_GAMMA10}, | ||
4038 | {0xa0, 0x22, ZC3XX_R131_GAMMA11}, | ||
4039 | {0xa0, 0x20, ZC3XX_R132_GAMMA12}, | ||
4040 | {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, | ||
4041 | {0xa0, 0x16, ZC3XX_R134_GAMMA14}, | ||
4042 | {0xa0, 0x13, ZC3XX_R135_GAMMA15}, | ||
4043 | {0xa0, 0x10, ZC3XX_R136_GAMMA16}, | ||
4044 | {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, | ||
4045 | {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, | ||
4046 | {0xa0, 0x09, ZC3XX_R139_GAMMA19}, | ||
4047 | {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, | ||
4048 | {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, | ||
4049 | {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, | ||
4050 | {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, | ||
4051 | {0xa0, 0x00, ZC3XX_R13E_GAMMA1E}, | ||
4052 | {0xa0, 0x01, ZC3XX_R13F_GAMMA1F}, | ||
4053 | {0xa0, 0x4e, ZC3XX_R10A_RGB00}, /* matrix */ | ||
4054 | {0xa0, 0xfe, ZC3XX_R10B_RGB01}, | ||
4055 | {0xa0, 0xf4, ZC3XX_R10C_RGB02}, | ||
4056 | {0xa0, 0xf7, ZC3XX_R10D_RGB10}, | ||
4057 | {0xa0, 0x4d, ZC3XX_R10E_RGB11}, | ||
4058 | {0xa0, 0xfc, ZC3XX_R10F_RGB12}, | ||
4059 | {0xa0, 0x00, ZC3XX_R110_RGB20}, | ||
4060 | {0xa0, 0xf6, ZC3XX_R111_RGB21}, | ||
4061 | {0xa0, 0x4a, ZC3XX_R112_RGB22}, | ||
4062 | |||
4063 | {0xa1, 0x01, 0x0180}, | ||
4064 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
4065 | {0xaa, 0x10, 0x000d}, | ||
4066 | {0xaa, 0x76, 0x0002}, | ||
4067 | {0xaa, 0x2a, 0x0081}, | ||
4068 | {0xaa, 0x2b, 0x0000}, | ||
4069 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, | ||
4070 | {0xa0, 0x00, ZC3XX_R191_EXPOSURELIMITMID}, | ||
4071 | {0xa0, 0xd8, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
4072 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
4073 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, | ||
4074 | {0xa0, 0x1b, ZC3XX_R197_ANTIFLICKERLOW}, | ||
4075 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, | ||
4076 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, | ||
4077 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
4078 | {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
4079 | {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, | ||
4080 | {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
4081 | {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
4082 | {0xaa, 0x13, 0x00c3}, | ||
4083 | |||
4084 | {0xa1, 0x01, 0x0180}, | ||
4085 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
4086 | {} | ||
4087 | }; | ||
4088 | |||
4089 | static const struct usb_action pas106b_Initial_com[] = { | ||
4090 | /* Sream and Sensor specific */ | ||
4091 | {0xa1, 0x01, 0x0010}, /* CMOSSensorSelect */ | ||
4092 | /* System */ | ||
4093 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* SystemControl */ | ||
4094 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* SystemControl */ | ||
4095 | /* Picture size */ | ||
4096 | {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* ClockSelect */ | ||
4097 | {0xa0, 0x03, 0x003a}, | ||
4098 | {0xa0, 0x0c, 0x003b}, | ||
4099 | {0xa0, 0x04, 0x0038}, | ||
4100 | {} | ||
4101 | }; | ||
4102 | |||
4103 | static const struct usb_action pas106b_Initial[] = { /* 176x144 */ | ||
4104 | /* JPEG control */ | ||
4105 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */ | ||
4106 | /* Sream and Sensor specific */ | ||
4107 | {0xa0, 0x0f, ZC3XX_R010_CMOSSENSORSELECT}, /* CMOSSensorSelect */ | ||
4108 | /* Picture size */ | ||
4109 | {0xa0, 0x00, ZC3XX_R003_FRAMEWIDTHHIGH}, /* FrameWidthHigh 00 */ | ||
4110 | {0xa0, 0xb0, ZC3XX_R004_FRAMEWIDTHLOW}, /* FrameWidthLow B0 */ | ||
4111 | {0xa0, 0x00, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* FrameHeightHigh 00 */ | ||
4112 | {0xa0, 0x90, ZC3XX_R006_FRAMEHEIGHTLOW}, /* FrameHightLow 90 */ | ||
4113 | /* System */ | ||
4114 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* SystemOperating */ | ||
4115 | /* Sream and Sensor specific */ | ||
4116 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */ | ||
4117 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */ | ||
4118 | /* Sensor Interface */ | ||
4119 | {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* Compatibily Mode */ | ||
4120 | /* Window inside sensor array */ | ||
4121 | {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW}, /* WinXStartLow */ | ||
4122 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* FirstYLow */ | ||
4123 | {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW}, /* FirstxLow */ | ||
4124 | {0xa0, 0x28, ZC3XX_R09C_WINHEIGHTLOW}, /* WinHeightLow */ | ||
4125 | {0xa0, 0x68, ZC3XX_R09E_WINWIDTHLOW}, /* WinWidthLow */ | ||
4126 | /* Init the sensor */ | ||
4127 | {0xaa, 0x02, 0x0004}, | ||
4128 | {0xaa, 0x08, 0x0000}, | ||
4129 | {0xaa, 0x09, 0x0005}, | ||
4130 | {0xaa, 0x0a, 0x0002}, | ||
4131 | {0xaa, 0x0b, 0x0002}, | ||
4132 | {0xaa, 0x0c, 0x0005}, | ||
4133 | {0xaa, 0x0d, 0x0000}, | ||
4134 | {0xaa, 0x0e, 0x0002}, | ||
4135 | {0xaa, 0x14, 0x0081}, | ||
4136 | |||
4137 | /* Other registors */ | ||
4138 | {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* SensorCorrection */ | ||
4139 | /* Frame retreiving */ | ||
4140 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* AutoAdjustFPS */ | ||
4141 | /* Gains */ | ||
4142 | {0xa0, 0xa0, ZC3XX_R1A8_DIGITALGAIN}, /* DigitalGain */ | ||
4143 | /* Unknown */ | ||
4144 | {0xa0, 0x00, 0x01ad}, | ||
4145 | /* Sharpness */ | ||
4146 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* SharpnessMode */ | ||
4147 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* Sharpness05 */ | ||
4148 | /* Other registors */ | ||
4149 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* OperationMode */ | ||
4150 | /* Auto exposure and white balance */ | ||
4151 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* AWBStatus */ | ||
4152 | /*Dead pixels */ | ||
4153 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */ | ||
4154 | /* EEPROM */ | ||
4155 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* EEPROMAccess */ | ||
4156 | /* JPEG control */ | ||
4157 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */ | ||
4158 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
4159 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
4160 | /* Other registers */ | ||
4161 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* OperationMode */ | ||
4162 | /* Auto exposure and white balance */ | ||
4163 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* AWBStatus */ | ||
4164 | /*Dead pixels */ | ||
4165 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */ | ||
4166 | /* EEPROM */ | ||
4167 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* EEPROMAccess */ | ||
4168 | /* JPEG control */ | ||
4169 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */ | ||
4170 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
4171 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
4172 | |||
4173 | {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ | ||
4174 | {0xa0, 0xf4, ZC3XX_R10B_RGB01}, | ||
4175 | {0xa0, 0xf4, ZC3XX_R10C_RGB02}, | ||
4176 | {0xa0, 0xf4, ZC3XX_R10D_RGB10}, | ||
4177 | {0xa0, 0x58, ZC3XX_R10E_RGB11}, | ||
4178 | {0xa0, 0xf4, ZC3XX_R10F_RGB12}, | ||
4179 | {0xa0, 0xf4, ZC3XX_R110_RGB20}, | ||
4180 | {0xa0, 0xf4, ZC3XX_R111_RGB21}, | ||
4181 | {0xa0, 0x58, ZC3XX_R112_RGB22}, | ||
4182 | /* Auto correction */ | ||
4183 | {0xa0, 0x03, ZC3XX_R181_WINXSTART}, /* WinXstart */ | ||
4184 | {0xa0, 0x08, ZC3XX_R182_WINXWIDTH}, /* WinXWidth */ | ||
4185 | {0xa0, 0x16, ZC3XX_R183_WINXCENTER}, /* WinXCenter */ | ||
4186 | {0xa0, 0x03, ZC3XX_R184_WINYSTART}, /* WinYStart */ | ||
4187 | {0xa0, 0x05, ZC3XX_R185_WINYWIDTH}, /* WinYWidth */ | ||
4188 | {0xa0, 0x14, ZC3XX_R186_WINYCENTER}, /* WinYCenter */ | ||
4189 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */ | ||
4190 | |||
4191 | /* Auto exposure and white balance */ | ||
4192 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* ExposureLimitHigh */ | ||
4193 | {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* ExposureLimitMid */ | ||
4194 | {0xa0, 0xb1, ZC3XX_R192_EXPOSURELIMITLOW}, /* ExposureLimitLow */ | ||
4195 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* AntiFlickerHigh */ | ||
4196 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* AntiFlickerLow */ | ||
4197 | {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW}, /* AntiFlickerLow */ | ||
4198 | {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* AEBFreeze */ | ||
4199 | {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* AEBUnfreeze */ | ||
4200 | /* sensor on */ | ||
4201 | {0xaa, 0x07, 0x00b1}, | ||
4202 | {0xaa, 0x05, 0x0003}, | ||
4203 | {0xaa, 0x04, 0x0001}, | ||
4204 | {0xaa, 0x03, 0x003b}, | ||
4205 | /* Gains */ | ||
4206 | {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* DigitalLimitDiff */ | ||
4207 | {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* DigitalGainStep */ | ||
4208 | {0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN}, /* GlobalGain */ | ||
4209 | {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* GlobalGain */ | ||
4210 | /* Auto correction */ | ||
4211 | {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */ | ||
4212 | {0xa1, 0x01, 0x0180}, /* AutoCorrectEnable */ | ||
4213 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */ | ||
4214 | /* Gains */ | ||
4215 | {0xa0, 0x40, ZC3XX_R116_RGAIN}, /* RGain */ | ||
4216 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, /* GGain */ | ||
4217 | {0xa0, 0x40, ZC3XX_R118_BGAIN}, /* BGain */ | ||
4218 | {} | ||
4219 | }; | ||
4220 | |||
4221 | static const struct usb_action pas106b_InitialScale[] = { /* 352x288 */ | ||
4222 | /* JPEG control */ | ||
4223 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */ | ||
4224 | /* Sream and Sensor specific */ | ||
4225 | {0xa0, 0x0f, ZC3XX_R010_CMOSSENSORSELECT}, /* CMOSSensorSelect */ | ||
4226 | /* Picture size */ | ||
4227 | {0xa0, 0x01, ZC3XX_R003_FRAMEWIDTHHIGH}, /* FrameWidthHigh */ | ||
4228 | {0xa0, 0x60, ZC3XX_R004_FRAMEWIDTHLOW}, /* FrameWidthLow */ | ||
4229 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* FrameHeightHigh */ | ||
4230 | {0xa0, 0x20, ZC3XX_R006_FRAMEHEIGHTLOW}, /* FrameHightLow */ | ||
4231 | /* System */ | ||
4232 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* SystemOperating */ | ||
4233 | /* Sream and Sensor specific */ | ||
4234 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */ | ||
4235 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */ | ||
4236 | /* Sensor Interface */ | ||
4237 | {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* Compatibily Mode */ | ||
4238 | /* Window inside sensor array */ | ||
4239 | {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW}, /* WinXStartLow */ | ||
4240 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* FirstYLow */ | ||
4241 | {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW}, /* FirstxLow */ | ||
4242 | {0xa0, 0x28, ZC3XX_R09C_WINHEIGHTLOW}, /* WinHeightLow */ | ||
4243 | {0xa0, 0x68, ZC3XX_R09E_WINWIDTHLOW}, /* WinWidthLow */ | ||
4244 | /* Init the sensor */ | ||
4245 | {0xaa, 0x02, 0x0004}, | ||
4246 | {0xaa, 0x08, 0x0000}, | ||
4247 | {0xaa, 0x09, 0x0005}, | ||
4248 | {0xaa, 0x0a, 0x0002}, | ||
4249 | {0xaa, 0x0b, 0x0002}, | ||
4250 | {0xaa, 0x0c, 0x0005}, | ||
4251 | {0xaa, 0x0d, 0x0000}, | ||
4252 | {0xaa, 0x0e, 0x0002}, | ||
4253 | {0xaa, 0x14, 0x0081}, | ||
4254 | |||
4255 | /* Other registors */ | ||
4256 | {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* SensorCorrection */ | ||
4257 | /* Frame retreiving */ | ||
4258 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* AutoAdjustFPS */ | ||
4259 | /* Gains */ | ||
4260 | {0xa0, 0xa0, ZC3XX_R1A8_DIGITALGAIN}, /* DigitalGain */ | ||
4261 | /* Unknown */ | ||
4262 | {0xa0, 0x00, 0x01ad}, | ||
4263 | /* Sharpness */ | ||
4264 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* SharpnessMode */ | ||
4265 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* Sharpness05 */ | ||
4266 | /* Other registors */ | ||
4267 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* OperationMode */ | ||
4268 | /* Auto exposure and white balance */ | ||
4269 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* AWBStatus */ | ||
4270 | {0xa0, 0x80, ZC3XX_R18D_YTARGET}, /* ????????? */ | ||
4271 | /*Dead pixels */ | ||
4272 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */ | ||
4273 | /* EEPROM */ | ||
4274 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* EEPROMAccess */ | ||
4275 | /* JPEG control */ | ||
4276 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */ | ||
4277 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
4278 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
4279 | /* Other registers */ | ||
4280 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* OperationMode */ | ||
4281 | /* Auto exposure and white balance */ | ||
4282 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* AWBStatus */ | ||
4283 | /*Dead pixels */ | ||
4284 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */ | ||
4285 | /* EEPROM */ | ||
4286 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* EEPROMAccess */ | ||
4287 | /* JPEG control */ | ||
4288 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */ | ||
4289 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
4290 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
4291 | |||
4292 | {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ | ||
4293 | {0xa0, 0xf4, ZC3XX_R10B_RGB01}, | ||
4294 | {0xa0, 0xf4, ZC3XX_R10C_RGB02}, | ||
4295 | {0xa0, 0xf4, ZC3XX_R10D_RGB10}, | ||
4296 | {0xa0, 0x58, ZC3XX_R10E_RGB11}, | ||
4297 | {0xa0, 0xf4, ZC3XX_R10F_RGB12}, | ||
4298 | {0xa0, 0xf4, ZC3XX_R110_RGB20}, | ||
4299 | {0xa0, 0xf4, ZC3XX_R111_RGB21}, | ||
4300 | {0xa0, 0x58, ZC3XX_R112_RGB22}, | ||
4301 | /* Auto correction */ | ||
4302 | {0xa0, 0x03, ZC3XX_R181_WINXSTART}, /* WinXstart */ | ||
4303 | {0xa0, 0x08, ZC3XX_R182_WINXWIDTH}, /* WinXWidth */ | ||
4304 | {0xa0, 0x16, ZC3XX_R183_WINXCENTER}, /* WinXCenter */ | ||
4305 | {0xa0, 0x03, ZC3XX_R184_WINYSTART}, /* WinYStart */ | ||
4306 | {0xa0, 0x05, ZC3XX_R185_WINYWIDTH}, /* WinYWidth */ | ||
4307 | {0xa0, 0x14, ZC3XX_R186_WINYCENTER}, /* WinYCenter */ | ||
4308 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */ | ||
4309 | |||
4310 | /* Auto exposure and white balance */ | ||
4311 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* ExposureLimitHigh 0 */ | ||
4312 | {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* ExposureLimitMid */ | ||
4313 | {0xa0, 0xb1, ZC3XX_R192_EXPOSURELIMITLOW}, /* ExposureLimitLow 0xb1 */ | ||
4314 | |||
4315 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* AntiFlickerHigh 0x00 */ | ||
4316 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* AntiFlickerLow 0x00 */ | ||
4317 | {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW}, /* AntiFlickerLow 0x87 */ | ||
4318 | |||
4319 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* AEBFreeze 0x10 0x0c */ | ||
4320 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* AEBUnfreeze 0x30 0x18 */ | ||
4321 | /* sensor on */ | ||
4322 | {0xaa, 0x07, 0x00b1}, | ||
4323 | {0xaa, 0x05, 0x0003}, | ||
4324 | {0xaa, 0x04, 0x0001}, | ||
4325 | {0xaa, 0x03, 0x003b}, | ||
4326 | /* Gains */ | ||
4327 | {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* DigitalLimitDiff */ | ||
4328 | {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* DigitalGainStep */ | ||
4329 | {0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN}, /* GlobalGain */ | ||
4330 | {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* GlobalGain */ | ||
4331 | /* Auto correction */ | ||
4332 | {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */ | ||
4333 | {0xa1, 0x01, 0x0180}, /* AutoCorrectEnable */ | ||
4334 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */ | ||
4335 | /* Gains */ | ||
4336 | {0xa0, 0x40, ZC3XX_R116_RGAIN}, /* RGain */ | ||
4337 | {0xa0, 0x40, ZC3XX_R117_GGAIN}, /* GGain */ | ||
4338 | {0xa0, 0x40, ZC3XX_R118_BGAIN}, /* BGain */ | ||
4339 | |||
4340 | {0xa0, 0x00, 0x0007}, /* AutoCorrectEnable */ | ||
4341 | {0xa0, 0xff, ZC3XX_R018_FRAMELOST}, /* Frame adjust */ | ||
4342 | {} | ||
4343 | }; | ||
4344 | static const struct usb_action pas106b_50HZ[] = { | ||
4345 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
4346 | {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,06,cc */ | ||
4347 | {0xa0, 0x54, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,54,cc */ | ||
4348 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
4349 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
4350 | {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,87,cc */ | ||
4351 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
4352 | {0xa0, 0x30, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,30,cc */ | ||
4353 | {0xaa, 0x03, 0x0021}, /* 00,03,21,aa */ | ||
4354 | {0xaa, 0x04, 0x000c}, /* 00,04,0c,aa */ | ||
4355 | {0xaa, 0x05, 0x0002}, /* 00,05,02,aa */ | ||
4356 | {0xaa, 0x07, 0x001c}, /* 00,07,1c,aa */ | ||
4357 | {0xa0, 0x04, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,04,cc */ | ||
4358 | {} | ||
4359 | }; | ||
4360 | static const struct usb_action pas106b_60HZ[] = { | ||
4361 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
4362 | {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,06,cc */ | ||
4363 | {0xa0, 0x2e, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,2e,cc */ | ||
4364 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
4365 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
4366 | {0xa0, 0x71, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,71,cc */ | ||
4367 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
4368 | {0xa0, 0x30, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,30,cc */ | ||
4369 | {0xaa, 0x03, 0x001c}, /* 00,03,1c,aa */ | ||
4370 | {0xaa, 0x04, 0x0004}, /* 00,04,04,aa */ | ||
4371 | {0xaa, 0x05, 0x0001}, /* 00,05,01,aa */ | ||
4372 | {0xaa, 0x07, 0x00c4}, /* 00,07,c4,aa */ | ||
4373 | {0xa0, 0x04, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,04,cc */ | ||
4374 | {} | ||
4375 | }; | ||
4376 | static const struct usb_action pas106b_NoFliker[] = { | ||
4377 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
4378 | {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,06,cc */ | ||
4379 | {0xa0, 0x50, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,50,cc */ | ||
4380 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
4381 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
4382 | {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ | ||
4383 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
4384 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
4385 | {0xaa, 0x03, 0x0013}, /* 00,03,13,aa */ | ||
4386 | {0xaa, 0x04, 0x0000}, /* 00,04,00,aa */ | ||
4387 | {0xaa, 0x05, 0x0001}, /* 00,05,01,aa */ | ||
4388 | {0xaa, 0x07, 0x0030}, /* 00,07,30,aa */ | ||
4389 | {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ | ||
4390 | {} | ||
4391 | }; | ||
4392 | |||
4393 | static const struct usb_action pb03303x_Initial[] = { | ||
4394 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
4395 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | ||
4396 | {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, | ||
4397 | {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, | ||
4398 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
4399 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
4400 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
4401 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
4402 | {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, /* 8b -> dc */ | ||
4403 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
4404 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
4405 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
4406 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, | ||
4407 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, | ||
4408 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, | ||
4409 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, | ||
4410 | {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, | ||
4411 | {0xaa, 0x01, 0x0001}, | ||
4412 | {0xaa, 0x06, 0x0000}, | ||
4413 | {0xaa, 0x08, 0x0483}, | ||
4414 | {0xaa, 0x01, 0x0004}, | ||
4415 | {0xaa, 0x08, 0x0006}, | ||
4416 | {0xaa, 0x02, 0x0011}, | ||
4417 | {0xaa, 0x03, 0x01e7}, | ||
4418 | {0xaa, 0x04, 0x0287}, | ||
4419 | {0xaa, 0x07, 0x3002}, | ||
4420 | {0xaa, 0x20, 0x1100}, | ||
4421 | {0xaa, 0x35, 0x0050}, | ||
4422 | {0xaa, 0x30, 0x0005}, | ||
4423 | {0xaa, 0x31, 0x0000}, | ||
4424 | {0xaa, 0x58, 0x0078}, | ||
4425 | {0xaa, 0x62, 0x0411}, | ||
4426 | {0xaa, 0x2b, 0x0028}, | ||
4427 | {0xaa, 0x2c, 0x0030}, | ||
4428 | {0xaa, 0x2d, 0x0030}, | ||
4429 | {0xaa, 0x2e, 0x0028}, | ||
4430 | {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, | ||
4431 | {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, | ||
4432 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
4433 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
4434 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
4435 | {0xa0, 0x00, 0x01ad}, | ||
4436 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
4437 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
4438 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
4439 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
4440 | {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, | ||
4441 | {0xa0, 0x78, ZC3XX_R18D_YTARGET}, | ||
4442 | {0xa0, 0x61, ZC3XX_R116_RGAIN}, | ||
4443 | {0xa0, 0x65, ZC3XX_R118_BGAIN}, | ||
4444 | |||
4445 | {0xa1, 0x01, 0x0002}, | ||
4446 | {0xa0, 0x09, 0x01ad}, | ||
4447 | {0xa0, 0x15, 0x01ae}, | ||
4448 | {0xa0, 0x0d, 0x003a}, | ||
4449 | {0xa0, 0x02, 0x003b}, | ||
4450 | {0xa0, 0x00, 0x0038}, | ||
4451 | {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ | ||
4452 | {0xa0, 0xf8, ZC3XX_R10B_RGB01}, | ||
4453 | {0xa0, 0xf8, ZC3XX_R10C_RGB02}, | ||
4454 | {0xa0, 0xf8, ZC3XX_R10D_RGB10}, | ||
4455 | {0xa0, 0x50, ZC3XX_R10E_RGB11}, | ||
4456 | {0xa0, 0xf8, ZC3XX_R10F_RGB12}, | ||
4457 | {0xa0, 0xf8, ZC3XX_R110_RGB20}, | ||
4458 | {0xa0, 0xf8, ZC3XX_R111_RGB21}, | ||
4459 | {0xa0, 0x50, ZC3XX_R112_RGB22}, | ||
4460 | |||
4461 | {0xa1, 0x01, 0x0008}, | ||
4462 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ | ||
4463 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
4464 | {0xa1, 0x01, 0x01c8}, | ||
4465 | {0xa1, 0x01, 0x01c9}, | ||
4466 | {0xa1, 0x01, 0x01ca}, | ||
4467 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
4468 | {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */ | ||
4469 | {0xa0, 0x38, ZC3XX_R121_GAMMA01}, | ||
4470 | {0xa0, 0x59, ZC3XX_R122_GAMMA02}, | ||
4471 | {0xa0, 0x79, ZC3XX_R123_GAMMA03}, | ||
4472 | {0xa0, 0x92, ZC3XX_R124_GAMMA04}, | ||
4473 | {0xa0, 0xa7, ZC3XX_R125_GAMMA05}, | ||
4474 | {0xa0, 0xb9, ZC3XX_R126_GAMMA06}, | ||
4475 | {0xa0, 0xc8, ZC3XX_R127_GAMMA07}, | ||
4476 | {0xa0, 0xd4, ZC3XX_R128_GAMMA08}, | ||
4477 | {0xa0, 0xdf, ZC3XX_R129_GAMMA09}, | ||
4478 | {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A}, | ||
4479 | {0xa0, 0xee, ZC3XX_R12B_GAMMA0B}, | ||
4480 | {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C}, | ||
4481 | {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D}, | ||
4482 | {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E}, | ||
4483 | {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, | ||
4484 | {0xa0, 0x26, ZC3XX_R130_GAMMA10}, | ||
4485 | {0xa0, 0x22, ZC3XX_R131_GAMMA11}, | ||
4486 | {0xa0, 0x20, ZC3XX_R132_GAMMA12}, | ||
4487 | {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, | ||
4488 | {0xa0, 0x16, ZC3XX_R134_GAMMA14}, | ||
4489 | {0xa0, 0x13, ZC3XX_R135_GAMMA15}, | ||
4490 | {0xa0, 0x10, ZC3XX_R136_GAMMA16}, | ||
4491 | {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, | ||
4492 | {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, | ||
4493 | {0xa0, 0x09, ZC3XX_R139_GAMMA19}, | ||
4494 | {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, | ||
4495 | {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, | ||
4496 | {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, | ||
4497 | {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, | ||
4498 | {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, | ||
4499 | {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, | ||
4500 | {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ | ||
4501 | {0xa0, 0xf8, ZC3XX_R10B_RGB01}, | ||
4502 | {0xa0, 0xf8, ZC3XX_R10C_RGB02}, | ||
4503 | {0xa0, 0xf8, ZC3XX_R10D_RGB10}, | ||
4504 | {0xa0, 0x50, ZC3XX_R10E_RGB11}, | ||
4505 | {0xa0, 0xf8, ZC3XX_R10F_RGB12}, | ||
4506 | {0xa0, 0xf8, ZC3XX_R110_RGB20}, | ||
4507 | {0xa0, 0xf8, ZC3XX_R111_RGB21}, | ||
4508 | {0xa0, 0x50, ZC3XX_R112_RGB22}, | ||
4509 | |||
4510 | {0xa1, 0x01, 0x0180}, | ||
4511 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
4512 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
4513 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
4514 | {0xaa, 0x05, 0x0009}, | ||
4515 | {0xaa, 0x09, 0x0134}, | ||
4516 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, | ||
4517 | {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, | ||
4518 | {0xa0, 0xec, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
4519 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
4520 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, | ||
4521 | {0xa0, 0x9c, ZC3XX_R197_ANTIFLICKERLOW}, | ||
4522 | {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, | ||
4523 | {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, | ||
4524 | {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
4525 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
4526 | {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, | ||
4527 | {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, | ||
4528 | {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2}, | ||
4529 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, | ||
4530 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
4531 | {0xa0, 0x09, 0x01ad}, | ||
4532 | {0xa0, 0x15, 0x01ae}, | ||
4533 | {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
4534 | {0xa1, 0x01, 0x0180}, | ||
4535 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
4536 | {} | ||
4537 | }; | ||
4538 | |||
4539 | static const struct usb_action pb03303x_InitialScale[] = { | ||
4540 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
4541 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | ||
4542 | {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, | ||
4543 | {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, | ||
4544 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
4545 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
4546 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
4547 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
4548 | {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, /* 8b -> dc */ | ||
4549 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
4550 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
4551 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
4552 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, | ||
4553 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, | ||
4554 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, | ||
4555 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, | ||
4556 | {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, | ||
4557 | {0xaa, 0x01, 0x0001}, | ||
4558 | {0xaa, 0x06, 0x0000}, | ||
4559 | {0xaa, 0x08, 0x0483}, | ||
4560 | {0xaa, 0x01, 0x0004}, | ||
4561 | {0xaa, 0x08, 0x0006}, | ||
4562 | {0xaa, 0x02, 0x0011}, | ||
4563 | {0xaa, 0x03, 0x01e7}, | ||
4564 | {0xaa, 0x04, 0x0287}, | ||
4565 | {0xaa, 0x07, 0x3002}, | ||
4566 | {0xaa, 0x20, 0x1100}, | ||
4567 | {0xaa, 0x35, 0x0050}, | ||
4568 | {0xaa, 0x30, 0x0005}, | ||
4569 | {0xaa, 0x31, 0x0000}, | ||
4570 | {0xaa, 0x58, 0x0078}, | ||
4571 | {0xaa, 0x62, 0x0411}, | ||
4572 | {0xaa, 0x2b, 0x0028}, | ||
4573 | {0xaa, 0x2c, 0x0030}, | ||
4574 | {0xaa, 0x2d, 0x0030}, | ||
4575 | {0xaa, 0x2e, 0x0028}, | ||
4576 | {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, | ||
4577 | {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, | ||
4578 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
4579 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
4580 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
4581 | {0xa0, 0x00, 0x01ad}, | ||
4582 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
4583 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
4584 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
4585 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
4586 | {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, | ||
4587 | {0xa0, 0x78, ZC3XX_R18D_YTARGET}, | ||
4588 | {0xa0, 0x61, ZC3XX_R116_RGAIN}, | ||
4589 | {0xa0, 0x65, ZC3XX_R118_BGAIN}, | ||
4590 | |||
4591 | {0xa1, 0x01, 0x0002}, | ||
4592 | |||
4593 | {0xa0, 0x09, 0x01ad}, | ||
4594 | {0xa0, 0x15, 0x01ae}, | ||
4595 | |||
4596 | {0xa0, 0x0d, 0x003a}, | ||
4597 | {0xa0, 0x02, 0x003b}, | ||
4598 | {0xa0, 0x00, 0x0038}, | ||
4599 | {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ | ||
4600 | {0xa0, 0xf8, ZC3XX_R10B_RGB01}, | ||
4601 | {0xa0, 0xf8, ZC3XX_R10C_RGB02}, | ||
4602 | {0xa0, 0xf8, ZC3XX_R10D_RGB10}, | ||
4603 | {0xa0, 0x50, ZC3XX_R10E_RGB11}, | ||
4604 | {0xa0, 0xf8, ZC3XX_R10F_RGB12}, | ||
4605 | {0xa0, 0xf8, ZC3XX_R110_RGB20}, | ||
4606 | {0xa0, 0xf8, ZC3XX_R111_RGB21}, | ||
4607 | {0xa0, 0x50, ZC3XX_R112_RGB22}, | ||
4608 | |||
4609 | {0xa1, 0x01, 0x0008}, | ||
4610 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ | ||
4611 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
4612 | {0xa1, 0x01, 0x01c8}, | ||
4613 | {0xa1, 0x01, 0x01c9}, | ||
4614 | {0xa1, 0x01, 0x01ca}, | ||
4615 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
4616 | |||
4617 | {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */ | ||
4618 | {0xa0, 0x38, ZC3XX_R121_GAMMA01}, | ||
4619 | {0xa0, 0x59, ZC3XX_R122_GAMMA02}, | ||
4620 | {0xa0, 0x79, ZC3XX_R123_GAMMA03}, | ||
4621 | {0xa0, 0x92, ZC3XX_R124_GAMMA04}, | ||
4622 | {0xa0, 0xa7, ZC3XX_R125_GAMMA05}, | ||
4623 | {0xa0, 0xb9, ZC3XX_R126_GAMMA06}, | ||
4624 | {0xa0, 0xc8, ZC3XX_R127_GAMMA07}, | ||
4625 | {0xa0, 0xd4, ZC3XX_R128_GAMMA08}, | ||
4626 | {0xa0, 0xdf, ZC3XX_R129_GAMMA09}, | ||
4627 | {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A}, | ||
4628 | {0xa0, 0xee, ZC3XX_R12B_GAMMA0B}, | ||
4629 | {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C}, | ||
4630 | {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D}, | ||
4631 | {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E}, | ||
4632 | {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, | ||
4633 | {0xa0, 0x26, ZC3XX_R130_GAMMA10}, | ||
4634 | {0xa0, 0x22, ZC3XX_R131_GAMMA11}, | ||
4635 | {0xa0, 0x20, ZC3XX_R132_GAMMA12}, | ||
4636 | {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, | ||
4637 | {0xa0, 0x16, ZC3XX_R134_GAMMA14}, | ||
4638 | {0xa0, 0x13, ZC3XX_R135_GAMMA15}, | ||
4639 | {0xa0, 0x10, ZC3XX_R136_GAMMA16}, | ||
4640 | {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, | ||
4641 | {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, | ||
4642 | {0xa0, 0x09, ZC3XX_R139_GAMMA19}, | ||
4643 | {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, | ||
4644 | {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, | ||
4645 | {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, | ||
4646 | {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, | ||
4647 | {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, | ||
4648 | {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, | ||
4649 | {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ | ||
4650 | {0xa0, 0xf8, ZC3XX_R10B_RGB01}, | ||
4651 | {0xa0, 0xf8, ZC3XX_R10C_RGB02}, | ||
4652 | {0xa0, 0xf8, ZC3XX_R10D_RGB10}, | ||
4653 | {0xa0, 0x50, ZC3XX_R10E_RGB11}, | ||
4654 | {0xa0, 0xf8, ZC3XX_R10F_RGB12}, | ||
4655 | {0xa0, 0xf8, ZC3XX_R110_RGB20}, | ||
4656 | {0xa0, 0xf8, ZC3XX_R111_RGB21}, | ||
4657 | {0xa0, 0x50, ZC3XX_R112_RGB22}, | ||
4658 | |||
4659 | {0xa1, 0x01, 0x0180}, | ||
4660 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
4661 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
4662 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
4663 | {0xaa, 0x05, 0x0009}, | ||
4664 | {0xaa, 0x09, 0x0134}, | ||
4665 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, | ||
4666 | {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, | ||
4667 | {0xa0, 0xec, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
4668 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
4669 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, | ||
4670 | {0xa0, 0x9c, ZC3XX_R197_ANTIFLICKERLOW}, | ||
4671 | {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, | ||
4672 | {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, | ||
4673 | {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
4674 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
4675 | {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, | ||
4676 | {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, | ||
4677 | {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2}, | ||
4678 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, | ||
4679 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
4680 | {0xa0, 0x09, 0x01ad}, | ||
4681 | {0xa0, 0x15, 0x01ae}, | ||
4682 | {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
4683 | {0xa1, 0x01, 0x0180}, | ||
4684 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
4685 | {} | ||
4686 | }; | ||
4687 | static const struct usb_action pb0330xx_Initial[] = { | ||
4688 | {0xa1, 0x01, 0x0008}, | ||
4689 | {0xa1, 0x01, 0x0008}, | ||
4690 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
4691 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ | ||
4692 | {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, | ||
4693 | {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, | ||
4694 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
4695 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
4696 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
4697 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
4698 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
4699 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
4700 | {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
4701 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, | ||
4702 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, | ||
4703 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, | ||
4704 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, | ||
4705 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
4706 | {0xaa, 0x01, 0x0006}, | ||
4707 | {0xaa, 0x02, 0x0011}, | ||
4708 | {0xaa, 0x03, 0x01e7}, | ||
4709 | {0xaa, 0x04, 0x0287}, | ||
4710 | {0xaa, 0x06, 0x0003}, | ||
4711 | {0xaa, 0x07, 0x3002}, | ||
4712 | {0xaa, 0x20, 0x1100}, | ||
4713 | {0xaa, 0x2f, 0xf7b0}, | ||
4714 | {0xaa, 0x30, 0x0005}, | ||
4715 | {0xaa, 0x31, 0x0000}, | ||
4716 | {0xaa, 0x34, 0x0100}, | ||
4717 | {0xaa, 0x35, 0x0060}, | ||
4718 | {0xaa, 0x3d, 0x068f}, | ||
4719 | {0xaa, 0x40, 0x01e0}, | ||
4720 | {0xaa, 0x58, 0x0078}, | ||
4721 | {0xaa, 0x62, 0x0411}, | ||
4722 | {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, | ||
4723 | {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, | ||
4724 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
4725 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
4726 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
4727 | {0xa0, 0x00, 0x01ad}, | ||
4728 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
4729 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
4730 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
4731 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
4732 | {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, | ||
4733 | {0xa0, 0x6c, ZC3XX_R18D_YTARGET}, | ||
4734 | {0xa1, 0x01, 0x0002}, | ||
4735 | {0xa0, 0x09, 0x01ad}, | ||
4736 | {0xa0, 0x15, 0x01ae}, | ||
4737 | {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT}, | ||
4738 | {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND}, | ||
4739 | {0xa1, 0x01, 0x0091}, | ||
4740 | {0xa1, 0x01, 0x0095}, | ||
4741 | {0xa1, 0x01, 0x0096}, | ||
4742 | {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ | ||
4743 | {0xa0, 0xf8, ZC3XX_R10B_RGB01}, | ||
4744 | {0xa0, 0xf8, ZC3XX_R10C_RGB02}, | ||
4745 | {0xa0, 0xf8, ZC3XX_R10D_RGB10}, | ||
4746 | {0xa0, 0x50, ZC3XX_R10E_RGB11}, | ||
4747 | {0xa0, 0xf8, ZC3XX_R10F_RGB12}, | ||
4748 | {0xa0, 0xf8, ZC3XX_R110_RGB20}, | ||
4749 | {0xa0, 0xf8, ZC3XX_R111_RGB21}, | ||
4750 | {0xa0, 0x50, ZC3XX_R112_RGB22}, | ||
4751 | {0xa1, 0x01, 0x0008}, | ||
4752 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ | ||
4753 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
4754 | {0xa1, 0x01, 0x01c8}, | ||
4755 | {0xa1, 0x01, 0x01c9}, | ||
4756 | {0xa1, 0x01, 0x01ca}, | ||
4757 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
4758 | |||
4759 | {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ | ||
4760 | {0xa0, 0xf8, ZC3XX_R10B_RGB01}, | ||
4761 | {0xa0, 0xf8, ZC3XX_R10C_RGB02}, | ||
4762 | {0xa0, 0xf8, ZC3XX_R10D_RGB10}, | ||
4763 | {0xa0, 0x50, ZC3XX_R10E_RGB11}, | ||
4764 | {0xa0, 0xf8, ZC3XX_R10F_RGB12}, | ||
4765 | {0xa0, 0xf8, ZC3XX_R110_RGB20}, | ||
4766 | {0xa0, 0xf8, ZC3XX_R111_RGB21}, | ||
4767 | {0xa0, 0x50, ZC3XX_R112_RGB22}, | ||
4768 | {0xa1, 0x01, 0x0180}, | ||
4769 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
4770 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
4771 | {0xaa, 0x05, 0x0066}, | ||
4772 | {0xaa, 0x09, 0x02b2}, | ||
4773 | {0xaa, 0x10, 0x0002}, | ||
4774 | |||
4775 | {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, | ||
4776 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, | ||
4777 | {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, | ||
4778 | {0xa0, 0x8c, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
4779 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
4780 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, | ||
4781 | {0xa0, 0x8a, ZC3XX_R197_ANTIFLICKERLOW}, | ||
4782 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, | ||
4783 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, | ||
4784 | {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
4785 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
4786 | {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, | ||
4787 | {0xa0, 0xf0, ZC3XX_R01E_HSYNC_1}, | ||
4788 | {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, | ||
4789 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, | ||
4790 | {0xa0, 0x09, 0x01ad}, | ||
4791 | {0xa0, 0x15, 0x01ae}, | ||
4792 | {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
4793 | {0xa1, 0x01, 0x0180}, | ||
4794 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
4795 | {0xa1, 0x01, 0x0008}, | ||
4796 | {0xa1, 0x01, 0x0007}, | ||
4797 | /* {0xa0, 0x30, 0x0007}, */ | ||
4798 | /* {0xa0, 0x00, 0x0007}, */ | ||
4799 | {} | ||
4800 | }; | ||
4801 | |||
4802 | static const struct usb_action pb0330xx_InitialScale[] = { | ||
4803 | {0xa1, 0x01, 0x0008}, | ||
4804 | {0xa1, 0x01, 0x0008}, | ||
4805 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
4806 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ | ||
4807 | {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, | ||
4808 | {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 10 */ | ||
4809 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
4810 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
4811 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
4812 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
4813 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
4814 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
4815 | {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
4816 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, | ||
4817 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, | ||
4818 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, | ||
4819 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, | ||
4820 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
4821 | {0xaa, 0x01, 0x0006}, | ||
4822 | {0xaa, 0x02, 0x0011}, | ||
4823 | {0xaa, 0x03, 0x01e7}, | ||
4824 | {0xaa, 0x04, 0x0287}, | ||
4825 | {0xaa, 0x06, 0x0003}, | ||
4826 | {0xaa, 0x07, 0x3002}, | ||
4827 | {0xaa, 0x20, 0x1100}, | ||
4828 | {0xaa, 0x2f, 0xf7b0}, | ||
4829 | {0xaa, 0x30, 0x0005}, | ||
4830 | {0xaa, 0x31, 0x0000}, | ||
4831 | {0xaa, 0x34, 0x0100}, | ||
4832 | {0xaa, 0x35, 0x0060}, | ||
4833 | {0xaa, 0x3d, 0x068f}, | ||
4834 | {0xaa, 0x40, 0x01e0}, | ||
4835 | {0xaa, 0x58, 0x0078}, | ||
4836 | {0xaa, 0x62, 0x0411}, | ||
4837 | {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, | ||
4838 | {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, | ||
4839 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
4840 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
4841 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
4842 | {0xa0, 0x00, 0x01ad}, | ||
4843 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
4844 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
4845 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
4846 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
4847 | {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, | ||
4848 | {0xa0, 0x6c, ZC3XX_R18D_YTARGET}, | ||
4849 | {0xa1, 0x01, 0x0002}, | ||
4850 | {0xa0, 0x09, 0x01ad}, | ||
4851 | {0xa0, 0x15, 0x01ae}, | ||
4852 | {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT}, | ||
4853 | {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND}, | ||
4854 | {0xa1, 0x01, 0x0091}, | ||
4855 | {0xa1, 0x01, 0x0095}, | ||
4856 | {0xa1, 0x01, 0x0096}, | ||
4857 | {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ | ||
4858 | {0xa0, 0xf8, ZC3XX_R10B_RGB01}, | ||
4859 | {0xa0, 0xf8, ZC3XX_R10C_RGB02}, | ||
4860 | {0xa0, 0xf8, ZC3XX_R10D_RGB10}, | ||
4861 | {0xa0, 0x50, ZC3XX_R10E_RGB11}, | ||
4862 | {0xa0, 0xf8, ZC3XX_R10F_RGB12}, | ||
4863 | {0xa0, 0xf8, ZC3XX_R110_RGB20}, | ||
4864 | {0xa0, 0xf8, ZC3XX_R111_RGB21}, | ||
4865 | {0xa0, 0x50, ZC3XX_R112_RGB22}, | ||
4866 | {0xa1, 0x01, 0x0008}, | ||
4867 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ | ||
4868 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
4869 | {0xa1, 0x01, 0x01c8}, | ||
4870 | {0xa1, 0x01, 0x01c9}, | ||
4871 | {0xa1, 0x01, 0x01ca}, | ||
4872 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
4873 | |||
4874 | {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ | ||
4875 | {0xa0, 0xf8, ZC3XX_R10B_RGB01}, | ||
4876 | {0xa0, 0xf8, ZC3XX_R10C_RGB02}, | ||
4877 | {0xa0, 0xf8, ZC3XX_R10D_RGB10}, | ||
4878 | {0xa0, 0x50, ZC3XX_R10E_RGB11}, | ||
4879 | {0xa0, 0xf8, ZC3XX_R10F_RGB12}, | ||
4880 | {0xa0, 0xf8, ZC3XX_R110_RGB20}, | ||
4881 | {0xa0, 0xf8, ZC3XX_R111_RGB21}, | ||
4882 | {0xa0, 0x50, ZC3XX_R112_RGB22}, | ||
4883 | {0xa1, 0x01, 0x0180}, | ||
4884 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
4885 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
4886 | {0xaa, 0x05, 0x0066}, | ||
4887 | {0xaa, 0x09, 0x02b2}, | ||
4888 | {0xaa, 0x10, 0x0002}, | ||
4889 | {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, | ||
4890 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, | ||
4891 | {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, | ||
4892 | {0xa0, 0x8c, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
4893 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
4894 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, | ||
4895 | {0xa0, 0x8a, ZC3XX_R197_ANTIFLICKERLOW}, | ||
4896 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, | ||
4897 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, | ||
4898 | {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
4899 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
4900 | {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, | ||
4901 | {0xa0, 0xf0, ZC3XX_R01E_HSYNC_1}, | ||
4902 | {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, | ||
4903 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, | ||
4904 | {0xa0, 0x09, 0x01ad}, | ||
4905 | {0xa0, 0x15, 0x01ae}, | ||
4906 | {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
4907 | {0xa1, 0x01, 0x0180}, | ||
4908 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
4909 | {0xa1, 0x01, 0x0008}, | ||
4910 | {0xa1, 0x01, 0x0007}, | ||
4911 | /* {0xa0, 0x30, 0x0007}, */ | ||
4912 | /* {0xa0, 0x00, 0x0007}, */ | ||
4913 | {} | ||
4914 | }; | ||
4915 | static const struct usb_action pb0330_50HZ[] = { | ||
4916 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
4917 | {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ | ||
4918 | {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,ee,cc */ | ||
4919 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
4920 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
4921 | {0xa0, 0x46, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,46,cc */ | ||
4922 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
4923 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
4924 | {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ | ||
4925 | {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ | ||
4926 | {0xa0, 0x68, ZC3XX_R01D_HSYNC_0}, /* 00,1d,68,cc */ | ||
4927 | {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */ | ||
4928 | {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */ | ||
4929 | {} | ||
4930 | }; | ||
4931 | static const struct usb_action pb0330_50HZScale[] = { | ||
4932 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
4933 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
4934 | {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ | ||
4935 | {0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,a0,cc */ | ||
4936 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
4937 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
4938 | {0xa0, 0x7a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7a,cc */ | ||
4939 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
4940 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
4941 | {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ | ||
4942 | {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ | ||
4943 | {0xa0, 0xe5, ZC3XX_R01D_HSYNC_0}, /* 00,1d,e5,cc */ | ||
4944 | {0xa0, 0xf0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,f0,cc */ | ||
4945 | {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f8,cc */ | ||
4946 | {} | ||
4947 | }; | ||
4948 | static const struct usb_action pb0330_60HZ[] = { | ||
4949 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
4950 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
4951 | {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ | ||
4952 | {0xa0, 0xdd, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,dd,cc */ | ||
4953 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
4954 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
4955 | {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3d,cc */ | ||
4956 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
4957 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
4958 | {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ | ||
4959 | {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ | ||
4960 | {0xa0, 0x43, ZC3XX_R01D_HSYNC_0}, /* 00,1d,43,cc */ | ||
4961 | {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */ | ||
4962 | {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ | ||
4963 | {} | ||
4964 | }; | ||
4965 | static const struct usb_action pb0330_60HZScale[] = { | ||
4966 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
4967 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
4968 | {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ | ||
4969 | {0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,a0,cc */ | ||
4970 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
4971 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
4972 | {0xa0, 0x7a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7a,cc */ | ||
4973 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
4974 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
4975 | {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ | ||
4976 | {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ | ||
4977 | {0xa0, 0x41, ZC3XX_R01D_HSYNC_0}, /* 00,1d,41,cc */ | ||
4978 | {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */ | ||
4979 | {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ | ||
4980 | {} | ||
4981 | }; | ||
4982 | static const struct usb_action pb0330_NoFliker[] = { | ||
4983 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
4984 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
4985 | {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ | ||
4986 | {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ | ||
4987 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
4988 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
4989 | {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ | ||
4990 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
4991 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
4992 | {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ | ||
4993 | {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ | ||
4994 | {0xa0, 0x09, ZC3XX_R01D_HSYNC_0}, /* 00,1d,09,cc */ | ||
4995 | {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, /* 00,1e,40,cc */ | ||
4996 | {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ | ||
4997 | {} | ||
4998 | }; | ||
4999 | static const struct usb_action pb0330_NoFlikerScale[] = { | ||
5000 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
5001 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
5002 | {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ | ||
5003 | {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ | ||
5004 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
5005 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
5006 | {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ | ||
5007 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
5008 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
5009 | {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ | ||
5010 | {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ | ||
5011 | {0xa0, 0x09, ZC3XX_R01D_HSYNC_0}, /* 00,1d,09,cc */ | ||
5012 | {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, /* 00,1e,40,cc */ | ||
5013 | {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ | ||
5014 | {} | ||
5015 | }; | ||
5016 | |||
5017 | /* from oem9.inf - HKR,%PO2030%,Initial - 640x480 - (close to CS2102) */ | ||
5018 | static const struct usb_action PO2030_mode0[] = { | ||
5019 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ | ||
5020 | {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */ | ||
5021 | {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ | ||
5022 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ | ||
5023 | {0xa0, 0x04, ZC3XX_R080_HBLANKHIGH}, /* 00,80,04,cc */ | ||
5024 | {0xa0, 0x05, ZC3XX_R081_HBLANKLOW}, /* 00,81,05,cc */ | ||
5025 | {0xa0, 0x16, ZC3XX_R083_RGAINADDR}, /* 00,83,16,cc */ | ||
5026 | {0xa0, 0x18, ZC3XX_R085_BGAINADDR}, /* 00,85,18,cc */ | ||
5027 | {0xa0, 0x1a, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,1a,cc */ | ||
5028 | {0xa0, 0x1b, ZC3XX_R087_EXPTIMEMID}, /* 00,87,1b,cc */ | ||
5029 | {0xa0, 0x1c, ZC3XX_R088_EXPTIMELOW}, /* 00,88,1c,cc */ | ||
5030 | {0xa0, 0xee, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,ee,cc */ | ||
5031 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ | ||
5032 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ | ||
5033 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ | ||
5034 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ | ||
5035 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ | ||
5036 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ | ||
5037 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */ | ||
5038 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */ | ||
5039 | {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */ | ||
5040 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ | ||
5041 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ | ||
5042 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ | ||
5043 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ | ||
5044 | {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e6,cc */ | ||
5045 | {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */ | ||
5046 | {0xaa, 0x09, 0x00ce}, /* 00,09,ce,aa */ | ||
5047 | {0xaa, 0x0b, 0x0005}, /* 00,0b,05,aa */ | ||
5048 | {0xaa, 0x0d, 0x0054}, /* 00,0d,54,aa */ | ||
5049 | {0xaa, 0x0f, 0x00eb}, /* 00,0f,eb,aa */ | ||
5050 | {0xaa, 0x87, 0x0000}, /* 00,87,00,aa */ | ||
5051 | {0xaa, 0x88, 0x0004}, /* 00,88,04,aa */ | ||
5052 | {0xaa, 0x89, 0x0000}, /* 00,89,00,aa */ | ||
5053 | {0xaa, 0x8a, 0x0005}, /* 00,8a,05,aa */ | ||
5054 | {0xaa, 0x13, 0x0003}, /* 00,13,03,aa */ | ||
5055 | {0xaa, 0x16, 0x0040}, /* 00,16,40,aa */ | ||
5056 | {0xaa, 0x18, 0x0040}, /* 00,18,40,aa */ | ||
5057 | {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ | ||
5058 | {0xaa, 0x29, 0x00e8}, /* 00,29,e8,aa */ | ||
5059 | {0xaa, 0x45, 0x0045}, /* 00,45,45,aa */ | ||
5060 | {0xaa, 0x50, 0x00ed}, /* 00,50,ed,aa */ | ||
5061 | {0xaa, 0x51, 0x0025}, /* 00,51,25,aa */ | ||
5062 | {0xaa, 0x52, 0x0042}, /* 00,52,42,aa */ | ||
5063 | {0xaa, 0x53, 0x002f}, /* 00,53,2f,aa */ | ||
5064 | {0xaa, 0x79, 0x0025}, /* 00,79,25,aa */ | ||
5065 | {0xaa, 0x7b, 0x0000}, /* 00,7b,00,aa */ | ||
5066 | {0xaa, 0x7e, 0x0025}, /* 00,7e,25,aa */ | ||
5067 | {0xaa, 0x7f, 0x0025}, /* 00,7f,25,aa */ | ||
5068 | {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */ | ||
5069 | {0xaa, 0x33, 0x0036}, /* 00,33,36,aa */ | ||
5070 | {0xaa, 0x36, 0x0060}, /* 00,36,60,aa */ | ||
5071 | {0xaa, 0x37, 0x0008}, /* 00,37,08,aa */ | ||
5072 | {0xaa, 0x3b, 0x0031}, /* 00,3b,31,aa */ | ||
5073 | {0xaa, 0x44, 0x000f}, /* 00,44,0f,aa */ | ||
5074 | {0xaa, 0x58, 0x0002}, /* 00,58,02,aa */ | ||
5075 | {0xaa, 0x66, 0x00c0}, /* 00,66,c0,aa */ | ||
5076 | {0xaa, 0x67, 0x0044}, /* 00,67,44,aa */ | ||
5077 | {0xaa, 0x6b, 0x00a0}, /* 00,6b,a0,aa */ | ||
5078 | {0xaa, 0x6c, 0x0054}, /* 00,6c,54,aa */ | ||
5079 | {0xaa, 0xd6, 0x0007}, /* 00,d6,07,aa */ | ||
5080 | {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,f7,cc */ | ||
5081 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ | ||
5082 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ | ||
5083 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ | ||
5084 | {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */ | ||
5085 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ | ||
5086 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ | ||
5087 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ | ||
5088 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ | ||
5089 | {0xa0, 0x7a, ZC3XX_R116_RGAIN}, /* 01,16,7a,cc */ | ||
5090 | {0xa0, 0x4a, ZC3XX_R118_BGAIN}, /* 01,18,4a,cc */ | ||
5091 | {} | ||
5092 | }; | ||
5093 | |||
5094 | /* from oem9.inf - HKR,%PO2030%,InitialScale - 320x240 */ | ||
5095 | static const struct usb_action PO2030_mode1[] = { | ||
5096 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ | ||
5097 | {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */ | ||
5098 | {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ | ||
5099 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ | ||
5100 | {0xa0, 0x04, ZC3XX_R080_HBLANKHIGH}, /* 00,80,04,cc */ | ||
5101 | {0xa0, 0x05, ZC3XX_R081_HBLANKLOW}, /* 00,81,05,cc */ | ||
5102 | {0xa0, 0x16, ZC3XX_R083_RGAINADDR}, /* 00,83,16,cc */ | ||
5103 | {0xa0, 0x18, ZC3XX_R085_BGAINADDR}, /* 00,85,18,cc */ | ||
5104 | {0xa0, 0x1a, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,1a,cc */ | ||
5105 | {0xa0, 0x1b, ZC3XX_R087_EXPTIMEMID}, /* 00,87,1b,cc */ | ||
5106 | {0xa0, 0x1c, ZC3XX_R088_EXPTIMELOW}, /* 00,88,1c,cc */ | ||
5107 | {0xa0, 0xee, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,ee,cc */ | ||
5108 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ | ||
5109 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ | ||
5110 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ | ||
5111 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ | ||
5112 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ | ||
5113 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ | ||
5114 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */ | ||
5115 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */ | ||
5116 | {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */ | ||
5117 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ | ||
5118 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ | ||
5119 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ | ||
5120 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ | ||
5121 | {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e8,cc */ | ||
5122 | {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */ | ||
5123 | {0xaa, 0x09, 0x00cc}, /* 00,09,cc,aa */ | ||
5124 | {0xaa, 0x0b, 0x0005}, /* 00,0b,05,aa */ | ||
5125 | {0xaa, 0x0d, 0x0058}, /* 00,0d,58,aa */ | ||
5126 | {0xaa, 0x0f, 0x00ed}, /* 00,0f,ed,aa */ | ||
5127 | {0xaa, 0x87, 0x0000}, /* 00,87,00,aa */ | ||
5128 | {0xaa, 0x88, 0x0004}, /* 00,88,04,aa */ | ||
5129 | {0xaa, 0x89, 0x0000}, /* 00,89,00,aa */ | ||
5130 | {0xaa, 0x8a, 0x0005}, /* 00,8a,05,aa */ | ||
5131 | {0xaa, 0x13, 0x0003}, /* 00,13,03,aa */ | ||
5132 | {0xaa, 0x16, 0x0040}, /* 00,16,40,aa */ | ||
5133 | {0xaa, 0x18, 0x0040}, /* 00,18,40,aa */ | ||
5134 | {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ | ||
5135 | {0xaa, 0x29, 0x00e8}, /* 00,29,e8,aa */ | ||
5136 | {0xaa, 0x45, 0x0045}, /* 00,45,45,aa */ | ||
5137 | {0xaa, 0x50, 0x00ed}, /* 00,50,ed,aa */ | ||
5138 | {0xaa, 0x51, 0x0025}, /* 00,51,25,aa */ | ||
5139 | {0xaa, 0x52, 0x0042}, /* 00,52,42,aa */ | ||
5140 | {0xaa, 0x53, 0x002f}, /* 00,53,2f,aa */ | ||
5141 | {0xaa, 0x79, 0x0025}, /* 00,79,25,aa */ | ||
5142 | {0xaa, 0x7b, 0x0000}, /* 00,7b,00,aa */ | ||
5143 | {0xaa, 0x7e, 0x0025}, /* 00,7e,25,aa */ | ||
5144 | {0xaa, 0x7f, 0x0025}, /* 00,7f,25,aa */ | ||
5145 | {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */ | ||
5146 | {0xaa, 0x33, 0x0036}, /* 00,33,36,aa */ | ||
5147 | {0xaa, 0x36, 0x0060}, /* 00,36,60,aa */ | ||
5148 | {0xaa, 0x37, 0x0008}, /* 00,37,08,aa */ | ||
5149 | {0xaa, 0x3b, 0x0031}, /* 00,3b,31,aa */ | ||
5150 | {0xaa, 0x44, 0x000f}, /* 00,44,0f,aa */ | ||
5151 | {0xaa, 0x58, 0x0002}, /* 00,58,02,aa */ | ||
5152 | {0xaa, 0x66, 0x00c0}, /* 00,66,c0,aa */ | ||
5153 | {0xaa, 0x67, 0x0044}, /* 00,67,44,aa */ | ||
5154 | {0xaa, 0x6b, 0x00a0}, /* 00,6b,a0,aa */ | ||
5155 | {0xaa, 0x6c, 0x0054}, /* 00,6c,54,aa */ | ||
5156 | {0xaa, 0xd6, 0x0007}, /* 00,d6,07,aa */ | ||
5157 | {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,f7,cc */ | ||
5158 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ | ||
5159 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ | ||
5160 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ | ||
5161 | {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */ | ||
5162 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ | ||
5163 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ | ||
5164 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ | ||
5165 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ | ||
5166 | {0xa0, 0x7a, ZC3XX_R116_RGAIN}, /* 01,16,7a,cc */ | ||
5167 | {0xa0, 0x4a, ZC3XX_R118_BGAIN}, /* 01,18,4a,cc */ | ||
5168 | {} | ||
5169 | }; | ||
5170 | |||
5171 | static const struct usb_action PO2030_50HZ[] = { | ||
5172 | {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */ | ||
5173 | {0xaa, 0x1a, 0x0001}, /* 00,1a,01,aa */ | ||
5174 | {0xaa, 0x1b, 0x000a}, /* 00,1b,0a,aa */ | ||
5175 | {0xaa, 0x1c, 0x00b0}, /* 00,1c,b0,aa */ | ||
5176 | {0xa0, 0x05, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,05,cc */ | ||
5177 | {0xa0, 0x35, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,35,cc */ | ||
5178 | {0xa0, 0x70, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,70,cc */ | ||
5179 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
5180 | {0xa0, 0x85, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,85,cc */ | ||
5181 | {0xa0, 0x58, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,58,cc */ | ||
5182 | {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0c,cc */ | ||
5183 | {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,18,cc */ | ||
5184 | {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc */ | ||
5185 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ | ||
5186 | {0xa0, 0x22, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,22,cc */ | ||
5187 | {0xa0, 0x88, ZC3XX_R18D_YTARGET}, /* 01,8d,88,cc */ | ||
5188 | {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc */ | ||
5189 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */ | ||
5190 | {} | ||
5191 | }; | ||
5192 | |||
5193 | static const struct usb_action PO2030_60HZ[] = { | ||
5194 | {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */ | ||
5195 | {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */ | ||
5196 | {0xaa, 0x1b, 0x00de}, /* 00,1b,de,aa */ | ||
5197 | {0xaa, 0x1c, 0x0040}, /* 00,1c,40,aa */ | ||
5198 | {0xa0, 0x08, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,08,cc */ | ||
5199 | {0xa0, 0xae, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,ae,cc */ | ||
5200 | {0xa0, 0x80, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,80,cc */ | ||
5201 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
5202 | {0xa0, 0x6f, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,6f,cc */ | ||
5203 | {0xa0, 0x20, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,20,cc */ | ||
5204 | {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0c,cc */ | ||
5205 | {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,18,cc */ | ||
5206 | {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc */ | ||
5207 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ | ||
5208 | {0xa0, 0x22, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,22,cc */ | ||
5209 | {0xa0, 0x88, ZC3XX_R18D_YTARGET}, /* 01,8d,88,cc */ | ||
5210 | /* win: 01,8d,80 */ | ||
5211 | {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc */ | ||
5212 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */ | ||
5213 | {} | ||
5214 | }; | ||
5215 | |||
5216 | static const struct usb_action PO2030_NoFliker[] = { | ||
5217 | {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ | ||
5218 | {0xaa, 0x8d, 0x000d}, /* 00,8d,0d,aa */ | ||
5219 | {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */ | ||
5220 | {0xaa, 0x1b, 0x0002}, /* 00,1b,02,aa */ | ||
5221 | {0xaa, 0x1c, 0x0078}, /* 00,1c,78,aa */ | ||
5222 | {0xaa, 0x46, 0x0000}, /* 00,46,00,aa */ | ||
5223 | {0xaa, 0x15, 0x0000}, /* 00,15,00,aa */ | ||
5224 | {} | ||
5225 | }; | ||
5226 | |||
5227 | /* TEST */ | ||
5228 | static const struct usb_action tas5130CK_Initial[] = { | ||
5229 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
5230 | {0xa0, 0x01, 0x003b}, | ||
5231 | {0xa0, 0x0e, 0x003a}, | ||
5232 | {0xa0, 0x01, 0x0038}, | ||
5233 | {0xa0, 0x0b, 0x0039}, | ||
5234 | {0xa0, 0x00, 0x0038}, | ||
5235 | {0xa0, 0x0b, 0x0039}, | ||
5236 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
5237 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | ||
5238 | {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, | ||
5239 | {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, | ||
5240 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
5241 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
5242 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
5243 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
5244 | {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, | ||
5245 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
5246 | {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
5247 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, | ||
5248 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, | ||
5249 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, | ||
5250 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, | ||
5251 | {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, | ||
5252 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
5253 | {0xa0, 0x01, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5254 | {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, | ||
5255 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5256 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5257 | {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5258 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
5259 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5260 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5261 | {0xa0, 0x08, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5262 | {0xa0, 0x83, ZC3XX_R093_I2CSETVALUE}, | ||
5263 | {0xa0, 0x04, ZC3XX_R094_I2CWRITEACK}, | ||
5264 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5265 | {0xa0, 0x01, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5266 | {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, | ||
5267 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5268 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5269 | {0xa0, 0x08, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5270 | {0xa0, 0x06, ZC3XX_R093_I2CSETVALUE}, | ||
5271 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5272 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5273 | {0xa0, 0x02, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5274 | {0xa0, 0x11, ZC3XX_R093_I2CSETVALUE}, | ||
5275 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5276 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5277 | {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5278 | {0xa0, 0xE7, ZC3XX_R093_I2CSETVALUE}, | ||
5279 | {0xa0, 0x01, ZC3XX_R094_I2CWRITEACK}, | ||
5280 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5281 | {0xa0, 0x04, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5282 | {0xa0, 0x87, ZC3XX_R093_I2CSETVALUE}, | ||
5283 | {0xa0, 0x02, ZC3XX_R094_I2CWRITEACK}, | ||
5284 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5285 | {0xa0, 0x07, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5286 | {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, | ||
5287 | {0xa0, 0x30, ZC3XX_R094_I2CWRITEACK}, | ||
5288 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5289 | {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5290 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
5291 | {0xa0, 0x51, ZC3XX_R094_I2CWRITEACK}, | ||
5292 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5293 | {0xa0, 0x35, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5294 | {0xa0, 0x7F, ZC3XX_R093_I2CSETVALUE}, | ||
5295 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5296 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5297 | {0xa0, 0x30, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5298 | {0xa0, 0x05, ZC3XX_R093_I2CSETVALUE}, | ||
5299 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5300 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5301 | {0xa0, 0x31, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5302 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
5303 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5304 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5305 | {0xa0, 0x58, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5306 | {0xa0, 0x78, ZC3XX_R093_I2CSETVALUE}, | ||
5307 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5308 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5309 | {0xa0, 0x62, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5310 | {0xa0, 0x11, ZC3XX_R093_I2CSETVALUE}, | ||
5311 | {0xa0, 0x04, ZC3XX_R094_I2CWRITEACK}, | ||
5312 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5313 | {0xa0, 0x2B, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5314 | {0xa0, 0x7f, ZC3XX_R093_I2CSETVALUE}, | ||
5315 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5316 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5317 | {0xa0, 0x2c, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5318 | {0xa0, 0x7f, ZC3XX_R093_I2CSETVALUE}, | ||
5319 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5320 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5321 | {0xa0, 0x2D, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5322 | {0xa0, 0x7f, ZC3XX_R093_I2CSETVALUE}, | ||
5323 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5324 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5325 | {0xa0, 0x2e, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5326 | {0xa0, 0x7f, ZC3XX_R093_I2CSETVALUE}, | ||
5327 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5328 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5329 | {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, | ||
5330 | {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, | ||
5331 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
5332 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
5333 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
5334 | {0xa0, 0x09, 0x01ad}, | ||
5335 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
5336 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
5337 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
5338 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
5339 | {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, | ||
5340 | {0xa0, 0x6c, ZC3XX_R18D_YTARGET}, | ||
5341 | {0xa0, 0x61, ZC3XX_R116_RGAIN}, | ||
5342 | {0xa0, 0x65, ZC3XX_R118_BGAIN}, | ||
5343 | {0xa0, 0x09, 0x01ad}, | ||
5344 | {0xa0, 0x15, 0x01ae}, | ||
5345 | {0xa0, 0x4c, ZC3XX_R10A_RGB00}, /* matrix */ | ||
5346 | {0xa0, 0xf1, ZC3XX_R10B_RGB01}, | ||
5347 | {0xa0, 0x03, ZC3XX_R10C_RGB02}, | ||
5348 | {0xa0, 0xfe, ZC3XX_R10D_RGB10}, | ||
5349 | {0xa0, 0x51, ZC3XX_R10E_RGB11}, | ||
5350 | {0xa0, 0xf1, ZC3XX_R10F_RGB12}, | ||
5351 | {0xa0, 0xec, ZC3XX_R110_RGB20}, | ||
5352 | {0xa0, 0x03, ZC3XX_R111_RGB21}, | ||
5353 | {0xa0, 0x51, ZC3XX_R112_RGB22}, | ||
5354 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | ||
5355 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
5356 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
5357 | {0xa0, 0x38, ZC3XX_R120_GAMMA00}, /* gamma > 5 */ | ||
5358 | {0xa0, 0x51, ZC3XX_R121_GAMMA01}, | ||
5359 | {0xa0, 0x6e, ZC3XX_R122_GAMMA02}, | ||
5360 | {0xa0, 0x8c, ZC3XX_R123_GAMMA03}, | ||
5361 | {0xa0, 0xa2, ZC3XX_R124_GAMMA04}, | ||
5362 | {0xa0, 0xb6, ZC3XX_R125_GAMMA05}, | ||
5363 | {0xa0, 0xc8, ZC3XX_R126_GAMMA06}, | ||
5364 | {0xa0, 0xd6, ZC3XX_R127_GAMMA07}, | ||
5365 | {0xa0, 0xe2, ZC3XX_R128_GAMMA08}, | ||
5366 | {0xa0, 0xed, ZC3XX_R129_GAMMA09}, | ||
5367 | {0xa0, 0xf5, ZC3XX_R12A_GAMMA0A}, | ||
5368 | {0xa0, 0xfc, ZC3XX_R12B_GAMMA0B}, | ||
5369 | {0xa0, 0xff, ZC3XX_R12C_GAMMA0C}, | ||
5370 | {0xa0, 0xff, ZC3XX_R12D_GAMMA0D}, | ||
5371 | {0xa0, 0xff, ZC3XX_R12E_GAMMA0E}, | ||
5372 | {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, | ||
5373 | {0xa0, 0x12, ZC3XX_R130_GAMMA10}, | ||
5374 | {0xa0, 0x1b, ZC3XX_R131_GAMMA11}, | ||
5375 | {0xa0, 0x1d, ZC3XX_R132_GAMMA12}, | ||
5376 | {0xa0, 0x1a, ZC3XX_R133_GAMMA13}, | ||
5377 | {0xa0, 0x15, ZC3XX_R134_GAMMA14}, | ||
5378 | {0xa0, 0x12, ZC3XX_R135_GAMMA15}, | ||
5379 | {0xa0, 0x0f, ZC3XX_R136_GAMMA16}, | ||
5380 | {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, | ||
5381 | {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, | ||
5382 | {0xa0, 0x09, ZC3XX_R139_GAMMA19}, | ||
5383 | {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, | ||
5384 | {0xa0, 0x05, ZC3XX_R13B_GAMMA1B}, | ||
5385 | {0xa0, 0x00, ZC3XX_R13C_GAMMA1C}, | ||
5386 | {0xa0, 0x00, ZC3XX_R13D_GAMMA1D}, | ||
5387 | {0xa0, 0x00, ZC3XX_R13E_GAMMA1E}, | ||
5388 | {0xa0, 0x01, ZC3XX_R13F_GAMMA1F}, | ||
5389 | {0xa0, 0x4c, ZC3XX_R10A_RGB00}, /* matrix */ | ||
5390 | {0xa0, 0xf1, ZC3XX_R10B_RGB01}, | ||
5391 | {0xa0, 0x03, ZC3XX_R10C_RGB02}, | ||
5392 | {0xa0, 0xfe, ZC3XX_R10D_RGB10}, | ||
5393 | {0xa0, 0x51, ZC3XX_R10E_RGB11}, | ||
5394 | {0xa0, 0xf1, ZC3XX_R10F_RGB12}, | ||
5395 | {0xa0, 0xec, ZC3XX_R110_RGB20}, | ||
5396 | {0xa0, 0x03, ZC3XX_R111_RGB21}, | ||
5397 | {0xa0, 0x51, ZC3XX_R112_RGB22}, | ||
5398 | {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
5399 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
5400 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
5401 | {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5402 | {0xa0, 0x09, ZC3XX_R093_I2CSETVALUE}, | ||
5403 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5404 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5405 | {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5406 | {0xa0, 0x34, ZC3XX_R093_I2CSETVALUE}, | ||
5407 | {0xa0, 0x01, ZC3XX_R094_I2CWRITEACK}, | ||
5408 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5409 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, | ||
5410 | {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, | ||
5411 | {0xa0, 0xd2, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
5412 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
5413 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, | ||
5414 | {0xa0, 0x9a, ZC3XX_R197_ANTIFLICKERLOW}, | ||
5415 | {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, | ||
5416 | {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, | ||
5417 | {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
5418 | {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
5419 | {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, | ||
5420 | {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, | ||
5421 | {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2}, | ||
5422 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, | ||
5423 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
5424 | {0xa0, 0x09, 0x01ad}, | ||
5425 | {0xa0, 0x15, 0x01ae}, | ||
5426 | {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
5427 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
5428 | {} | ||
5429 | }; | ||
5430 | |||
5431 | static const struct usb_action tas5130CK_InitialScale[] = { | ||
5432 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
5433 | {0xa0, 0x01, 0x003b}, | ||
5434 | {0xa0, 0x0e, 0x003a}, | ||
5435 | {0xa0, 0x01, 0x0038}, | ||
5436 | {0xa0, 0x0b, 0x0039}, | ||
5437 | {0xa0, 0x00, 0x0038}, | ||
5438 | {0xa0, 0x0b, 0x0039}, | ||
5439 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
5440 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | ||
5441 | {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, | ||
5442 | {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, | ||
5443 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
5444 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
5445 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
5446 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
5447 | {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, | ||
5448 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
5449 | {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
5450 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, | ||
5451 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, | ||
5452 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, | ||
5453 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, | ||
5454 | {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, | ||
5455 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
5456 | {0xa0, 0x01, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5457 | {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, | ||
5458 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5459 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5460 | {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5461 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
5462 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5463 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5464 | {0xa0, 0x08, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5465 | {0xa0, 0x83, ZC3XX_R093_I2CSETVALUE}, | ||
5466 | {0xa0, 0x04, ZC3XX_R094_I2CWRITEACK}, | ||
5467 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5468 | {0xa0, 0x01, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5469 | {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, | ||
5470 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5471 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5472 | {0xa0, 0x08, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5473 | {0xa0, 0x06, ZC3XX_R093_I2CSETVALUE}, | ||
5474 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5475 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5476 | {0xa0, 0x02, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5477 | {0xa0, 0x11, ZC3XX_R093_I2CSETVALUE}, | ||
5478 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5479 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5480 | {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5481 | {0xa0, 0xe5, ZC3XX_R093_I2CSETVALUE}, | ||
5482 | {0xa0, 0x01, ZC3XX_R094_I2CWRITEACK}, | ||
5483 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5484 | {0xa0, 0x04, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5485 | {0xa0, 0x85, ZC3XX_R093_I2CSETVALUE}, | ||
5486 | {0xa0, 0x02, ZC3XX_R094_I2CWRITEACK}, | ||
5487 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5488 | {0xa0, 0x07, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5489 | {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, | ||
5490 | {0xa0, 0x30, ZC3XX_R094_I2CWRITEACK}, | ||
5491 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5492 | {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5493 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
5494 | {0xa0, 0x51, ZC3XX_R094_I2CWRITEACK}, | ||
5495 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5496 | {0xa0, 0x35, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5497 | {0xa0, 0x7F, ZC3XX_R093_I2CSETVALUE}, | ||
5498 | {0xa0, 0x50, ZC3XX_R094_I2CWRITEACK}, | ||
5499 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5500 | {0xa0, 0x30, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5501 | {0xa0, 0x05, ZC3XX_R093_I2CSETVALUE}, | ||
5502 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5503 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5504 | {0xa0, 0x31, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5505 | {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, | ||
5506 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5507 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5508 | {0xa0, 0x58, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5509 | {0xa0, 0x78, ZC3XX_R093_I2CSETVALUE}, | ||
5510 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5511 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5512 | {0xa0, 0x62, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5513 | {0xa0, 0x11, ZC3XX_R093_I2CSETVALUE}, | ||
5514 | {0xa0, 0x04, ZC3XX_R094_I2CWRITEACK}, | ||
5515 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5516 | {0xa0, 0x2B, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5517 | {0xa0, 0x7f, ZC3XX_R093_I2CSETVALUE}, | ||
5518 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5519 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5520 | {0xa0, 0x2C, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5521 | {0xa0, 0x7F, ZC3XX_R093_I2CSETVALUE}, | ||
5522 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5523 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5524 | {0xa0, 0x2D, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5525 | {0xa0, 0x7f, ZC3XX_R093_I2CSETVALUE}, | ||
5526 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5527 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5528 | {0xa0, 0x2e, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5529 | {0xa0, 0x7f, ZC3XX_R093_I2CSETVALUE}, | ||
5530 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5531 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5532 | {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, | ||
5533 | {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, | ||
5534 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
5535 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
5536 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
5537 | {0xa0, 0x09, 0x01ad}, | ||
5538 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
5539 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
5540 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
5541 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
5542 | {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, | ||
5543 | {0xa0, 0x6c, ZC3XX_R18D_YTARGET}, | ||
5544 | {0xa0, 0x61, ZC3XX_R116_RGAIN}, | ||
5545 | {0xa0, 0x65, ZC3XX_R118_BGAIN}, | ||
5546 | {0xa0, 0x09, 0x01ad}, | ||
5547 | {0xa0, 0x15, 0x01ae}, | ||
5548 | {0xa0, 0x4c, ZC3XX_R10A_RGB00}, /* matrix */ | ||
5549 | {0xa0, 0xf1, ZC3XX_R10B_RGB01}, | ||
5550 | {0xa0, 0x03, ZC3XX_R10C_RGB02}, | ||
5551 | {0xa0, 0xfe, ZC3XX_R10D_RGB10}, | ||
5552 | {0xa0, 0x51, ZC3XX_R10E_RGB11}, | ||
5553 | {0xa0, 0xf1, ZC3XX_R10F_RGB12}, | ||
5554 | {0xa0, 0xec, ZC3XX_R110_RGB20}, | ||
5555 | {0xa0, 0x03, ZC3XX_R111_RGB21}, | ||
5556 | {0xa0, 0x51, ZC3XX_R112_RGB22}, | ||
5557 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | ||
5558 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
5559 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
5560 | {0xa0, 0x38, ZC3XX_R120_GAMMA00}, /* gamma > 5 */ | ||
5561 | {0xa0, 0x51, ZC3XX_R121_GAMMA01}, | ||
5562 | {0xa0, 0x6e, ZC3XX_R122_GAMMA02}, | ||
5563 | {0xa0, 0x8c, ZC3XX_R123_GAMMA03}, | ||
5564 | {0xa0, 0xa2, ZC3XX_R124_GAMMA04}, | ||
5565 | {0xa0, 0xb6, ZC3XX_R125_GAMMA05}, | ||
5566 | {0xa0, 0xc8, ZC3XX_R126_GAMMA06}, | ||
5567 | {0xa0, 0xd6, ZC3XX_R127_GAMMA07}, | ||
5568 | {0xa0, 0xe2, ZC3XX_R128_GAMMA08}, | ||
5569 | {0xa0, 0xed, ZC3XX_R129_GAMMA09}, | ||
5570 | {0xa0, 0xf5, ZC3XX_R12A_GAMMA0A}, | ||
5571 | {0xa0, 0xfc, ZC3XX_R12B_GAMMA0B}, | ||
5572 | {0xa0, 0xff, ZC3XX_R12C_GAMMA0C}, | ||
5573 | {0xa0, 0xff, ZC3XX_R12D_GAMMA0D}, | ||
5574 | {0xa0, 0xff, ZC3XX_R12E_GAMMA0E}, | ||
5575 | {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, | ||
5576 | {0xa0, 0x12, ZC3XX_R130_GAMMA10}, | ||
5577 | {0xa0, 0x1b, ZC3XX_R131_GAMMA11}, | ||
5578 | {0xa0, 0x1d, ZC3XX_R132_GAMMA12}, | ||
5579 | {0xa0, 0x1a, ZC3XX_R133_GAMMA13}, | ||
5580 | {0xa0, 0x15, ZC3XX_R134_GAMMA14}, | ||
5581 | {0xa0, 0x12, ZC3XX_R135_GAMMA15}, | ||
5582 | {0xa0, 0x0f, ZC3XX_R136_GAMMA16}, | ||
5583 | {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, | ||
5584 | {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, | ||
5585 | {0xa0, 0x09, ZC3XX_R139_GAMMA19}, | ||
5586 | {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, | ||
5587 | {0xa0, 0x05, ZC3XX_R13B_GAMMA1B}, | ||
5588 | {0xa0, 0x00, ZC3XX_R13C_GAMMA1C}, | ||
5589 | {0xa0, 0x00, ZC3XX_R13D_GAMMA1D}, | ||
5590 | {0xa0, 0x00, ZC3XX_R13E_GAMMA1E}, | ||
5591 | {0xa0, 0x01, ZC3XX_R13F_GAMMA1F}, | ||
5592 | {0xa0, 0x4c, ZC3XX_R10A_RGB00}, /* matrix */ | ||
5593 | {0xa0, 0xf1, ZC3XX_R10B_RGB01}, | ||
5594 | {0xa0, 0x03, ZC3XX_R10C_RGB02}, | ||
5595 | {0xa0, 0xfe, ZC3XX_R10D_RGB10}, | ||
5596 | {0xa0, 0x51, ZC3XX_R10E_RGB11}, | ||
5597 | {0xa0, 0xf1, ZC3XX_R10F_RGB12}, | ||
5598 | {0xa0, 0xec, ZC3XX_R110_RGB20}, | ||
5599 | {0xa0, 0x03, ZC3XX_R111_RGB21}, | ||
5600 | {0xa0, 0x51, ZC3XX_R112_RGB22}, | ||
5601 | {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
5602 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
5603 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
5604 | {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5605 | {0xa0, 0x62, ZC3XX_R093_I2CSETVALUE}, | ||
5606 | {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, | ||
5607 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5608 | {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT}, | ||
5609 | {0xa0, 0xaa, ZC3XX_R093_I2CSETVALUE}, | ||
5610 | {0xa0, 0x01, ZC3XX_R094_I2CWRITEACK}, | ||
5611 | {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, | ||
5612 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, | ||
5613 | {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, | ||
5614 | {0xa0, 0x9b, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
5615 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
5616 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, | ||
5617 | {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, | ||
5618 | {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, | ||
5619 | {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, | ||
5620 | {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
5621 | {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
5622 | {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, | ||
5623 | {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, | ||
5624 | {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, | ||
5625 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, | ||
5626 | {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, | ||
5627 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
5628 | {0xa0, 0x09, 0x01ad}, | ||
5629 | {0xa0, 0x15, 0x01ae}, | ||
5630 | {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
5631 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
5632 | {0xa0, 0x30, 0x0007}, | ||
5633 | {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, | ||
5634 | {0xa0, 0x00, 0x0007}, | ||
5635 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | ||
5636 | {} | ||
5637 | }; | ||
5638 | |||
5639 | static const struct usb_action tas5130cxx_Initial[] = { | ||
5640 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
5641 | {0xa0, 0x50, ZC3XX_R002_CLOCKSELECT}, | ||
5642 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | ||
5643 | {0xa0, 0x02, ZC3XX_R010_CMOSSENSORSELECT}, | ||
5644 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
5645 | {0xa0, 0x00, ZC3XX_R001_SYSTEMOPERATING}, | ||
5646 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
5647 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
5648 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
5649 | {0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN}, | ||
5650 | {0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL}, | ||
5651 | |||
5652 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
5653 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
5654 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
5655 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
5656 | |||
5657 | {0xa0, 0x04, ZC3XX_R098_WINYSTARTLOW}, | ||
5658 | {0xa0, 0x0f, ZC3XX_R09A_WINXSTARTLOW}, | ||
5659 | {0xa0, 0x04, ZC3XX_R11A_FIRSTYLOW}, | ||
5660 | {0xa0, 0x0f, ZC3XX_R11C_FIRSTXLOW}, | ||
5661 | {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, | ||
5662 | {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, | ||
5663 | {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, | ||
5664 | {0xa0, 0x06, ZC3XX_R08D_COMPABILITYMODE}, | ||
5665 | {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, | ||
5666 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
5667 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
5668 | {0xa0, 0x68, ZC3XX_R18D_YTARGET}, | ||
5669 | {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, | ||
5670 | {0xa0, 0x00, 0x01ad}, | ||
5671 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
5672 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
5673 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
5674 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
5675 | {0xa1, 0x01, 0x0002}, | ||
5676 | {0xa1, 0x01, 0x0008}, | ||
5677 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ | ||
5678 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
5679 | {0xa1, 0x01, 0x01c8}, | ||
5680 | {0xa1, 0x01, 0x01c9}, | ||
5681 | {0xa1, 0x01, 0x01ca}, | ||
5682 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
5683 | |||
5684 | {0xa0, 0x68, ZC3XX_R10A_RGB00}, /* matrix */ | ||
5685 | {0xa0, 0xec, ZC3XX_R10B_RGB01}, | ||
5686 | {0xa0, 0xec, ZC3XX_R10C_RGB02}, | ||
5687 | {0xa0, 0xec, ZC3XX_R10D_RGB10}, | ||
5688 | {0xa0, 0x68, ZC3XX_R10E_RGB11}, | ||
5689 | {0xa0, 0xec, ZC3XX_R10F_RGB12}, | ||
5690 | {0xa0, 0xec, ZC3XX_R110_RGB20}, | ||
5691 | {0xa0, 0xec, ZC3XX_R111_RGB21}, | ||
5692 | {0xa0, 0x68, ZC3XX_R112_RGB22}, | ||
5693 | |||
5694 | {0xa1, 0x01, 0x018d}, | ||
5695 | {0xa0, 0x90, ZC3XX_R18D_YTARGET}, /* 90 */ | ||
5696 | {0xa1, 0x01, 0x0180}, | ||
5697 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
5698 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
5699 | |||
5700 | {0xaa, 0xa3, 0x0001}, | ||
5701 | {0xaa, 0xa4, 0x0077}, | ||
5702 | {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, | ||
5703 | {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, | ||
5704 | |||
5705 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 00 */ | ||
5706 | {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 03 */ | ||
5707 | {0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW}, /* e8 */ | ||
5708 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 0 */ | ||
5709 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 0 */ | ||
5710 | {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 7d */ | ||
5711 | |||
5712 | {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, | ||
5713 | {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, | ||
5714 | {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 08 */ | ||
5715 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 24 */ | ||
5716 | {0xa0, 0xf0, ZC3XX_R01D_HSYNC_0}, | ||
5717 | {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, | ||
5718 | {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, | ||
5719 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, | ||
5720 | {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, | ||
5721 | {0xa0, 0xc0, ZC3XX_R0A0_MAXXLOW}, | ||
5722 | {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, /* 50 */ | ||
5723 | {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
5724 | {0xa1, 0x01, 0x0180}, | ||
5725 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
5726 | {} | ||
5727 | }; | ||
5728 | static const struct usb_action tas5130cxx_InitialScale[] = { | ||
5729 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
5730 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | ||
5731 | {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, | ||
5732 | |||
5733 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | ||
5734 | {0xa1, 0x01, 0x0008}, | ||
5735 | |||
5736 | {0xa0, 0x02, ZC3XX_R010_CMOSSENSORSELECT}, | ||
5737 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
5738 | {0xa0, 0x00, ZC3XX_R001_SYSTEMOPERATING}, | ||
5739 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
5740 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, | ||
5741 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, | ||
5742 | {0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN}, | ||
5743 | {0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL}, | ||
5744 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, | ||
5745 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, | ||
5746 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, | ||
5747 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, | ||
5748 | {0xa0, 0x05, ZC3XX_R098_WINYSTARTLOW}, | ||
5749 | {0xa0, 0x0f, ZC3XX_R09A_WINXSTARTLOW}, | ||
5750 | {0xa0, 0x05, ZC3XX_R11A_FIRSTYLOW}, | ||
5751 | {0xa0, 0x0f, ZC3XX_R11C_FIRSTXLOW}, | ||
5752 | {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, | ||
5753 | {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, | ||
5754 | {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, | ||
5755 | {0xa0, 0x06, ZC3XX_R08D_COMPABILITYMODE}, | ||
5756 | {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, | ||
5757 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, | ||
5758 | {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, | ||
5759 | {0xa0, 0x68, ZC3XX_R18D_YTARGET}, | ||
5760 | {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, | ||
5761 | {0xa0, 0x00, 0x01ad}, | ||
5762 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, | ||
5763 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | ||
5764 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | ||
5765 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | ||
5766 | {0xa1, 0x01, 0x0002}, | ||
5767 | {0xa1, 0x01, 0x0008}, | ||
5768 | |||
5769 | {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, | ||
5770 | {0xa1, 0x01, 0x0008}, /* clock ? */ | ||
5771 | {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ | ||
5772 | {0xa1, 0x01, 0x01c8}, | ||
5773 | {0xa1, 0x01, 0x01c9}, | ||
5774 | {0xa1, 0x01, 0x01ca}, | ||
5775 | {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ | ||
5776 | |||
5777 | {0xa0, 0x68, ZC3XX_R10A_RGB00}, /* matrix */ | ||
5778 | {0xa0, 0xec, ZC3XX_R10B_RGB01}, | ||
5779 | {0xa0, 0xec, ZC3XX_R10C_RGB02}, | ||
5780 | {0xa0, 0xec, ZC3XX_R10D_RGB10}, | ||
5781 | {0xa0, 0x68, ZC3XX_R10E_RGB11}, | ||
5782 | {0xa0, 0xec, ZC3XX_R10F_RGB12}, | ||
5783 | {0xa0, 0xec, ZC3XX_R110_RGB20}, | ||
5784 | {0xa0, 0xec, ZC3XX_R111_RGB21}, | ||
5785 | {0xa0, 0x68, ZC3XX_R112_RGB22}, | ||
5786 | |||
5787 | {0xa1, 0x01, 0x018d}, | ||
5788 | {0xa0, 0x90, ZC3XX_R18D_YTARGET}, | ||
5789 | {0xa1, 0x01, 0x0180}, | ||
5790 | {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
5791 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, | ||
5792 | {0xaa, 0xa3, 0x0001}, | ||
5793 | {0xaa, 0xa4, 0x0063}, | ||
5794 | {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, | ||
5795 | {0xa0, 0x63, ZC3XX_R0A4_EXPOSURETIMELOW}, | ||
5796 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, | ||
5797 | {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, | ||
5798 | {0xa0, 0x38, ZC3XX_R192_EXPOSURELIMITLOW}, | ||
5799 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, | ||
5800 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, | ||
5801 | {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, | ||
5802 | {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, | ||
5803 | {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, | ||
5804 | {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF}, | ||
5805 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, | ||
5806 | {0xa0, 0xd3, ZC3XX_R01D_HSYNC_0}, | ||
5807 | {0xa0, 0xda, ZC3XX_R01E_HSYNC_1}, | ||
5808 | {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, | ||
5809 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, | ||
5810 | {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, | ||
5811 | {0xa0, 0x4c, ZC3XX_R0A0_MAXXLOW}, | ||
5812 | {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, | ||
5813 | {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
5814 | {0xa1, 0x01, 0x0180}, | ||
5815 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, | ||
5816 | {} | ||
5817 | }; | ||
5818 | static const struct usb_action tas5130cxx_50HZ[] = { | ||
5819 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
5820 | {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ | ||
5821 | {0xaa, 0xa4, 0x0063}, /* 00,a4,63,aa */ | ||
5822 | {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ | ||
5823 | {0xa0, 0x63, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,63,cc */ | ||
5824 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
5825 | {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */ | ||
5826 | {0xa0, 0x38, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,38,cc */ | ||
5827 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
5828 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
5829 | {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,47,cc */ | ||
5830 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
5831 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
5832 | {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ | ||
5833 | {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ | ||
5834 | {0xa0, 0xd3, ZC3XX_R01D_HSYNC_0}, /* 00,1d,d3,cc */ | ||
5835 | {0xa0, 0xda, ZC3XX_R01E_HSYNC_1}, /* 00,1e,da,cc */ | ||
5836 | {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ea,cc */ | ||
5837 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ | ||
5838 | {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ | ||
5839 | {} | ||
5840 | }; | ||
5841 | static const struct usb_action tas5130cxx_50HZScale[] = { | ||
5842 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
5843 | {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ | ||
5844 | {0xaa, 0xa4, 0x0077}, /* 00,a4,77,aa */ | ||
5845 | {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ | ||
5846 | {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */ | ||
5847 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
5848 | {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */ | ||
5849 | {0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e8,cc */ | ||
5850 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
5851 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
5852 | {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */ | ||
5853 | {0xa0, 0x14, ZC3XX_R18C_AEFREEZE}, /* 01,8c,14,cc */ | ||
5854 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
5855 | {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ | ||
5856 | {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ | ||
5857 | {0xa0, 0xf0, ZC3XX_R01D_HSYNC_0}, /* 00,1d,f0,cc */ | ||
5858 | {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,f4,cc */ | ||
5859 | {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f8,cc */ | ||
5860 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ | ||
5861 | {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ | ||
5862 | {} | ||
5863 | }; | ||
5864 | static const struct usb_action tas5130cxx_60HZ[] = { | ||
5865 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
5866 | {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ | ||
5867 | {0xaa, 0xa4, 0x0036}, /* 00,a4,36,aa */ | ||
5868 | {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ | ||
5869 | {0xa0, 0x36, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,36,cc */ | ||
5870 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
5871 | {0xa0, 0x01, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,01,cc */ | ||
5872 | {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ | ||
5873 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
5874 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
5875 | {0xa0, 0x3e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3e,cc */ | ||
5876 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
5877 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
5878 | {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ | ||
5879 | {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ | ||
5880 | {0xa0, 0xca, ZC3XX_R01D_HSYNC_0}, /* 00,1d,ca,cc */ | ||
5881 | {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */ | ||
5882 | {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ | ||
5883 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ | ||
5884 | {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ | ||
5885 | {} | ||
5886 | }; | ||
5887 | static const struct usb_action tas5130cxx_60HZScale[] = { | ||
5888 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
5889 | {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ | ||
5890 | {0xaa, 0xa4, 0x0077}, /* 00,a4,77,aa */ | ||
5891 | {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ | ||
5892 | {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */ | ||
5893 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
5894 | {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */ | ||
5895 | {0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e8,cc */ | ||
5896 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
5897 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
5898 | {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */ | ||
5899 | {0xa0, 0x14, ZC3XX_R18C_AEFREEZE}, /* 01,8c,14,cc */ | ||
5900 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
5901 | {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ | ||
5902 | {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ | ||
5903 | {0xa0, 0xc8, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c8,cc */ | ||
5904 | {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */ | ||
5905 | {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ | ||
5906 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ | ||
5907 | {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ | ||
5908 | {} | ||
5909 | }; | ||
5910 | static const struct usb_action tas5130cxx_NoFliker[] = { | ||
5911 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
5912 | {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ | ||
5913 | {0xaa, 0xa4, 0x0040}, /* 00,a4,40,aa */ | ||
5914 | {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ | ||
5915 | {0xa0, 0x40, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,40,cc */ | ||
5916 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
5917 | {0xa0, 0x01, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,01,cc */ | ||
5918 | {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ | ||
5919 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
5920 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
5921 | {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ | ||
5922 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
5923 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
5924 | {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ | ||
5925 | {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ | ||
5926 | {0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */ | ||
5927 | {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */ | ||
5928 | {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ | ||
5929 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ | ||
5930 | {0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */ | ||
5931 | {} | ||
5932 | }; | ||
5933 | |||
5934 | static const struct usb_action tas5130cxx_NoFlikerScale[] = { | ||
5935 | {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ | ||
5936 | {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ | ||
5937 | {0xaa, 0xa4, 0x0090}, /* 00,a4,90,aa */ | ||
5938 | {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ | ||
5939 | {0xa0, 0x90, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,90,cc */ | ||
5940 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ | ||
5941 | {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */ | ||
5942 | {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ | ||
5943 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ | ||
5944 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ | ||
5945 | {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ | ||
5946 | {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ | ||
5947 | {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ | ||
5948 | {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ | ||
5949 | {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ | ||
5950 | {0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */ | ||
5951 | {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */ | ||
5952 | {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ | ||
5953 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ | ||
5954 | {0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */ | ||
5955 | {} | ||
5956 | }; | ||
5957 | |||
5958 | static const struct usb_action tas5130c_vf0250_Initial[] = { | ||
5959 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */ | ||
5960 | {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */ | ||
5961 | {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */ | ||
5962 | {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc, | ||
5963 | * 0<->10 */ | ||
5964 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc, */ | ||
5965 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc, */ | ||
5966 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc, */ | ||
5967 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc, */ | ||
5968 | {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */ | ||
5969 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc, */ | ||
5970 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc, */ | ||
5971 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc, */ | ||
5972 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc, */ | ||
5973 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc, */ | ||
5974 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc, */ | ||
5975 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc, */ | ||
5976 | {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e6,cc, | ||
5977 | * 6<->8 */ | ||
5978 | {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc, | ||
5979 | * 6<->8 */ | ||
5980 | {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, /* 00,87,10,cc, */ | ||
5981 | {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */ | ||
5982 | {0xaa, 0x1b, 0x0024}, /* 00,1b,24,aa, */ | ||
5983 | {0xdd, 0x00, 0x0080}, /* 00,00,80,dd, */ | ||
5984 | {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa, */ | ||
5985 | {0xaa, 0x13, 0x0002}, /* 00,13,02,aa, */ | ||
5986 | {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */ | ||
5987 | {0xaa, 0x01, 0x0000}, | ||
5988 | {0xaa, 0x01, 0x0000}, | ||
5989 | {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */ | ||
5990 | {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */ | ||
5991 | {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc, */ | ||
5992 | {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc, */ | ||
5993 | {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc, */ | ||
5994 | {0xaa, 0x05, 0x0010}, /* 00,05,10,aa, */ | ||
5995 | {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa, */ | ||
5996 | {0xaa, 0x0b, 0x00a0}, /* 00,0b,a0,aa, */ | ||
5997 | {0xaa, 0x0c, 0x0000}, /* 00,0c,00,aa, */ | ||
5998 | {0xaa, 0x0d, 0x00a0}, /* 00,0d,a0,aa, */ | ||
5999 | {0xaa, 0x0e, 0x0000}, /* 00,0e,00,aa, */ | ||
6000 | {0xaa, 0x0f, 0x00a0}, /* 00,0f,a0,aa, */ | ||
6001 | {0xaa, 0x10, 0x0000}, /* 00,10,00,aa, */ | ||
6002 | {0xaa, 0x11, 0x00a0}, /* 00,11,a0,aa, */ | ||
6003 | {0xa0, 0x00, 0x0039}, | ||
6004 | {0xa1, 0x01, 0x0037}, | ||
6005 | {0xaa, 0x16, 0x0001}, /* 00,16,01,aa, */ | ||
6006 | {0xaa, 0x17, 0x00e8}, /* 00,17,e6,aa, (e6 -> e8) */ | ||
6007 | {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */ | ||
6008 | {0xaa, 0x19, 0x0088}, /* 00,19,86,aa, */ | ||
6009 | {0xaa, 0x20, 0x0020}, /* 00,20,20,aa, */ | ||
6010 | {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc, */ | ||
6011 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc, */ | ||
6012 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc, */ | ||
6013 | {0xa0, 0x76, ZC3XX_R189_AWBSTATUS}, /* 01,89,76,cc, */ | ||
6014 | {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc, */ | ||
6015 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc, */ | ||
6016 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc, */ | ||
6017 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc, */ | ||
6018 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc, */ | ||
6019 | {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc, */ | ||
6020 | {0xa0, 0x61, ZC3XX_R116_RGAIN}, /* 01,16,61,cc, */ | ||
6021 | {0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */ | ||
6022 | {} | ||
6023 | }; | ||
6024 | |||
6025 | static const struct usb_action tas5130c_vf0250_InitialScale[] = { | ||
6026 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */ | ||
6027 | {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */ | ||
6028 | {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */ | ||
6029 | {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc, */ | ||
6030 | {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc, */ | ||
6031 | {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc, */ | ||
6032 | {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc, */ | ||
6033 | {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc, */ | ||
6034 | {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */ | ||
6035 | {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc, */ | ||
6036 | {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc, */ | ||
6037 | {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc, */ | ||
6038 | {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc, */ | ||
6039 | {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc, */ | ||
6040 | {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc, */ | ||
6041 | {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc, */ | ||
6042 | {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e8,cc, | ||
6043 | * 8<->6 */ | ||
6044 | {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc, | ||
6045 | * 8<->6 */ | ||
6046 | {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, /* 00,87,10,cc, */ | ||
6047 | {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */ | ||
6048 | {0xaa, 0x1b, 0x0024}, /* 00,1b,24,aa, */ | ||
6049 | {0xdd, 0x00, 0x0080}, /* 00,00,80,dd, */ | ||
6050 | {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa, */ | ||
6051 | {0xaa, 0x13, 0x0002}, /* 00,13,02,aa, */ | ||
6052 | {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */ | ||
6053 | {0xaa, 0x01, 0x0000}, | ||
6054 | {0xaa, 0x01, 0x0000}, | ||
6055 | {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */ | ||
6056 | {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */ | ||
6057 | {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc, */ | ||
6058 | {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc, */ | ||
6059 | {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc, */ | ||
6060 | {0xaa, 0x05, 0x0010}, /* 00,05,10,aa, */ | ||
6061 | {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa, */ | ||
6062 | {0xaa, 0x0b, 0x00a0}, /* 00,0b,a0,aa, */ | ||
6063 | {0xaa, 0x0c, 0x0000}, /* 00,0c,00,aa, */ | ||
6064 | {0xaa, 0x0d, 0x00a0}, /* 00,0d,a0,aa, */ | ||
6065 | {0xaa, 0x0e, 0x0000}, /* 00,0e,00,aa, */ | ||
6066 | {0xaa, 0x0f, 0x00a0}, /* 00,0f,a0,aa, */ | ||
6067 | {0xaa, 0x10, 0x0000}, /* 00,10,00,aa, */ | ||
6068 | {0xaa, 0x11, 0x00a0}, /* 00,11,a0,aa, */ | ||
6069 | {0xa0, 0x00, 0x0039}, | ||
6070 | {0xa1, 0x01, 0x0037}, | ||
6071 | {0xaa, 0x16, 0x0001}, /* 00,16,01,aa, */ | ||
6072 | {0xaa, 0x17, 0x00e8}, /* 00,17,e6,aa (e6 -> e8) */ | ||
6073 | {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */ | ||
6074 | {0xaa, 0x19, 0x0088}, /* 00,19,88,aa, */ | ||
6075 | {0xaa, 0x20, 0x0020}, /* 00,20,20,aa, */ | ||
6076 | {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc, */ | ||
6077 | {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc, */ | ||
6078 | {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc, */ | ||
6079 | {0xa0, 0x76, ZC3XX_R189_AWBSTATUS}, /* 01,89,76,cc, */ | ||
6080 | {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc, */ | ||
6081 | {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc, */ | ||
6082 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc, */ | ||
6083 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc, */ | ||
6084 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc, */ | ||
6085 | {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc, */ | ||
6086 | {0xa0, 0x61, ZC3XX_R116_RGAIN}, /* 01,16,61,cc, */ | ||
6087 | {0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */ | ||
6088 | {} | ||
6089 | }; | ||
6090 | /* "50HZ" light frequency banding filter */ | ||
6091 | static const struct usb_action tas5130c_vf0250_50HZ[] = { | ||
6092 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | ||
6093 | {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */ | ||
6094 | {0xaa, 0x84, 0x00aa}, /* 00,84,aa,aa */ | ||
6095 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ | ||
6096 | {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0d,cc, */ | ||
6097 | {0xa0, 0xa8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,50,cc, */ | ||
6098 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ | ||
6099 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ | ||
6100 | {0xa0, 0x8e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,47,cc, */ | ||
6101 | {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */ | ||
6102 | {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */ | ||
6103 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc, */ | ||
6104 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc, */ | ||
6105 | {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */ | ||
6106 | {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */ | ||
6107 | {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */ | ||
6108 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ | ||
6109 | {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ | ||
6110 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ | ||
6111 | {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /* 01,8d,78,cc */ | ||
6112 | {} | ||
6113 | }; | ||
6114 | |||
6115 | /* "50HZScale" light frequency banding filter */ | ||
6116 | static const struct usb_action tas5130c_vf0250_50HZScale[] = { | ||
6117 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | ||
6118 | {0xaa, 0x83, 0x0003}, /* 00,83,03,aa */ | ||
6119 | {0xaa, 0x84, 0x0054}, /* 00,84,54,aa */ | ||
6120 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ | ||
6121 | {0xa0, 0x0d, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0d,cc, */ | ||
6122 | {0xa0, 0x50, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,50,cc, */ | ||
6123 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ | ||
6124 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ | ||
6125 | {0xa0, 0x8e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,8e,cc, */ | ||
6126 | {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */ | ||
6127 | {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */ | ||
6128 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc, */ | ||
6129 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc, */ | ||
6130 | {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */ | ||
6131 | {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */ | ||
6132 | {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */ | ||
6133 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ | ||
6134 | {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ | ||
6135 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ | ||
6136 | {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /* 01,8d,78,cc */ | ||
6137 | {} | ||
6138 | }; | ||
6139 | |||
6140 | /* "60HZ" light frequency banding filter */ | ||
6141 | static const struct usb_action tas5130c_vf0250_60HZ[] = { | ||
6142 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | ||
6143 | {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */ | ||
6144 | {0xaa, 0x84, 0x0062}, /* 00,84,62,aa */ | ||
6145 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ | ||
6146 | {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,05,cc, */ | ||
6147 | {0xa0, 0x88, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,88,cc, */ | ||
6148 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ | ||
6149 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ | ||
6150 | {0xa0, 0x3b, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3b,cc, */ | ||
6151 | {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */ | ||
6152 | {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */ | ||
6153 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc, */ | ||
6154 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc, */ | ||
6155 | {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */ | ||
6156 | {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */ | ||
6157 | {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */ | ||
6158 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ | ||
6159 | {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ | ||
6160 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ | ||
6161 | {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /* 01,8d,78,cc */ | ||
6162 | {} | ||
6163 | }; | ||
6164 | |||
6165 | /* "60HZScale" light frequency banding ilter */ | ||
6166 | static const struct usb_action tas5130c_vf0250_60HZScale[] = { | ||
6167 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | ||
6168 | {0xaa, 0x83, 0x0002}, /* 00,83,02,aa */ | ||
6169 | {0xaa, 0x84, 0x00c4}, /* 00,84,c4,aa */ | ||
6170 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ | ||
6171 | {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,1,0b,cc, */ | ||
6172 | {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,2,10,cc, */ | ||
6173 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,5,00,cc, */ | ||
6174 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,6,00,cc, */ | ||
6175 | {0xa0, 0x76, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,7,76,cc, */ | ||
6176 | {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,c,0e,cc, */ | ||
6177 | {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,f,15,cc, */ | ||
6178 | {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,9,10,cc, */ | ||
6179 | {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,a,24,cc, */ | ||
6180 | {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,d,62,cc, */ | ||
6181 | {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,e,90,cc, */ | ||
6182 | {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,f,c8,cc, */ | ||
6183 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,0,ff,cc, */ | ||
6184 | {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,d,58,cc, */ | ||
6185 | {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ | ||
6186 | {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /* 01,d,78,cc */ | ||
6187 | {} | ||
6188 | }; | ||
6189 | |||
6190 | /* "NoFliker" light frequency banding flter */ | ||
6191 | static const struct usb_action tas5130c_vf0250_NoFliker[] = { | ||
6192 | {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */ | ||
6193 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | ||
6194 | {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ | ||
6195 | {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */ | ||
6196 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,0,00,cc, */ | ||
6197 | {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,05,cc, */ | ||
6198 | {0xa0, 0x88, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,88,cc, */ | ||
6199 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ | ||
6200 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ | ||
6201 | {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc, */ | ||
6202 | {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */ | ||
6203 | {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */ | ||
6204 | {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */ | ||
6205 | {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */ | ||
6206 | {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */ | ||
6207 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ | ||
6208 | {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ | ||
6209 | {0xa0, 0x03, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,03,cc */ | ||
6210 | {} | ||
6211 | }; | ||
6212 | |||
6213 | /* "NoFlikerScale" light frequency banding filter */ | ||
6214 | static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = { | ||
6215 | {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */ | ||
6216 | {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ | ||
6217 | {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ | ||
6218 | {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */ | ||
6219 | {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ | ||
6220 | {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0b,cc, */ | ||
6221 | {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,10,cc, */ | ||
6222 | {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ | ||
6223 | {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ | ||
6224 | {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc, */ | ||
6225 | {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */ | ||
6226 | {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */ | ||
6227 | {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */ | ||
6228 | {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */ | ||
6229 | {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */ | ||
6230 | {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ | ||
6231 | {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ | ||
6232 | {0xa0, 0x03, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,03,cc */ | ||
6233 | {} | ||
6234 | }; | ||
6235 | |||
6236 | static int reg_r_i(struct gspca_dev *gspca_dev, | ||
6237 | __u16 index) | ||
6238 | { | ||
6239 | usb_control_msg(gspca_dev->dev, | ||
6240 | usb_rcvctrlpipe(gspca_dev->dev, 0), | ||
6241 | 0xa1, | ||
6242 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
6243 | 0x01, /* value */ | ||
6244 | index, gspca_dev->usb_buf, 1, | ||
6245 | 500); | ||
6246 | return gspca_dev->usb_buf[0]; | ||
6247 | } | ||
6248 | |||
6249 | static int reg_r(struct gspca_dev *gspca_dev, | ||
6250 | __u16 index) | ||
6251 | { | ||
6252 | int ret; | ||
6253 | |||
6254 | ret = reg_r_i(gspca_dev, index); | ||
6255 | PDEBUG(D_USBI, "reg r [%04x] -> %02x", index, ret); | ||
6256 | return ret; | ||
6257 | } | ||
6258 | |||
6259 | static void reg_w_i(struct usb_device *dev, | ||
6260 | __u8 value, | ||
6261 | __u16 index) | ||
6262 | { | ||
6263 | usb_control_msg(dev, | ||
6264 | usb_sndctrlpipe(dev, 0), | ||
6265 | 0xa0, | ||
6266 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
6267 | value, index, NULL, 0, | ||
6268 | 500); | ||
6269 | } | ||
6270 | |||
6271 | static void reg_w(struct usb_device *dev, | ||
6272 | __u8 value, | ||
6273 | __u16 index) | ||
6274 | { | ||
6275 | PDEBUG(D_USBO, "reg w %02x -> [%04x]", value, index); | ||
6276 | reg_w_i(dev, value, index); | ||
6277 | } | ||
6278 | |||
6279 | static __u16 i2c_read(struct gspca_dev *gspca_dev, | ||
6280 | __u8 reg) | ||
6281 | { | ||
6282 | __u8 retbyte; | ||
6283 | __u8 retval[2]; | ||
6284 | |||
6285 | reg_w_i(gspca_dev->dev, reg, 0x92); | ||
6286 | reg_w_i(gspca_dev->dev, 0x02, 0x90); /* <- read command */ | ||
6287 | msleep(25); | ||
6288 | retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ | ||
6289 | retval[0] = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */ | ||
6290 | retval[1] = reg_r_i(gspca_dev, 0x0096); /* read Hightbyte */ | ||
6291 | PDEBUG(D_USBO, "i2c r [%02x] -> (%02x) %02x%02x", | ||
6292 | reg, retbyte, retval[1], retval[0]); | ||
6293 | return (retval[1] << 8) | retval[0]; | ||
6294 | } | ||
6295 | |||
6296 | static __u8 i2c_write(struct gspca_dev *gspca_dev, | ||
6297 | __u8 reg, | ||
6298 | __u8 valL, | ||
6299 | __u8 valH) | ||
6300 | { | ||
6301 | __u8 retbyte; | ||
6302 | |||
6303 | reg_w_i(gspca_dev->dev, reg, 0x92); | ||
6304 | reg_w_i(gspca_dev->dev, valL, 0x93); | ||
6305 | reg_w_i(gspca_dev->dev, valH, 0x94); | ||
6306 | reg_w_i(gspca_dev->dev, 0x01, 0x90); /* <- write command */ | ||
6307 | msleep(5); | ||
6308 | retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ | ||
6309 | PDEBUG(D_USBO, "i2c w [%02x] %02x%02x (%02x)", | ||
6310 | reg, valH, valL, retbyte); | ||
6311 | return retbyte; | ||
6312 | } | ||
6313 | |||
6314 | static void usb_exchange(struct gspca_dev *gspca_dev, | ||
6315 | const struct usb_action *action) | ||
6316 | { | ||
6317 | while (action->req) { | ||
6318 | switch (action->req) { | ||
6319 | case 0xa0: /* write register */ | ||
6320 | reg_w(gspca_dev->dev, action->val, action->idx); | ||
6321 | break; | ||
6322 | case 0xa1: /* read status */ | ||
6323 | reg_r(gspca_dev, action->idx); | ||
6324 | break; | ||
6325 | case 0xaa: | ||
6326 | i2c_write(gspca_dev, | ||
6327 | action->val, /* reg */ | ||
6328 | action->idx & 0xff, /* valL */ | ||
6329 | action->idx >> 8); /* valH */ | ||
6330 | break; | ||
6331 | default: | ||
6332 | /* case 0xdd: * delay */ | ||
6333 | msleep(action->val / 64 + 10); | ||
6334 | break; | ||
6335 | } | ||
6336 | action++; | ||
6337 | /* msleep(1); */ | ||
6338 | } | ||
6339 | } | ||
6340 | |||
6341 | static void setmatrix(struct gspca_dev *gspca_dev) | ||
6342 | { | ||
6343 | struct sd *sd = (struct sd *) gspca_dev; | ||
6344 | int i; | ||
6345 | const __u8 *matrix; | ||
6346 | static const __u8 gc0305_matrix[9] = | ||
6347 | {0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50}; | ||
6348 | static const __u8 ov7620_matrix[9] = | ||
6349 | {0x58, 0xf4, 0xf4, 0xf4, 0x58, 0xf4, 0xf4, 0xf4, 0x58}; | ||
6350 | static const __u8 po2030_matrix[9] = | ||
6351 | {0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60}; | ||
6352 | |||
6353 | switch (sd->sensor) { | ||
6354 | case SENSOR_GC0305: | ||
6355 | matrix = gc0305_matrix; | ||
6356 | break; | ||
6357 | case SENSOR_MC501CB: | ||
6358 | return; /* no matrix? */ | ||
6359 | case SENSOR_OV7620: | ||
6360 | /* case SENSOR_OV7648: */ | ||
6361 | matrix = ov7620_matrix; | ||
6362 | break; | ||
6363 | case SENSOR_PO2030: | ||
6364 | matrix = po2030_matrix; | ||
6365 | break; | ||
6366 | case SENSOR_TAS5130C_VF0250: /* no matrix? */ | ||
6367 | return; | ||
6368 | default: /* matrix already loaded */ | ||
6369 | return; | ||
6370 | } | ||
6371 | for (i = 0; i < ARRAY_SIZE(ov7620_matrix); i++) | ||
6372 | reg_w(gspca_dev->dev, matrix[i], 0x010a + i); | ||
6373 | } | ||
6374 | |||
6375 | static void setbrightness(struct gspca_dev *gspca_dev) | ||
6376 | { | ||
6377 | struct sd *sd = (struct sd *) gspca_dev; | ||
6378 | __u8 brightness; | ||
6379 | |||
6380 | switch (sd->sensor) { | ||
6381 | case SENSOR_GC0305: | ||
6382 | case SENSOR_OV7620: | ||
6383 | case SENSOR_PO2030: | ||
6384 | return; | ||
6385 | } | ||
6386 | /*fixme: is it really write to 011d and 018d for all other sensors? */ | ||
6387 | brightness = sd->brightness; | ||
6388 | reg_w(gspca_dev->dev, brightness, 0x011d); | ||
6389 | if (brightness < 0x70) | ||
6390 | brightness += 0x10; | ||
6391 | else | ||
6392 | brightness = 0x80; | ||
6393 | reg_w(gspca_dev->dev, brightness, 0x018d); | ||
6394 | } | ||
6395 | |||
6396 | static void setsharpness(struct gspca_dev *gspca_dev) | ||
6397 | { | ||
6398 | struct sd *sd = (struct sd *) gspca_dev; | ||
6399 | struct usb_device *dev = gspca_dev->dev; | ||
6400 | int sharpness; | ||
6401 | static const __u8 sharpness_tb[][2] = { | ||
6402 | {0x02, 0x03}, | ||
6403 | {0x04, 0x07}, | ||
6404 | {0x08, 0x0f}, | ||
6405 | {0x10, 0x1e} | ||
6406 | }; | ||
6407 | |||
6408 | sharpness = sd->sharpness; | ||
6409 | reg_w(dev, sharpness_tb[sharpness][0], 0x01c6); | ||
6410 | reg_r(gspca_dev, 0x01c8); | ||
6411 | reg_r(gspca_dev, 0x01c9); | ||
6412 | reg_r(gspca_dev, 0x01ca); | ||
6413 | reg_w(dev, sharpness_tb[sharpness][1], 0x01cb); | ||
6414 | } | ||
6415 | |||
6416 | static void setcontrast(struct gspca_dev *gspca_dev) | ||
6417 | { | ||
6418 | struct sd *sd = (struct sd *) gspca_dev; | ||
6419 | struct usb_device *dev = gspca_dev->dev; | ||
6420 | const __u8 *Tgamma, *Tgradient; | ||
6421 | int g, i, k; | ||
6422 | static const __u8 kgamma_tb[16] = /* delta for contrast */ | ||
6423 | {0x15, 0x0d, 0x0a, 0x09, 0x08, 0x08, 0x08, 0x08, | ||
6424 | 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}; | ||
6425 | static const __u8 kgrad_tb[16] = | ||
6426 | {0x1b, 0x06, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, | ||
6427 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x04}; | ||
6428 | static const __u8 Tgamma_1[16] = | ||
6429 | {0x00, 0x00, 0x03, 0x0d, 0x1b, 0x2e, 0x45, 0x5f, | ||
6430 | 0x79, 0x93, 0xab, 0xc1, 0xd4, 0xe5, 0xf3, 0xff}; | ||
6431 | static const __u8 Tgradient_1[16] = | ||
6432 | {0x00, 0x01, 0x05, 0x0b, 0x10, 0x15, 0x18, 0x1a, | ||
6433 | 0x1a, 0x18, 0x16, 0x14, 0x12, 0x0f, 0x0d, 0x06}; | ||
6434 | static const __u8 Tgamma_2[16] = | ||
6435 | {0x01, 0x0c, 0x1f, 0x3a, 0x53, 0x6d, 0x85, 0x9c, | ||
6436 | 0xb0, 0xc2, 0xd1, 0xde, 0xe9, 0xf2, 0xf9, 0xff}; | ||
6437 | static const __u8 Tgradient_2[16] = | ||
6438 | {0x05, 0x0f, 0x16, 0x1a, 0x19, 0x19, 0x17, 0x15, | ||
6439 | 0x12, 0x10, 0x0e, 0x0b, 0x09, 0x08, 0x06, 0x03}; | ||
6440 | static const __u8 Tgamma_3[16] = | ||
6441 | {0x04, 0x16, 0x30, 0x4e, 0x68, 0x81, 0x98, 0xac, | ||
6442 | 0xbe, 0xcd, 0xda, 0xe4, 0xed, 0xf5, 0xfb, 0xff}; | ||
6443 | static const __u8 Tgradient_3[16] = | ||
6444 | {0x0c, 0x16, 0x1b, 0x1c, 0x19, 0x18, 0x15, 0x12, | ||
6445 | 0x10, 0x0d, 0x0b, 0x09, 0x08, 0x06, 0x05, 0x03}; | ||
6446 | static const __u8 Tgamma_4[16] = | ||
6447 | {0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, | ||
6448 | 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff}; | ||
6449 | static const __u8 Tgradient_4[16] = | ||
6450 | {0x26, 0x22, 0x20, 0x1c, 0x16, 0x13, 0x10, 0x0d, | ||
6451 | 0x0b, 0x09, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02}; | ||
6452 | static const __u8 Tgamma_5[16] = | ||
6453 | {0x20, 0x4b, 0x6e, 0x8d, 0xa3, 0xb5, 0xc5, 0xd2, | ||
6454 | 0xdc, 0xe5, 0xec, 0xf2, 0xf6, 0xfa, 0xfd, 0xff}; | ||
6455 | static const __u8 Tgradient_5[16] = | ||
6456 | {0x37, 0x26, 0x20, 0x1a, 0x14, 0x10, 0x0e, 0x0b, | ||
6457 | 0x09, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x02}; | ||
6458 | static const __u8 Tgamma_6[16] = /* ?? was gamma 5 */ | ||
6459 | {0x24, 0x44, 0x64, 0x84, 0x9d, 0xb2, 0xc4, 0xd3, | ||
6460 | 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff}; | ||
6461 | static const __u8 Tgradient_6[16] = | ||
6462 | {0x18, 0x20, 0x20, 0x1c, 0x16, 0x13, 0x10, 0x0e, | ||
6463 | 0x0b, 0x09, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01}; | ||
6464 | static const __u8 *gamma_tb[] = { | ||
6465 | NULL, Tgamma_1, Tgamma_2, | ||
6466 | Tgamma_3, Tgamma_4, Tgamma_5, Tgamma_6 | ||
6467 | }; | ||
6468 | static const __u8 *gradient_tb[] = { | ||
6469 | NULL, Tgradient_1, Tgradient_2, | ||
6470 | Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6 | ||
6471 | }; | ||
6472 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
6473 | __u8 v[16]; | ||
6474 | #endif | ||
6475 | |||
6476 | Tgamma = gamma_tb[sd->gamma]; | ||
6477 | Tgradient = gradient_tb[sd->gamma]; | ||
6478 | |||
6479 | k = (sd->contrast - 128) /* -128 / 128 */ | ||
6480 | * Tgamma[0]; | ||
6481 | PDEBUG(D_CONF, "gamma:%d contrast:%d gamma coeff: %d/128", | ||
6482 | sd->gamma, sd->contrast, k); | ||
6483 | for (i = 0; i < 16; i++) { | ||
6484 | g = Tgamma[i] + kgamma_tb[i] * k / 128; | ||
6485 | if (g > 0xff) | ||
6486 | g = 0xff; | ||
6487 | else if (g <= 0) | ||
6488 | g = 1; | ||
6489 | reg_w(dev, g, 0x0120 + i); /* gamma */ | ||
6490 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
6491 | if (gspca_debug & D_CONF) | ||
6492 | v[i] = g; | ||
6493 | #endif | ||
6494 | } | ||
6495 | PDEBUG(D_CONF, "tb: %02x %02x %02x %02x %02x %02x %02x %02x", | ||
6496 | v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); | ||
6497 | PDEBUG(D_CONF, " %02x %02x %02x %02x %02x %02x %02x %02x", | ||
6498 | v[8], v[9], v[10], v[11], v[12], v[13], v[14], v[15]); | ||
6499 | for (i = 0; i < 16; i++) { | ||
6500 | g = Tgradient[i] - kgrad_tb[i] * k / 128; | ||
6501 | if (g > 0xff) | ||
6502 | g = 0xff; | ||
6503 | else if (g <= 0) { | ||
6504 | if (i != 15) | ||
6505 | g = 0; | ||
6506 | else | ||
6507 | g = 1; | ||
6508 | } | ||
6509 | reg_w(dev, g, 0x0130 + i); /* gradient */ | ||
6510 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
6511 | if (gspca_debug & D_CONF) | ||
6512 | v[i] = g; | ||
6513 | #endif | ||
6514 | } | ||
6515 | PDEBUG(D_CONF, " %02x %02x %02x %02x %02x %02x %02x %02x", | ||
6516 | v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); | ||
6517 | PDEBUG(D_CONF, " %02x %02x %02x %02x %02x %02x %02x %02x", | ||
6518 | v[8], v[9], v[10], v[11], v[12], v[13], v[14], v[15]); | ||
6519 | } | ||
6520 | |||
6521 | static void setquality(struct gspca_dev *gspca_dev) | ||
6522 | { | ||
6523 | struct sd *sd = (struct sd *) gspca_dev; | ||
6524 | struct usb_device *dev = gspca_dev->dev; | ||
6525 | __u8 quality; | ||
6526 | __u8 frxt; | ||
6527 | |||
6528 | switch (sd->sensor) { | ||
6529 | case SENSOR_GC0305: | ||
6530 | case SENSOR_OV7620: | ||
6531 | case SENSOR_PO2030: | ||
6532 | return; | ||
6533 | } | ||
6534 | /*fixme: is it really 0008 0007 0018 for all other sensors? */ | ||
6535 | quality = sd->qindex; | ||
6536 | reg_w(dev, quality, 0x0008); | ||
6537 | frxt = 0x30; | ||
6538 | reg_w(dev, frxt, 0x0007); | ||
6539 | switch (quality) { | ||
6540 | case 0: | ||
6541 | case 1: | ||
6542 | case 2: | ||
6543 | frxt = 0xff; | ||
6544 | break; | ||
6545 | case 3: | ||
6546 | frxt = 0xf0; | ||
6547 | break; | ||
6548 | case 4: | ||
6549 | frxt = 0xe0; | ||
6550 | break; | ||
6551 | case 5: | ||
6552 | frxt = 0x20; | ||
6553 | break; | ||
6554 | } | ||
6555 | reg_w(dev, frxt, 0x0018); | ||
6556 | } | ||
6557 | |||
6558 | /* Matches the sensor's internal frame rate to the lighting frequency. | ||
6559 | * Valid frequencies are: | ||
6560 | * 50Hz, for European and Asian lighting (default) | ||
6561 | * 60Hz, for American lighting | ||
6562 | * 0 = No Fliker (for outdoore usage) | ||
6563 | * Returns: 0 for success | ||
6564 | */ | ||
6565 | static int setlightfreq(struct gspca_dev *gspca_dev) | ||
6566 | { | ||
6567 | struct sd *sd = (struct sd *) gspca_dev; | ||
6568 | int i, mode; | ||
6569 | const struct usb_action *zc3_freq; | ||
6570 | static const struct usb_action *freq_tb[SENSOR_MAX][6] = { | ||
6571 | /* SENSOR_CS2102 0 */ | ||
6572 | {cs2102_NoFliker, cs2102_NoFlikerScale, | ||
6573 | cs2102_50HZ, cs2102_50HZScale, | ||
6574 | cs2102_60HZ, cs2102_60HZScale}, | ||
6575 | /* SENSOR_CS2102K 1 */ | ||
6576 | {cs2102_NoFliker, cs2102_NoFlikerScale, | ||
6577 | cs2102_50HZ, cs2102_50HZScale, | ||
6578 | cs2102_60HZ, cs2102_60HZScale}, | ||
6579 | /* SENSOR_GC0305 2 */ | ||
6580 | {gc0305_NoFliker, gc0305_NoFliker, | ||
6581 | gc0305_50HZ, gc0305_50HZ, | ||
6582 | gc0305_60HZ, gc0305_60HZ}, | ||
6583 | /* SENSOR_HDCS2020 3 */ | ||
6584 | {NULL, NULL, | ||
6585 | NULL, NULL, | ||
6586 | NULL, NULL}, | ||
6587 | /* SENSOR_HDCS2020b 4 */ | ||
6588 | {hdcs2020b_NoFliker, hdcs2020b_NoFliker, | ||
6589 | hdcs2020b_50HZ, hdcs2020b_50HZ, | ||
6590 | hdcs2020b_60HZ, hdcs2020b_60HZ}, | ||
6591 | /* SENSOR_HV7131B 5 */ | ||
6592 | {NULL, NULL, | ||
6593 | NULL, NULL, | ||
6594 | NULL, NULL}, | ||
6595 | /* SENSOR_HV7131C 6 */ | ||
6596 | {NULL, NULL, | ||
6597 | NULL, NULL, | ||
6598 | NULL, NULL}, | ||
6599 | /* SENSOR_ICM105A 7 */ | ||
6600 | {icm105a_NoFliker, icm105a_NoFlikerScale, | ||
6601 | icm105a_50HZ, icm105a_50HZScale, | ||
6602 | icm105a_60HZ, icm105a_60HZScale}, | ||
6603 | /* SENSOR_MC501CB 8 */ | ||
6604 | {MC501CB_NoFliker, MC501CB_NoFlikerScale, | ||
6605 | MC501CB_50HZ, MC501CB_50HZScale, | ||
6606 | MC501CB_60HZ, MC501CB_60HZScale}, | ||
6607 | /* SENSOR_OV7620 9 */ | ||
6608 | {OV7620_NoFliker, OV7620_NoFliker, | ||
6609 | OV7620_50HZ, OV7620_50HZ, | ||
6610 | OV7620_60HZ, OV7620_60HZ}, | ||
6611 | /* SENSOR_OV7630C 10 */ | ||
6612 | {NULL, NULL, | ||
6613 | NULL, NULL, | ||
6614 | NULL, NULL}, | ||
6615 | /* SENSOR_PAS106 11 */ | ||
6616 | {pas106b_NoFliker, pas106b_NoFliker, | ||
6617 | pas106b_50HZ, pas106b_50HZ, | ||
6618 | pas106b_60HZ, pas106b_60HZ}, | ||
6619 | /* SENSOR_PB0330 12 */ | ||
6620 | {pb0330_NoFliker, pb0330_NoFlikerScale, | ||
6621 | pb0330_50HZ, pb0330_50HZScale, | ||
6622 | pb0330_60HZ, pb0330_60HZScale}, | ||
6623 | /* SENSOR_PO2030 13 */ | ||
6624 | {PO2030_NoFliker, PO2030_NoFliker, | ||
6625 | PO2030_50HZ, PO2030_50HZ, | ||
6626 | PO2030_60HZ, PO2030_60HZ}, | ||
6627 | /* SENSOR_TAS5130CK 14 */ | ||
6628 | {tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale, | ||
6629 | tas5130cxx_50HZ, tas5130cxx_50HZScale, | ||
6630 | tas5130cxx_60HZ, tas5130cxx_60HZScale}, | ||
6631 | /* SENSOR_TAS5130CXX 15 */ | ||
6632 | {tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale, | ||
6633 | tas5130cxx_50HZ, tas5130cxx_50HZScale, | ||
6634 | tas5130cxx_60HZ, tas5130cxx_60HZScale}, | ||
6635 | /* SENSOR_TAS5130C_VF0250 16 */ | ||
6636 | {tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale, | ||
6637 | tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale, | ||
6638 | tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale}, | ||
6639 | }; | ||
6640 | |||
6641 | i = sd->lightfreq * 2; | ||
6642 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | ||
6643 | if (!mode) | ||
6644 | i++; /* 640x480 */ | ||
6645 | zc3_freq = freq_tb[(int) sd->sensor][i]; | ||
6646 | if (zc3_freq != NULL) { | ||
6647 | usb_exchange(gspca_dev, zc3_freq); | ||
6648 | switch (sd->sensor) { | ||
6649 | case SENSOR_GC0305: | ||
6650 | if (mode /* if 320x240 */ | ||
6651 | && sd->lightfreq == 1) /* and 50Hz */ | ||
6652 | reg_w(gspca_dev->dev, 0x85, 0x018d); | ||
6653 | /* win: 0x80, 0x018d */ | ||
6654 | break; | ||
6655 | case SENSOR_OV7620: | ||
6656 | if (!mode) { /* if 640x480 */ | ||
6657 | if (sd->lightfreq != 0) /* and 50 or 60 Hz */ | ||
6658 | reg_w(gspca_dev->dev, 0x40, 0x0002); | ||
6659 | else | ||
6660 | reg_w(gspca_dev->dev, 0x44, 0x0002); | ||
6661 | } | ||
6662 | break; | ||
6663 | } | ||
6664 | } | ||
6665 | return 0; | ||
6666 | } | ||
6667 | |||
6668 | static void setautogain(struct gspca_dev *gspca_dev) | ||
6669 | { | ||
6670 | struct sd *sd = (struct sd *) gspca_dev; | ||
6671 | __u8 autoval; | ||
6672 | |||
6673 | if (sd->autogain) | ||
6674 | autoval = 0x42; | ||
6675 | else | ||
6676 | autoval = 0x02; | ||
6677 | reg_w(gspca_dev->dev, autoval, 0x0180); | ||
6678 | } | ||
6679 | |||
6680 | static void send_unknown(struct usb_device *dev, int sensor) | ||
6681 | { | ||
6682 | reg_w(dev, 0x01, 0x0000); /* led off */ | ||
6683 | switch (sensor) { | ||
6684 | case SENSOR_PAS106: | ||
6685 | reg_w(dev, 0x03, 0x003a); | ||
6686 | reg_w(dev, 0x0c, 0x003b); | ||
6687 | reg_w(dev, 0x08, 0x0038); | ||
6688 | break; | ||
6689 | case SENSOR_GC0305: | ||
6690 | case SENSOR_OV7620: | ||
6691 | case SENSOR_PB0330: | ||
6692 | case SENSOR_PO2030: | ||
6693 | reg_w(dev, 0x0d, 0x003a); | ||
6694 | reg_w(dev, 0x02, 0x003b); | ||
6695 | reg_w(dev, 0x00, 0x0038); | ||
6696 | break; | ||
6697 | } | ||
6698 | } | ||
6699 | |||
6700 | /* start probe 2 wires */ | ||
6701 | static void start_2wr_probe(struct usb_device *dev, int sensor) | ||
6702 | { | ||
6703 | reg_w(dev, 0x01, 0x0000); | ||
6704 | reg_w(dev, sensor, 0x0010); | ||
6705 | reg_w(dev, 0x01, 0x0001); | ||
6706 | reg_w(dev, 0x03, 0x0012); | ||
6707 | reg_w(dev, 0x01, 0x0012); | ||
6708 | /* msleep(2); */ | ||
6709 | } | ||
6710 | |||
6711 | static int sif_probe(struct gspca_dev *gspca_dev) | ||
6712 | { | ||
6713 | __u16 checkword; | ||
6714 | |||
6715 | start_2wr_probe(gspca_dev->dev, 0x0f); /* PAS106 */ | ||
6716 | reg_w(gspca_dev->dev, 0x08, 0x008d); | ||
6717 | msleep(150); | ||
6718 | checkword = ((i2c_read(gspca_dev, 0x00) & 0x0f) << 4) | ||
6719 | | ((i2c_read(gspca_dev, 0x01) & 0xf0) >> 4); | ||
6720 | PDEBUG(D_PROBE, "probe sif 0x%04x", checkword); | ||
6721 | if (checkword == 0x0007) { | ||
6722 | send_unknown(gspca_dev->dev, SENSOR_PAS106); | ||
6723 | return 0x0f; /* PAS106 */ | ||
6724 | } | ||
6725 | return -1; | ||
6726 | } | ||
6727 | |||
6728 | static int vga_2wr_probe(struct gspca_dev *gspca_dev) | ||
6729 | { | ||
6730 | struct usb_device *dev = gspca_dev->dev; | ||
6731 | __u8 retbyte; | ||
6732 | __u16 checkword; | ||
6733 | |||
6734 | start_2wr_probe(dev, 0x00); /* HV7131B */ | ||
6735 | i2c_write(gspca_dev, 0x01, 0xaa, 0x00); | ||
6736 | retbyte = i2c_read(gspca_dev, 0x01); | ||
6737 | if (retbyte != 0) | ||
6738 | return 0x00; /* HV7131B */ | ||
6739 | |||
6740 | start_2wr_probe(dev, 0x04); /* CS2102 */ | ||
6741 | i2c_write(gspca_dev, 0x01, 0xaa, 0x00); | ||
6742 | retbyte = i2c_read(gspca_dev, 0x01); | ||
6743 | if (retbyte != 0) | ||
6744 | return 0x04; /* CS2102 */ | ||
6745 | |||
6746 | start_2wr_probe(dev, 0x06); /* OmniVision */ | ||
6747 | reg_w(dev, 0x08, 0x8d); | ||
6748 | i2c_write(gspca_dev, 0x11, 0xaa, 0x00); | ||
6749 | retbyte = i2c_read(gspca_dev, 0x11); | ||
6750 | if (retbyte != 0) { | ||
6751 | /* (should have returned 0xaa) --> Omnivision? */ | ||
6752 | /* reg_r 0x10 -> 0x06 --> */ | ||
6753 | goto ov_check; | ||
6754 | } | ||
6755 | |||
6756 | start_2wr_probe(dev, 0x08); /* HDCS2020 */ | ||
6757 | i2c_write(gspca_dev, 0x15, 0xaa, 0x00); | ||
6758 | retbyte = i2c_read(gspca_dev, 0x15); | ||
6759 | if (retbyte != 0) | ||
6760 | return 0x08; /* HDCS2020 */ | ||
6761 | |||
6762 | start_2wr_probe(dev, 0x0a); /* PB0330 */ | ||
6763 | i2c_write(gspca_dev, 0x07, 0xaa, 0xaa); | ||
6764 | retbyte = i2c_read(gspca_dev, 0x07); | ||
6765 | if (retbyte != 0) | ||
6766 | return 0x0a; /* PB0330 */ | ||
6767 | retbyte = i2c_read(gspca_dev, 0x03); | ||
6768 | if (retbyte != 0) | ||
6769 | return 0x0a; /* PB0330 ?? */ | ||
6770 | retbyte = i2c_read(gspca_dev, 0x04); | ||
6771 | if (retbyte != 0) | ||
6772 | return 0x0a; /* PB0330 ?? */ | ||
6773 | |||
6774 | start_2wr_probe(dev, 0x0c); /* ICM105A */ | ||
6775 | i2c_write(gspca_dev, 0x01, 0x11, 0x00); | ||
6776 | retbyte = i2c_read(gspca_dev, 0x01); | ||
6777 | if (retbyte != 0) | ||
6778 | return 0x0c; /* ICM105A */ | ||
6779 | |||
6780 | start_2wr_probe(dev, 0x0e); /* PAS202BCB */ | ||
6781 | reg_w(dev, 0x08, 0x8d); | ||
6782 | i2c_write(gspca_dev, 0x03, 0xaa, 0x00); | ||
6783 | msleep(500); | ||
6784 | retbyte = i2c_read(gspca_dev, 0x03); | ||
6785 | if (retbyte != 0) | ||
6786 | return 0x0e; /* PAS202BCB */ | ||
6787 | |||
6788 | start_2wr_probe(dev, 0x02); /* ?? */ | ||
6789 | i2c_write(gspca_dev, 0x01, 0xaa, 0x00); | ||
6790 | retbyte = i2c_read(gspca_dev, 0x01); | ||
6791 | if (retbyte != 0) | ||
6792 | return 0x02; /* ?? */ | ||
6793 | ov_check: | ||
6794 | reg_r(gspca_dev, 0x0010); /* ?? */ | ||
6795 | reg_r(gspca_dev, 0x0010); | ||
6796 | |||
6797 | reg_w(dev, 0x01, 0x0000); | ||
6798 | reg_w(dev, 0x01, 0x0001); | ||
6799 | reg_w(dev, 0x06, 0x0010); /* OmniVision */ | ||
6800 | reg_w(dev, 0xa1, 0x008b); | ||
6801 | reg_w(dev, 0x08, 0x008d); | ||
6802 | msleep(500); | ||
6803 | reg_w(dev, 0x01, 0x0012); | ||
6804 | i2c_write(gspca_dev, 0x12, 0x80, 0x00); /* sensor reset */ | ||
6805 | retbyte = i2c_read(gspca_dev, 0x0a); | ||
6806 | checkword = retbyte << 8; | ||
6807 | retbyte = i2c_read(gspca_dev, 0x0b); | ||
6808 | checkword |= retbyte; | ||
6809 | PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", checkword); | ||
6810 | switch (checkword) { | ||
6811 | case 0x7631: /* OV7630C */ | ||
6812 | reg_w(dev, 0x06, 0x0010); | ||
6813 | break; | ||
6814 | case 0x7620: /* OV7620 */ | ||
6815 | case 0x7648: /* OV7648 */ | ||
6816 | break; | ||
6817 | default: | ||
6818 | return -1; /* not OmniVision */ | ||
6819 | } | ||
6820 | return checkword; | ||
6821 | } | ||
6822 | |||
6823 | struct sensor_by_chipset_revision { | ||
6824 | __u16 revision; | ||
6825 | __u8 internal_sensor_id; | ||
6826 | }; | ||
6827 | static const struct sensor_by_chipset_revision chipset_revision_sensor[] = { | ||
6828 | {0xc001, 0x13}, /* MI0360 */ | ||
6829 | {0xe001, 0x13}, | ||
6830 | {0x8001, 0x13}, | ||
6831 | {0x8000, 0x14}, /* CS2102K */ | ||
6832 | {0x8400, 0x15}, /* TAS5130K */ | ||
6833 | {0, 0} | ||
6834 | }; | ||
6835 | |||
6836 | static int vga_3wr_probe(struct gspca_dev *gspca_dev) | ||
6837 | { | ||
6838 | struct sd *sd = (struct sd *) gspca_dev; | ||
6839 | struct usb_device *dev = gspca_dev->dev; | ||
6840 | int i; | ||
6841 | __u8 retbyte; | ||
6842 | __u16 checkword; | ||
6843 | |||
6844 | /*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/ | ||
6845 | reg_w(dev, 0x02, 0x0010); | ||
6846 | reg_r(gspca_dev, 0x10); | ||
6847 | reg_w(dev, 0x01, 0x0000); | ||
6848 | reg_w(dev, 0x00, 0x0010); | ||
6849 | reg_w(dev, 0x01, 0x0001); | ||
6850 | reg_w(dev, 0x91, 0x008b); | ||
6851 | reg_w(dev, 0x03, 0x0012); | ||
6852 | reg_w(dev, 0x01, 0x0012); | ||
6853 | reg_w(dev, 0x05, 0x0012); | ||
6854 | retbyte = i2c_read(gspca_dev, 0x14); | ||
6855 | if (retbyte != 0) | ||
6856 | return 0x11; /* HV7131R */ | ||
6857 | retbyte = i2c_read(gspca_dev, 0x15); | ||
6858 | if (retbyte != 0) | ||
6859 | return 0x11; /* HV7131R */ | ||
6860 | retbyte = i2c_read(gspca_dev, 0x16); | ||
6861 | if (retbyte != 0) | ||
6862 | return 0x11; /* HV7131R */ | ||
6863 | |||
6864 | reg_w(dev, 0x02, 0x0010); | ||
6865 | retbyte = reg_r(gspca_dev, 0x000b); | ||
6866 | checkword = retbyte << 8; | ||
6867 | retbyte = reg_r(gspca_dev, 0x000a); | ||
6868 | checkword |= retbyte; | ||
6869 | PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", checkword); | ||
6870 | reg_r(gspca_dev, 0x0010); | ||
6871 | /* this is tested only once anyway */ | ||
6872 | i = 0; | ||
6873 | while (chipset_revision_sensor[i].revision) { | ||
6874 | if (chipset_revision_sensor[i].revision == checkword) { | ||
6875 | sd->chip_revision = checkword; | ||
6876 | send_unknown(dev, SENSOR_PB0330); | ||
6877 | return chipset_revision_sensor[i].internal_sensor_id; | ||
6878 | } | ||
6879 | i++; | ||
6880 | } | ||
6881 | |||
6882 | reg_w(dev, 0x01, 0x0000); | ||
6883 | reg_w(dev, 0x01, 0x0001); | ||
6884 | reg_w(dev, 0xdd, 0x008b); | ||
6885 | reg_w(dev, 0x0a, 0x0010); | ||
6886 | reg_w(dev, 0x03, 0x0012); | ||
6887 | reg_w(dev, 0x01, 0x0012); | ||
6888 | retbyte = i2c_read(gspca_dev, 0x00); | ||
6889 | if (retbyte != 0) { | ||
6890 | PDEBUG(D_PROBE, "probe 3wr vga type 0a ?"); | ||
6891 | return 0x0a; /* ?? */ | ||
6892 | } | ||
6893 | |||
6894 | reg_w(dev, 0x01, 0x0000); | ||
6895 | reg_w(dev, 0x01, 0x0001); | ||
6896 | reg_w(dev, 0x98, 0x008b); | ||
6897 | reg_w(dev, 0x01, 0x0010); | ||
6898 | reg_w(dev, 0x03, 0x0012); | ||
6899 | msleep(2); | ||
6900 | reg_w(dev, 0x01, 0x0012); | ||
6901 | retbyte = i2c_read(gspca_dev, 0x00); | ||
6902 | if (retbyte != 0) { | ||
6903 | PDEBUG(D_PROBE, "probe 3wr vga type %02x", retbyte); | ||
6904 | send_unknown(dev, SENSOR_GC0305); | ||
6905 | return retbyte; /* 0x29 = gc0305 - should continue? */ | ||
6906 | } | ||
6907 | |||
6908 | reg_w(dev, 0x01, 0x0000); /* check OmniVision */ | ||
6909 | reg_w(dev, 0x01, 0x0001); | ||
6910 | reg_w(dev, 0xa1, 0x008b); | ||
6911 | reg_w(dev, 0x08, 0x008d); | ||
6912 | reg_w(dev, 0x06, 0x0010); | ||
6913 | reg_w(dev, 0x01, 0x0012); | ||
6914 | reg_w(dev, 0x05, 0x0012); | ||
6915 | if (i2c_read(gspca_dev, 0x1c) == 0x7f /* OV7610 - manufacturer ID */ | ||
6916 | && i2c_read(gspca_dev, 0x1d) == 0xa2) { | ||
6917 | send_unknown(dev, SENSOR_OV7620); | ||
6918 | return 0x06; /* OmniVision confirm ? */ | ||
6919 | } | ||
6920 | |||
6921 | reg_w(dev, 0x01, 0x00); | ||
6922 | reg_w(dev, 0x00, 0x02); | ||
6923 | reg_w(dev, 0x01, 0x10); | ||
6924 | reg_w(dev, 0x01, 0x01); | ||
6925 | reg_w(dev, 0xee, 0x8b); | ||
6926 | reg_w(dev, 0x03, 0x12); | ||
6927 | /* msleep(150); */ | ||
6928 | reg_w(dev, 0x01, 0x12); | ||
6929 | reg_w(dev, 0x05, 0x12); | ||
6930 | retbyte = i2c_read(gspca_dev, 0x00); /* ID 0 */ | ||
6931 | checkword = retbyte << 8; | ||
6932 | retbyte = i2c_read(gspca_dev, 0x01); /* ID 1 */ | ||
6933 | checkword |= retbyte; | ||
6934 | PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", checkword); | ||
6935 | if (checkword == 0x2030) { | ||
6936 | retbyte = i2c_read(gspca_dev, 0x02); /* revision number */ | ||
6937 | PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte); | ||
6938 | send_unknown(dev, SENSOR_PO2030); | ||
6939 | return checkword; | ||
6940 | } | ||
6941 | |||
6942 | reg_w(dev, 0x01, 0x00); | ||
6943 | reg_w(dev, 0x0a, 0x10); | ||
6944 | reg_w(dev, 0xd3, 0x8b); | ||
6945 | reg_w(dev, 0x01, 0x01); | ||
6946 | reg_w(dev, 0x03, 0x12); | ||
6947 | reg_w(dev, 0x01, 0x12); | ||
6948 | reg_w(dev, 0x05, 0x01); | ||
6949 | reg_w(dev, 0xd3, 0x8b); | ||
6950 | retbyte = i2c_read(gspca_dev, 0x01); | ||
6951 | if (retbyte != 0) { | ||
6952 | PDEBUG(D_PROBE, "probe 3wr vga type 0a ?"); | ||
6953 | return 0x0a; /* ?? */ | ||
6954 | } | ||
6955 | return -1; | ||
6956 | } | ||
6957 | |||
6958 | static int zcxx_probeSensor(struct gspca_dev *gspca_dev) | ||
6959 | { | ||
6960 | struct sd *sd = (struct sd *) gspca_dev; | ||
6961 | int sensor, sensor2; | ||
6962 | |||
6963 | switch (sd->sensor) { | ||
6964 | case SENSOR_MC501CB: | ||
6965 | case SENSOR_TAS5130C_VF0250: | ||
6966 | return -1; /* don't probe */ | ||
6967 | } | ||
6968 | sensor = vga_2wr_probe(gspca_dev); | ||
6969 | if (sensor >= 0) { | ||
6970 | if (sensor < 0x7600) | ||
6971 | return sensor; | ||
6972 | /* next probe is needed for OmniVision ? */ | ||
6973 | } | ||
6974 | sensor2 = vga_3wr_probe(gspca_dev); | ||
6975 | if (sensor2 >= 0) { | ||
6976 | if (sensor >= 0) | ||
6977 | return sensor; | ||
6978 | return sensor2; | ||
6979 | } | ||
6980 | return sif_probe(gspca_dev); | ||
6981 | } | ||
6982 | |||
6983 | /* this function is called at probe time */ | ||
6984 | static int sd_config(struct gspca_dev *gspca_dev, | ||
6985 | const struct usb_device_id *id) | ||
6986 | { | ||
6987 | struct sd *sd = (struct sd *) gspca_dev; | ||
6988 | struct cam *cam; | ||
6989 | int sensor; | ||
6990 | int vga = 1; /* 1: vga, 0: sif */ | ||
6991 | static const __u8 gamma[SENSOR_MAX] = { | ||
6992 | 5, /* SENSOR_CS2102 0 */ | ||
6993 | 5, /* SENSOR_CS2102K 1 */ | ||
6994 | 4, /* SENSOR_GC0305 2 */ | ||
6995 | 4, /* SENSOR_HDCS2020 3 */ | ||
6996 | 4, /* SENSOR_HDCS2020b 4 */ | ||
6997 | 4, /* SENSOR_HV7131B 5 */ | ||
6998 | 4, /* SENSOR_HV7131C 6 */ | ||
6999 | 4, /* SENSOR_ICM105A 7 */ | ||
7000 | 4, /* SENSOR_MC501CB 8 */ | ||
7001 | 3, /* SENSOR_OV7620 9 */ | ||
7002 | 4, /* SENSOR_OV7630C 10 */ | ||
7003 | 4, /* SENSOR_PAS106 11 */ | ||
7004 | 4, /* SENSOR_PB0330 12 */ | ||
7005 | 4, /* SENSOR_PO2030 13 */ | ||
7006 | 4, /* SENSOR_TAS5130CK 14 */ | ||
7007 | 4, /* SENSOR_TAS5130CXX 15 */ | ||
7008 | 3, /* SENSOR_TAS5130C_VF0250 16 */ | ||
7009 | }; | ||
7010 | |||
7011 | /* define some sensors from the vendor/product */ | ||
7012 | sd->sharpness = 2; | ||
7013 | switch (id->idVendor) { | ||
7014 | case 0x041e: /* Creative */ | ||
7015 | switch (id->idProduct) { | ||
7016 | case 0x4051: /* zc301 chips */ | ||
7017 | case 0x4053: | ||
7018 | sd->sensor = SENSOR_TAS5130C_VF0250; | ||
7019 | break; | ||
7020 | } | ||
7021 | break; | ||
7022 | case 0x046d: /* Logitech Labtec */ | ||
7023 | switch (id->idProduct) { | ||
7024 | case 0x08dd: | ||
7025 | sd->sensor = SENSOR_MC501CB; | ||
7026 | break; | ||
7027 | } | ||
7028 | break; | ||
7029 | case 0x0ac8: /* Vimicro z-star */ | ||
7030 | switch (id->idProduct) { | ||
7031 | case 0x305b: | ||
7032 | sd->sensor = SENSOR_TAS5130C_VF0250; | ||
7033 | break; | ||
7034 | } | ||
7035 | break; | ||
7036 | } | ||
7037 | sensor = zcxx_probeSensor(gspca_dev); | ||
7038 | if (sensor >= 0) | ||
7039 | PDEBUG(D_PROBE, "probe sensor -> %02x", sensor); | ||
7040 | if ((unsigned) force_sensor < SENSOR_MAX) { | ||
7041 | sd->sensor = force_sensor; | ||
7042 | PDEBUG(D_PROBE, "sensor forced to %d", force_sensor); | ||
7043 | } else { | ||
7044 | switch (sensor) { | ||
7045 | case -1: | ||
7046 | switch (sd->sensor) { | ||
7047 | case SENSOR_MC501CB: | ||
7048 | PDEBUG(D_PROBE, "Sensor MC501CB"); | ||
7049 | break; | ||
7050 | case SENSOR_TAS5130C_VF0250: | ||
7051 | PDEBUG(D_PROBE, "Sensor Tas5130 (VF0250)"); | ||
7052 | break; | ||
7053 | default: | ||
7054 | PDEBUG(D_PROBE, | ||
7055 | "Sensor UNKNOW_0 force Tas5130"); | ||
7056 | sd->sensor = SENSOR_TAS5130CXX; | ||
7057 | } | ||
7058 | break; | ||
7059 | case 0: | ||
7060 | PDEBUG(D_PROBE, "Find Sensor HV7131B"); | ||
7061 | sd->sensor = SENSOR_HV7131B; | ||
7062 | break; | ||
7063 | case 0x04: | ||
7064 | PDEBUG(D_PROBE, "Find Sensor CS2102"); | ||
7065 | sd->sensor = SENSOR_CS2102; | ||
7066 | break; | ||
7067 | case 0x08: | ||
7068 | PDEBUG(D_PROBE, "Find Sensor HDCS2020(b)"); | ||
7069 | sd->sensor = SENSOR_HDCS2020b; | ||
7070 | break; | ||
7071 | case 0x0a: | ||
7072 | PDEBUG(D_PROBE, | ||
7073 | "Find Sensor PB0330. Chip revision %x", | ||
7074 | sd->chip_revision); | ||
7075 | sd->sensor = SENSOR_PB0330; | ||
7076 | break; | ||
7077 | case 0x0c: | ||
7078 | PDEBUG(D_PROBE, "Find Sensor ICM105A"); | ||
7079 | sd->sensor = SENSOR_ICM105A; | ||
7080 | break; | ||
7081 | case 0x0e: | ||
7082 | PDEBUG(D_PROBE, "Find Sensor HDCS2020"); | ||
7083 | sd->sensor = SENSOR_HDCS2020; | ||
7084 | sd->sharpness = 1; | ||
7085 | break; | ||
7086 | case 0x0f: | ||
7087 | PDEBUG(D_PROBE, "Find Sensor PAS106"); | ||
7088 | sd->sensor = SENSOR_PAS106; | ||
7089 | vga = 0; /* SIF */ | ||
7090 | break; | ||
7091 | case 0x10: | ||
7092 | case 0x12: | ||
7093 | PDEBUG(D_PROBE, "Find Sensor TAS5130"); | ||
7094 | sd->sensor = SENSOR_TAS5130CXX; | ||
7095 | break; | ||
7096 | case 0x11: | ||
7097 | PDEBUG(D_PROBE, "Find Sensor HV7131R(c)"); | ||
7098 | sd->sensor = SENSOR_HV7131C; | ||
7099 | break; | ||
7100 | case 0x13: | ||
7101 | PDEBUG(D_PROBE, | ||
7102 | "Find Sensor MI0360. Chip revision %x", | ||
7103 | sd->chip_revision); | ||
7104 | sd->sensor = SENSOR_PB0330; | ||
7105 | break; | ||
7106 | case 0x14: | ||
7107 | PDEBUG(D_PROBE, | ||
7108 | "Find Sensor CS2102K?. Chip revision %x", | ||
7109 | sd->chip_revision); | ||
7110 | sd->sensor = SENSOR_CS2102K; | ||
7111 | break; | ||
7112 | case 0x15: | ||
7113 | PDEBUG(D_PROBE, | ||
7114 | "Find Sensor TAS5130CK?. Chip revision %x", | ||
7115 | sd->chip_revision); | ||
7116 | sd->sensor = SENSOR_TAS5130CK; | ||
7117 | break; | ||
7118 | case 0x29: | ||
7119 | PDEBUG(D_PROBE, "Find Sensor GC0305"); | ||
7120 | sd->sensor = SENSOR_GC0305; | ||
7121 | break; | ||
7122 | case 0x2030: | ||
7123 | PDEBUG(D_PROBE, "Find Sensor PO2030"); | ||
7124 | sd->sensor = SENSOR_PO2030; | ||
7125 | sd->sharpness = 0; /* from win traces */ | ||
7126 | break; | ||
7127 | case 0x7620: | ||
7128 | PDEBUG(D_PROBE, "Find Sensor OV7620"); | ||
7129 | sd->sensor = SENSOR_OV7620; | ||
7130 | break; | ||
7131 | case 0x7648: | ||
7132 | PDEBUG(D_PROBE, "Find Sensor OV7648"); | ||
7133 | sd->sensor = SENSOR_OV7620; /* same sensor (?) */ | ||
7134 | break; | ||
7135 | default: | ||
7136 | PDEBUG(D_ERR|D_PROBE, "Unknown sensor %02x", sensor); | ||
7137 | return -EINVAL; | ||
7138 | } | ||
7139 | } | ||
7140 | if (sensor < 0x20) { | ||
7141 | if (sensor == -1 || sensor == 0x10 || sensor == 0x12) | ||
7142 | reg_w(gspca_dev->dev, 0x02, 0x0010); | ||
7143 | else | ||
7144 | reg_w(gspca_dev->dev, sensor & 0x0f, 0x0010); | ||
7145 | reg_r(gspca_dev, 0x0010); | ||
7146 | } | ||
7147 | |||
7148 | cam = &gspca_dev->cam; | ||
7149 | cam->dev_name = (char *) id->driver_info; | ||
7150 | cam->epaddr = 0x01; | ||
7151 | /*fixme:test*/ | ||
7152 | gspca_dev->nbalt--; | ||
7153 | if (vga) { | ||
7154 | cam->cam_mode = vga_mode; | ||
7155 | cam->nmodes = ARRAY_SIZE(vga_mode); | ||
7156 | } else { | ||
7157 | cam->cam_mode = sif_mode; | ||
7158 | cam->nmodes = ARRAY_SIZE(sif_mode); | ||
7159 | } | ||
7160 | sd->qindex = 1; | ||
7161 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | ||
7162 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | ||
7163 | sd->gamma = gamma[(int) sd->sensor]; | ||
7164 | sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; | ||
7165 | sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value; | ||
7166 | sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value; | ||
7167 | |||
7168 | /* switch the led off */ | ||
7169 | reg_w(gspca_dev->dev, 0x01, 0x0000); | ||
7170 | return 0; | ||
7171 | } | ||
7172 | |||
7173 | /* this function is called at open time */ | ||
7174 | static int sd_open(struct gspca_dev *gspca_dev) | ||
7175 | { | ||
7176 | reg_w(gspca_dev->dev, 0x01, 0x0000); | ||
7177 | return 0; | ||
7178 | } | ||
7179 | |||
7180 | static void sd_start(struct gspca_dev *gspca_dev) | ||
7181 | { | ||
7182 | struct sd *sd = (struct sd *) gspca_dev; | ||
7183 | struct usb_device *dev = gspca_dev->dev; | ||
7184 | const struct usb_action *zc3_init; | ||
7185 | int mode; | ||
7186 | static const struct usb_action *init_tb[SENSOR_MAX][2] = { | ||
7187 | {cs2102_InitialScale, cs2102_Initial}, /* 0 */ | ||
7188 | {cs2102K_InitialScale, cs2102K_Initial}, /* 1 */ | ||
7189 | {gc0305_Initial, gc0305_InitialScale}, /* 2 */ | ||
7190 | {hdcs2020xx_InitialScale, hdcs2020xx_Initial}, /* 3 */ | ||
7191 | {hdcs2020xb_InitialScale, hdcs2020xb_Initial}, /* 4 */ | ||
7192 | {hv7131bxx_InitialScale, hv7131bxx_Initial}, /* 5 */ | ||
7193 | {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 6 */ | ||
7194 | {icm105axx_InitialScale, icm105axx_Initial}, /* 7 */ | ||
7195 | {MC501CB_InitialScale, MC501CB_Initial}, /* 9 */ | ||
7196 | {OV7620_mode0, OV7620_mode1}, /* 9 */ | ||
7197 | {ov7630c_InitialScale, ov7630c_Initial}, /* 10 */ | ||
7198 | {pas106b_InitialScale, pas106b_Initial}, /* 11 */ | ||
7199 | {pb0330xx_InitialScale, pb0330xx_Initial}, /* 12 */ | ||
7200 | /* or {pb03303x_InitialScale, pb03303x_Initial}, */ | ||
7201 | {PO2030_mode0, PO2030_mode1}, /* 13 */ | ||
7202 | {tas5130CK_InitialScale, tas5130CK_Initial}, /* 14 */ | ||
7203 | {tas5130cxx_InitialScale, tas5130cxx_Initial}, /* 15 */ | ||
7204 | {tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial}, | ||
7205 | /* 16 */ | ||
7206 | }; | ||
7207 | |||
7208 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | ||
7209 | zc3_init = init_tb[(int) sd->sensor][mode]; | ||
7210 | switch (sd->sensor) { | ||
7211 | case SENSOR_HV7131B: | ||
7212 | case SENSOR_HV7131C: | ||
7213 | zcxx_probeSensor(gspca_dev); | ||
7214 | break; | ||
7215 | case SENSOR_PAS106: | ||
7216 | usb_exchange(gspca_dev, pas106b_Initial_com); | ||
7217 | break; | ||
7218 | case SENSOR_PB0330: | ||
7219 | if (mode) { | ||
7220 | if (sd->chip_revision == 0xc001 | ||
7221 | || sd->chip_revision == 0xe001 | ||
7222 | || sd->chip_revision == 0x8001) | ||
7223 | zc3_init = pb03303x_Initial; | ||
7224 | } else { | ||
7225 | if (sd->chip_revision == 0xc001 | ||
7226 | || sd->chip_revision == 0xe001 | ||
7227 | || sd->chip_revision == 0x8001) | ||
7228 | zc3_init = pb03303x_InitialScale; | ||
7229 | } | ||
7230 | break; | ||
7231 | } | ||
7232 | usb_exchange(gspca_dev, zc3_init); | ||
7233 | |||
7234 | switch (sd->sensor) { | ||
7235 | case SENSOR_GC0305: | ||
7236 | case SENSOR_OV7620: | ||
7237 | case SENSOR_PO2030: | ||
7238 | msleep(100); /* ?? */ | ||
7239 | reg_r(gspca_dev, 0x0002); /* --> 0x40 */ | ||
7240 | reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ | ||
7241 | reg_w(dev, 0x15, 0x01ae); | ||
7242 | reg_w(dev, 0x0d, 0x003a); | ||
7243 | reg_w(dev, 0x02, 0x003b); | ||
7244 | reg_w(dev, 0x00, 0x0038); | ||
7245 | break; | ||
7246 | } | ||
7247 | |||
7248 | setmatrix(gspca_dev); | ||
7249 | setbrightness(gspca_dev); | ||
7250 | switch (sd->sensor) { | ||
7251 | case SENSOR_OV7620: | ||
7252 | reg_r(gspca_dev, 0x0008); | ||
7253 | reg_w(dev, 0x00, 0x0008); | ||
7254 | break; | ||
7255 | case SENSOR_GC0305: | ||
7256 | reg_r(gspca_dev, 0x0008); | ||
7257 | /* fall thru */ | ||
7258 | case SENSOR_PO2030: | ||
7259 | reg_w(dev, 0x03, 0x0008); | ||
7260 | break; | ||
7261 | } | ||
7262 | setsharpness(gspca_dev); | ||
7263 | |||
7264 | /* set the gamma tables when not set */ | ||
7265 | switch (sd->sensor) { | ||
7266 | case SENSOR_CS2102: /* gamma set in xxx_Initial */ | ||
7267 | case SENSOR_CS2102K: | ||
7268 | case SENSOR_HDCS2020: | ||
7269 | case SENSOR_HDCS2020b: | ||
7270 | case SENSOR_PB0330: /* pb with chip_revision - see above */ | ||
7271 | case SENSOR_OV7630C: | ||
7272 | case SENSOR_TAS5130CK: | ||
7273 | break; | ||
7274 | default: | ||
7275 | setcontrast(gspca_dev); | ||
7276 | break; | ||
7277 | } | ||
7278 | setmatrix(gspca_dev); /* one more time? */ | ||
7279 | switch (sd->sensor) { | ||
7280 | case SENSOR_OV7620: | ||
7281 | reg_r(gspca_dev, 0x0180); /* from win */ | ||
7282 | reg_w(dev, 0x00, 0x0180); | ||
7283 | break; | ||
7284 | default: | ||
7285 | setquality(gspca_dev); | ||
7286 | break; | ||
7287 | } | ||
7288 | setlightfreq(gspca_dev); | ||
7289 | |||
7290 | switch (sd->sensor) { | ||
7291 | case SENSOR_GC0305: | ||
7292 | case SENSOR_OV7620: | ||
7293 | reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ | ||
7294 | reg_w(dev, 0x15, 0x01ae); | ||
7295 | sd->autogain = 0; | ||
7296 | break; | ||
7297 | case SENSOR_PO2030: | ||
7298 | reg_w(dev, 0x40, 0x0117); /* (from win traces) */ | ||
7299 | reg_r(gspca_dev, 0x0180); | ||
7300 | break; | ||
7301 | } | ||
7302 | |||
7303 | setautogain(gspca_dev); | ||
7304 | switch (sd->sensor) { | ||
7305 | case SENSOR_GC0305: | ||
7306 | /* setlightfreq(gspca_dev); ?? (end: 80 -> [18d]) */ | ||
7307 | reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ | ||
7308 | reg_w(dev, 0x15, 0x01ae); | ||
7309 | reg_w(dev, 0x40, 0x0180); | ||
7310 | reg_w(dev, 0x40, 0x0117); | ||
7311 | reg_r(gspca_dev, 0x0180); | ||
7312 | sd->autogain = 1; | ||
7313 | setautogain(gspca_dev); | ||
7314 | break; | ||
7315 | case SENSOR_OV7620: | ||
7316 | i2c_read(gspca_dev, 0x13); /*fixme: returns 0xa3 */ | ||
7317 | i2c_write(gspca_dev, 0x13, 0xa3, 0x00); | ||
7318 | /*fixme: returned value to send? */ | ||
7319 | reg_w(dev, 0x40, 0x0117); /* (from win traces) */ | ||
7320 | reg_r(gspca_dev, 0x0180); | ||
7321 | setautogain(gspca_dev); | ||
7322 | msleep(500); | ||
7323 | break; | ||
7324 | case SENSOR_PO2030: | ||
7325 | msleep(500); | ||
7326 | reg_r(gspca_dev, 0x0008); | ||
7327 | reg_r(gspca_dev, 0x0007); | ||
7328 | reg_w(dev, 0x00, 0x0007); /* (from win traces) */ | ||
7329 | reg_w(dev, 0x02, 0x0008); | ||
7330 | break; | ||
7331 | } | ||
7332 | } | ||
7333 | |||
7334 | static void sd_stopN(struct gspca_dev *gspca_dev) | ||
7335 | { | ||
7336 | } | ||
7337 | |||
7338 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
7339 | { | ||
7340 | struct sd *sd = (struct sd *) gspca_dev; | ||
7341 | |||
7342 | send_unknown(gspca_dev->dev, sd->sensor); | ||
7343 | } | ||
7344 | |||
7345 | /* this function is called at close time */ | ||
7346 | static void sd_close(struct gspca_dev *gspca_dev) | ||
7347 | { | ||
7348 | } | ||
7349 | |||
7350 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | ||
7351 | struct gspca_frame *frame, | ||
7352 | __u8 *data, | ||
7353 | int len) | ||
7354 | { | ||
7355 | |||
7356 | if (data[0] == 0xff && data[1] == 0xd8) { /* start of frame */ | ||
7357 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | ||
7358 | data, 0); | ||
7359 | /* put the JPEG header in the new frame */ | ||
7360 | jpeg_put_header(gspca_dev, frame, | ||
7361 | ((struct sd *) gspca_dev)->qindex, | ||
7362 | 0x21); | ||
7363 | /* remove the webcam's header: | ||
7364 | * ff d8 ff fe 00 0e 00 00 ss ss 00 01 ww ww hh hh pp pp | ||
7365 | * - 'ss ss' is the frame sequence number (BE) | ||
7366 | * - 'ww ww' and 'hh hh' are the window dimensions (BE) | ||
7367 | * - 'pp pp' is the packet sequence number (BE) | ||
7368 | */ | ||
7369 | data += 18; | ||
7370 | len -= 18; | ||
7371 | } | ||
7372 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | ||
7373 | } | ||
7374 | |||
7375 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
7376 | { | ||
7377 | struct sd *sd = (struct sd *) gspca_dev; | ||
7378 | |||
7379 | sd->brightness = val; | ||
7380 | if (gspca_dev->streaming) | ||
7381 | setbrightness(gspca_dev); | ||
7382 | return 0; | ||
7383 | } | ||
7384 | |||
7385 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
7386 | { | ||
7387 | struct sd *sd = (struct sd *) gspca_dev; | ||
7388 | |||
7389 | *val = sd->brightness; | ||
7390 | return 0; | ||
7391 | } | ||
7392 | |||
7393 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
7394 | { | ||
7395 | struct sd *sd = (struct sd *) gspca_dev; | ||
7396 | |||
7397 | sd->contrast = val; | ||
7398 | if (gspca_dev->streaming) | ||
7399 | setcontrast(gspca_dev); | ||
7400 | return 0; | ||
7401 | } | ||
7402 | |||
7403 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
7404 | { | ||
7405 | struct sd *sd = (struct sd *) gspca_dev; | ||
7406 | |||
7407 | *val = sd->contrast; | ||
7408 | return 0; | ||
7409 | } | ||
7410 | |||
7411 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
7412 | { | ||
7413 | struct sd *sd = (struct sd *) gspca_dev; | ||
7414 | |||
7415 | sd->autogain = val; | ||
7416 | if (gspca_dev->streaming) | ||
7417 | setautogain(gspca_dev); | ||
7418 | return 0; | ||
7419 | } | ||
7420 | |||
7421 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | ||
7422 | { | ||
7423 | struct sd *sd = (struct sd *) gspca_dev; | ||
7424 | |||
7425 | *val = sd->autogain; | ||
7426 | return 0; | ||
7427 | } | ||
7428 | |||
7429 | static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val) | ||
7430 | { | ||
7431 | struct sd *sd = (struct sd *) gspca_dev; | ||
7432 | |||
7433 | sd->gamma = val; | ||
7434 | if (gspca_dev->streaming) | ||
7435 | setcontrast(gspca_dev); | ||
7436 | return 0; | ||
7437 | } | ||
7438 | |||
7439 | static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) | ||
7440 | { | ||
7441 | struct sd *sd = (struct sd *) gspca_dev; | ||
7442 | |||
7443 | *val = sd->gamma; | ||
7444 | return 0; | ||
7445 | } | ||
7446 | |||
7447 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | ||
7448 | { | ||
7449 | struct sd *sd = (struct sd *) gspca_dev; | ||
7450 | |||
7451 | sd->lightfreq = val; | ||
7452 | if (gspca_dev->streaming) | ||
7453 | setlightfreq(gspca_dev); | ||
7454 | return 0; | ||
7455 | } | ||
7456 | |||
7457 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) | ||
7458 | { | ||
7459 | struct sd *sd = (struct sd *) gspca_dev; | ||
7460 | |||
7461 | *val = sd->lightfreq; | ||
7462 | return 0; | ||
7463 | } | ||
7464 | |||
7465 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) | ||
7466 | { | ||
7467 | struct sd *sd = (struct sd *) gspca_dev; | ||
7468 | |||
7469 | sd->sharpness = val; | ||
7470 | if (gspca_dev->streaming) | ||
7471 | setsharpness(gspca_dev); | ||
7472 | return 0; | ||
7473 | } | ||
7474 | |||
7475 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) | ||
7476 | { | ||
7477 | struct sd *sd = (struct sd *) gspca_dev; | ||
7478 | |||
7479 | *val = sd->sharpness; | ||
7480 | return 0; | ||
7481 | } | ||
7482 | |||
7483 | static int sd_querymenu(struct gspca_dev *gspca_dev, | ||
7484 | struct v4l2_querymenu *menu) | ||
7485 | { | ||
7486 | switch (menu->id) { | ||
7487 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
7488 | switch (menu->index) { | ||
7489 | case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ | ||
7490 | strcpy((char *) menu->name, "NoFliker"); | ||
7491 | return 0; | ||
7492 | case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ | ||
7493 | strcpy((char *) menu->name, "50 Hz"); | ||
7494 | return 0; | ||
7495 | case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ | ||
7496 | strcpy((char *) menu->name, "60 Hz"); | ||
7497 | return 0; | ||
7498 | } | ||
7499 | break; | ||
7500 | } | ||
7501 | return -EINVAL; | ||
7502 | } | ||
7503 | |||
7504 | static const struct sd_desc sd_desc = { | ||
7505 | .name = MODULE_NAME, | ||
7506 | .ctrls = sd_ctrls, | ||
7507 | .nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0], | ||
7508 | .config = sd_config, | ||
7509 | .open = sd_open, | ||
7510 | .start = sd_start, | ||
7511 | .stopN = sd_stopN, | ||
7512 | .stop0 = sd_stop0, | ||
7513 | .close = sd_close, | ||
7514 | .pkt_scan = sd_pkt_scan, | ||
7515 | .querymenu = sd_querymenu, | ||
7516 | }; | ||
7517 | |||
7518 | #define DVNM(name) .driver_info = (kernel_ulong_t) name | ||
7519 | static const __devinitdata struct usb_device_id device_table[] = { | ||
7520 | {USB_DEVICE(0x041e, 0x041e), DVNM("Creative WebCam Live!")}, | ||
7521 | #ifndef CONFIG_USB_ZC0301 | ||
7522 | {USB_DEVICE(0x041e, 0x4017), DVNM("Creative Webcam Mobile PD1090")}, | ||
7523 | {USB_DEVICE(0x041e, 0x401c), DVNM("Creative NX")}, | ||
7524 | {USB_DEVICE(0x041e, 0x401e), DVNM("Creative Nx Pro")}, | ||
7525 | {USB_DEVICE(0x041e, 0x401f), DVNM("Creative Webcam Notebook PD1171")}, | ||
7526 | #endif | ||
7527 | {USB_DEVICE(0x041e, 0x4029), DVNM("Creative WebCam Vista Pro")}, | ||
7528 | #ifndef CONFIG_USB_ZC0301 | ||
7529 | {USB_DEVICE(0x041e, 0x4034), DVNM("Creative Instant P0620")}, | ||
7530 | {USB_DEVICE(0x041e, 0x4035), DVNM("Creative Instant P0620D")}, | ||
7531 | {USB_DEVICE(0x041e, 0x4036), DVNM("Creative Live !")}, | ||
7532 | {USB_DEVICE(0x041e, 0x403a), DVNM("Creative Nx Pro 2")}, | ||
7533 | #endif | ||
7534 | {USB_DEVICE(0x041e, 0x4051), DVNM("Creative Notebook Pro (VF0250)")}, | ||
7535 | {USB_DEVICE(0x041e, 0x4053), DVNM("Creative Live!Cam Video IM")}, | ||
7536 | #ifndef CONFIG_USB_ZC0301 | ||
7537 | {USB_DEVICE(0x0458, 0x7007), DVNM("Genius VideoCam V2")}, | ||
7538 | {USB_DEVICE(0x0458, 0x700c), DVNM("Genius VideoCam V3")}, | ||
7539 | {USB_DEVICE(0x0458, 0x700f), DVNM("Genius VideoCam Web V2")}, | ||
7540 | #endif | ||
7541 | {USB_DEVICE(0x0461, 0x0a00), DVNM("MicroInnovation WebCam320")}, | ||
7542 | {USB_DEVICE(0x046d, 0x08a0), DVNM("Logitech QC IM")}, | ||
7543 | {USB_DEVICE(0x046d, 0x08a1), DVNM("Logitech QC IM 0x08A1 +sound")}, | ||
7544 | {USB_DEVICE(0x046d, 0x08a2), DVNM("Labtec Webcam Pro")}, | ||
7545 | {USB_DEVICE(0x046d, 0x08a3), DVNM("Logitech QC Chat")}, | ||
7546 | {USB_DEVICE(0x046d, 0x08a6), DVNM("Logitech QCim")}, | ||
7547 | {USB_DEVICE(0x046d, 0x08a7), DVNM("Logitech QuickCam Image")}, | ||
7548 | {USB_DEVICE(0x046d, 0x08a9), DVNM("Logitech Notebook Deluxe")}, | ||
7549 | {USB_DEVICE(0x046d, 0x08aa), DVNM("Labtec Webcam Notebook")}, | ||
7550 | {USB_DEVICE(0x046d, 0x08ac), DVNM("Logitech QuickCam Cool")}, | ||
7551 | {USB_DEVICE(0x046d, 0x08ad), DVNM("Logitech QCCommunicate STX")}, | ||
7552 | #ifndef CONFIG_USB_ZC0301 | ||
7553 | {USB_DEVICE(0x046d, 0x08ae), DVNM("Logitech QuickCam for Notebooks")}, | ||
7554 | #endif | ||
7555 | {USB_DEVICE(0x046d, 0x08af), DVNM("Logitech QuickCam Cool")}, | ||
7556 | {USB_DEVICE(0x046d, 0x08b9), DVNM("Logitech QC IM ???")}, | ||
7557 | {USB_DEVICE(0x046d, 0x08d7), DVNM("Logitech QCam STX")}, | ||
7558 | {USB_DEVICE(0x046d, 0x08d9), DVNM("Logitech QuickCam IM/Connect")}, | ||
7559 | {USB_DEVICE(0x046d, 0x08d8), DVNM("Logitech Notebook Deluxe")}, | ||
7560 | {USB_DEVICE(0x046d, 0x08da), DVNM("Logitech QuickCam Messenger")}, | ||
7561 | {USB_DEVICE(0x046d, 0x08dd), DVNM("Logitech QuickCam for Notebooks")}, | ||
7562 | {USB_DEVICE(0x0471, 0x0325), DVNM("Philips SPC 200 NC")}, | ||
7563 | {USB_DEVICE(0x0471, 0x0326), DVNM("Philips SPC 300 NC")}, | ||
7564 | {USB_DEVICE(0x0471, 0x032d), DVNM("Philips spc210nc")}, | ||
7565 | {USB_DEVICE(0x0471, 0x032e), DVNM("Philips spc315nc")}, | ||
7566 | {USB_DEVICE(0x055f, 0xc005), DVNM("Mustek Wcam300A")}, | ||
7567 | #ifndef CONFIG_USB_ZC0301 | ||
7568 | {USB_DEVICE(0x055f, 0xd003), DVNM("Mustek WCam300A")}, | ||
7569 | {USB_DEVICE(0x055f, 0xd004), DVNM("Mustek WCam300 AN")}, | ||
7570 | #endif | ||
7571 | {USB_DEVICE(0x0698, 0x2003), DVNM("CTX M730V built in")}, | ||
7572 | {USB_DEVICE(0x0ac8, 0x0302), DVNM("Z-star Vimicro zc0302")}, | ||
7573 | #ifndef CONFIG_USB_ZC0301 | ||
7574 | {USB_DEVICE(0x0ac8, 0x301b), DVNM("Z-Star zc301b")}, | ||
7575 | {USB_DEVICE(0x0ac8, 0x303b), DVNM("Vimicro 0x303b")}, | ||
7576 | #endif | ||
7577 | {USB_DEVICE(0x0ac8, 0x305b), DVNM("Z-star Vimicro zc0305b")}, | ||
7578 | #ifndef CONFIG_USB_ZC0301 | ||
7579 | {USB_DEVICE(0x0ac8, 0x307b), DVNM("Z-Star 307b")}, | ||
7580 | {USB_DEVICE(0x10fd, 0x0128), DVNM("Typhoon Webshot II 300k 0x0128")}, | ||
7581 | {USB_DEVICE(0x10fd, 0x8050), DVNM("Typhoon Webshot II USB 300k")}, | ||
7582 | #endif | ||
7583 | {} /* end of entry */ | ||
7584 | }; | ||
7585 | #undef DVNAME | ||
7586 | MODULE_DEVICE_TABLE(usb, device_table); | ||
7587 | |||
7588 | /* -- device connect -- */ | ||
7589 | static int sd_probe(struct usb_interface *intf, | ||
7590 | const struct usb_device_id *id) | ||
7591 | { | ||
7592 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | ||
7593 | THIS_MODULE); | ||
7594 | } | ||
7595 | |||
7596 | /* USB driver */ | ||
7597 | static struct usb_driver sd_driver = { | ||
7598 | .name = MODULE_NAME, | ||
7599 | .id_table = device_table, | ||
7600 | .probe = sd_probe, | ||
7601 | .disconnect = gspca_disconnect, | ||
7602 | }; | ||
7603 | |||
7604 | static int __init sd_mod_init(void) | ||
7605 | { | ||
7606 | if (usb_register(&sd_driver) < 0) | ||
7607 | return -1; | ||
7608 | PDEBUG(D_PROBE, "v%s registered", version); | ||
7609 | return 0; | ||
7610 | } | ||
7611 | |||
7612 | static void __exit sd_mod_exit(void) | ||
7613 | { | ||
7614 | usb_deregister(&sd_driver); | ||
7615 | PDEBUG(D_PROBE, "deregistered"); | ||
7616 | } | ||
7617 | |||
7618 | module_init(sd_mod_init); | ||
7619 | module_exit(sd_mod_exit); | ||
7620 | |||
7621 | module_param(force_sensor, int, 0644); | ||
7622 | MODULE_PARM_DESC(force_sensor, | ||
7623 | "Force sensor. Only for experts!!!"); | ||