diff options
Diffstat (limited to 'drivers/media/video/gspca/ov534.c')
-rw-r--r-- | drivers/media/video/gspca/ov534.c | 1537 |
1 files changed, 1393 insertions, 144 deletions
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 4b528b372911..4dbb882c83dc 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * ov534 gspca driver | 2 | * ov534 gspca driver |
3 | * | ||
3 | * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it> | 4 | * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it> |
4 | * Copyright (C) 2008 Jim Paris <jim@jtan.com> | 5 | * Copyright (C) 2008 Jim Paris <jim@jtan.com> |
5 | * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr | 6 | * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr |
@@ -8,6 +9,10 @@ | |||
8 | * USB protocol reverse engineered by Jim Paris <jim@jtan.com> | 9 | * USB protocol reverse engineered by Jim Paris <jim@jtan.com> |
9 | * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/ | 10 | * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/ |
10 | * | 11 | * |
12 | * PS3 Eye camera enhanced by Richard Kaswy http://kaswy.free.fr | ||
13 | * PS3 Eye camera, brightness, contrast, hue, AWB control added | ||
14 | * by Max Thrun <bear24rw@gmail.com> | ||
15 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | 16 | * 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 | 17 | * 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 | 18 | * the Free Software Foundation; either version 2 of the License, or |
@@ -51,16 +56,335 @@ struct sd { | |||
51 | u16 last_fid; | 56 | u16 last_fid; |
52 | u8 frame_rate; | 57 | u8 frame_rate; |
53 | 58 | ||
59 | u8 brightness; | ||
60 | u8 contrast; | ||
61 | u8 gain; | ||
62 | u8 exposure; | ||
63 | u8 redblc; | ||
64 | u8 blueblc; | ||
65 | u8 hue; | ||
66 | u8 autogain; | ||
67 | u8 awb; | ||
68 | s8 sharpness; | ||
69 | u8 hflip; | ||
70 | u8 vflip; | ||
71 | u8 satur; | ||
72 | u8 lightfreq; | ||
73 | |||
54 | u8 sensor; | 74 | u8 sensor; |
55 | #define SENSOR_OV772X 0 | 75 | #define SENSOR_OV772X 0 |
56 | #define SENSOR_OV965X 1 | 76 | #define SENSOR_OV965X 1 |
57 | }; | 77 | }; |
58 | 78 | ||
59 | /* V4L2 controls supported by the driver */ | 79 | /* V4L2 controls supported by the driver */ |
60 | static struct ctrl sd_ctrls[] = { | 80 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); |
81 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); | ||
82 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); | ||
83 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
84 | static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val); | ||
85 | static int sd_getredblc(struct gspca_dev *gspca_dev, __s32 *val); | ||
86 | static int sd_setblueblc(struct gspca_dev *gspca_dev, __s32 val); | ||
87 | static int sd_getblueblc(struct gspca_dev *gspca_dev, __s32 *val); | ||
88 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | ||
89 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); | ||
90 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); | ||
91 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | ||
92 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); | ||
93 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
94 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); | ||
95 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
96 | static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val); | ||
97 | static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val); | ||
98 | static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val); | ||
99 | static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val); | ||
100 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
101 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
102 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | ||
103 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | ||
104 | static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val); | ||
105 | static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val); | ||
106 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); | ||
107 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); | ||
108 | |||
109 | static struct ctrl sd_ctrls_ov772x[] = { | ||
110 | { /* 0 */ | ||
111 | { | ||
112 | .id = V4L2_CID_BRIGHTNESS, | ||
113 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
114 | .name = "Brightness", | ||
115 | .minimum = 0, | ||
116 | .maximum = 255, | ||
117 | .step = 1, | ||
118 | #define BRIGHTNESS_77_DEF 20 | ||
119 | .default_value = BRIGHTNESS_77_DEF, | ||
120 | }, | ||
121 | .set = sd_setbrightness, | ||
122 | .get = sd_getbrightness, | ||
123 | }, | ||
124 | { /* 1 */ | ||
125 | { | ||
126 | .id = V4L2_CID_CONTRAST, | ||
127 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
128 | .name = "Contrast", | ||
129 | .minimum = 0, | ||
130 | .maximum = 255, | ||
131 | .step = 1, | ||
132 | #define CONTRAST_77_DEF 37 | ||
133 | .default_value = CONTRAST_77_DEF, | ||
134 | }, | ||
135 | .set = sd_setcontrast, | ||
136 | .get = sd_getcontrast, | ||
137 | }, | ||
138 | { /* 2 */ | ||
139 | { | ||
140 | .id = V4L2_CID_GAIN, | ||
141 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
142 | .name = "Main Gain", | ||
143 | .minimum = 0, | ||
144 | .maximum = 63, | ||
145 | .step = 1, | ||
146 | #define GAIN_DEF 20 | ||
147 | .default_value = GAIN_DEF, | ||
148 | }, | ||
149 | .set = sd_setgain, | ||
150 | .get = sd_getgain, | ||
151 | }, | ||
152 | { /* 3 */ | ||
153 | { | ||
154 | .id = V4L2_CID_EXPOSURE, | ||
155 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
156 | .name = "Exposure", | ||
157 | .minimum = 0, | ||
158 | .maximum = 255, | ||
159 | .step = 1, | ||
160 | #define EXPO_77_DEF 120 | ||
161 | .default_value = EXPO_77_DEF, | ||
162 | }, | ||
163 | .set = sd_setexposure, | ||
164 | .get = sd_getexposure, | ||
165 | }, | ||
166 | { /* 4 */ | ||
167 | { | ||
168 | .id = V4L2_CID_RED_BALANCE, | ||
169 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
170 | .name = "Red Balance", | ||
171 | .minimum = 0, | ||
172 | .maximum = 255, | ||
173 | .step = 1, | ||
174 | #define RED_BALANCE_DEF 128 | ||
175 | .default_value = RED_BALANCE_DEF, | ||
176 | }, | ||
177 | .set = sd_setredblc, | ||
178 | .get = sd_getredblc, | ||
179 | }, | ||
180 | { /* 5 */ | ||
181 | { | ||
182 | .id = V4L2_CID_BLUE_BALANCE, | ||
183 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
184 | .name = "Blue Balance", | ||
185 | .minimum = 0, | ||
186 | .maximum = 255, | ||
187 | .step = 1, | ||
188 | #define BLUE_BALANCE_DEF 128 | ||
189 | .default_value = BLUE_BALANCE_DEF, | ||
190 | }, | ||
191 | .set = sd_setblueblc, | ||
192 | .get = sd_getblueblc, | ||
193 | }, | ||
194 | { /* 6 */ | ||
195 | { | ||
196 | .id = V4L2_CID_HUE, | ||
197 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
198 | .name = "Hue", | ||
199 | .minimum = 0, | ||
200 | .maximum = 255, | ||
201 | .step = 1, | ||
202 | #define HUE_DEF 143 | ||
203 | .default_value = HUE_DEF, | ||
204 | }, | ||
205 | .set = sd_sethue, | ||
206 | .get = sd_gethue, | ||
207 | }, | ||
208 | { /* 7 */ | ||
209 | { | ||
210 | .id = V4L2_CID_AUTOGAIN, | ||
211 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
212 | .name = "Autogain", | ||
213 | .minimum = 0, | ||
214 | .maximum = 1, | ||
215 | .step = 1, | ||
216 | #define AUTOGAIN_77_DEF 0 | ||
217 | .default_value = AUTOGAIN_77_DEF, | ||
218 | }, | ||
219 | .set = sd_setautogain, | ||
220 | .get = sd_getautogain, | ||
221 | }, | ||
222 | #define AWB_77_IDX 8 | ||
223 | { /* 8 */ | ||
224 | { | ||
225 | .id = V4L2_CID_AUTO_WHITE_BALANCE, | ||
226 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
227 | .name = "Auto White Balance", | ||
228 | .minimum = 0, | ||
229 | .maximum = 1, | ||
230 | .step = 1, | ||
231 | #define AWB_DEF 0 | ||
232 | .default_value = AWB_DEF, | ||
233 | }, | ||
234 | .set = sd_setawb, | ||
235 | .get = sd_getawb, | ||
236 | }, | ||
237 | { /* 9 */ | ||
238 | { | ||
239 | .id = V4L2_CID_SHARPNESS, | ||
240 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
241 | .name = "Sharpness", | ||
242 | .minimum = 0, | ||
243 | .maximum = 63, | ||
244 | .step = 1, | ||
245 | #define SHARPNESS_77_DEF 0 | ||
246 | .default_value = SHARPNESS_77_DEF, | ||
247 | }, | ||
248 | .set = sd_setsharpness, | ||
249 | .get = sd_getsharpness, | ||
250 | }, | ||
251 | { /* 10 */ | ||
252 | { | ||
253 | .id = V4L2_CID_HFLIP, | ||
254 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
255 | .name = "HFlip", | ||
256 | .minimum = 0, | ||
257 | .maximum = 1, | ||
258 | .step = 1, | ||
259 | #define HFLIP_DEF 0 | ||
260 | .default_value = HFLIP_DEF, | ||
261 | }, | ||
262 | .set = sd_sethflip, | ||
263 | .get = sd_gethflip, | ||
264 | }, | ||
265 | { /* 11 */ | ||
266 | { | ||
267 | .id = V4L2_CID_VFLIP, | ||
268 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
269 | .name = "VFlip", | ||
270 | .minimum = 0, | ||
271 | .maximum = 1, | ||
272 | .step = 1, | ||
273 | #define VFLIP_DEF 0 | ||
274 | .default_value = VFLIP_DEF, | ||
275 | }, | ||
276 | .set = sd_setvflip, | ||
277 | .get = sd_getvflip, | ||
278 | }, | ||
279 | }; | ||
280 | static struct ctrl sd_ctrls_ov965x[] = { | ||
281 | { /* 0 */ | ||
282 | { | ||
283 | .id = V4L2_CID_BRIGHTNESS, | ||
284 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
285 | .name = "Brightness", | ||
286 | .minimum = 0, | ||
287 | .maximum = 15, | ||
288 | .step = 1, | ||
289 | #define BRIGHTNESS_96_DEF 7 | ||
290 | .default_value = BRIGHTNESS_96_DEF, | ||
291 | }, | ||
292 | .set = sd_setbrightness, | ||
293 | .get = sd_getbrightness, | ||
294 | }, | ||
295 | { /* 1 */ | ||
296 | { | ||
297 | .id = V4L2_CID_CONTRAST, | ||
298 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
299 | .name = "Contrast", | ||
300 | .minimum = 0, | ||
301 | .maximum = 15, | ||
302 | .step = 1, | ||
303 | #define CONTRAST_96_DEF 3 | ||
304 | .default_value = CONTRAST_96_DEF, | ||
305 | }, | ||
306 | .set = sd_setcontrast, | ||
307 | .get = sd_getcontrast, | ||
308 | }, | ||
309 | { /* 2 */ | ||
310 | { | ||
311 | .id = V4L2_CID_AUTOGAIN, | ||
312 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
313 | .name = "Autogain", | ||
314 | .minimum = 0, | ||
315 | .maximum = 1, | ||
316 | .step = 1, | ||
317 | #define AUTOGAIN_96_DEF 1 | ||
318 | .default_value = AUTOGAIN_96_DEF, | ||
319 | }, | ||
320 | .set = sd_setautogain, | ||
321 | .get = sd_getautogain, | ||
322 | }, | ||
323 | #define EXPO_96_IDX 3 | ||
324 | { /* 3 */ | ||
325 | { | ||
326 | .id = V4L2_CID_EXPOSURE, | ||
327 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
328 | .name = "Exposure", | ||
329 | .minimum = 0, | ||
330 | .maximum = 3, | ||
331 | .step = 1, | ||
332 | #define EXPO_96_DEF 0 | ||
333 | .default_value = EXPO_96_DEF, | ||
334 | }, | ||
335 | .set = sd_setexposure, | ||
336 | .get = sd_getexposure, | ||
337 | }, | ||
338 | { /* 4 */ | ||
339 | { | ||
340 | .id = V4L2_CID_SHARPNESS, | ||
341 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
342 | .name = "Sharpness", | ||
343 | .minimum = -1, /* -1 = auto */ | ||
344 | .maximum = 4, | ||
345 | .step = 1, | ||
346 | #define SHARPNESS_96_DEF -1 | ||
347 | .default_value = SHARPNESS_96_DEF, | ||
348 | }, | ||
349 | .set = sd_setsharpness, | ||
350 | .get = sd_getsharpness, | ||
351 | }, | ||
352 | { /* 5 */ | ||
353 | { | ||
354 | .id = V4L2_CID_SATURATION, | ||
355 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
356 | .name = "Saturation", | ||
357 | .minimum = 0, | ||
358 | .maximum = 4, | ||
359 | .step = 1, | ||
360 | #define SATUR_DEF 2 | ||
361 | .default_value = SATUR_DEF, | ||
362 | }, | ||
363 | .set = sd_setsatur, | ||
364 | .get = sd_getsatur, | ||
365 | }, | ||
366 | { | ||
367 | { | ||
368 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | ||
369 | .type = V4L2_CTRL_TYPE_MENU, | ||
370 | .name = "Light frequency filter", | ||
371 | .minimum = 0, | ||
372 | .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ | ||
373 | .step = 1, | ||
374 | #define FREQ_DEF 0 | ||
375 | .default_value = FREQ_DEF, | ||
376 | }, | ||
377 | .set = sd_setfreq, | ||
378 | .get = sd_getfreq, | ||
379 | }, | ||
61 | }; | 380 | }; |
62 | 381 | ||
63 | static const struct v4l2_pix_format vga_yuyv_mode[] = { | 382 | static const struct v4l2_pix_format ov772x_mode[] = { |
383 | {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | ||
384 | .bytesperline = 320 * 2, | ||
385 | .sizeimage = 320 * 240 * 2, | ||
386 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
387 | .priv = 1}, | ||
64 | {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, | 388 | {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, |
65 | .bytesperline = 640 * 2, | 389 | .bytesperline = 640 * 2, |
66 | .sizeimage = 640 * 480 * 2, | 390 | .sizeimage = 640 * 480 * 2, |
@@ -68,20 +392,35 @@ static const struct v4l2_pix_format vga_yuyv_mode[] = { | |||
68 | .priv = 0}, | 392 | .priv = 0}, |
69 | }; | 393 | }; |
70 | 394 | ||
71 | static const struct v4l2_pix_format vga_jpeg_mode[] = { | 395 | static const struct v4l2_pix_format ov965x_mode[] = { |
72 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 396 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
73 | .bytesperline = 320, | 397 | .bytesperline = 320, |
74 | .sizeimage = 320 * 240 * 3 / 8 + 590, | 398 | .sizeimage = 320 * 240 * 3 / 8 + 590, |
75 | .colorspace = V4L2_COLORSPACE_JPEG, | 399 | .colorspace = V4L2_COLORSPACE_JPEG, |
76 | .priv = 1}, | 400 | .priv = 4}, |
77 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 401 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
78 | .bytesperline = 640, | 402 | .bytesperline = 640, |
79 | .sizeimage = 640 * 480 * 3 / 8 + 590, | 403 | .sizeimage = 640 * 480 * 3 / 8 + 590, |
80 | .colorspace = V4L2_COLORSPACE_JPEG, | 404 | .colorspace = V4L2_COLORSPACE_JPEG, |
405 | .priv = 3}, | ||
406 | {800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
407 | .bytesperline = 800, | ||
408 | .sizeimage = 800 * 600 * 3 / 8 + 590, | ||
409 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
410 | .priv = 2}, | ||
411 | {1024, 768, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
412 | .bytesperline = 1024, | ||
413 | .sizeimage = 1024 * 768 * 3 / 8 + 590, | ||
414 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
415 | .priv = 1}, | ||
416 | {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | ||
417 | .bytesperline = 1280, | ||
418 | .sizeimage = 1280 * 1024 * 3 / 8 + 590, | ||
419 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
81 | .priv = 0}, | 420 | .priv = 0}, |
82 | }; | 421 | }; |
83 | 422 | ||
84 | static const u8 bridge_init_ov722x[][2] = { | 423 | static const u8 bridge_init_ov772x[][2] = { |
85 | { 0xc2, 0x0c }, | 424 | { 0xc2, 0x0c }, |
86 | { 0x88, 0xf8 }, | 425 | { 0x88, 0xf8 }, |
87 | { 0xc3, 0x69 }, | 426 | { 0xc3, 0x69 }, |
@@ -122,6 +461,7 @@ static const u8 bridge_init_ov722x[][2] = { | |||
122 | { 0x1d, 0x40 }, | 461 | { 0x1d, 0x40 }, |
123 | { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */ | 462 | { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */ |
124 | { 0x1d, 0x00 }, /* payload size */ | 463 | { 0x1d, 0x00 }, /* payload size */ |
464 | |||
125 | { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */ | 465 | { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */ |
126 | { 0x1d, 0x58 }, /* frame size */ | 466 | { 0x1d, 0x58 }, /* frame size */ |
127 | { 0x1d, 0x00 }, /* frame size */ | 467 | { 0x1d, 0x00 }, /* frame size */ |
@@ -138,10 +478,20 @@ static const u8 bridge_init_ov722x[][2] = { | |||
138 | { 0xc1, 0x3c }, | 478 | { 0xc1, 0x3c }, |
139 | { 0xc2, 0x0c }, | 479 | { 0xc2, 0x0c }, |
140 | }; | 480 | }; |
141 | 481 | static const u8 sensor_init_ov772x[][2] = { | |
142 | static const u8 sensor_init_ov722x[][2] = { | ||
143 | { 0x12, 0x80 }, | 482 | { 0x12, 0x80 }, |
144 | { 0x11, 0x01 }, | 483 | { 0x11, 0x01 }, |
484 | /*fixme: better have a delay?*/ | ||
485 | { 0x11, 0x01 }, | ||
486 | { 0x11, 0x01 }, | ||
487 | { 0x11, 0x01 }, | ||
488 | { 0x11, 0x01 }, | ||
489 | { 0x11, 0x01 }, | ||
490 | { 0x11, 0x01 }, | ||
491 | { 0x11, 0x01 }, | ||
492 | { 0x11, 0x01 }, | ||
493 | { 0x11, 0x01 }, | ||
494 | { 0x11, 0x01 }, | ||
145 | 495 | ||
146 | { 0x3d, 0x03 }, | 496 | { 0x3d, 0x03 }, |
147 | { 0x17, 0x26 }, | 497 | { 0x17, 0x26 }, |
@@ -154,10 +504,10 @@ static const u8 sensor_init_ov722x[][2] = { | |||
154 | { 0x65, 0x20 }, | 504 | { 0x65, 0x20 }, |
155 | { 0x11, 0x01 }, | 505 | { 0x11, 0x01 }, |
156 | { 0x42, 0x7f }, | 506 | { 0x42, 0x7f }, |
157 | { 0x63, 0xe0 }, | 507 | { 0x63, 0xaa }, /* AWB - was e0 */ |
158 | { 0x64, 0xff }, | 508 | { 0x64, 0xff }, |
159 | { 0x66, 0x00 }, | 509 | { 0x66, 0x00 }, |
160 | { 0x13, 0xf0 }, | 510 | { 0x13, 0xf0 }, /* com8 */ |
161 | { 0x0d, 0x41 }, | 511 | { 0x0d, 0x41 }, |
162 | { 0x0f, 0xc5 }, | 512 | { 0x0f, 0xc5 }, |
163 | { 0x14, 0x11 }, | 513 | { 0x14, 0x11 }, |
@@ -170,7 +520,7 @@ static const u8 sensor_init_ov722x[][2] = { | |||
170 | { 0x2a, 0x00 }, | 520 | { 0x2a, 0x00 }, |
171 | { 0x2b, 0x00 }, | 521 | { 0x2b, 0x00 }, |
172 | { 0x6b, 0xaa }, | 522 | { 0x6b, 0xaa }, |
173 | { 0x13, 0xff }, | 523 | { 0x13, 0xff }, /* AWB */ |
174 | 524 | ||
175 | { 0x90, 0x05 }, | 525 | { 0x90, 0x05 }, |
176 | { 0x91, 0x01 }, | 526 | { 0x91, 0x01 }, |
@@ -218,9 +568,51 @@ static const u8 sensor_init_ov722x[][2] = { | |||
218 | { 0x14, 0x41 }, | 568 | { 0x14, 0x41 }, |
219 | { 0x0e, 0xcd }, | 569 | { 0x0e, 0xcd }, |
220 | { 0xac, 0xbf }, | 570 | { 0xac, 0xbf }, |
221 | { 0x8e, 0x00 }, | 571 | { 0x8e, 0x00 }, /* De-noise threshold */ |
222 | { 0x0c, 0xd0 } | 572 | { 0x0c, 0xd0 } |
223 | }; | 573 | }; |
574 | static const u8 bridge_start_ov772x_vga[][2] = { | ||
575 | {0x1c, 0x00}, | ||
576 | {0x1d, 0x40}, | ||
577 | {0x1d, 0x02}, | ||
578 | {0x1d, 0x00}, | ||
579 | {0x1d, 0x02}, | ||
580 | {0x1d, 0x58}, | ||
581 | {0x1d, 0x00}, | ||
582 | {0xc0, 0x50}, | ||
583 | {0xc1, 0x3c}, | ||
584 | }; | ||
585 | static const u8 sensor_start_ov772x_vga[][2] = { | ||
586 | {0x12, 0x00}, | ||
587 | {0x17, 0x26}, | ||
588 | {0x18, 0xa0}, | ||
589 | {0x19, 0x07}, | ||
590 | {0x1a, 0xf0}, | ||
591 | {0x29, 0xa0}, | ||
592 | {0x2c, 0xf0}, | ||
593 | {0x65, 0x20}, | ||
594 | }; | ||
595 | static const u8 bridge_start_ov772x_qvga[][2] = { | ||
596 | {0x1c, 0x00}, | ||
597 | {0x1d, 0x40}, | ||
598 | {0x1d, 0x02}, | ||
599 | {0x1d, 0x00}, | ||
600 | {0x1d, 0x01}, | ||
601 | {0x1d, 0x4b}, | ||
602 | {0x1d, 0x00}, | ||
603 | {0xc0, 0x28}, | ||
604 | {0xc1, 0x1e}, | ||
605 | }; | ||
606 | static const u8 sensor_start_ov772x_qvga[][2] = { | ||
607 | {0x12, 0x40}, | ||
608 | {0x17, 0x3f}, | ||
609 | {0x18, 0x50}, | ||
610 | {0x19, 0x03}, | ||
611 | {0x1a, 0x78}, | ||
612 | {0x29, 0x50}, | ||
613 | {0x2c, 0x78}, | ||
614 | {0x65, 0x2f}, | ||
615 | }; | ||
224 | 616 | ||
225 | static const u8 bridge_init_ov965x[][2] = { | 617 | static const u8 bridge_init_ov965x[][2] = { |
226 | {0x88, 0xf8}, | 618 | {0x88, 0xf8}, |
@@ -403,7 +795,7 @@ static const u8 sensor_init_ov965x[][2] = { | |||
403 | {0xcb, 0xf0}, | 795 | {0xcb, 0xf0}, |
404 | {0xcc, 0xd8}, | 796 | {0xcc, 0xd8}, |
405 | {0xcd, 0xf1}, | 797 | {0xcd, 0xf1}, |
406 | {0x4f, 0x98}, | 798 | {0x4f, 0x98}, /* matrix */ |
407 | {0x50, 0x98}, | 799 | {0x50, 0x98}, |
408 | {0x51, 0x00}, | 800 | {0x51, 0x00}, |
409 | {0x52, 0x28}, | 801 | {0x52, 0x28}, |
@@ -412,6 +804,7 @@ static const u8 sensor_init_ov965x[][2] = { | |||
412 | {0x58, 0x1a}, | 804 | {0x58, 0x1a}, |
413 | {0xff, 0x41}, /* read 41, write ff 00 */ | 805 | {0xff, 0x41}, /* read 41, write ff 00 */ |
414 | {0x41, 0x40}, /* com16 */ | 806 | {0x41, 0x40}, /* com16 */ |
807 | |||
415 | {0xc5, 0x03}, /* 60 Hz banding filter */ | 808 | {0xc5, 0x03}, /* 60 Hz banding filter */ |
416 | {0x6a, 0x02}, /* 50 Hz banding filter */ | 809 | {0x6a, 0x02}, /* 50 Hz banding filter */ |
417 | 810 | ||
@@ -455,8 +848,8 @@ static const u8 bridge_init_ov965x_2[][2] = { | |||
455 | {0x52, 0x3c}, | 848 | {0x52, 0x3c}, |
456 | {0x53, 0x00}, | 849 | {0x53, 0x00}, |
457 | {0x54, 0x00}, | 850 | {0x54, 0x00}, |
458 | {0x55, 0x00}, /* brightness */ | 851 | {0x55, 0x00}, |
459 | {0x57, 0x00}, /* contrast 2 */ | 852 | {0x57, 0x00}, |
460 | {0x5c, 0x00}, | 853 | {0x5c, 0x00}, |
461 | {0x5a, 0xa0}, | 854 | {0x5a, 0xa0}, |
462 | {0x5b, 0x78}, | 855 | {0x5b, 0x78}, |
@@ -479,14 +872,16 @@ static const u8 sensor_init_ov965x_2[][2] = { | |||
479 | {0xa3, 0x3e}, | 872 | {0xa3, 0x3e}, |
480 | {0x2d, 0x00}, | 873 | {0x2d, 0x00}, |
481 | {0xff, 0x42}, /* read 42, write ff 00 */ | 874 | {0xff, 0x42}, /* read 42, write ff 00 */ |
482 | {0x42, 0xc0}, | 875 | {0x42, 0xc0}, /* com17 */ |
483 | {0x2d, 0x00}, | 876 | {0x2d, 0x00}, |
484 | {0xff, 0x42}, /* read 42, write ff 00 */ | 877 | {0xff, 0x42}, /* read 42, write ff 00 */ |
485 | {0x42, 0xc1}, | 878 | {0x42, 0xc1}, /* com17 */ |
879 | /* sharpness */ | ||
486 | {0x3f, 0x01}, | 880 | {0x3f, 0x01}, |
487 | {0xff, 0x42}, /* read 42, write ff 00 */ | 881 | {0xff, 0x42}, /* read 42, write ff 00 */ |
488 | {0x42, 0xc1}, | 882 | {0x42, 0xc1}, /* com17 */ |
489 | {0x4f, 0x98}, | 883 | /* saturation */ |
884 | {0x4f, 0x98}, /* matrix */ | ||
490 | {0x50, 0x98}, | 885 | {0x50, 0x98}, |
491 | {0x51, 0x00}, | 886 | {0x51, 0x00}, |
492 | {0x52, 0x28}, | 887 | {0x52, 0x28}, |
@@ -495,14 +890,17 @@ static const u8 sensor_init_ov965x_2[][2] = { | |||
495 | {0x58, 0x1a}, | 890 | {0x58, 0x1a}, |
496 | {0xff, 0x41}, /* read 41, write ff 00 */ | 891 | {0xff, 0x41}, /* read 41, write ff 00 */ |
497 | {0x41, 0x40}, /* com16 */ | 892 | {0x41, 0x40}, /* com16 */ |
893 | /* contrast */ | ||
498 | {0x56, 0x40}, | 894 | {0x56, 0x40}, |
895 | /* brightness */ | ||
499 | {0x55, 0x8f}, | 896 | {0x55, 0x8f}, |
897 | /* expo */ | ||
500 | {0x10, 0x25}, /* aech - exposure high bits */ | 898 | {0x10, 0x25}, /* aech - exposure high bits */ |
501 | {0xff, 0x13}, /* read 13, write ff 00 */ | 899 | {0xff, 0x13}, /* read 13, write ff 00 */ |
502 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ | 900 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ |
503 | }; | 901 | }; |
504 | 902 | ||
505 | static const u8 sensor_start_ov965x[][2] = { | 903 | static const u8 sensor_start_ov965x_1_vga[][2] = { /* same for qvga */ |
506 | {0x12, 0x62}, /* com7 - 30fps VGA YUV */ | 904 | {0x12, 0x62}, /* com7 - 30fps VGA YUV */ |
507 | {0x36, 0xfa}, /* aref3 */ | 905 | {0x36, 0xfa}, /* aref3 */ |
508 | {0x69, 0x0a}, /* hv */ | 906 | {0x69, 0x0a}, /* hv */ |
@@ -523,10 +921,77 @@ static const u8 sensor_start_ov965x[][2] = { | |||
523 | {0x1a, 0x3d}, /* vstop */ | 921 | {0x1a, 0x3d}, /* vstop */ |
524 | {0x32, 0xff}, /* href */ | 922 | {0x32, 0xff}, /* href */ |
525 | {0xc0, 0xaa}, | 923 | {0xc0, 0xaa}, |
526 | {} | ||
527 | }; | 924 | }; |
528 | 925 | ||
529 | static const u8 bridge_start_ov965x[][2] = { | 926 | static const u8 sensor_start_ov965x_1_svga[][2] = { |
927 | {0x12, 0x02}, /* com7 - YUYV - VGA 15 full resolution */ | ||
928 | {0x36, 0xf8}, /* aref3 */ | ||
929 | {0x69, 0x02}, /* hv */ | ||
930 | {0x8c, 0x0d}, /* com22 */ | ||
931 | {0x3e, 0x0c}, /* com14 */ | ||
932 | {0x41, 0x40}, /* com16 */ | ||
933 | {0x72, 0x00}, | ||
934 | {0x73, 0x01}, | ||
935 | {0x74, 0x3a}, | ||
936 | {0x75, 0x35}, | ||
937 | {0x76, 0x01}, | ||
938 | {0xc7, 0x80}, /* com24 */ | ||
939 | {0x03, 0x1b}, /* vref */ | ||
940 | {0x17, 0x1d}, /* hstart */ | ||
941 | {0x18, 0xbd}, /* hstop */ | ||
942 | {0x19, 0x01}, /* vstrt */ | ||
943 | {0x1a, 0x81}, /* vstop */ | ||
944 | {0x32, 0xff}, /* href */ | ||
945 | {0xc0, 0xe2}, | ||
946 | }; | ||
947 | |||
948 | static const u8 sensor_start_ov965x_1_xga[][2] = { | ||
949 | {0x12, 0x02}, /* com7 */ | ||
950 | {0x36, 0xf8}, /* aref3 */ | ||
951 | {0x69, 0x02}, /* hv */ | ||
952 | {0x8c, 0x89}, /* com22 */ | ||
953 | {0x14, 0x28}, /* com9 */ | ||
954 | {0x3e, 0x0c}, /* com14 */ | ||
955 | {0x41, 0x40}, /* com16 */ | ||
956 | {0x72, 0x00}, | ||
957 | {0x73, 0x01}, | ||
958 | {0x74, 0x3a}, | ||
959 | {0x75, 0x35}, | ||
960 | {0x76, 0x01}, | ||
961 | {0xc7, 0x80}, /* com24 */ | ||
962 | {0x03, 0x1b}, /* vref */ | ||
963 | {0x17, 0x1d}, /* hstart */ | ||
964 | {0x18, 0xbd}, /* hstop */ | ||
965 | {0x19, 0x01}, /* vstrt */ | ||
966 | {0x1a, 0x81}, /* vstop */ | ||
967 | {0x32, 0xff}, /* href */ | ||
968 | {0xc0, 0xe2}, | ||
969 | }; | ||
970 | |||
971 | static const u8 sensor_start_ov965x_1_sxga[][2] = { | ||
972 | {0x12, 0x02}, /* com7 */ | ||
973 | {0x36, 0xf8}, /* aref3 */ | ||
974 | {0x69, 0x02}, /* hv */ | ||
975 | {0x8c, 0x89}, /* com22 */ | ||
976 | {0x14, 0x28}, /* com9 */ | ||
977 | {0x3e, 0x0c}, /* com14 */ | ||
978 | {0x41, 0x40}, /* com16 */ | ||
979 | {0x72, 0x00}, | ||
980 | {0x73, 0x01}, | ||
981 | {0x74, 0x3a}, | ||
982 | {0x75, 0x35}, | ||
983 | {0x76, 0x01}, | ||
984 | {0xc7, 0x80}, /* com24 */ | ||
985 | {0x03, 0x1b}, /* vref */ | ||
986 | {0x17, 0x1d}, /* hstart */ | ||
987 | {0x18, 0x02}, /* hstop */ | ||
988 | {0x19, 0x01}, /* vstrt */ | ||
989 | {0x1a, 0x81}, /* vstop */ | ||
990 | {0x32, 0xff}, /* href */ | ||
991 | {0xc0, 0xe2}, | ||
992 | }; | ||
993 | |||
994 | static const u8 bridge_start_ov965x_qvga[][2] = { | ||
530 | {0x94, 0xaa}, | 995 | {0x94, 0xaa}, |
531 | {0xf1, 0x60}, | 996 | {0xf1, 0x60}, |
532 | {0xe5, 0x04}, | 997 | {0xe5, 0x04}, |
@@ -535,10 +1000,34 @@ static const u8 bridge_start_ov965x[][2] = { | |||
535 | {0x8c, 0x00}, | 1000 | {0x8c, 0x00}, |
536 | {0x8d, 0x1c}, | 1001 | {0x8d, 0x1c}, |
537 | {0x34, 0x05}, | 1002 | {0x34, 0x05}, |
538 | {} | 1003 | |
1004 | {0xc2, 0x4c}, | ||
1005 | {0xc3, 0xf9}, | ||
1006 | {0xda, 0x00}, | ||
1007 | {0x50, 0x00}, | ||
1008 | {0x51, 0xa0}, | ||
1009 | {0x52, 0x78}, | ||
1010 | {0x53, 0x00}, | ||
1011 | {0x54, 0x00}, | ||
1012 | {0x55, 0x00}, | ||
1013 | {0x57, 0x00}, | ||
1014 | {0x5c, 0x00}, | ||
1015 | {0x5a, 0x50}, | ||
1016 | {0x5b, 0x3c}, | ||
1017 | {0x35, 0x02}, | ||
1018 | {0xd9, 0x10}, | ||
1019 | {0x94, 0x11}, | ||
539 | }; | 1020 | }; |
540 | 1021 | ||
541 | static const u8 bridge_start_ov965x_vga[][2] = { | 1022 | static const u8 bridge_start_ov965x_vga[][2] = { |
1023 | {0x94, 0xaa}, | ||
1024 | {0xf1, 0x60}, | ||
1025 | {0xe5, 0x04}, | ||
1026 | {0xc0, 0x50}, | ||
1027 | {0xc1, 0x3c}, | ||
1028 | {0x8c, 0x00}, | ||
1029 | {0x8d, 0x1c}, | ||
1030 | {0x34, 0x05}, | ||
542 | {0xc2, 0x0c}, | 1031 | {0xc2, 0x0c}, |
543 | {0xc3, 0xf9}, | 1032 | {0xc3, 0xf9}, |
544 | {0xda, 0x01}, | 1033 | {0xda, 0x01}, |
@@ -555,30 +1044,98 @@ static const u8 bridge_start_ov965x_vga[][2] = { | |||
555 | {0x35, 0x02}, | 1044 | {0x35, 0x02}, |
556 | {0xd9, 0x10}, | 1045 | {0xd9, 0x10}, |
557 | {0x94, 0x11}, | 1046 | {0x94, 0x11}, |
558 | {} | ||
559 | }; | 1047 | }; |
560 | 1048 | ||
561 | static const u8 bridge_start_ov965x_cif[][2] = { | 1049 | static const u8 bridge_start_ov965x_svga[][2] = { |
1050 | {0x94, 0xaa}, | ||
1051 | {0xf1, 0x60}, | ||
1052 | {0xe5, 0x04}, | ||
1053 | {0xc0, 0xa0}, | ||
1054 | {0xc1, 0x80}, | ||
1055 | {0x8c, 0x00}, | ||
1056 | {0x8d, 0x1c}, | ||
1057 | {0x34, 0x05}, | ||
562 | {0xc2, 0x4c}, | 1058 | {0xc2, 0x4c}, |
563 | {0xc3, 0xf9}, | 1059 | {0xc3, 0xf9}, |
564 | {0xda, 0x00}, | ||
565 | {0x50, 0x00}, | 1060 | {0x50, 0x00}, |
566 | {0x51, 0xa0}, | 1061 | {0x51, 0x40}, |
567 | {0x52, 0x78}, | 1062 | {0x52, 0x00}, |
568 | {0x53, 0x00}, | 1063 | {0x53, 0x00}, |
569 | {0x54, 0x00}, | 1064 | {0x54, 0x00}, |
570 | {0x55, 0x00}, | 1065 | {0x55, 0x88}, |
571 | {0x57, 0x00}, | 1066 | {0x57, 0x00}, |
572 | {0x5c, 0x00}, | 1067 | {0x5c, 0x00}, |
573 | {0x5a, 0x50}, | 1068 | {0x5a, 0xc8}, |
574 | {0x5b, 0x3c}, | 1069 | {0x5b, 0x96}, |
575 | {0x35, 0x02}, | 1070 | {0x35, 0x02}, |
576 | {0xd9, 0x10}, | 1071 | {0xd9, 0x10}, |
1072 | {0xda, 0x00}, | ||
577 | {0x94, 0x11}, | 1073 | {0x94, 0x11}, |
578 | {} | ||
579 | }; | 1074 | }; |
580 | 1075 | ||
581 | static const u8 sensor_start_ov965x_vga[][2] = { | 1076 | static const u8 bridge_start_ov965x_xga[][2] = { |
1077 | {0x94, 0xaa}, | ||
1078 | {0xf1, 0x60}, | ||
1079 | {0xe5, 0x04}, | ||
1080 | {0xc0, 0xa0}, | ||
1081 | {0xc1, 0x80}, | ||
1082 | {0x8c, 0x00}, | ||
1083 | {0x8d, 0x1c}, | ||
1084 | {0x34, 0x05}, | ||
1085 | {0xc2, 0x4c}, | ||
1086 | {0xc3, 0xf9}, | ||
1087 | {0x50, 0x00}, | ||
1088 | {0x51, 0x40}, | ||
1089 | {0x52, 0x00}, | ||
1090 | {0x53, 0x00}, | ||
1091 | {0x54, 0x00}, | ||
1092 | {0x55, 0x88}, | ||
1093 | {0x57, 0x00}, | ||
1094 | {0x5c, 0x01}, | ||
1095 | {0x5a, 0x00}, | ||
1096 | {0x5b, 0xc0}, | ||
1097 | {0x35, 0x02}, | ||
1098 | {0xd9, 0x10}, | ||
1099 | {0xda, 0x01}, | ||
1100 | {0x94, 0x11}, | ||
1101 | }; | ||
1102 | |||
1103 | static const u8 bridge_start_ov965x_sxga[][2] = { | ||
1104 | {0x94, 0xaa}, | ||
1105 | {0xf1, 0x60}, | ||
1106 | {0xe5, 0x04}, | ||
1107 | {0xc0, 0xa0}, | ||
1108 | {0xc1, 0x80}, | ||
1109 | {0x8c, 0x00}, | ||
1110 | {0x8d, 0x1c}, | ||
1111 | {0x34, 0x05}, | ||
1112 | {0xc2, 0x0c}, | ||
1113 | {0xc3, 0xf9}, | ||
1114 | {0xda, 0x00}, | ||
1115 | {0x35, 0x02}, | ||
1116 | {0xd9, 0x10}, | ||
1117 | {0x94, 0x11}, | ||
1118 | }; | ||
1119 | |||
1120 | static const u8 sensor_start_ov965x_2_qvga[][2] = { | ||
1121 | {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */ | ||
1122 | {0x1e, 0x04}, /* mvfp */ | ||
1123 | {0x13, 0xe0}, /* com8 */ | ||
1124 | {0x00, 0x00}, | ||
1125 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ | ||
1126 | {0x11, 0x01}, /* clkrc */ | ||
1127 | {0x6b, 0x5a}, /* dblv */ | ||
1128 | {0x6a, 0x02}, /* 50 Hz banding filter */ | ||
1129 | {0xc5, 0x03}, /* 60 Hz banding filter */ | ||
1130 | {0xa2, 0x96}, /* bd50 */ | ||
1131 | {0xa3, 0x7d}, /* bd60 */ | ||
1132 | |||
1133 | {0xff, 0x13}, /* read 13, write ff 00 */ | ||
1134 | {0x13, 0xe7}, | ||
1135 | {0x3a, 0x80}, /* tslb - yuyv */ | ||
1136 | }; | ||
1137 | |||
1138 | static const u8 sensor_start_ov965x_2_vga[][2] = { | ||
582 | {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ | 1139 | {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ |
583 | {0x1e, 0x04}, /* mvfp */ | 1140 | {0x1e, 0x04}, /* mvfp */ |
584 | {0x13, 0xe0}, /* com8 */ | 1141 | {0x13, 0xe0}, /* com8 */ |
@@ -592,35 +1149,36 @@ static const u8 sensor_start_ov965x_vga[][2] = { | |||
592 | {0xa3, 0x3e}, /* bd60 */ | 1149 | {0xa3, 0x3e}, /* bd60 */ |
593 | 1150 | ||
594 | {0x2d, 0x00}, /* advfl */ | 1151 | {0x2d, 0x00}, /* advfl */ |
595 | {} | ||
596 | }; | 1152 | }; |
597 | 1153 | ||
598 | static const u8 sensor_start_ov965x_cif[][2] = { | 1154 | static const u8 sensor_start_ov965x_2_svga[][2] = { /* same for xga */ |
599 | {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */ | 1155 | {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ |
600 | {0x1e, 0x04}, /* mvfp */ | 1156 | {0x1e, 0x04}, /* mvfp */ |
601 | {0x13, 0xe0}, /* com8 */ | 1157 | {0x13, 0xe0}, /* com8 */ |
602 | {0x00, 0x00}, | 1158 | {0x00, 0x00}, |
603 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ | 1159 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ |
604 | {0x11, 0x01}, /* clkrc */ | 1160 | {0x11, 0x01}, /* clkrc */ |
605 | {0x6b, 0x5a}, /* dblv */ | 1161 | {0x6b, 0x5a}, /* dblv */ |
606 | {0x6a, 0x02}, /* 50 Hz banding filter */ | 1162 | {0x6a, 0x0c}, /* 50 Hz banding filter */ |
607 | {0xc5, 0x03}, /* 60 Hz banding filter */ | 1163 | {0xc5, 0x0f}, /* 60 Hz banding filter */ |
608 | {0xa2, 0x96}, /* bd50 */ | 1164 | {0xa2, 0x4e}, /* bd50 */ |
609 | {0xa3, 0x7d}, /* bd60 */ | 1165 | {0xa3, 0x41}, /* bd60 */ |
610 | |||
611 | {0xff, 0x13}, /* read 13, write ff 00 */ | ||
612 | {0x13, 0xe7}, | ||
613 | {0x3a, 0x80}, /* tslb - yuyv */ | ||
614 | {} | ||
615 | }; | 1166 | }; |
616 | 1167 | ||
617 | static const u8 sensor_start_ov965x_2[][2] = { | 1168 | static const u8 sensor_start_ov965x_2_sxga[][2] = { |
618 | {0xff, 0x42}, /* read 42, write ff 00 */ | 1169 | {0x13, 0xe0}, /* com8 */ |
619 | {0x42, 0xc1}, /* com17 - 50 Hz filter */ | 1170 | {0x00, 0x00}, |
620 | {} | 1171 | {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ |
1172 | {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ | ||
1173 | {0x1e, 0x04}, /* mvfp */ | ||
1174 | {0x11, 0x01}, /* clkrc */ | ||
1175 | {0x6b, 0x5a}, /* dblv */ | ||
1176 | {0x6a, 0x0c}, /* 50 Hz banding filter */ | ||
1177 | {0xc5, 0x0f}, /* 60 Hz banding filter */ | ||
1178 | {0xa2, 0x4e}, /* bd50 */ | ||
1179 | {0xa3, 0x41}, /* bd60 */ | ||
621 | }; | 1180 | }; |
622 | 1181 | ||
623 | |||
624 | static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val) | 1182 | static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val) |
625 | { | 1183 | { |
626 | struct usb_device *udev = gspca_dev->dev; | 1184 | struct usb_device *udev = gspca_dev->dev; |
@@ -753,39 +1311,310 @@ static void sccb_w_array(struct gspca_dev *gspca_dev, | |||
753 | } | 1311 | } |
754 | } | 1312 | } |
755 | 1313 | ||
756 | /* set framerate */ | 1314 | /* ov772x specific controls */ |
757 | static void ov534_set_frame_rate(struct gspca_dev *gspca_dev) | 1315 | static void set_frame_rate(struct gspca_dev *gspca_dev) |
1316 | { | ||
1317 | struct sd *sd = (struct sd *) gspca_dev; | ||
1318 | int i; | ||
1319 | struct rate_s { | ||
1320 | u8 fps; | ||
1321 | u8 r11; | ||
1322 | u8 r0d; | ||
1323 | u8 re5; | ||
1324 | }; | ||
1325 | const struct rate_s *r; | ||
1326 | static const struct rate_s rate_0[] = { /* 640x480 */ | ||
1327 | {60, 0x01, 0xc1, 0x04}, | ||
1328 | {50, 0x01, 0x41, 0x02}, | ||
1329 | {40, 0x02, 0xc1, 0x04}, | ||
1330 | {30, 0x04, 0x81, 0x02}, | ||
1331 | {15, 0x03, 0x41, 0x04}, | ||
1332 | }; | ||
1333 | static const struct rate_s rate_1[] = { /* 320x240 */ | ||
1334 | {125, 0x02, 0x81, 0x02}, | ||
1335 | {100, 0x02, 0xc1, 0x04}, | ||
1336 | {75, 0x03, 0xc1, 0x04}, | ||
1337 | {60, 0x04, 0xc1, 0x04}, | ||
1338 | {50, 0x02, 0x41, 0x04}, | ||
1339 | {40, 0x03, 0x41, 0x04}, | ||
1340 | {30, 0x04, 0x41, 0x04}, | ||
1341 | }; | ||
1342 | |||
1343 | if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv == 0) { | ||
1344 | r = rate_0; | ||
1345 | i = ARRAY_SIZE(rate_0); | ||
1346 | } else { | ||
1347 | r = rate_1; | ||
1348 | i = ARRAY_SIZE(rate_1); | ||
1349 | } | ||
1350 | while (--i > 0) { | ||
1351 | if (sd->frame_rate >= r->fps) | ||
1352 | break; | ||
1353 | r++; | ||
1354 | } | ||
1355 | |||
1356 | sccb_reg_write(gspca_dev, 0x11, r->r11); | ||
1357 | sccb_reg_write(gspca_dev, 0x0d, r->r0d); | ||
1358 | ov534_reg_write(gspca_dev, 0xe5, r->re5); | ||
1359 | |||
1360 | PDEBUG(D_PROBE, "frame_rate: %d", r->fps); | ||
1361 | } | ||
1362 | |||
1363 | static void setbrightness_77(struct gspca_dev *gspca_dev) | ||
1364 | { | ||
1365 | struct sd *sd = (struct sd *) gspca_dev; | ||
1366 | |||
1367 | sccb_reg_write(gspca_dev, 0x9B, sd->brightness); | ||
1368 | } | ||
1369 | |||
1370 | static void setcontrast_77(struct gspca_dev *gspca_dev) | ||
758 | { | 1371 | { |
759 | struct sd *sd = (struct sd *) gspca_dev; | 1372 | struct sd *sd = (struct sd *) gspca_dev; |
760 | int fr = sd->frame_rate; | ||
761 | 1373 | ||
762 | switch (fr) { | 1374 | sccb_reg_write(gspca_dev, 0x9C, sd->contrast); |
763 | case 50: | 1375 | } |
764 | sccb_reg_write(gspca_dev, 0x11, 0x01); | 1376 | |
765 | sccb_reg_write(gspca_dev, 0x0d, 0x41); | 1377 | static void setgain(struct gspca_dev *gspca_dev) |
766 | ov534_reg_write(gspca_dev, 0xe5, 0x02); | 1378 | { |
1379 | struct sd *sd = (struct sd *) gspca_dev; | ||
1380 | u8 val; | ||
1381 | |||
1382 | val = sd->gain; | ||
1383 | switch (val & 0x30) { | ||
1384 | case 0x00: | ||
1385 | val &= 0x0f; | ||
767 | break; | 1386 | break; |
768 | case 40: | 1387 | case 0x10: |
769 | sccb_reg_write(gspca_dev, 0x11, 0x02); | 1388 | val &= 0x0f; |
770 | sccb_reg_write(gspca_dev, 0x0d, 0xc1); | 1389 | val |= 0x30; |
771 | ov534_reg_write(gspca_dev, 0xe5, 0x04); | ||
772 | break; | 1390 | break; |
773 | /* case 30: */ | 1391 | case 0x20: |
774 | default: | 1392 | val &= 0x0f; |
775 | fr = 30; | 1393 | val |= 0x70; |
776 | sccb_reg_write(gspca_dev, 0x11, 0x04); | ||
777 | sccb_reg_write(gspca_dev, 0x0d, 0x81); | ||
778 | ov534_reg_write(gspca_dev, 0xe5, 0x02); | ||
779 | break; | 1394 | break; |
780 | case 15: | 1395 | default: |
781 | sccb_reg_write(gspca_dev, 0x11, 0x03); | 1396 | /* case 0x30: */ |
782 | sccb_reg_write(gspca_dev, 0x0d, 0x41); | 1397 | val &= 0x0f; |
783 | ov534_reg_write(gspca_dev, 0xe5, 0x04); | 1398 | val |= 0xf0; |
784 | break; | 1399 | break; |
785 | } | 1400 | } |
1401 | sccb_reg_write(gspca_dev, 0x00, val); | ||
1402 | } | ||
1403 | |||
1404 | static void setexposure_77(struct gspca_dev *gspca_dev) | ||
1405 | { | ||
1406 | struct sd *sd = (struct sd *) gspca_dev; | ||
1407 | u8 val; | ||
1408 | |||
1409 | val = sd->exposure; | ||
1410 | sccb_reg_write(gspca_dev, 0x08, val >> 7); | ||
1411 | sccb_reg_write(gspca_dev, 0x10, val << 1); | ||
1412 | } | ||
1413 | |||
1414 | static void setredblc(struct gspca_dev *gspca_dev) | ||
1415 | { | ||
1416 | struct sd *sd = (struct sd *) gspca_dev; | ||
1417 | |||
1418 | sccb_reg_write(gspca_dev, 0x43, sd->redblc); | ||
1419 | } | ||
1420 | |||
1421 | static void setblueblc(struct gspca_dev *gspca_dev) | ||
1422 | { | ||
1423 | struct sd *sd = (struct sd *) gspca_dev; | ||
1424 | |||
1425 | sccb_reg_write(gspca_dev, 0x42, sd->blueblc); | ||
1426 | } | ||
1427 | |||
1428 | static void sethue(struct gspca_dev *gspca_dev) | ||
1429 | { | ||
1430 | struct sd *sd = (struct sd *) gspca_dev; | ||
1431 | |||
1432 | sccb_reg_write(gspca_dev, 0x01, sd->hue); | ||
1433 | } | ||
1434 | |||
1435 | static void setautogain_77(struct gspca_dev *gspca_dev) | ||
1436 | { | ||
1437 | struct sd *sd = (struct sd *) gspca_dev; | ||
1438 | |||
1439 | if (sd->autogain) { | ||
1440 | sccb_reg_write(gspca_dev, 0x13, 0xf7); /* AGC,AEC,AWB ON */ | ||
1441 | sccb_reg_write(gspca_dev, 0x64, | ||
1442 | sccb_reg_read(gspca_dev, 0x64) | 0x03); | ||
1443 | } else { | ||
1444 | sccb_reg_write(gspca_dev, 0x13, 0xf0); /* AGC,AEC,AWB OFF */ | ||
1445 | sccb_reg_write(gspca_dev, 0x64, | ||
1446 | sccb_reg_read(gspca_dev, 0x64) & 0xfc); | ||
1447 | } | ||
1448 | } | ||
1449 | |||
1450 | static void setawb(struct gspca_dev *gspca_dev) | ||
1451 | { | ||
1452 | struct sd *sd = (struct sd *) gspca_dev; | ||
1453 | |||
1454 | if (sd->awb) | ||
1455 | sccb_reg_write(gspca_dev, 0x63, 0xe0); /* AWB on */ | ||
1456 | else | ||
1457 | sccb_reg_write(gspca_dev, 0x63, 0xaa); /* AWB off */ | ||
1458 | } | ||
1459 | |||
1460 | static void setsharpness_77(struct gspca_dev *gspca_dev) | ||
1461 | { | ||
1462 | struct sd *sd = (struct sd *) gspca_dev; | ||
1463 | u8 val; | ||
1464 | |||
1465 | val = sd->sharpness; | ||
1466 | sccb_reg_write(gspca_dev, 0x91, val); /* vga noise */ | ||
1467 | sccb_reg_write(gspca_dev, 0x8e, val); /* qvga noise */ | ||
1468 | } | ||
1469 | |||
1470 | static void sethflip(struct gspca_dev *gspca_dev) | ||
1471 | { | ||
1472 | struct sd *sd = (struct sd *) gspca_dev; | ||
1473 | |||
1474 | if (sd->hflip == 0) | ||
1475 | sccb_reg_write(gspca_dev, 0x0c, | ||
1476 | sccb_reg_read(gspca_dev, 0x0c) | 0x40); | ||
1477 | else | ||
1478 | sccb_reg_write(gspca_dev, 0x0c, | ||
1479 | sccb_reg_read(gspca_dev, 0x0c) & 0xbf); | ||
1480 | } | ||
1481 | |||
1482 | static void setvflip(struct gspca_dev *gspca_dev) | ||
1483 | { | ||
1484 | struct sd *sd = (struct sd *) gspca_dev; | ||
1485 | |||
1486 | if (sd->vflip == 0) | ||
1487 | sccb_reg_write(gspca_dev, 0x0c, | ||
1488 | sccb_reg_read(gspca_dev, 0x0c) | 0x80); | ||
1489 | else | ||
1490 | sccb_reg_write(gspca_dev, 0x0c, | ||
1491 | sccb_reg_read(gspca_dev, 0x0c) & 0x7f); | ||
1492 | } | ||
1493 | |||
1494 | /* ov965x specific controls */ | ||
1495 | static void setbrightness_96(struct gspca_dev *gspca_dev) | ||
1496 | { | ||
1497 | struct sd *sd = (struct sd *) gspca_dev; | ||
1498 | u8 val; | ||
1499 | |||
1500 | val = sd->brightness; | ||
1501 | if (val < 8) | ||
1502 | val = 15 - val; /* f .. 8 */ | ||
1503 | else | ||
1504 | val = val - 8; /* 0 .. 7 */ | ||
1505 | sccb_reg_write(gspca_dev, 0x55, /* brtn - brightness adjustment */ | ||
1506 | 0x0f | (val << 4)); | ||
1507 | } | ||
1508 | |||
1509 | static void setcontrast_96(struct gspca_dev *gspca_dev) | ||
1510 | { | ||
1511 | struct sd *sd = (struct sd *) gspca_dev; | ||
1512 | |||
1513 | sccb_reg_write(gspca_dev, 0x56, /* cnst1 - contrast 1 ctrl coeff */ | ||
1514 | sd->contrast << 4); | ||
1515 | } | ||
1516 | |||
1517 | static void setexposure_96(struct gspca_dev *gspca_dev) | ||
1518 | { | ||
1519 | struct sd *sd = (struct sd *) gspca_dev; | ||
1520 | u8 val; | ||
1521 | static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e}; | ||
1522 | |||
1523 | sccb_reg_write(gspca_dev, 0x10, /* aec[9:2] */ | ||
1524 | expo[sd->exposure]); | ||
1525 | val = sccb_reg_read(gspca_dev, 0x13); /* com8 */ | ||
1526 | sccb_reg_write(gspca_dev, 0xff, 0x00); | ||
1527 | sccb_reg_write(gspca_dev, 0x13, val); | ||
1528 | val = sccb_reg_read(gspca_dev, 0xa1); /* aech */ | ||
1529 | sccb_reg_write(gspca_dev, 0xff, 0x00); | ||
1530 | sccb_reg_write(gspca_dev, 0xa1, val & 0xe0); /* aec[15:10] = 0 */ | ||
1531 | } | ||
1532 | |||
1533 | static void setsharpness_96(struct gspca_dev *gspca_dev) | ||
1534 | { | ||
1535 | struct sd *sd = (struct sd *) gspca_dev; | ||
1536 | u8 val; | ||
1537 | |||
1538 | val = sd->sharpness; | ||
1539 | if (val < 0) { /* auto */ | ||
1540 | val = sccb_reg_read(gspca_dev, 0x42); /* com17 */ | ||
1541 | sccb_reg_write(gspca_dev, 0xff, 0x00); | ||
1542 | sccb_reg_write(gspca_dev, 0x42, val | 0x40); | ||
1543 | /* Edge enhancement strength auto adjust */ | ||
1544 | return; | ||
1545 | } | ||
1546 | if (val != 0) | ||
1547 | val = 1 << (val - 1); | ||
1548 | sccb_reg_write(gspca_dev, 0x3f, /* edge - edge enhance. factor */ | ||
1549 | val); | ||
1550 | val = sccb_reg_read(gspca_dev, 0x42); /* com17 */ | ||
1551 | sccb_reg_write(gspca_dev, 0xff, 0x00); | ||
1552 | sccb_reg_write(gspca_dev, 0x42, val & 0xbf); | ||
1553 | } | ||
1554 | |||
1555 | static void setautogain_96(struct gspca_dev *gspca_dev) | ||
1556 | { | ||
1557 | struct sd *sd = (struct sd *) gspca_dev; | ||
1558 | u8 val; | ||
1559 | |||
1560 | /*fixme: should adjust agc/awb/aec by different controls */ | ||
1561 | val = sd->autogain; | ||
1562 | val = sccb_reg_read(gspca_dev, 0x13); /* com8 */ | ||
1563 | sccb_reg_write(gspca_dev, 0xff, 0x00); | ||
1564 | if (sd->autogain) | ||
1565 | val |= 0x05; /* agc & aec */ | ||
1566 | else | ||
1567 | val &= 0xfa; | ||
1568 | sccb_reg_write(gspca_dev, 0x13, val); | ||
1569 | } | ||
1570 | |||
1571 | static void setsatur(struct gspca_dev *gspca_dev) | ||
1572 | { | ||
1573 | struct sd *sd = (struct sd *) gspca_dev; | ||
1574 | u8 val1, val2, val3; | ||
1575 | static const u8 matrix[5][2] = { | ||
1576 | {0x14, 0x38}, | ||
1577 | {0x1e, 0x54}, | ||
1578 | {0x28, 0x70}, | ||
1579 | {0x32, 0x8c}, | ||
1580 | {0x48, 0x90} | ||
1581 | }; | ||
1582 | |||
1583 | val1 = matrix[sd->satur][0]; | ||
1584 | val2 = matrix[sd->satur][1]; | ||
1585 | val3 = val1 + val2; | ||
1586 | sccb_reg_write(gspca_dev, 0x4f, val3); /* matrix coeff */ | ||
1587 | sccb_reg_write(gspca_dev, 0x50, val3); | ||
1588 | sccb_reg_write(gspca_dev, 0x51, 0x00); | ||
1589 | sccb_reg_write(gspca_dev, 0x52, val1); | ||
1590 | sccb_reg_write(gspca_dev, 0x53, val2); | ||
1591 | sccb_reg_write(gspca_dev, 0x54, val3); | ||
1592 | sccb_reg_write(gspca_dev, 0x58, 0x1a); /* mtxs - coeff signs */ | ||
1593 | val1 = sccb_reg_read(gspca_dev, 0x41); /* com16 */ | ||
1594 | sccb_reg_write(gspca_dev, 0xff, 0x00); | ||
1595 | sccb_reg_write(gspca_dev, 0x41, val1); | ||
1596 | } | ||
1597 | |||
1598 | static void setfreq(struct gspca_dev *gspca_dev) | ||
1599 | { | ||
1600 | struct sd *sd = (struct sd *) gspca_dev; | ||
1601 | u8 val; | ||
1602 | |||
1603 | val = sccb_reg_read(gspca_dev, 0x13); /* com8 */ | ||
1604 | sccb_reg_write(gspca_dev, 0xff, 0x00); | ||
1605 | if (sd->lightfreq == 0) { | ||
1606 | sccb_reg_write(gspca_dev, 0x13, val & 0xdf); | ||
1607 | return; | ||
1608 | } | ||
1609 | sccb_reg_write(gspca_dev, 0x13, val | 0x20); | ||
786 | 1610 | ||
787 | sd->frame_rate = fr; | 1611 | val = sccb_reg_read(gspca_dev, 0x42); /* com17 */ |
788 | PDEBUG(D_PROBE, "frame_rate: %d", fr); | 1612 | sccb_reg_write(gspca_dev, 0xff, 0x00); |
1613 | if (sd->lightfreq == 1) | ||
1614 | val |= 0x01; | ||
1615 | else | ||
1616 | val &= 0xfe; | ||
1617 | sccb_reg_write(gspca_dev, 0x42, val); | ||
789 | } | 1618 | } |
790 | 1619 | ||
791 | /* this function is called at probe time */ | 1620 | /* this function is called at probe time */ |
@@ -800,17 +1629,60 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
800 | cam = &gspca_dev->cam; | 1629 | cam = &gspca_dev->cam; |
801 | 1630 | ||
802 | if (sd->sensor == SENSOR_OV772X) { | 1631 | if (sd->sensor == SENSOR_OV772X) { |
803 | cam->cam_mode = vga_yuyv_mode; | 1632 | cam->cam_mode = ov772x_mode; |
804 | cam->nmodes = ARRAY_SIZE(vga_yuyv_mode); | 1633 | cam->nmodes = ARRAY_SIZE(ov772x_mode); |
805 | 1634 | ||
806 | cam->bulk = 1; | 1635 | cam->bulk = 1; |
807 | cam->bulk_size = 16384; | 1636 | cam->bulk_size = 16384; |
808 | cam->bulk_nurbs = 2; | 1637 | cam->bulk_nurbs = 2; |
809 | } else { /* ov965x */ | 1638 | } else { /* ov965x */ |
810 | cam->cam_mode = vga_jpeg_mode; | 1639 | cam->cam_mode = ov965x_mode; |
811 | cam->nmodes = ARRAY_SIZE(vga_jpeg_mode); | 1640 | cam->nmodes = ARRAY_SIZE(ov965x_mode); |
812 | } | 1641 | } |
813 | 1642 | ||
1643 | sd->frame_rate = 30; | ||
1644 | |||
1645 | if (sd->sensor == SENSOR_OV772X) { | ||
1646 | sd->brightness = BRIGHTNESS_77_DEF; | ||
1647 | sd->contrast = CONTRAST_77_DEF; | ||
1648 | sd->gain = GAIN_DEF; | ||
1649 | sd->exposure = EXPO_77_DEF; | ||
1650 | sd->redblc = RED_BALANCE_DEF; | ||
1651 | sd->blueblc = BLUE_BALANCE_DEF; | ||
1652 | sd->hue = HUE_DEF; | ||
1653 | #if AUTOGAIN_77_DEF != 0 | ||
1654 | sd->autogain = AUTOGAIN_77_DEF; | ||
1655 | #else | ||
1656 | gspca_dev->ctrl_inac |= (1 << AWB_77_IDX); | ||
1657 | #endif | ||
1658 | #if AWB_DEF != 0 | ||
1659 | sd->awb = AWB_DEF | ||
1660 | #endif | ||
1661 | #if SHARPNESS_77_DEF != 0 | ||
1662 | sd->sharpness = SHARPNESS_77_DEF; | ||
1663 | #endif | ||
1664 | #if HFLIP_DEF != 0 | ||
1665 | sd->hflip = HFLIP_DEF; | ||
1666 | #endif | ||
1667 | #if VFLIP_DEF != 0 | ||
1668 | sd->vflip = VFLIP_DEF; | ||
1669 | #endif | ||
1670 | } else { | ||
1671 | sd->brightness = BRIGHTNESS_96_DEF; | ||
1672 | sd->contrast = CONTRAST_96_DEF; | ||
1673 | #if AUTOGAIN_96_DEF != 0 | ||
1674 | sd->autogain = AUTOGAIN_96_DEF; | ||
1675 | gspca_dev->ctrl_inac |= (1 << EXPO_96_IDX); | ||
1676 | #endif | ||
1677 | #if EXPO_96_DEF != 0 | ||
1678 | sd->exposure = EXPO_96_DEF; | ||
1679 | #endif | ||
1680 | #if SHARPNESS_96_DEF != 0 | ||
1681 | sd->sharpness = SHARPNESS_96_DEF; | ||
1682 | #endif | ||
1683 | sd->satur = SATUR_DEF; | ||
1684 | sd->lightfreq = FREQ_DEF; | ||
1685 | } | ||
814 | return 0; | 1686 | return 0; |
815 | } | 1687 | } |
816 | 1688 | ||
@@ -847,14 +1719,14 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
847 | /* initialize */ | 1719 | /* initialize */ |
848 | switch (sd->sensor) { | 1720 | switch (sd->sensor) { |
849 | case SENSOR_OV772X: | 1721 | case SENSOR_OV772X: |
850 | reg_w_array(gspca_dev, bridge_init_ov722x, | 1722 | reg_w_array(gspca_dev, bridge_init_ov772x, |
851 | ARRAY_SIZE(bridge_init_ov722x)); | 1723 | ARRAY_SIZE(bridge_init_ov772x)); |
852 | ov534_set_led(gspca_dev, 1); | 1724 | ov534_set_led(gspca_dev, 1); |
853 | sccb_w_array(gspca_dev, sensor_init_ov722x, | 1725 | sccb_w_array(gspca_dev, sensor_init_ov772x, |
854 | ARRAY_SIZE(sensor_init_ov722x)); | 1726 | ARRAY_SIZE(sensor_init_ov772x)); |
855 | ov534_reg_write(gspca_dev, 0xe0, 0x09); | 1727 | ov534_reg_write(gspca_dev, 0xe0, 0x09); |
856 | ov534_set_led(gspca_dev, 0); | 1728 | ov534_set_led(gspca_dev, 0); |
857 | ov534_set_frame_rate(gspca_dev); | 1729 | set_frame_rate(gspca_dev); |
858 | break; | 1730 | break; |
859 | default: | 1731 | default: |
860 | /* case SENSOR_OV965X: */ | 1732 | /* case SENSOR_OV965X: */ |
@@ -875,60 +1747,115 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
875 | return 0; | 1747 | return 0; |
876 | } | 1748 | } |
877 | 1749 | ||
878 | static int sd_start(struct gspca_dev *gspca_dev) | 1750 | static int sd_start_ov772x(struct gspca_dev *gspca_dev) |
879 | { | 1751 | { |
880 | struct sd *sd = (struct sd *) gspca_dev; | ||
881 | int mode; | 1752 | int mode; |
882 | 1753 | ||
883 | switch (sd->sensor) { | 1754 | mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; |
884 | case SENSOR_OV772X: | 1755 | if (mode != 0) { /* 320x240 */ |
885 | ov534_set_led(gspca_dev, 1); | 1756 | reg_w_array(gspca_dev, bridge_start_ov772x_qvga, |
886 | ov534_reg_write(gspca_dev, 0xe0, 0x00); | 1757 | ARRAY_SIZE(bridge_start_ov772x_qvga)); |
887 | break; | 1758 | sccb_w_array(gspca_dev, sensor_start_ov772x_qvga, |
888 | default: | 1759 | ARRAY_SIZE(sensor_start_ov772x_qvga)); |
889 | /* case SENSOR_OV965X: */ | 1760 | } else { /* 640x480 */ |
890 | 1761 | reg_w_array(gspca_dev, bridge_start_ov772x_vga, | |
891 | sccb_w_array(gspca_dev, sensor_start_ov965x, | 1762 | ARRAY_SIZE(bridge_start_ov772x_vga)); |
892 | ARRAY_SIZE(sensor_start_ov965x)); | 1763 | sccb_w_array(gspca_dev, sensor_start_ov772x_vga, |
893 | reg_w_array(gspca_dev, bridge_start_ov965x, | 1764 | ARRAY_SIZE(sensor_start_ov772x_vga)); |
894 | ARRAY_SIZE(bridge_start_ov965x)); | ||
895 | mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; | ||
896 | if (mode != 0) { /* 320x240 */ | ||
897 | reg_w_array(gspca_dev, bridge_start_ov965x_cif, | ||
898 | ARRAY_SIZE(bridge_start_ov965x_cif)); | ||
899 | sccb_w_array(gspca_dev, sensor_start_ov965x_cif, | ||
900 | ARRAY_SIZE(sensor_start_ov965x_cif)); | ||
901 | } else { /* 640x480 */ | ||
902 | reg_w_array(gspca_dev, bridge_start_ov965x_vga, | ||
903 | ARRAY_SIZE(bridge_start_ov965x_vga)); | ||
904 | sccb_w_array(gspca_dev, sensor_start_ov965x_vga, | ||
905 | ARRAY_SIZE(sensor_start_ov965x_vga)); | ||
906 | } | ||
907 | sccb_w_array(gspca_dev, sensor_start_ov965x_2, | ||
908 | ARRAY_SIZE(sensor_start_ov965x_2)); | ||
909 | ov534_reg_write(gspca_dev, 0xe0, 0x00); | ||
910 | ov534_reg_write(gspca_dev, 0xe0, 0x00); | ||
911 | ov534_set_led(gspca_dev, 1); | ||
912 | } | 1765 | } |
1766 | set_frame_rate(gspca_dev); | ||
1767 | |||
1768 | setautogain_77(gspca_dev); | ||
1769 | setawb(gspca_dev); | ||
1770 | setgain(gspca_dev); | ||
1771 | setredblc(gspca_dev); | ||
1772 | setblueblc(gspca_dev); | ||
1773 | sethue(gspca_dev); | ||
1774 | setexposure_77(gspca_dev); | ||
1775 | setbrightness_77(gspca_dev); | ||
1776 | setcontrast_77(gspca_dev); | ||
1777 | setsharpness_77(gspca_dev); | ||
1778 | setvflip(gspca_dev); | ||
1779 | sethflip(gspca_dev); | ||
1780 | |||
1781 | ov534_set_led(gspca_dev, 1); | ||
1782 | ov534_reg_write(gspca_dev, 0xe0, 0x00); | ||
913 | return 0; | 1783 | return 0; |
914 | } | 1784 | } |
915 | 1785 | ||
916 | static void sd_stopN(struct gspca_dev *gspca_dev) | 1786 | static int sd_start_ov965x(struct gspca_dev *gspca_dev) |
917 | { | 1787 | { |
918 | struct sd *sd = (struct sd *) gspca_dev; | 1788 | int mode; |
919 | 1789 | ||
920 | switch (sd->sensor) { | 1790 | mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; |
921 | case SENSOR_OV772X: | 1791 | switch (mode) { |
922 | ov534_reg_write(gspca_dev, 0xe0, 0x09); | ||
923 | ov534_set_led(gspca_dev, 0); | ||
924 | break; | ||
925 | default: | 1792 | default: |
926 | /* case SENSOR_OV965X: */ | 1793 | /* case 4: * 320x240 */ |
927 | ov534_reg_write(gspca_dev, 0xe0, 0x01); | 1794 | sccb_w_array(gspca_dev, sensor_start_ov965x_1_vga, |
928 | ov534_set_led(gspca_dev, 0); | 1795 | ARRAY_SIZE(sensor_start_ov965x_1_vga)); |
929 | ov534_reg_write(gspca_dev, 0xe0, 0x00); | 1796 | reg_w_array(gspca_dev, bridge_start_ov965x_qvga, |
1797 | ARRAY_SIZE(bridge_start_ov965x_qvga)); | ||
1798 | sccb_w_array(gspca_dev, sensor_start_ov965x_2_qvga, | ||
1799 | ARRAY_SIZE(sensor_start_ov965x_2_qvga)); | ||
1800 | break; | ||
1801 | case 3: /* 640x480 */ | ||
1802 | sccb_w_array(gspca_dev, sensor_start_ov965x_1_vga, | ||
1803 | ARRAY_SIZE(sensor_start_ov965x_1_vga)); | ||
1804 | reg_w_array(gspca_dev, bridge_start_ov965x_vga, | ||
1805 | ARRAY_SIZE(bridge_start_ov965x_vga)); | ||
1806 | sccb_w_array(gspca_dev, sensor_start_ov965x_2_vga, | ||
1807 | ARRAY_SIZE(sensor_start_ov965x_2_vga)); | ||
1808 | break; | ||
1809 | case 2: /* 800x600 */ | ||
1810 | sccb_w_array(gspca_dev, sensor_start_ov965x_1_svga, | ||
1811 | ARRAY_SIZE(sensor_start_ov965x_1_svga)); | ||
1812 | reg_w_array(gspca_dev, bridge_start_ov965x_svga, | ||
1813 | ARRAY_SIZE(bridge_start_ov965x_svga)); | ||
1814 | sccb_w_array(gspca_dev, sensor_start_ov965x_2_svga, | ||
1815 | ARRAY_SIZE(sensor_start_ov965x_2_svga)); | ||
1816 | break; | ||
1817 | case 1: /* 1024x768 */ | ||
1818 | sccb_w_array(gspca_dev, sensor_start_ov965x_1_xga, | ||
1819 | ARRAY_SIZE(sensor_start_ov965x_1_xga)); | ||
1820 | reg_w_array(gspca_dev, bridge_start_ov965x_xga, | ||
1821 | ARRAY_SIZE(bridge_start_ov965x_xga)); | ||
1822 | sccb_w_array(gspca_dev, sensor_start_ov965x_2_svga, | ||
1823 | ARRAY_SIZE(sensor_start_ov965x_2_svga)); | ||
1824 | break; | ||
1825 | case 0: /* 1280x1024 */ | ||
1826 | sccb_w_array(gspca_dev, sensor_start_ov965x_1_sxga, | ||
1827 | ARRAY_SIZE(sensor_start_ov965x_1_sxga)); | ||
1828 | reg_w_array(gspca_dev, bridge_start_ov965x_sxga, | ||
1829 | ARRAY_SIZE(bridge_start_ov965x_sxga)); | ||
1830 | sccb_w_array(gspca_dev, sensor_start_ov965x_2_sxga, | ||
1831 | ARRAY_SIZE(sensor_start_ov965x_2_sxga)); | ||
930 | break; | 1832 | break; |
931 | } | 1833 | } |
1834 | setfreq(gspca_dev); | ||
1835 | setautogain_96(gspca_dev); | ||
1836 | setbrightness_96(gspca_dev); | ||
1837 | setcontrast_96(gspca_dev); | ||
1838 | setexposure_96(gspca_dev); | ||
1839 | setsharpness_96(gspca_dev); | ||
1840 | setsatur(gspca_dev); | ||
1841 | |||
1842 | ov534_reg_write(gspca_dev, 0xe0, 0x00); | ||
1843 | ov534_reg_write(gspca_dev, 0xe0, 0x00); | ||
1844 | ov534_set_led(gspca_dev, 1); | ||
1845 | return 0; | ||
1846 | } | ||
1847 | |||
1848 | static void sd_stopN_ov772x(struct gspca_dev *gspca_dev) | ||
1849 | { | ||
1850 | ov534_reg_write(gspca_dev, 0xe0, 0x09); | ||
1851 | ov534_set_led(gspca_dev, 0); | ||
1852 | } | ||
1853 | |||
1854 | static void sd_stopN_ov965x(struct gspca_dev *gspca_dev) | ||
1855 | { | ||
1856 | ov534_reg_write(gspca_dev, 0xe0, 0x01); | ||
1857 | ov534_set_led(gspca_dev, 0); | ||
1858 | ov534_reg_write(gspca_dev, 0xe0, 0x00); | ||
932 | } | 1859 | } |
933 | 1860 | ||
934 | /* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */ | 1861 | /* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */ |
@@ -941,8 +1868,8 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
941 | #define UVC_STREAM_EOF (1 << 1) | 1868 | #define UVC_STREAM_EOF (1 << 1) |
942 | #define UVC_STREAM_FID (1 << 0) | 1869 | #define UVC_STREAM_FID (1 << 0) |
943 | 1870 | ||
944 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, | 1871 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, |
945 | __u8 *data, int len) | 1872 | u8 *data, int len) |
946 | { | 1873 | { |
947 | struct sd *sd = (struct sd *) gspca_dev; | 1874 | struct sd *sd = (struct sd *) gspca_dev; |
948 | __u32 this_pts; | 1875 | __u32 this_pts; |
@@ -983,32 +1910,30 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, | |||
983 | /* If PTS or FID has changed, start a new frame. */ | 1910 | /* If PTS or FID has changed, start a new frame. */ |
984 | if (this_pts != sd->last_pts || this_fid != sd->last_fid) { | 1911 | if (this_pts != sd->last_pts || this_fid != sd->last_fid) { |
985 | if (gspca_dev->last_packet_type == INTER_PACKET) | 1912 | if (gspca_dev->last_packet_type == INTER_PACKET) |
986 | frame = gspca_frame_add(gspca_dev, | 1913 | gspca_frame_add(gspca_dev, LAST_PACKET, |
987 | LAST_PACKET, frame, | 1914 | NULL, 0); |
988 | NULL, 0); | ||
989 | sd->last_pts = this_pts; | 1915 | sd->last_pts = this_pts; |
990 | sd->last_fid = this_fid; | 1916 | sd->last_fid = this_fid; |
991 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | 1917 | gspca_frame_add(gspca_dev, FIRST_PACKET, |
992 | data + 12, len - 12); | 1918 | data + 12, len - 12); |
993 | /* If this packet is marked as EOF, end the frame */ | 1919 | /* If this packet is marked as EOF, end the frame */ |
994 | } else if (data[1] & UVC_STREAM_EOF) { | 1920 | } else if (data[1] & UVC_STREAM_EOF) { |
995 | sd->last_pts = 0; | 1921 | sd->last_pts = 0; |
996 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, | 1922 | gspca_frame_add(gspca_dev, LAST_PACKET, |
997 | data + 12, len - 12); | 1923 | data + 12, len - 12); |
998 | } else { | 1924 | } else { |
999 | 1925 | ||
1000 | /* Add the data from this payload */ | 1926 | /* Add the data from this payload */ |
1001 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | 1927 | gspca_frame_add(gspca_dev, INTER_PACKET, |
1002 | data + 12, len - 12); | 1928 | data + 12, len - 12); |
1003 | } | 1929 | } |
1004 | 1930 | ||
1005 | |||
1006 | /* Done this payload */ | 1931 | /* Done this payload */ |
1007 | goto scan_next; | 1932 | goto scan_next; |
1008 | 1933 | ||
1009 | discard: | 1934 | discard: |
1010 | /* Discard data until a new frame starts. */ | 1935 | /* Discard data until a new frame starts. */ |
1011 | gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0); | 1936 | gspca_dev->last_packet_type = DISCARD_PACKET; |
1012 | 1937 | ||
1013 | scan_next: | 1938 | scan_next: |
1014 | remaining_len -= len; | 1939 | remaining_len -= len; |
@@ -1016,6 +1941,291 @@ scan_next: | |||
1016 | } while (remaining_len > 0); | 1941 | } while (remaining_len > 0); |
1017 | } | 1942 | } |
1018 | 1943 | ||
1944 | /* controls */ | ||
1945 | static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) | ||
1946 | { | ||
1947 | struct sd *sd = (struct sd *) gspca_dev; | ||
1948 | |||
1949 | sd->gain = val; | ||
1950 | if (gspca_dev->streaming) | ||
1951 | setgain(gspca_dev); | ||
1952 | return 0; | ||
1953 | } | ||
1954 | |||
1955 | static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) | ||
1956 | { | ||
1957 | struct sd *sd = (struct sd *) gspca_dev; | ||
1958 | |||
1959 | *val = sd->gain; | ||
1960 | return 0; | ||
1961 | } | ||
1962 | |||
1963 | static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val) | ||
1964 | { | ||
1965 | struct sd *sd = (struct sd *) gspca_dev; | ||
1966 | |||
1967 | sd->exposure = val; | ||
1968 | if (gspca_dev->streaming) { | ||
1969 | if (sd->sensor == SENSOR_OV772X) | ||
1970 | setexposure_77(gspca_dev); | ||
1971 | else | ||
1972 | setexposure_96(gspca_dev); | ||
1973 | } | ||
1974 | return 0; | ||
1975 | } | ||
1976 | |||
1977 | static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) | ||
1978 | { | ||
1979 | struct sd *sd = (struct sd *) gspca_dev; | ||
1980 | |||
1981 | *val = sd->exposure; | ||
1982 | return 0; | ||
1983 | } | ||
1984 | |||
1985 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
1986 | { | ||
1987 | struct sd *sd = (struct sd *) gspca_dev; | ||
1988 | |||
1989 | sd->brightness = val; | ||
1990 | if (gspca_dev->streaming) { | ||
1991 | if (sd->sensor == SENSOR_OV772X) | ||
1992 | setbrightness_77(gspca_dev); | ||
1993 | else | ||
1994 | setbrightness_96(gspca_dev); | ||
1995 | } | ||
1996 | return 0; | ||
1997 | } | ||
1998 | |||
1999 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
2000 | { | ||
2001 | struct sd *sd = (struct sd *) gspca_dev; | ||
2002 | |||
2003 | *val = sd->brightness; | ||
2004 | return 0; | ||
2005 | } | ||
2006 | |||
2007 | static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) | ||
2008 | { | ||
2009 | struct sd *sd = (struct sd *) gspca_dev; | ||
2010 | |||
2011 | sd->contrast = val; | ||
2012 | if (gspca_dev->streaming) { | ||
2013 | if (sd->sensor == SENSOR_OV772X) | ||
2014 | setcontrast_77(gspca_dev); | ||
2015 | else | ||
2016 | setcontrast_96(gspca_dev); | ||
2017 | } | ||
2018 | return 0; | ||
2019 | } | ||
2020 | |||
2021 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) | ||
2022 | { | ||
2023 | struct sd *sd = (struct sd *) gspca_dev; | ||
2024 | |||
2025 | *val = sd->contrast; | ||
2026 | return 0; | ||
2027 | } | ||
2028 | |||
2029 | static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val) | ||
2030 | { | ||
2031 | struct sd *sd = (struct sd *) gspca_dev; | ||
2032 | |||
2033 | sd->satur = val; | ||
2034 | if (gspca_dev->streaming) | ||
2035 | setsatur(gspca_dev); | ||
2036 | return 0; | ||
2037 | } | ||
2038 | |||
2039 | static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val) | ||
2040 | { | ||
2041 | struct sd *sd = (struct sd *) gspca_dev; | ||
2042 | |||
2043 | *val = sd->satur; | ||
2044 | return 0; | ||
2045 | } | ||
2046 | static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | ||
2047 | { | ||
2048 | struct sd *sd = (struct sd *) gspca_dev; | ||
2049 | |||
2050 | sd->lightfreq = val; | ||
2051 | if (gspca_dev->streaming) | ||
2052 | setfreq(gspca_dev); | ||
2053 | return 0; | ||
2054 | } | ||
2055 | |||
2056 | static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) | ||
2057 | { | ||
2058 | struct sd *sd = (struct sd *) gspca_dev; | ||
2059 | |||
2060 | *val = sd->lightfreq; | ||
2061 | return 0; | ||
2062 | } | ||
2063 | |||
2064 | static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val) | ||
2065 | { | ||
2066 | struct sd *sd = (struct sd *) gspca_dev; | ||
2067 | |||
2068 | sd->redblc = val; | ||
2069 | if (gspca_dev->streaming) | ||
2070 | setredblc(gspca_dev); | ||
2071 | return 0; | ||
2072 | } | ||
2073 | |||
2074 | static int sd_getredblc(struct gspca_dev *gspca_dev, __s32 *val) | ||
2075 | { | ||
2076 | struct sd *sd = (struct sd *) gspca_dev; | ||
2077 | |||
2078 | *val = sd->redblc; | ||
2079 | return 0; | ||
2080 | } | ||
2081 | |||
2082 | static int sd_setblueblc(struct gspca_dev *gspca_dev, __s32 val) | ||
2083 | { | ||
2084 | struct sd *sd = (struct sd *) gspca_dev; | ||
2085 | |||
2086 | sd->blueblc = val; | ||
2087 | if (gspca_dev->streaming) | ||
2088 | setblueblc(gspca_dev); | ||
2089 | return 0; | ||
2090 | } | ||
2091 | |||
2092 | static int sd_getblueblc(struct gspca_dev *gspca_dev, __s32 *val) | ||
2093 | { | ||
2094 | struct sd *sd = (struct sd *) gspca_dev; | ||
2095 | |||
2096 | *val = sd->blueblc; | ||
2097 | return 0; | ||
2098 | } | ||
2099 | |||
2100 | static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val) | ||
2101 | { | ||
2102 | struct sd *sd = (struct sd *) gspca_dev; | ||
2103 | |||
2104 | sd->hue = val; | ||
2105 | if (gspca_dev->streaming) | ||
2106 | sethue(gspca_dev); | ||
2107 | return 0; | ||
2108 | } | ||
2109 | |||
2110 | static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val) | ||
2111 | { | ||
2112 | struct sd *sd = (struct sd *) gspca_dev; | ||
2113 | |||
2114 | *val = sd->hue; | ||
2115 | return 0; | ||
2116 | } | ||
2117 | |||
2118 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | ||
2119 | { | ||
2120 | struct sd *sd = (struct sd *) gspca_dev; | ||
2121 | |||
2122 | sd->autogain = val; | ||
2123 | |||
2124 | if (gspca_dev->streaming) { | ||
2125 | if (sd->sensor == SENSOR_OV772X) { | ||
2126 | |||
2127 | /* the auto white balance control works only | ||
2128 | * when auto gain is set */ | ||
2129 | if (val) | ||
2130 | gspca_dev->ctrl_inac &= ~(1 << AWB_77_IDX); | ||
2131 | else | ||
2132 | gspca_dev->ctrl_inac |= (1 << AWB_77_IDX); | ||
2133 | setautogain_77(gspca_dev); | ||
2134 | } else { | ||
2135 | if (val) | ||
2136 | gspca_dev->ctrl_inac |= (1 << EXPO_96_IDX); | ||
2137 | else | ||
2138 | gspca_dev->ctrl_inac &= ~(1 << EXPO_96_IDX); | ||
2139 | setautogain_96(gspca_dev); | ||
2140 | } | ||
2141 | } | ||
2142 | return 0; | ||
2143 | } | ||
2144 | |||
2145 | static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) | ||
2146 | { | ||
2147 | struct sd *sd = (struct sd *) gspca_dev; | ||
2148 | |||
2149 | *val = sd->autogain; | ||
2150 | return 0; | ||
2151 | } | ||
2152 | |||
2153 | static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val) | ||
2154 | { | ||
2155 | struct sd *sd = (struct sd *) gspca_dev; | ||
2156 | |||
2157 | sd->awb = val; | ||
2158 | if (gspca_dev->streaming) | ||
2159 | setawb(gspca_dev); | ||
2160 | return 0; | ||
2161 | } | ||
2162 | |||
2163 | static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val) | ||
2164 | { | ||
2165 | struct sd *sd = (struct sd *) gspca_dev; | ||
2166 | |||
2167 | *val = sd->awb; | ||
2168 | return 0; | ||
2169 | } | ||
2170 | |||
2171 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) | ||
2172 | { | ||
2173 | struct sd *sd = (struct sd *) gspca_dev; | ||
2174 | |||
2175 | sd->sharpness = val; | ||
2176 | if (gspca_dev->streaming) { | ||
2177 | if (sd->sensor == SENSOR_OV772X) | ||
2178 | setsharpness_77(gspca_dev); | ||
2179 | else | ||
2180 | setsharpness_96(gspca_dev); | ||
2181 | } | ||
2182 | return 0; | ||
2183 | } | ||
2184 | |||
2185 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) | ||
2186 | { | ||
2187 | struct sd *sd = (struct sd *) gspca_dev; | ||
2188 | |||
2189 | *val = sd->sharpness; | ||
2190 | return 0; | ||
2191 | } | ||
2192 | |||
2193 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) | ||
2194 | { | ||
2195 | struct sd *sd = (struct sd *) gspca_dev; | ||
2196 | |||
2197 | sd->hflip = val; | ||
2198 | if (gspca_dev->streaming) | ||
2199 | sethflip(gspca_dev); | ||
2200 | return 0; | ||
2201 | } | ||
2202 | |||
2203 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
2204 | { | ||
2205 | struct sd *sd = (struct sd *) gspca_dev; | ||
2206 | |||
2207 | *val = sd->hflip; | ||
2208 | return 0; | ||
2209 | } | ||
2210 | |||
2211 | static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val) | ||
2212 | { | ||
2213 | struct sd *sd = (struct sd *) gspca_dev; | ||
2214 | |||
2215 | sd->vflip = val; | ||
2216 | if (gspca_dev->streaming) | ||
2217 | setvflip(gspca_dev); | ||
2218 | return 0; | ||
2219 | } | ||
2220 | |||
2221 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
2222 | { | ||
2223 | struct sd *sd = (struct sd *) gspca_dev; | ||
2224 | |||
2225 | *val = sd->vflip; | ||
2226 | return 0; | ||
2227 | } | ||
2228 | |||
1019 | /* get stream parameters (framerate) */ | 2229 | /* get stream parameters (framerate) */ |
1020 | static int sd_get_streamparm(struct gspca_dev *gspca_dev, | 2230 | static int sd_get_streamparm(struct gspca_dev *gspca_dev, |
1021 | struct v4l2_streamparm *parm) | 2231 | struct v4l2_streamparm *parm) |
@@ -1047,7 +2257,8 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev, | |||
1047 | 2257 | ||
1048 | /* Set requested framerate */ | 2258 | /* Set requested framerate */ |
1049 | sd->frame_rate = tpf->denominator / tpf->numerator; | 2259 | sd->frame_rate = tpf->denominator / tpf->numerator; |
1050 | ov534_set_frame_rate(gspca_dev); | 2260 | if (gspca_dev->streaming && sd->sensor == SENSOR_OV772X) |
2261 | set_frame_rate(gspca_dev); | ||
1051 | 2262 | ||
1052 | /* Return the actual framerate */ | 2263 | /* Return the actual framerate */ |
1053 | tpf->numerator = 1; | 2264 | tpf->numerator = 1; |
@@ -1056,20 +2267,53 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev, | |||
1056 | return 0; | 2267 | return 0; |
1057 | } | 2268 | } |
1058 | 2269 | ||
2270 | static int sd_querymenu(struct gspca_dev *gspca_dev, | ||
2271 | struct v4l2_querymenu *menu) | ||
2272 | { | ||
2273 | switch (menu->id) { | ||
2274 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
2275 | switch (menu->index) { | ||
2276 | case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ | ||
2277 | strcpy((char *) menu->name, "NoFliker"); | ||
2278 | return 0; | ||
2279 | case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ | ||
2280 | strcpy((char *) menu->name, "50 Hz"); | ||
2281 | return 0; | ||
2282 | case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ | ||
2283 | strcpy((char *) menu->name, "60 Hz"); | ||
2284 | return 0; | ||
2285 | } | ||
2286 | break; | ||
2287 | } | ||
2288 | return -EINVAL; | ||
2289 | } | ||
2290 | |||
1059 | /* sub-driver description */ | 2291 | /* sub-driver description */ |
1060 | static const struct sd_desc sd_desc = { | 2292 | static const struct sd_desc sd_desc_ov772x = { |
1061 | .name = MODULE_NAME, | 2293 | .name = MODULE_NAME, |
1062 | .ctrls = sd_ctrls, | 2294 | .ctrls = sd_ctrls_ov772x, |
1063 | .nctrls = ARRAY_SIZE(sd_ctrls), | 2295 | .nctrls = ARRAY_SIZE(sd_ctrls_ov772x), |
1064 | .config = sd_config, | 2296 | .config = sd_config, |
1065 | .init = sd_init, | 2297 | .init = sd_init, |
1066 | .start = sd_start, | 2298 | .start = sd_start_ov772x, |
1067 | .stopN = sd_stopN, | 2299 | .stopN = sd_stopN_ov772x, |
1068 | .pkt_scan = sd_pkt_scan, | 2300 | .pkt_scan = sd_pkt_scan, |
1069 | .get_streamparm = sd_get_streamparm, | 2301 | .get_streamparm = sd_get_streamparm, |
1070 | .set_streamparm = sd_set_streamparm, | 2302 | .set_streamparm = sd_set_streamparm, |
1071 | }; | 2303 | }; |
1072 | 2304 | ||
2305 | static const struct sd_desc sd_desc_ov965x = { | ||
2306 | .name = MODULE_NAME, | ||
2307 | .ctrls = sd_ctrls_ov965x, | ||
2308 | .nctrls = ARRAY_SIZE(sd_ctrls_ov965x), | ||
2309 | .config = sd_config, | ||
2310 | .init = sd_init, | ||
2311 | .start = sd_start_ov965x, | ||
2312 | .stopN = sd_stopN_ov965x, | ||
2313 | .pkt_scan = sd_pkt_scan, | ||
2314 | .querymenu = sd_querymenu, | ||
2315 | }; | ||
2316 | |||
1073 | /* -- module initialisation -- */ | 2317 | /* -- module initialisation -- */ |
1074 | static const __devinitdata struct usb_device_id device_table[] = { | 2318 | static const __devinitdata struct usb_device_id device_table[] = { |
1075 | {USB_DEVICE(0x06f8, 0x3003), .driver_info = SENSOR_OV965X}, | 2319 | {USB_DEVICE(0x06f8, 0x3003), .driver_info = SENSOR_OV965X}, |
@@ -1082,8 +2326,12 @@ MODULE_DEVICE_TABLE(usb, device_table); | |||
1082 | /* -- device connect -- */ | 2326 | /* -- device connect -- */ |
1083 | static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) | 2327 | static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) |
1084 | { | 2328 | { |
1085 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | 2329 | return gspca_dev_probe(intf, id, |
1086 | THIS_MODULE); | 2330 | id->driver_info == SENSOR_OV772X |
2331 | ? &sd_desc_ov772x | ||
2332 | : &sd_desc_ov965x, | ||
2333 | sizeof(struct sd), | ||
2334 | THIS_MODULE); | ||
1087 | } | 2335 | } |
1088 | 2336 | ||
1089 | static struct usb_driver sd_driver = { | 2337 | static struct usb_driver sd_driver = { |
@@ -1101,6 +2349,7 @@ static struct usb_driver sd_driver = { | |||
1101 | static int __init sd_mod_init(void) | 2349 | static int __init sd_mod_init(void) |
1102 | { | 2350 | { |
1103 | int ret; | 2351 | int ret; |
2352 | |||
1104 | ret = usb_register(&sd_driver); | 2353 | ret = usb_register(&sd_driver); |
1105 | if (ret < 0) | 2354 | if (ret < 0) |
1106 | return ret; | 2355 | return ret; |