]>
Commit | Line | Data |
---|---|---|
8bce5f09 | 1 | diff -Nur --exclude '*.orig' linux-2.6.6.org/drivers/usb/media/Kconfig linux-2.6.6/drivers/usb/media/Kconfig |
2 | --- linux-2.6.6.org/drivers/usb/media/Kconfig 2004-05-10 04:31:57.000000000 +0200 | |
3 | +++ linux-2.6.6/drivers/usb/media/Kconfig 2004-05-10 14:18:23.000000000 +0200 | |
4 | @@ -114,22 +114,22 @@ | |
5 | webcams: | |
6 | * Philips PCA645, PCA646 | |
7 | * Philips PCVC675, PCVC680, PCVC690 | |
8 | - * Philips PCVC720/40, PCVC730, PCVC740, PCVC750 | |
9 | + * Philips PCVC720/40 PCVC730, PCVC740, PCVC750 | |
10 | * Askey VC010 | |
11 | - * Logitech QuickCam Pro 3000, 4000, 'Zoom', 'Notebook Pro' | |
12 | - and 'Orbit'/'Sphere' | |
13 | - * Samsung MPC-C10, MPC-C30 | |
14 | + * Logitech QuickCam Pro 3000, 4000, 'Zoom' and 'Notebook' | |
15 | + * Logitech QuickCam Orbit/Sphere | |
16 | + * Samsung MPC-C10, MPC-C30 | |
17 | * Creative Webcam 5, Pro Ex | |
18 | - * SOTEC Afina Eye | |
19 | + * SOTEC Afina Eye / AME Optimedia CU-001 | |
20 | * Visionite VCS-UC300, VCS-UM100 | |
21 | ||
22 | The PCA635, PCVC665 and PCVC720/20 are not supported by this driver | |
23 | - and never will be, but the 665 and 720/20 are supported by other | |
24 | + and never will be, but the 665 and 720 are supported by other | |
25 | drivers. | |
26 | ||
27 | - This driver has an optional plugin (called PWCX), which is | |
28 | - distributed as a binary module only. It contains code that allow you | |
29 | - to use higher resolutions and framerates but may not be distributed | |
30 | + This driver has an optional plugin (called PWCX), which is | |
31 | + distributed with a binary-only part. It contains code that allow you | |
32 | + to use higher resolutions and framerates but may not be distributed | |
33 | as source. But even without this plugin you can these cams for most | |
34 | applications. | |
35 | ||
36 | @@ -146,6 +146,10 @@ | |
37 | To compile this driver as a module, choose M here: the | |
38 | module will be called pwc. | |
39 | ||
40 | +config USB_PWCX | |
41 | + tristate "PWCX decompressor module" | |
42 | + depends on USB_PWC | |
43 | + | |
44 | config USB_SE401 | |
45 | tristate "USB SE401 Camera support" | |
46 | depends on USB && VIDEO_DEV | |
47 | diff -Nur --exclude '*.orig' linux-2.6.6.org/drivers/usb/media/Makefile linux-2.6.6/drivers/usb/media/Makefile | |
48 | --- linux-2.6.6.org/drivers/usb/media/Makefile 2004-05-10 04:31:55.000000000 +0200 | |
49 | +++ linux-2.6.6/drivers/usb/media/Makefile 2004-05-10 14:18:23.000000000 +0200 | |
50 | @@ -3,6 +3,7 @@ | |
51 | # | |
52 | ||
53 | pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o | |
54 | +pwcx-objs := pwcx-glue.o libpwcx.a | |
55 | ||
56 | obj-$(CONFIG_USB_DABUSB) += dabusb.o | |
57 | obj-$(CONFIG_USB_DSBR) += dsbr100.o | |
58 | @@ -10,6 +11,7 @@ | |
59 | obj-$(CONFIG_USB_KONICAWC) += konicawc.o usbvideo.o | |
60 | obj-$(CONFIG_USB_OV511) += ov511.o | |
61 | obj-$(CONFIG_USB_PWC) += pwc.o | |
62 | +obj-$(CONFIG_USB_PWCX) += pwcx.o | |
63 | obj-$(CONFIG_USB_SE401) += se401.o | |
64 | obj-$(CONFIG_USB_STV680) += stv680.o | |
65 | obj-$(CONFIG_USB_VICAM) += vicam.o usbvideo.o | |
66 | diff -Nur --exclude '*.orig' linux-2.6.6.org/drivers/usb/media/pwc-ctrl.c linux-2.6.6/drivers/usb/media/pwc-ctrl.c | |
67 | --- linux-2.6.6.org/drivers/usb/media/pwc-ctrl.c 2004-05-10 04:33:20.000000000 +0200 | |
68 | +++ linux-2.6.6/drivers/usb/media/pwc-ctrl.c 2004-05-07 00:52:23.000000000 +0200 | |
69 | @@ -30,6 +30,7 @@ | |
70 | #include <asm/uaccess.h> | |
71 | #endif | |
72 | #include <asm/errno.h> | |
73 | +#include <linux/version.h> | |
74 | ||
75 | #include "pwc.h" | |
76 | #include "pwc-ioctl.h" | |
77 | @@ -127,19 +128,19 @@ | |
78 | ||
79 | /* This tables contains entries for the 675/680/690 (Timon) camera, with | |
80 | 4 different qualities (no compression, low, medium, high). | |
81 | - It lists the bandwidth requirements for said mode by its alternate interface | |
82 | + It lists the bandwidth requirements for said mode by its alternate interface | |
83 | number. An alternate of 0 means that the mode is unavailable. | |
84 | - | |
85 | - There are 6 * 4 * 4 entries: | |
86 | + | |
87 | + There are 6 * 4 * 4 entries: | |
88 | 6 different resolutions subqcif, qsif, qcif, sif, cif, vga | |
89 | 6 framerates: 5, 10, 15, 20, 25, 30 | |
90 | 4 compression modi: none, low, medium, high | |
91 | - | |
92 | - When an uncompressed mode is not available, the next available compressed mode | |
93 | + | |
94 | + When an uncompressed mode is not available, the next available compressed mode | |
95 | will be chosen (unless the decompressor is absent). Sometimes there are only | |
96 | 1 or 2 compressed modes available; in that case entries are duplicated. | |
97 | */ | |
98 | -struct Timon_table_entry | |
99 | +struct Timon_table_entry | |
100 | { | |
101 | char alternate; /* USB alternate interface */ | |
102 | unsigned short packetsize; /* Normal packet size */ | |
103 | @@ -147,7 +148,7 @@ | |
104 | unsigned char mode[13]; /* precomputed mode settings for cam */ | |
105 | }; | |
106 | ||
107 | -static struct Timon_table_entry Timon_table[PSZ_MAX][6][4] = | |
108 | +static struct Timon_table_entry Timon_table[PSZ_MAX][6][4] = | |
109 | { | |
110 | #include "pwc_timon.h" | |
111 | }; | |
112 | @@ -194,7 +195,7 @@ | |
113 | int i; | |
114 | unsigned char *s; | |
115 | char buf[100], *d; | |
116 | - | |
117 | + | |
118 | s = (unsigned char *)p; | |
119 | d = buf; | |
120 | *d = '\0'; | |
121 | @@ -230,7 +231,7 @@ | |
122 | unsigned char buf[3]; | |
123 | int ret, fps; | |
124 | struct Nala_table_entry *pEntry; | |
125 | - int frames2frames[31] = | |
126 | + int frames2frames[31] = | |
127 | { /* closest match of framerate */ | |
128 | 0, 0, 0, 0, 4, /* 0-4 */ | |
129 | 5, 5, 7, 7, 10, /* 5-9 */ | |
130 | @@ -267,9 +268,12 @@ | |
131 | Debug("Failed to send video command... %d\n", ret); | |
132 | return ret; | |
133 | } | |
134 | - if (pEntry->compressed && pdev->decompressor != NULL) | |
135 | - pdev->decompressor->init(pdev->release, buf, pdev->decompress_data); | |
136 | - | |
137 | + if (pEntry->compressed && pdev->decompressor != 0 && pdev->vpalette != VIDEO_PALETTE_RAW) | |
138 | + pdev->decompressor->init(pdev->type, pdev->release, buf, pdev->decompress_data); | |
139 | + | |
140 | + pdev->cmd_len = 3; | |
141 | + memcpy(pdev->cmd_buf, buf, 3); | |
142 | + | |
143 | /* Set various parameters */ | |
144 | pdev->vframes = frames; | |
145 | pdev->vsize = size; | |
146 | @@ -303,13 +307,13 @@ | |
147 | if (size == PSZ_VGA && frames > 15) | |
148 | return -EINVAL; | |
149 | fps = (frames / 5) - 1; | |
150 | - | |
151 | + | |
152 | /* Find a supported framerate with progressively higher compression ratios | |
153 | if the preferred ratio is not available. | |
154 | */ | |
155 | pChoose = NULL; | |
156 | if (pdev->decompressor == NULL) { | |
157 | -#if PWC_DEBUG | |
158 | +#if PWC_DEBUG | |
159 | Debug("Trying to find uncompressed mode.\n"); | |
160 | #endif | |
161 | pChoose = &Timon_table[size][fps][0]; | |
162 | @@ -319,7 +323,7 @@ | |
163 | pChoose = &Timon_table[size][fps][compression]; | |
164 | if (pChoose->alternate != 0) | |
165 | break; | |
166 | - compression++; | |
167 | + compression++; | |
168 | } | |
169 | } | |
170 | if (pChoose == NULL || pChoose->alternate == 0) | |
171 | @@ -332,9 +336,12 @@ | |
172 | if (ret < 0) | |
173 | return ret; | |
174 | ||
175 | - if (pChoose->bandlength > 0) | |
176 | - pdev->decompressor->init(pdev->release, buf, pdev->decompress_data); | |
177 | - | |
178 | + if (pChoose->bandlength > 0 && pdev->decompressor != 0 && pdev->vpalette != VIDEO_PALETTE_RAW) | |
179 | + pdev->decompressor->init(pdev->type, pdev->release, buf, pdev->decompress_data); | |
180 | + | |
181 | + pdev->cmd_len = 13; | |
182 | + memcpy(pdev->cmd_buf, buf, 13); | |
183 | + | |
184 | /* Set various parameters */ | |
185 | pdev->vframes = frames; | |
186 | pdev->vsize = size; | |
187 | @@ -342,7 +349,7 @@ | |
188 | pdev->valternate = pChoose->alternate; | |
189 | pdev->image = pwc_image_sizes[size]; | |
190 | pdev->vbandlength = pChoose->bandlength; | |
191 | - if (pChoose->bandlength > 0) | |
192 | + if (pChoose->bandlength > 0) | |
193 | pdev->frame_size = (pChoose->bandlength * pdev->image.y) / 4; | |
194 | else | |
195 | pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8; | |
196 | @@ -352,33 +359,54 @@ | |
197 | ||
198 | static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, int compression, int snapshot) | |
199 | { | |
200 | - struct Kiara_table_entry *pChoose; | |
201 | + struct Kiara_table_entry *pChoose = 0; | |
202 | int fps, ret; | |
203 | unsigned char buf[12]; | |
204 | - | |
205 | + struct Kiara_table_entry RawEntry = {6, 773, 1272, {0xAD, 0xF4, 0x10, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x03, 0x80}}; | |
206 | + | |
207 | if (size >= PSZ_MAX || frames < 5 || frames > 30 || compression < 0 || compression > 3) | |
208 | return -EINVAL; | |
209 | if (size == PSZ_VGA && frames > 15) | |
210 | return -EINVAL; | |
211 | fps = (frames / 5) - 1; | |
212 | - | |
213 | - /* Find a supported framerate with progressively higher compression ratios | |
214 | - if the preferred ratio is not available. | |
215 | - */ | |
216 | - pChoose = NULL; | |
217 | - if (pdev->decompressor == NULL) { | |
218 | -#if PWC_DEBUG | |
219 | - Debug("Trying to find uncompressed mode.\n"); | |
220 | -#endif | |
221 | - pChoose = &Kiara_table[size][fps][0]; | |
222 | + | |
223 | + /* special case: VGA @ 5 fps and snapshot is raw bayer mode */ | |
224 | + if (size == PSZ_VGA && frames == 5 && snapshot) | |
225 | + { | |
226 | + /* Only available in case the raw palette is selected or | |
227 | + we have the decompressor available. This mode is | |
228 | + only available in compressed form | |
229 | + */ | |
230 | + if (pdev->vpalette == VIDEO_PALETTE_RAW || pdev->decompressor != NULL) | |
231 | + { | |
232 | + Info("Choosing VGA/5 BAYER mode (%d).\n", pdev->vpalette); | |
233 | + pChoose = &RawEntry; | |
234 | + } | |
235 | + else | |
236 | + { | |
237 | + Info("VGA/5 BAYER mode _must_ have a decompressor available, or use RAW palette.\n"); | |
238 | + } | |
239 | } | |
240 | - else { | |
241 | - while (compression <= 3) { | |
242 | - pChoose = &Kiara_table[size][fps][compression]; | |
243 | - if (pChoose->alternate != 0) | |
244 | - break; | |
245 | - compression++; | |
246 | + else | |
247 | + { | |
248 | + /* Find a supported framerate with progressively higher compression ratios | |
249 | + if the preferred ratio is not available. | |
250 | + Skip this step when using RAW modes. | |
251 | + */ | |
252 | + if (pdev->decompressor == NULL && pdev->vpalette != VIDEO_PALETTE_RAW) { | |
253 | +#if PWC_DEBUG | |
254 | + Debug("Trying to find uncompressed mode.\n"); | |
255 | +#endif | |
256 | + pChoose = &Kiara_table[size][fps][0]; | |
257 | } | |
258 | + else { | |
259 | + while (compression <= 3) { | |
260 | + pChoose = &Kiara_table[size][fps][compression]; | |
261 | + if (pChoose->alternate != 0) | |
262 | + break; | |
263 | + compression++; | |
264 | + } | |
265 | + } | |
266 | } | |
267 | if (pChoose == NULL || pChoose->alternate == 0) | |
268 | return -ENOENT; /* Not supported. */ | |
269 | @@ -393,9 +421,11 @@ | |
270 | if (ret < 0) | |
271 | return ret; | |
272 | ||
273 | - if (pChoose->bandlength > 0) | |
274 | - pdev->decompressor->init(pdev->release, buf, pdev->decompress_data); | |
275 | - | |
276 | + if (pChoose->bandlength > 0 && pdev->decompressor != 0 && pdev->vpalette != VIDEO_PALETTE_RAW) | |
277 | + pdev->decompressor->init(pdev->type, pdev->release, buf, pdev->decompress_data); | |
278 | + | |
279 | + pdev->cmd_len = 12; | |
280 | + memcpy(pdev->cmd_buf, buf, 12); | |
281 | /* All set and go */ | |
282 | pdev->vframes = frames; | |
283 | pdev->vsize = size; | |
284 | @@ -403,15 +433,15 @@ | |
285 | pdev->valternate = pChoose->alternate; | |
286 | pdev->image = pwc_image_sizes[size]; | |
287 | pdev->vbandlength = pChoose->bandlength; | |
288 | - if (pChoose->bandlength > 0) | |
289 | - pdev->frame_size = (pChoose->bandlength * pdev->image.y) / 4; | |
290 | - else | |
291 | + if (pdev->vbandlength > 0) | |
292 | + pdev->frame_size = (pdev->vbandlength * pdev->image.y) / 4; | |
293 | + else | |
294 | pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8; | |
295 | - pdev->frame_size += (pdev->frame_header_size + pdev->frame_trailer_size); | |
296 | return 0; | |
297 | } | |
298 | ||
299 | ||
300 | + | |
301 | /** | |
302 | @pdev: device structure | |
303 | @width: viewport width | |
304 | @@ -422,14 +452,18 @@ | |
305 | */ | |
306 | int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot) | |
307 | { | |
308 | - int ret, size; | |
309 | - | |
310 | + | |
311 | + int ret, size; | |
312 | + | |
313 | + Trace(TRACE_FLOW, "set_video_mode(%dx%d @ %d, palette %d).\n", width, height, frames, pdev->vpalette); | |
314 | size = pwc_decode_size(pdev, width, height); | |
315 | if (size < 0) { | |
316 | Debug("Could not find suitable size.\n"); | |
317 | return -ERANGE; | |
318 | } | |
319 | - ret = -EINVAL; | |
320 | + Debug("decode_size = %d.\n", size); | |
321 | + | |
322 | + ret = -EINVAL; | |
323 | switch(pdev->type) { | |
324 | case 645: | |
325 | case 646: | |
326 | @@ -441,7 +475,7 @@ | |
327 | case 690: | |
328 | ret = set_video_mode_Timon(pdev, size, frames, compression, snapshot); | |
329 | break; | |
330 | - | |
331 | + | |
332 | case 720: | |
333 | case 730: | |
334 | case 740: | |
335 | @@ -459,6 +493,7 @@ | |
336 | } | |
337 | pdev->view.x = width; | |
338 | pdev->view.y = height; | |
339 | + pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size; | |
340 | pwc_set_image_buffer_size(pdev); | |
341 | Trace(TRACE_SIZE, "Set viewport to %dx%d, image size is %dx%d.\n", width, height, pwc_image_sizes[size].x, pwc_image_sizes[size].y); | |
342 | return 0; | |
343 | @@ -467,23 +502,33 @@ | |
344 | ||
345 | void pwc_set_image_buffer_size(struct pwc_device *pdev) | |
346 | { | |
347 | - int factor, i, filler = 0; | |
348 | + int i, factor = 0, filler = 0; | |
349 | ||
350 | - factor = 6; | |
351 | - filler = 128; | |
352 | + /* for PALETTE_YUV420P */ | |
353 | + switch(pdev->vpalette) | |
354 | + { | |
355 | + case VIDEO_PALETTE_YUV420P: | |
356 | + factor = 6; | |
357 | + filler = 128; | |
358 | + break; | |
359 | + case VIDEO_PALETTE_RAW: | |
360 | + factor = 6; /* can be uncompressed YUV420P */ | |
361 | + filler = 0; | |
362 | + break; | |
363 | + } | |
364 | ||
365 | /* Set sizes in bytes */ | |
366 | pdev->image.size = pdev->image.x * pdev->image.y * factor / 4; | |
367 | pdev->view.size = pdev->view.x * pdev->view.y * factor / 4; | |
368 | ||
369 | /* Align offset, or you'll get some very weird results in | |
370 | - YUV420 mode... x must be multiple of 4 (to get the Y's in | |
371 | + YUV420 mode... x must be multiple of 4 (to get the Y's in | |
372 | place), and y even (or you'll mixup U & V). This is less of a | |
373 | problem for YUV420P. | |
374 | */ | |
375 | pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC; | |
376 | pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE; | |
377 | - | |
378 | + | |
379 | /* Fill buffers with gray or black */ | |
380 | for (i = 0; i < MAX_IMAGES; i++) { | |
381 | if (pdev->image_ptr[i] != NULL) | |
382 | @@ -499,13 +544,8 @@ | |
383 | { | |
384 | char buf; | |
385 | int ret; | |
386 | - | |
387 | - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), | |
388 | - GET_LUM_CTL, | |
389 | - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
390 | - BRIGHTNESS_FORMATTER, | |
391 | - pdev->vcinterface, | |
392 | - &buf, 1, HZ / 2); | |
393 | + | |
394 | + ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1); | |
395 | if (ret < 0) | |
396 | return ret; | |
397 | return buf << 9; | |
398 | @@ -520,12 +560,7 @@ | |
399 | if (value > 0xffff) | |
400 | value = 0xffff; | |
401 | buf = (value >> 9) & 0x7f; | |
402 | - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | |
403 | - SET_LUM_CTL, | |
404 | - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
405 | - BRIGHTNESS_FORMATTER, | |
406 | - pdev->vcinterface, | |
407 | - &buf, 1, HZ / 2); | |
408 | + return SendControlMsg(SET_LUM_CTL, BRIGHTNESS_FORMATTER, 1); | |
409 | } | |
410 | ||
411 | /* CONTRAST */ | |
412 | @@ -534,13 +569,8 @@ | |
413 | { | |
414 | char buf; | |
415 | int ret; | |
416 | - | |
417 | - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), | |
418 | - GET_LUM_CTL, | |
419 | - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
420 | - CONTRAST_FORMATTER, | |
421 | - pdev->vcinterface, | |
422 | - &buf, 1, HZ / 2); | |
423 | + | |
424 | + ret = RecvControlMsg(GET_LUM_CTL, CONTRAST_FORMATTER, 1); | |
425 | if (ret < 0) | |
426 | return ret; | |
427 | return buf << 10; | |
428 | @@ -555,12 +585,7 @@ | |
429 | if (value > 0xffff) | |
430 | value = 0xffff; | |
431 | buf = (value >> 10) & 0x3f; | |
432 | - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | |
433 | - SET_LUM_CTL, | |
434 | - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
435 | - CONTRAST_FORMATTER, | |
436 | - pdev->vcinterface, | |
437 | - &buf, 1, HZ / 2); | |
438 | + return SendControlMsg(SET_LUM_CTL, CONTRAST_FORMATTER, 1); | |
439 | } | |
440 | ||
441 | /* GAMMA */ | |
442 | @@ -570,12 +595,7 @@ | |
443 | char buf; | |
444 | int ret; | |
445 | ||
446 | - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), | |
447 | - GET_LUM_CTL, | |
448 | - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
449 | - GAMMA_FORMATTER, | |
450 | - pdev->vcinterface, | |
451 | - &buf, 1, HZ / 2); | |
452 | + ret = RecvControlMsg(GET_LUM_CTL, GAMMA_FORMATTER, 1); | |
453 | if (ret < 0) | |
454 | return ret; | |
455 | return buf << 11; | |
456 | @@ -590,12 +610,7 @@ | |
457 | if (value > 0xffff) | |
458 | value = 0xffff; | |
459 | buf = (value >> 11) & 0x1f; | |
460 | - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | |
461 | - SET_LUM_CTL, | |
462 | - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
463 | - GAMMA_FORMATTER, | |
464 | - pdev->vcinterface, | |
465 | - &buf, 1, HZ / 2); | |
466 | + return SendControlMsg(SET_LUM_CTL, GAMMA_FORMATTER, 1); | |
467 | } | |
468 | ||
469 | ||
470 | @@ -608,12 +623,7 @@ | |
471 | ||
472 | if (pdev->type < 675) | |
473 | return -1; | |
474 | - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), | |
475 | - GET_CHROM_CTL, | |
476 | - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
477 | - pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, | |
478 | - pdev->vcinterface, | |
479 | - &buf, 1, HZ / 2); | |
480 | + ret = RecvControlMsg(GET_CHROM_CTL, pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, 1); | |
481 | if (ret < 0) | |
482 | return ret; | |
483 | return 32768 + buf * 327; | |
484 | @@ -631,12 +641,7 @@ | |
485 | value = 0xffff; | |
486 | /* saturation ranges from -100 to +100 */ | |
487 | buf = (value - 32768) / 327; | |
488 | - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | |
489 | - SET_CHROM_CTL, | |
490 | - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
491 | - pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, | |
492 | - pdev->vcinterface, | |
493 | - &buf, 1, HZ / 2); | |
494 | + return SendControlMsg(SET_CHROM_CTL, pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, 1); | |
495 | } | |
496 | ||
497 | /* AGC */ | |
498 | @@ -651,12 +656,7 @@ | |
499 | else | |
500 | buf = 0xff; /* fixed */ | |
501 | ||
502 | - ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | |
503 | - SET_LUM_CTL, | |
504 | - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
505 | - AGC_MODE_FORMATTER, | |
506 | - pdev->vcinterface, | |
507 | - &buf, 1, HZ / 2); | |
508 | + ret = SendControlMsg(SET_LUM_CTL, AGC_MODE_FORMATTER, 1); | |
509 | ||
510 | if (!mode && ret >= 0) { | |
511 | if (value < 0) | |
512 | @@ -664,12 +664,7 @@ | |
513 | if (value > 0xffff) | |
514 | value = 0xffff; | |
515 | buf = (value >> 10) & 0x3F; | |
516 | - ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | |
517 | - SET_LUM_CTL, | |
518 | - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
519 | - PRESET_AGC_FORMATTER, | |
520 | - pdev->vcinterface, | |
521 | - &buf, 1, HZ / 2); | |
522 | + ret = SendControlMsg(SET_LUM_CTL, PRESET_AGC_FORMATTER, 1); | |
523 | } | |
524 | if (ret < 0) | |
525 | return ret; | |
526 | @@ -681,22 +676,12 @@ | |
527 | unsigned char buf; | |
528 | int ret; | |
529 | ||
530 | - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), | |
531 | - GET_LUM_CTL, | |
532 | - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
533 | - AGC_MODE_FORMATTER, | |
534 | - pdev->vcinterface, | |
535 | - &buf, 1, HZ / 2); | |
536 | + ret = RecvControlMsg(GET_LUM_CTL, AGC_MODE_FORMATTER, 1); | |
537 | if (ret < 0) | |
538 | return ret; | |
539 | ||
540 | if (buf != 0) { /* fixed */ | |
541 | - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), | |
542 | - GET_LUM_CTL, | |
543 | - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
544 | - PRESET_AGC_FORMATTER, | |
545 | - pdev->vcinterface, | |
546 | - &buf, 1, HZ / 2); | |
547 | + ret = RecvControlMsg(GET_LUM_CTL, PRESET_AGC_FORMATTER, 1); | |
548 | if (ret < 0) | |
549 | return ret; | |
550 | if (buf > 0x3F) | |
551 | @@ -704,12 +689,7 @@ | |
552 | *value = (buf << 10); | |
553 | } | |
554 | else { /* auto */ | |
555 | - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), | |
556 | - GET_STATUS_CTL, | |
557 | - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
558 | - READ_AGC_FORMATTER, | |
559 | - pdev->vcinterface, | |
560 | - &buf, 1, HZ / 2); | |
561 | + ret = RecvControlMsg(GET_STATUS_CTL, READ_AGC_FORMATTER, 1); | |
562 | if (ret < 0) | |
563 | return ret; | |
564 | /* Gah... this value ranges from 0x00 ... 0x9F */ | |
565 | @@ -732,12 +712,7 @@ | |
566 | else | |
567 | buf[0] = 0xff; /* fixed */ | |
568 | ||
569 | - ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | |
570 | - SET_LUM_CTL, | |
571 | - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
572 | - SHUTTER_MODE_FORMATTER, | |
573 | - pdev->vcinterface, | |
574 | - buf, 1, HZ / 2); | |
575 | + ret = SendControlMsg(SET_LUM_CTL, SHUTTER_MODE_FORMATTER, 1); | |
576 | ||
577 | if (!mode && ret >= 0) { | |
578 | if (value < 0) | |
579 | @@ -763,12 +738,7 @@ | |
580 | break; | |
581 | } | |
582 | ||
583 | - ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | |
584 | - SET_LUM_CTL, | |
585 | - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
586 | - PRESET_SHUTTER_FORMATTER, | |
587 | - pdev->vcinterface, | |
588 | - &buf, 2, HZ / 2); | |
589 | + ret = SendControlMsg(SET_LUM_CTL, PRESET_SHUTTER_FORMATTER, 2); | |
590 | } | |
591 | return ret; | |
592 | } | |
593 | @@ -787,12 +757,7 @@ | |
594 | buf = 0x00; /* active */ | |
595 | else | |
596 | buf = 0xFF; /* power save */ | |
597 | - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | |
598 | - SET_STATUS_CTL, | |
599 | - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
600 | - SET_POWER_SAVE_MODE_FORMATTER, | |
601 | - pdev->vcinterface, | |
602 | - &buf, 1, HZ / 2); | |
603 | + return SendControlMsg(SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER, 1); | |
604 | } | |
605 | ||
606 | ||
607 | @@ -801,32 +766,20 @@ | |
608 | ||
609 | static inline int pwc_restore_user(struct pwc_device *pdev) | |
610 | { | |
611 | - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | |
612 | - SET_STATUS_CTL, | |
613 | - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
614 | - RESTORE_USER_DEFAULTS_FORMATTER, | |
615 | - pdev->vcinterface, | |
616 | - NULL, 0, HZ / 2); | |
617 | + char buf; /* dummy */ | |
618 | + return SendControlMsg(SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, 0); | |
619 | } | |
620 | ||
621 | static inline int pwc_save_user(struct pwc_device *pdev) | |
622 | { | |
623 | - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | |
624 | - SET_STATUS_CTL, | |
625 | - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
626 | - SAVE_USER_DEFAULTS_FORMATTER, | |
627 | - pdev->vcinterface, | |
628 | - NULL, 0, HZ / 2); | |
629 | + char buf; /* dummy */ | |
630 | + return SendControlMsg(SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, 0); | |
631 | } | |
632 | ||
633 | static inline int pwc_restore_factory(struct pwc_device *pdev) | |
634 | { | |
635 | - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | |
636 | - SET_STATUS_CTL, | |
637 | - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
638 | - RESTORE_FACTORY_DEFAULTS_FORMATTER, | |
639 | - pdev->vcinterface, | |
640 | - NULL, 0, HZ / 2); | |
641 | + char buf; /* dummy */ | |
642 | + return SendControlMsg(SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, 0); | |
643 | } | |
644 | ||
645 | /* ************************************************* */ | |
646 | @@ -854,12 +807,7 @@ | |
647 | ||
648 | buf = mode & 0x07; /* just the lowest three bits */ | |
649 | ||
650 | - ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | |
651 | - SET_CHROM_CTL, | |
652 | - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
653 | - WB_MODE_FORMATTER, | |
654 | - pdev->vcinterface, | |
655 | - &buf, 1, HZ / 2); | |
656 | + ret = SendControlMsg(SET_CHROM_CTL, WB_MODE_FORMATTER, 1); | |
657 | ||
658 | if (ret < 0) | |
659 | return ret; | |
660 | @@ -871,12 +819,7 @@ | |
661 | unsigned char buf; | |
662 | int ret; | |
663 | ||
664 | - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), | |
665 | - GET_CHROM_CTL, | |
666 | - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
667 | - WB_MODE_FORMATTER, | |
668 | - pdev->vcinterface, | |
669 | - &buf, 1, HZ / 2); | |
670 | + ret = RecvControlMsg(GET_CHROM_CTL, WB_MODE_FORMATTER, 1); | |
671 | ||
672 | if (ret < 0) | |
673 | return ret; | |
674 | @@ -891,34 +834,21 @@ | |
675 | value = 0; | |
676 | if (value > 0xffff) | |
677 | value = 0xffff; | |
678 | - | |
679 | - /* only the msb are considered */ | |
680 | + /* only the msb is considered */ | |
681 | buf = value >> 8; | |
682 | - | |
683 | - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | |
684 | - SET_CHROM_CTL, | |
685 | - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
686 | - PRESET_MANUAL_RED_GAIN_FORMATTER, | |
687 | - pdev->vcinterface, | |
688 | - &buf, 1, HZ / 2); | |
689 | + return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1); | |
690 | } | |
691 | ||
692 | -static inline int pwc_get_red_gain(struct pwc_device *pdev) | |
693 | +static inline int pwc_get_red_gain(struct pwc_device *pdev, int *value) | |
694 | { | |
695 | unsigned char buf; | |
696 | int ret; | |
697 | ||
698 | - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), | |
699 | - GET_CHROM_CTL, | |
700 | - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
701 | - PRESET_MANUAL_RED_GAIN_FORMATTER, | |
702 | - pdev->vcinterface, | |
703 | - &buf, 1, HZ / 2); | |
704 | - | |
705 | + ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1); | |
706 | if (ret < 0) | |
707 | return ret; | |
708 | - | |
709 | - return (buf << 8); | |
710 | + *value = buf << 8; | |
711 | + return 0; | |
712 | } | |
713 | ||
714 | ||
715 | @@ -930,34 +860,21 @@ | |
716 | value = 0; | |
717 | if (value > 0xffff) | |
718 | value = 0xffff; | |
719 | - | |
720 | - /* linear mapping of 0..0xffff to -0x80..0x7f */ | |
721 | - buf = (value >> 8); | |
722 | - | |
723 | - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | |
724 | - SET_CHROM_CTL, | |
725 | - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
726 | - PRESET_MANUAL_BLUE_GAIN_FORMATTER, | |
727 | - pdev->vcinterface, | |
728 | - &buf, 1, HZ / 2); | |
729 | + /* only the msb is considered */ | |
730 | + buf = value >> 8; | |
731 | + return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1); | |
732 | } | |
733 | ||
734 | -static inline int pwc_get_blue_gain(struct pwc_device *pdev) | |
735 | +static inline int pwc_get_blue_gain(struct pwc_device *pdev, int *value) | |
736 | { | |
737 | unsigned char buf; | |
738 | int ret; | |
739 | ||
740 | - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), | |
741 | - GET_CHROM_CTL, | |
742 | - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
743 | - PRESET_MANUAL_BLUE_GAIN_FORMATTER, | |
744 | - pdev->vcinterface, | |
745 | - &buf, 1, HZ / 2); | |
746 | - | |
747 | + ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1); | |
748 | if (ret < 0) | |
749 | return ret; | |
750 | - | |
751 | - return (buf << 8); | |
752 | + *value = buf << 8; | |
753 | + return 0; | |
754 | } | |
755 | ||
756 | ||
757 | @@ -965,40 +882,28 @@ | |
758 | internal red/blue gains, which may be different from the manual | |
759 | gains set or read above. | |
760 | */ | |
761 | -static inline int pwc_read_red_gain(struct pwc_device *pdev) | |
762 | +static inline int pwc_read_red_gain(struct pwc_device *pdev, int *value) | |
763 | { | |
764 | unsigned char buf; | |
765 | int ret; | |
766 | ||
767 | - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), | |
768 | - GET_STATUS_CTL, | |
769 | - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
770 | - READ_RED_GAIN_FORMATTER, | |
771 | - pdev->vcinterface, | |
772 | - &buf, 1, HZ / 2); | |
773 | - | |
774 | + ret = RecvControlMsg(GET_STATUS_CTL, READ_RED_GAIN_FORMATTER, 1); | |
775 | if (ret < 0) | |
776 | return ret; | |
777 | - | |
778 | - return (buf << 8); | |
779 | + *value = buf << 8; | |
780 | + return 0; | |
781 | } | |
782 | ||
783 | -static inline int pwc_read_blue_gain(struct pwc_device *pdev) | |
784 | +static inline int pwc_read_blue_gain(struct pwc_device *pdev, int *value) | |
785 | { | |
786 | unsigned char buf; | |
787 | int ret; | |
788 | ||
789 | - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), | |
790 | - GET_STATUS_CTL, | |
791 | - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
792 | - READ_BLUE_GAIN_FORMATTER, | |
793 | - pdev->vcinterface, | |
794 | - &buf, 1, HZ / 2); | |
795 | - | |
796 | + ret = RecvControlMsg(GET_STATUS_CTL, READ_BLUE_GAIN_FORMATTER, 1); | |
797 | if (ret < 0) | |
798 | return ret; | |
799 | - | |
800 | - return (buf << 8); | |
801 | + *value = buf << 8; | |
802 | + return 0; | |
803 | } | |
804 | ||
805 | ||
806 | @@ -1008,28 +913,19 @@ | |
807 | ||
808 | /* useful range is 0x01..0x20 */ | |
809 | buf = speed / 0x7f0; | |
810 | - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | |
811 | - SET_CHROM_CTL, | |
812 | - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
813 | - AWB_CONTROL_SPEED_FORMATTER, | |
814 | - pdev->vcinterface, | |
815 | - &buf, 1, HZ / 2); | |
816 | + return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1); | |
817 | } | |
818 | ||
819 | -static inline int pwc_get_wb_speed(struct pwc_device *pdev) | |
820 | +static inline int pwc_get_wb_speed(struct pwc_device *pdev, int *value) | |
821 | { | |
822 | unsigned char buf; | |
823 | int ret; | |
824 | ||
825 | - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), | |
826 | - GET_CHROM_CTL, | |
827 | - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
828 | - AWB_CONTROL_SPEED_FORMATTER, | |
829 | - pdev->vcinterface, | |
830 | - &buf, 1, HZ / 2); | |
831 | + ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1); | |
832 | if (ret < 0) | |
833 | return ret; | |
834 | - return (buf * 0x7f0); | |
835 | + *value = buf * 0x7f0; | |
836 | + return 0; | |
837 | } | |
838 | ||
839 | ||
840 | @@ -1039,28 +935,19 @@ | |
841 | ||
842 | /* useful range is 0x01..0x3F */ | |
843 | buf = (delay >> 10); | |
844 | - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | |
845 | - SET_CHROM_CTL, | |
846 | - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
847 | - AWB_CONTROL_DELAY_FORMATTER, | |
848 | - pdev->vcinterface, | |
849 | - &buf, 1, HZ / 2); | |
850 | + return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1); | |
851 | } | |
852 | ||
853 | -static inline int pwc_get_wb_delay(struct pwc_device *pdev) | |
854 | +static inline int pwc_get_wb_delay(struct pwc_device *pdev, int *value) | |
855 | { | |
856 | unsigned char buf; | |
857 | int ret; | |
858 | ||
859 | - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), | |
860 | - GET_CHROM_CTL, | |
861 | - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
862 | - AWB_CONTROL_DELAY_FORMATTER, | |
863 | - pdev->vcinterface, | |
864 | - &buf, 1, HZ / 2); | |
865 | + ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1); | |
866 | if (ret < 0) | |
867 | return ret; | |
868 | - return (buf << 10); | |
869 | + *value = buf << 10; | |
870 | + return 0; | |
871 | } | |
872 | ||
873 | ||
874 | @@ -1115,12 +1002,7 @@ | |
875 | buf = 0xff; /* auto contour on */ | |
876 | else | |
877 | buf = 0x0; /* auto contour off */ | |
878 | - ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | |
879 | - SET_LUM_CTL, | |
880 | - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
881 | - AUTO_CONTOUR_FORMATTER, | |
882 | - pdev->vcinterface, | |
883 | - &buf, 1, HZ / 2); | |
884 | + ret = SendControlMsg(SET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1); | |
885 | if (ret < 0) | |
886 | return ret; | |
887 | ||
888 | @@ -1130,12 +1012,7 @@ | |
889 | contour = 0xffff; | |
890 | ||
891 | buf = (contour >> 10); /* contour preset is [0..3f] */ | |
892 | - ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | |
893 | - SET_LUM_CTL, | |
894 | - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
895 | - PRESET_CONTOUR_FORMATTER, | |
896 | - pdev->vcinterface, | |
897 | - &buf, 1, HZ / 2); | |
898 | + ret = SendControlMsg(SET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1); | |
899 | if (ret < 0) | |
900 | return ret; | |
901 | return 0; | |
902 | @@ -1146,26 +1023,16 @@ | |
903 | unsigned char buf; | |
904 | int ret; | |
905 | ||
906 | - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), | |
907 | - GET_LUM_CTL, | |
908 | - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
909 | - AUTO_CONTOUR_FORMATTER, | |
910 | - pdev->vcinterface, | |
911 | - &buf, 1, HZ / 2); | |
912 | + ret = RecvControlMsg(GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1); | |
913 | if (ret < 0) | |
914 | return ret; | |
915 | ||
916 | if (buf == 0) { | |
917 | /* auto mode off, query current preset value */ | |
918 | - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), | |
919 | - GET_LUM_CTL, | |
920 | - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
921 | - PRESET_CONTOUR_FORMATTER, | |
922 | - pdev->vcinterface, | |
923 | - &buf, 1, HZ / 2); | |
924 | + ret = RecvControlMsg(GET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1); | |
925 | if (ret < 0) | |
926 | return ret; | |
927 | - *contour = (buf << 10); | |
928 | + *contour = buf << 10; | |
929 | } | |
930 | else | |
931 | *contour = -1; | |
932 | @@ -1181,28 +1048,19 @@ | |
933 | buf = 0xff; | |
934 | else | |
935 | buf = 0x0; | |
936 | - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), | |
937 | - SET_LUM_CTL, | |
938 | - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
939 | - BACK_LIGHT_COMPENSATION_FORMATTER, | |
940 | - pdev->vcinterface, | |
941 | - &buf, 1, HZ / 2); | |
942 | + return SendControlMsg(SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1); | |
943 | } | |
944 | ||
945 | -static inline int pwc_get_backlight(struct pwc_device *pdev) | |
946 | +static inline int pwc_get_backlight(struct pwc_device *pdev, int *backlight) | |
947 | { | |
948 | int ret; | |
949 | unsigned char buf; | |
950 | ||
951 | - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), | |
952 | - GET_LUM_CTL, | |
953 | - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
954 | - BACK_LIGHT_COMPENSATION_FORMATTER, | |
955 | - pdev->vcinterface, | |
956 | - &buf, 1, HZ / 2); | |
957 | + ret = RecvControlMsg(GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1); | |
958 | if (ret < 0) | |
959 | return ret; | |
960 | - return buf; | |
961 | + *backlight = buf; | |
962 | + return 0; | |
963 | } | |
964 | ||
965 | ||
966 | @@ -1217,7 +1075,7 @@ | |
967 | return SendControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1); | |
968 | } | |
969 | ||
970 | -static inline int pwc_get_flicker(struct pwc_device *pdev) | |
971 | +static inline int pwc_get_flicker(struct pwc_device *pdev, int *flicker) | |
972 | { | |
973 | int ret; | |
974 | unsigned char buf; | |
975 | @@ -1225,7 +1083,8 @@ | |
976 | ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1); | |
977 | if (ret < 0) | |
978 | return ret; | |
979 | - return buf; | |
980 | + *flicker = buf; | |
981 | + return 0; | |
982 | } | |
983 | ||
984 | ||
985 | @@ -1241,7 +1100,7 @@ | |
986 | return SendControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1); | |
987 | } | |
988 | ||
989 | -static inline int pwc_get_dynamic_noise(struct pwc_device *pdev) | |
990 | +static inline int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise) | |
991 | { | |
992 | int ret; | |
993 | unsigned char buf; | |
994 | @@ -1249,14 +1108,15 @@ | |
995 | ret = RecvControlMsg(GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1); | |
996 | if (ret < 0) | |
997 | return ret; | |
998 | - return buf; | |
999 | + *noise = buf; | |
1000 | + return 0; | |
1001 | } | |
1002 | ||
1003 | int pwc_mpt_reset(struct pwc_device *pdev, int flags) | |
1004 | { | |
1005 | unsigned char buf; | |
1006 | ||
1007 | - buf = flags & 0x03; // only lower two bits are currently used | |
1008 | + buf = flags & 0x03; // only lower two bits are currently used | |
1009 | return SendControlMsg(SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, 1); | |
1010 | } | |
1011 | ||
1012 | @@ -1293,7 +1153,7 @@ | |
1013 | } | |
1014 | ||
1015 | ||
1016 | -int pwc_get_cmos_sensor(struct pwc_device *pdev) | |
1017 | +int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) | |
1018 | { | |
1019 | unsigned char buf; | |
1020 | int ret = -1, request; | |
1021 | @@ -1305,24 +1165,60 @@ | |
1022 | else | |
1023 | request = SENSOR_TYPE_FORMATTER2; | |
1024 | ||
1025 | - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), | |
1026 | - GET_STATUS_CTL, | |
1027 | - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | |
1028 | - request, | |
1029 | - pdev->vcinterface, | |
1030 | - &buf, 1, HZ / 2); | |
1031 | + ret = RecvControlMsg(GET_STATUS_CTL, request, 1); | |
1032 | if (ret < 0) | |
1033 | return ret; | |
1034 | if (pdev->type < 675) | |
1035 | - return buf | 0x100; | |
1036 | + *sensor = buf | 0x100; | |
1037 | else | |
1038 | - return buf; | |
1039 | + *sensor = buf; | |
1040 | + return 0; | |
1041 | } | |
1042 | ||
1043 | ||
1044 | /* End of Add-Ons */ | |
1045 | /* ************************************************* */ | |
1046 | ||
1047 | +/* Linux 2.5.something and 2.6 pass direct pointers to arguments of | |
1048 | + ioctl() calls. With 2.4, you have to do tedious copy_from_user() | |
1049 | + and copy_to_user() calls. With these macros we circumvent this, | |
1050 | + and let me maintain only one source file. The functionality is | |
1051 | + exactly the same otherwise. | |
1052 | + */ | |
1053 | + | |
1054 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) | |
1055 | + | |
1056 | +/* define local variable for arg */ | |
1057 | +#define ARG_DEF(ARG_type, ARG_name)\ | |
1058 | + ARG_type *ARG_name = arg; | |
1059 | +/* copy arg to local variable */ | |
1060 | +#define ARG_IN(ARG_name) /* nothing */ | |
1061 | +/* argument itself (referenced) */ | |
1062 | +#define ARGR(ARG_name) (*ARG_name) | |
1063 | +/* argument address */ | |
1064 | +#define ARGA(ARG_name) ARG_name | |
1065 | +/* copy local variable to arg */ | |
1066 | +#define ARG_OUT(ARG_name) /* nothing */ | |
1067 | + | |
1068 | +#else | |
1069 | + | |
1070 | +#define ARG_DEF(ARG_type, ARG_name)\ | |
1071 | + ARG_type ARG_name; | |
1072 | +#define ARG_IN(ARG_name)\ | |
1073 | + if (copy_from_user(&ARG_name, arg, sizeof(ARG_name))) {\ | |
1074 | + ret = -EFAULT;\ | |
1075 | + break;\ | |
1076 | + } | |
1077 | +#define ARGR(ARG_name) ARG_name | |
1078 | +#define ARGA(ARG_name) &ARG_name | |
1079 | +#define ARG_OUT(ARG_name)\ | |
1080 | + if (copy_to_user(arg, &ARG_name, sizeof(ARG_name))) {\ | |
1081 | + ret = -EFAULT;\ | |
1082 | + break;\ | |
1083 | + } | |
1084 | + | |
1085 | +#endif | |
1086 | + | |
1087 | int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) | |
1088 | { | |
1089 | int ret = 0; | |
1090 | @@ -1351,225 +1247,245 @@ | |
1091 | ||
1092 | case VIDIOCPWCSCQUAL: | |
1093 | { | |
1094 | - int *qual = arg; | |
1095 | + ARG_DEF(int, qual) | |
1096 | ||
1097 | - if (*qual < 0 || *qual > 3) | |
1098 | + ARG_IN(qual) | |
1099 | + if (ARGR(qual) < 0 || ARGR(qual) > 3) | |
1100 | ret = -EINVAL; | |
1101 | else | |
1102 | - ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, *qual, pdev->vsnapshot); | |
1103 | + ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot); | |
1104 | if (ret >= 0) | |
1105 | - pdev->vcompression = *qual; | |
1106 | + pdev->vcompression = ARGR(qual); | |
1107 | break; | |
1108 | } | |
1109 | ||
1110 | case VIDIOCPWCGCQUAL: | |
1111 | { | |
1112 | - int *qual = arg; | |
1113 | + ARG_DEF(int, qual) | |
1114 | ||
1115 | - *qual = pdev->vcompression; | |
1116 | + ARGR(qual) = pdev->vcompression; | |
1117 | + ARG_OUT(qual) | |
1118 | break; | |
1119 | } | |
1120 | ||
1121 | case VIDIOCPWCPROBE: | |
1122 | { | |
1123 | - struct pwc_probe *probe = arg; | |
1124 | + ARG_DEF(struct pwc_probe, probe) | |
1125 | ||
1126 | - strcpy(probe->name, pdev->vdev.name); | |
1127 | - probe->type = pdev->type; | |
1128 | + strcpy(ARGR(probe).name, pdev->vdev.name); | |
1129 | + ARGR(probe).type = pdev->type; | |
1130 | + ARG_OUT(probe) | |
1131 | break; | |
1132 | } | |
1133 | ||
1134 | case VIDIOCPWCSAGC: | |
1135 | { | |
1136 | - int *agc = arg; | |
1137 | + ARG_DEF(int, agc) | |
1138 | ||
1139 | - if (pwc_set_agc(pdev, *agc < 0 ? 1 : 0, *agc)) | |
1140 | + ARG_IN(agc) | |
1141 | + if (pwc_set_agc(pdev, ARGR(agc) < 0 ? 1 : 0, ARGR(agc))) | |
1142 | ret = -EINVAL; | |
1143 | break; | |
1144 | } | |
1145 | ||
1146 | case VIDIOCPWCGAGC: | |
1147 | { | |
1148 | - int *agc = arg; | |
1149 | + ARG_DEF(int, agc) | |
1150 | ||
1151 | - if (pwc_get_agc(pdev, agc)) | |
1152 | + if (pwc_get_agc(pdev, ARGA(agc))) | |
1153 | ret = -EINVAL; | |
1154 | + ARG_OUT(agc) | |
1155 | break; | |
1156 | } | |
1157 | ||
1158 | case VIDIOCPWCSSHUTTER: | |
1159 | { | |
1160 | - int *shutter_speed = arg; | |
1161 | + ARG_DEF(int, shutter_speed) | |
1162 | ||
1163 | - ret = pwc_set_shutter_speed(pdev, *shutter_speed < 0 ? 1 : 0, *shutter_speed); | |
1164 | + ARG_IN(shutter_speed) | |
1165 | + ret = pwc_set_shutter_speed(pdev, ARGR(shutter_speed) < 0 ? 1 : 0, ARGR(shutter_speed)); | |
1166 | break; | |
1167 | } | |
1168 | ||
1169 | case VIDIOCPWCSAWB: | |
1170 | { | |
1171 | - struct pwc_whitebalance *wb = arg; | |
1172 | + ARG_DEF(struct pwc_whitebalance, wb) | |
1173 | ||
1174 | - ret = pwc_set_awb(pdev, wb->mode); | |
1175 | - if (ret >= 0 && wb->mode == PWC_WB_MANUAL) { | |
1176 | - pwc_set_red_gain(pdev, wb->manual_red); | |
1177 | - pwc_set_blue_gain(pdev, wb->manual_blue); | |
1178 | + ARG_IN(wb) | |
1179 | + ret = pwc_set_awb(pdev, ARGR(wb).mode); | |
1180 | + if (ret >= 0 && ARGR(wb).mode == PWC_WB_MANUAL) { | |
1181 | + pwc_set_red_gain(pdev, ARGR(wb).manual_red); | |
1182 | + pwc_set_blue_gain(pdev, ARGR(wb).manual_blue); | |
1183 | } | |
1184 | break; | |
1185 | } | |
1186 | ||
1187 | case VIDIOCPWCGAWB: | |
1188 | { | |
1189 | - struct pwc_whitebalance *wb = arg; | |
1190 | + ARG_DEF(struct pwc_whitebalance, wb) | |
1191 | ||
1192 | - memset(wb, 0, sizeof(*wb)); | |
1193 | - wb->mode = pwc_get_awb(pdev); | |
1194 | - if (wb->mode < 0) | |
1195 | + memset(ARGA(wb), 0, sizeof(struct pwc_whitebalance)); | |
1196 | + ARGR(wb).mode = pwc_get_awb(pdev); | |
1197 | + if (ARGR(wb).mode < 0) | |
1198 | ret = -EINVAL; | |
1199 | else { | |
1200 | - if (wb->mode == PWC_WB_MANUAL) { | |
1201 | - wb->manual_red = pwc_get_red_gain(pdev); | |
1202 | - wb->manual_blue = pwc_get_blue_gain(pdev); | |
1203 | + if (ARGR(wb).mode == PWC_WB_MANUAL) { | |
1204 | + ret = pwc_get_red_gain(pdev, &ARGR(wb).manual_red); | |
1205 | + if (ret < 0) | |
1206 | + break; | |
1207 | + ret = pwc_get_blue_gain(pdev, &ARGR(wb).manual_blue); | |
1208 | + if (ret < 0) | |
1209 | + break; | |
1210 | } | |
1211 | - if (wb->mode == PWC_WB_AUTO) { | |
1212 | - wb->read_red = pwc_read_red_gain(pdev); | |
1213 | - wb->read_blue = pwc_read_blue_gain(pdev); | |
1214 | + if (ARGR(wb).mode == PWC_WB_AUTO) { | |
1215 | + ret = pwc_read_red_gain(pdev, &ARGR(wb).read_red); | |
1216 | + if (ret < 0) | |
1217 | + break; | |
1218 | + ret =pwc_read_blue_gain(pdev, &ARGR(wb).read_blue); | |
1219 | + if (ret < 0) | |
1220 | + break; | |
1221 | } | |
1222 | } | |
1223 | + ARG_OUT(wb) | |
1224 | break; | |
1225 | } | |
1226 | ||
1227 | case VIDIOCPWCSAWBSPEED: | |
1228 | { | |
1229 | - struct pwc_wb_speed *wbs = arg; | |
1230 | + ARG_DEF(struct pwc_wb_speed, wbs) | |
1231 | ||
1232 | - if (wbs->control_speed > 0) { | |
1233 | - ret = pwc_set_wb_speed(pdev, wbs->control_speed); | |
1234 | + if (ARGR(wbs).control_speed > 0) { | |
1235 | + ret = pwc_set_wb_speed(pdev, ARGR(wbs).control_speed); | |
1236 | } | |
1237 | - if (wbs->control_delay > 0) { | |
1238 | - ret = pwc_set_wb_delay(pdev, wbs->control_delay); | |
1239 | + if (ARGR(wbs).control_delay > 0) { | |
1240 | + ret = pwc_set_wb_delay(pdev, ARGR(wbs).control_delay); | |
1241 | } | |
1242 | break; | |
1243 | } | |
1244 | ||
1245 | case VIDIOCPWCGAWBSPEED: | |
1246 | { | |
1247 | - struct pwc_wb_speed *wbs = arg; | |
1248 | + ARG_DEF(struct pwc_wb_speed, wbs) | |
1249 | ||
1250 | - ret = pwc_get_wb_speed(pdev); | |
1251 | + ret = pwc_get_wb_speed(pdev, &ARGR(wbs).control_speed); | |
1252 | if (ret < 0) | |
1253 | break; | |
1254 | - wbs->control_speed = ret; | |
1255 | - ret = pwc_get_wb_delay(pdev); | |
1256 | + ret = pwc_get_wb_delay(pdev, &ARGR(wbs).control_delay); | |
1257 | if (ret < 0) | |
1258 | break; | |
1259 | - wbs->control_delay = ret; | |
1260 | + ARG_OUT(wbs) | |
1261 | break; | |
1262 | } | |
1263 | ||
1264 | case VIDIOCPWCSLED: | |
1265 | { | |
1266 | - struct pwc_leds *leds = arg; | |
1267 | + ARG_DEF(struct pwc_leds, leds) | |
1268 | ||
1269 | - ret = pwc_set_leds(pdev, leds->led_on, leds->led_off); | |
1270 | + ARG_IN(leds) | |
1271 | + ret = pwc_set_leds(pdev, ARGR(leds).led_on, ARGR(leds).led_off); | |
1272 | break; | |
1273 | } | |
1274 | ||
1275 | ||
1276 | case VIDIOCPWCGLED: | |
1277 | { | |
1278 | - struct pwc_leds *leds = arg; | |
1279 | + ARG_DEF(struct pwc_leds, leds) | |
1280 | ||
1281 | - ret = pwc_get_leds(pdev, &leds->led_on, &leds->led_off); | |
1282 | + ret = pwc_get_leds(pdev, &ARGR(leds).led_on, &ARGR(leds).led_off); | |
1283 | + ARG_OUT(leds) | |
1284 | break; | |
1285 | } | |
1286 | ||
1287 | case VIDIOCPWCSCONTOUR: | |
1288 | { | |
1289 | - int *contour = arg; | |
1290 | + ARG_DEF(int, contour) | |
1291 | ||
1292 | - ret = pwc_set_contour(pdev, *contour); | |
1293 | + ARG_IN(contour) | |
1294 | + ret = pwc_set_contour(pdev, ARGR(contour)); | |
1295 | break; | |
1296 | } | |
1297 | ||
1298 | case VIDIOCPWCGCONTOUR: | |
1299 | { | |
1300 | - int *contour = arg; | |
1301 | + ARG_DEF(int, contour) | |
1302 | ||
1303 | - ret = pwc_get_contour(pdev, contour); | |
1304 | + ret = pwc_get_contour(pdev, ARGA(contour)); | |
1305 | + ARG_OUT(contour) | |
1306 | break; | |
1307 | } | |
1308 | ||
1309 | case VIDIOCPWCSBACKLIGHT: | |
1310 | { | |
1311 | - int *backlight = arg; | |
1312 | + ARG_DEF(int, backlight) | |
1313 | ||
1314 | - ret = pwc_set_backlight(pdev, *backlight); | |
1315 | + ARG_IN(backlight) | |
1316 | + ret = pwc_set_backlight(pdev, ARGR(backlight)); | |
1317 | break; | |
1318 | } | |
1319 | ||
1320 | case VIDIOCPWCGBACKLIGHT: | |
1321 | { | |
1322 | - int *backlight = arg; | |
1323 | + ARG_DEF(int, backlight) | |
1324 | ||
1325 | - ret = pwc_get_backlight(pdev); | |
1326 | - if (ret >= 0) | |
1327 | - *backlight = ret; | |
1328 | + ret = pwc_get_backlight(pdev, ARGA(backlight)); | |
1329 | + ARG_OUT(backlight) | |
1330 | break; | |
1331 | } | |
1332 | ||
1333 | case VIDIOCPWCSFLICKER: | |
1334 | { | |
1335 | - int *flicker = arg; | |
1336 | + ARG_DEF(int, flicker) | |
1337 | ||
1338 | - ret = pwc_set_flicker(pdev, *flicker); | |
1339 | + ARG_IN(flicker) | |
1340 | + ret = pwc_set_flicker(pdev, ARGR(flicker)); | |
1341 | break; | |
1342 | } | |
1343 | ||
1344 | case VIDIOCPWCGFLICKER: | |
1345 | { | |
1346 | - int *flicker = arg; | |
1347 | + ARG_DEF(int, flicker) | |
1348 | ||
1349 | - ret = pwc_get_flicker(pdev); | |
1350 | - if (ret >= 0) | |
1351 | - *flicker = ret; | |
1352 | + ret = pwc_get_flicker(pdev, ARGA(flicker)); | |
1353 | + ARG_OUT(flicker) | |
1354 | break; | |
1355 | } | |
1356 | ||
1357 | case VIDIOCPWCSDYNNOISE: | |
1358 | { | |
1359 | - int *dynnoise = arg; | |
1360 | + ARG_DEF(int, dynnoise) | |
1361 | ||
1362 | - ret = pwc_set_dynamic_noise(pdev, *dynnoise); | |
1363 | + ARG_IN(dynnoise) | |
1364 | + ret = pwc_set_dynamic_noise(pdev, ARGR(dynnoise)); | |
1365 | break; | |
1366 | } | |
1367 | ||
1368 | case VIDIOCPWCGDYNNOISE: | |
1369 | { | |
1370 | - int *dynnoise = arg; | |
1371 | + ARG_DEF(int, dynnoise) | |
1372 | ||
1373 | - ret = pwc_get_dynamic_noise(pdev); | |
1374 | - if (ret < 0) | |
1375 | - break; | |
1376 | - *dynnoise = ret; | |
1377 | + ret = pwc_get_dynamic_noise(pdev, ARGA(dynnoise)); | |
1378 | + ARG_OUT(dynnoise); | |
1379 | break; | |
1380 | } | |
1381 | ||
1382 | case VIDIOCPWCGREALSIZE: | |
1383 | { | |
1384 | - struct pwc_imagesize *size = arg; | |
1385 | + ARG_DEF(struct pwc_imagesize, size) | |
1386 | ||
1387 | - size->width = pdev->image.x; | |
1388 | - size->height = pdev->image.y; | |
1389 | + ARGR(size).width = pdev->image.x; | |
1390 | + ARGR(size).height = pdev->image.y; | |
1391 | + ARG_OUT(size) | |
1392 | break; | |
1393 | } | |
1394 | ||
1395 | case VIDIOCPWCMPTRESET: | |
1396 | { | |
1397 | - int *flags = arg; | |
1398 | - | |
1399 | if (pdev->features & FEATURE_MOTOR_PANTILT) | |
1400 | { | |
1401 | - ret = pwc_mpt_reset(pdev, *flags); | |
1402 | + ARG_DEF(int, flags) | |
1403 | + | |
1404 | + ARG_IN(flags) | |
1405 | + ret = pwc_mpt_reset(pdev, ARGR(flags)); | |
1406 | if (ret >= 0) | |
1407 | { | |
1408 | pdev->pan_angle = 0; | |
1409 | @@ -1582,11 +1498,15 @@ | |
1410 | } | |
1411 | break; | |
1412 | } | |
1413 | + | |
1414 | case VIDIOCPWCMPTGRANGE: | |
1415 | { | |
1416 | if (pdev->features & FEATURE_MOTOR_PANTILT) | |
1417 | { | |
1418 | - memcpy(arg, &pdev->angle_range, sizeof(struct pwc_mpt_range)); | |
1419 | + ARG_DEF(struct pwc_mpt_range, range) | |
1420 | + | |
1421 | + ARGR(range) = pdev->angle_range; | |
1422 | + ARG_OUT(range) | |
1423 | } | |
1424 | else | |
1425 | { | |
1426 | @@ -1597,23 +1517,25 @@ | |
1427 | ||
1428 | case VIDIOCPWCMPTSANGLE: | |
1429 | { | |
1430 | - struct pwc_mpt_angles *angles = arg; | |
1431 | int new_pan, new_tilt; | |
1432 | ||
1433 | if (pdev->features & FEATURE_MOTOR_PANTILT) | |
1434 | { | |
1435 | + ARG_DEF(struct pwc_mpt_angles, angles) | |
1436 | + | |
1437 | + ARG_IN(angles) | |
1438 | /* The camera can only set relative angles, so | |
1439 | do some calculations when getting an absolute angle . | |
1440 | */ | |
1441 | - if (angles->absolute) | |
1442 | + if (ARGR(angles).absolute) | |
1443 | { | |
1444 | - new_pan = angles->pan; | |
1445 | - new_tilt = angles->tilt; | |
1446 | + new_pan = ARGR(angles).pan; | |
1447 | + new_tilt = ARGR(angles).tilt; | |
1448 | } | |
1449 | else | |
1450 | { | |
1451 | - new_pan = pdev->pan_angle + angles->pan; | |
1452 | - new_tilt = pdev->tilt_angle + angles->tilt; | |
1453 | + new_pan = pdev->pan_angle + ARGR(angles).pan; | |
1454 | + new_tilt = pdev->tilt_angle + ARGR(angles).tilt; | |
1455 | } | |
1456 | /* check absolute ranges */ | |
1457 | if (new_pan < pdev->angle_range.pan_min || | |
1458 | @@ -1649,17 +1571,19 @@ | |
1459 | ret = -ENXIO; | |
1460 | } | |
1461 | break; | |
1462 | - } | |
1463 | - | |
1464 | + } | |
1465 | + | |
1466 | case VIDIOCPWCMPTGANGLE: | |
1467 | { | |
1468 | - struct pwc_mpt_angles *angles = arg; | |
1469 | ||
1470 | if (pdev->features & FEATURE_MOTOR_PANTILT) | |
1471 | { | |
1472 | - angles->absolute = 1; | |
1473 | - angles->pan = pdev->pan_angle; | |
1474 | - angles->tilt = pdev->tilt_angle; | |
1475 | + ARG_DEF(struct pwc_mpt_angles, angles) | |
1476 | + | |
1477 | + ARGR(angles).absolute = 1; | |
1478 | + ARGR(angles).pan = pdev->pan_angle; | |
1479 | + ARGR(angles).tilt = pdev->tilt_angle; | |
1480 | + ARG_OUT(angles) | |
1481 | } | |
1482 | else | |
1483 | { | |
1484 | @@ -1670,19 +1594,34 @@ | |
1485 | ||
1486 | case VIDIOCPWCMPTSTATUS: | |
1487 | { | |
1488 | - struct pwc_mpt_status *status = arg; | |
1489 | - | |
1490 | if (pdev->features & FEATURE_MOTOR_PANTILT) | |
1491 | { | |
1492 | - ret = pwc_mpt_get_status(pdev, status); | |
1493 | + ARG_DEF(struct pwc_mpt_status, status) | |
1494 | + | |
1495 | + ret = pwc_mpt_get_status(pdev, ARGA(status)); | |
1496 | + ARG_OUT(status) | |
1497 | } | |
1498 | else | |
1499 | { | |
1500 | ret = -ENXIO; | |
1501 | } | |
1502 | - break; | |
1503 | - } | |
1504 | - | |
1505 | + break; | |
1506 | + } | |
1507 | + | |
1508 | + case VIDIOCPWCGVIDCMD: | |
1509 | + { | |
1510 | + ARG_DEF(struct pwc_video_command, cmd); | |
1511 | + | |
1512 | + ARGR(cmd).type = pdev->type; | |
1513 | + ARGR(cmd).release = pdev->release; | |
1514 | + ARGR(cmd).command_len = pdev->cmd_len; | |
1515 | + memcpy(&ARGR(cmd).command_buf, pdev->cmd_buf, pdev->cmd_len); | |
1516 | + ARGR(cmd).bandlength = pdev->vbandlength; | |
1517 | + ARGR(cmd).frame_size = pdev->frame_size; | |
1518 | + ARG_OUT(cmd) | |
1519 | + break; | |
1520 | + } | |
1521 | + | |
1522 | default: | |
1523 | ret = -ENOIOCTLCMD; | |
1524 | break; | |
1525 | diff -Nur --exclude '*.orig' linux-2.6.6.org/drivers/usb/media/pwc-if.c linux-2.6.6/drivers/usb/media/pwc-if.c | |
1526 | --- linux-2.6.6.org/drivers/usb/media/pwc-if.c 2004-05-10 04:33:10.000000000 +0200 | |
1527 | +++ linux-2.6.6/drivers/usb/media/pwc-if.c 2004-05-07 00:52:23.000000000 +0200 | |
1528 | @@ -1,4 +1,4 @@ | |
1529 | -/* Linux driver for Philips webcam | |
1530 | +/* Linux driver for Philips webcam | |
1531 | USB and Video4Linux interface part. | |
1532 | (C) 1999-2003 Nemosoft Unv. | |
1533 | ||
1534 | @@ -42,7 +42,7 @@ | |
1535 | - Alistar Moire: QuickCam 3000 Pro device/product ID | |
1536 | - Tony Hoyle: Creative Labs Webcam 5 device/product ID | |
1537 | - Mark Burazin: solving hang in VIDIOCSYNC when camera gets unplugged | |
1538 | - - Jk Fang: SOTEC Afina Eye ID | |
1539 | + - Jk Fang: Sotec Afina Eye ID | |
1540 | - Xavier Roche: QuickCam Pro 4000 ID | |
1541 | - Jens Knudsen: QuickCam Zoom ID | |
1542 | - J. Debert: QuickCam for Notebooks ID | |
1543 | @@ -90,6 +90,7 @@ | |
1544 | { USB_DEVICE(0x041E, 0x400C) }, /* Creative Webcam 5 */ | |
1545 | { USB_DEVICE(0x041E, 0x4011) }, /* Creative Webcam Pro Ex */ | |
1546 | { USB_DEVICE(0x04CC, 0x8116) }, /* Afina Eye */ | |
1547 | + { USB_DEVICE(0x06BE, 0x8116) }, /* new Afina Eye */ | |
1548 | { USB_DEVICE(0x0d81, 0x1910) }, /* Visionite */ | |
1549 | { USB_DEVICE(0x0d81, 0x1900) }, | |
1550 | { } | |
1551 | @@ -129,7 +130,7 @@ | |
1552 | ||
1553 | static int pwc_video_open(struct inode *inode, struct file *file); | |
1554 | static int pwc_video_close(struct inode *inode, struct file *file); | |
1555 | -static int pwc_video_release(struct video_device *); | |
1556 | +static void pwc_video_release(struct video_device *); | |
1557 | static ssize_t pwc_video_read(struct file *file, char *buf, | |
1558 | size_t count, loff_t *ppos); | |
1559 | static unsigned int pwc_video_poll(struct file *file, poll_table *wait); | |
1560 | @@ -259,7 +260,7 @@ | |
1561 | return -ENXIO; | |
1562 | } | |
1563 | #endif | |
1564 | - /* Allocate Isochronous pipe buffers */ | |
1565 | + /* Allocate Isochronuous pipe buffers */ | |
1566 | for (i = 0; i < MAX_ISO_BUFS; i++) { | |
1567 | if (pdev->sbuf[i].data == NULL) { | |
1568 | kbuf = kmalloc(ISO_BUFFER_SIZE, GFP_KERNEL); | |
1569 | @@ -444,7 +445,7 @@ | |
1570 | { | |
1571 | int ret; | |
1572 | unsigned long flags; | |
1573 | - | |
1574 | + | |
1575 | ret = 0; | |
1576 | spin_lock_irqsave(&pdev->ptrlock, flags); | |
1577 | if (pdev->fill_frame != NULL) { | |
1578 | @@ -489,7 +490,7 @@ | |
1579 | ||
1580 | /** | |
1581 | \brief Reset all buffers, pointers and lists, except for the image_used[] buffer. | |
1582 | - | |
1583 | + | |
1584 | If the image_used[] buffer is cleared too, mmap()/VIDIOCSYNC will run into trouble. | |
1585 | */ | |
1586 | static void pwc_reset_buffers(struct pwc_device *pdev) | |
1587 | @@ -526,7 +527,7 @@ | |
1588 | { | |
1589 | int ret = 0; | |
1590 | unsigned long flags; | |
1591 | - | |
1592 | + | |
1593 | spin_lock_irqsave(&pdev->ptrlock, flags); | |
1594 | /* First grab our read_frame; this is removed from all lists, so | |
1595 | we can release the lock after this without problems */ | |
1596 | @@ -549,7 +550,7 @@ | |
1597 | Trace(TRACE_SEQUENCE, "Decompressing frame %d\n", pdev->read_frame->sequence); | |
1598 | #endif | |
1599 | /* Decompression is a lenghty process, so it's outside of the lock. | |
1600 | - This gives the isoc_handler the opportunity to fill more frames | |
1601 | + This gives the isoc_handler the opportunity to fill more frames | |
1602 | in the mean time. | |
1603 | */ | |
1604 | spin_unlock_irqrestore(&pdev->ptrlock, flags); | |
1605 | @@ -644,7 +645,7 @@ | |
1606 | else { | |
1607 | fillptr = fbuf->data + fbuf->filled; | |
1608 | } | |
1609 | - | |
1610 | + | |
1611 | /* Reset ISOC error counter. We did get here, after all. */ | |
1612 | pdev->visoc_errors = 0; | |
1613 | ||
1614 | @@ -663,8 +664,8 @@ | |
1615 | pdev->vsync = 2; | |
1616 | ||
1617 | /* ...copy data to frame buffer, if possible */ | |
1618 | - if (flen + fbuf->filled > pdev->frame_size) { | |
1619 | - Trace(TRACE_FLOW, "Frame buffer overflow (flen = %d, frame_size = %d).\n", flen, pdev->frame_size); | |
1620 | + if (flen + fbuf->filled > pdev->frame_total_size) { | |
1621 | + Trace(TRACE_FLOW, "Frame buffer overflow (flen = %d, frame_total_size = %d).\n", flen, pdev->frame_total_size); | |
1622 | pdev->vsync = 0; /* Hmm, let's wait for an EOF (end-of-frame) */ | |
1623 | pdev->vframes_error++; | |
1624 | } | |
1625 | @@ -729,7 +730,7 @@ | |
1626 | pdev->drop_frames--; | |
1627 | else { | |
1628 | /* Check for underflow first */ | |
1629 | - if (fbuf->filled < pdev->frame_size) { | |
1630 | + if (fbuf->filled < pdev->frame_total_size) { | |
1631 | Trace(TRACE_FLOW, "Frame buffer underflow (%d bytes); discarded.\n", fbuf->filled); | |
1632 | pdev->vframes_error++; | |
1633 | } | |
1634 | @@ -815,7 +816,7 @@ | |
1635 | ||
1636 | if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) { | |
1637 | Err("Failed to find packet size for video endpoint in current alternate setting.\n"); | |
1638 | - return -ENFILE; /* Odd error, that should be noticeable */ | |
1639 | + return -ENFILE; /* Odd error, that should be noticable */ | |
1640 | } | |
1641 | ||
1642 | /* Set alternate interface */ | |
1643 | @@ -872,7 +873,7 @@ | |
1644 | if (ret) | |
1645 | Err("isoc_init() submit_urb %d failed with error %d\n", i, ret); | |
1646 | else | |
1647 | - Trace(TRACE_OPEN, "URB 0x%p submitted.\n", pdev->sbuf[i].urb); | |
1648 | + Trace(TRACE_MEMORY, "URB 0x%p submitted.\n", pdev->sbuf[i].urb); | |
1649 | } | |
1650 | ||
1651 | /* All is done... */ | |
1652 | @@ -884,7 +885,7 @@ | |
1653 | static void pwc_isoc_cleanup(struct pwc_device *pdev) | |
1654 | { | |
1655 | int i; | |
1656 | - | |
1657 | + | |
1658 | Trace(TRACE_OPEN, ">> pwc_isoc_cleanup()\n"); | |
1659 | if (pdev == NULL) | |
1660 | return; | |
1661 | @@ -935,9 +936,9 @@ | |
1662 | Trace(TRACE_FLOW, "pwc_set_video_mode attempt 2 failed.\n"); | |
1663 | } | |
1664 | } | |
1665 | - if (start == 0) | |
1666 | + if (start == 0) | |
1667 | { | |
1668 | - if (pwc_isoc_init(pdev) < 0) | |
1669 | + if (pwc_isoc_init(pdev) < 0) | |
1670 | { | |
1671 | Info("Failed to restart ISOC transfers in pwc_try_video_mode.\n"); | |
1672 | ret = -EAGAIN; /* let's try again, who knows if it works a second time */ | |
1673 | @@ -970,24 +971,28 @@ | |
1674 | Trace(TRACE_OPEN, "Doing first time initialization.\n"); | |
1675 | pdev->usb_init = 1; | |
1676 | ||
1677 | - if (pwc_trace & TRACE_OPEN) { | |
1678 | + if (pwc_trace & TRACE_OPEN) | |
1679 | + { | |
1680 | /* Query sensor type */ | |
1681 | const char *sensor_type = NULL; | |
1682 | + int ret; | |
1683 | ||
1684 | - i = pwc_get_cmos_sensor(pdev); | |
1685 | - switch(i) { | |
1686 | - case -1: /* Unknown, show nothing */; break; | |
1687 | - case 0x00: sensor_type = "Hyundai CMOS sensor"; break; | |
1688 | - case 0x20: sensor_type = "Sony CCD sensor + TDA8787"; break; | |
1689 | - case 0x2E: sensor_type = "Sony CCD sensor + Exas 98L59"; break; | |
1690 | - case 0x2F: sensor_type = "Sony CCD sensor + ADI 9804"; break; | |
1691 | - case 0x30: sensor_type = "Sharp CCD sensor + TDA8787"; break; | |
1692 | - case 0x3E: sensor_type = "Sharp CCD sensor + Exas 98L59"; break; | |
1693 | - case 0x3F: sensor_type = "Sharp CCD sensor + ADI 9804"; break; | |
1694 | - case 0x40: sensor_type = "UPA 1021 sensor"; break; | |
1695 | - case 0x100: sensor_type = "VGA sensor"; break; | |
1696 | - case 0x101: sensor_type = "PAL MR sensor"; break; | |
1697 | - default: sensor_type = "unknown type of sensor"; break; | |
1698 | + ret = pwc_get_cmos_sensor(pdev, &i); | |
1699 | + if (ret >= 0) | |
1700 | + { | |
1701 | + switch(i) { | |
1702 | + case 0x00: sensor_type = "Hyundai CMOS sensor"; break; | |
1703 | + case 0x20: sensor_type = "Sony CCD sensor + TDA8787"; break; | |
1704 | + case 0x2E: sensor_type = "Sony CCD sensor + Exas 98L59"; break; | |
1705 | + case 0x2F: sensor_type = "Sony CCD sensor + ADI 9804"; break; | |
1706 | + case 0x30: sensor_type = "Sharp CCD sensor + TDA8787"; break; | |
1707 | + case 0x3E: sensor_type = "Sharp CCD sensor + Exas 98L59"; break; | |
1708 | + case 0x3F: sensor_type = "Sharp CCD sensor + ADI 9804"; break; | |
1709 | + case 0x40: sensor_type = "UPA 1021 sensor"; break; | |
1710 | + case 0x100: sensor_type = "VGA sensor"; break; | |
1711 | + case 0x101: sensor_type = "PAL MR sensor"; break; | |
1712 | + default: sensor_type = "unknown type of sensor"; break; | |
1713 | + } | |
1714 | } | |
1715 | if (sensor_type != NULL) | |
1716 | Info("This %s camera is equipped with a %s (%d).\n", pdev->vdev.name, sensor_type, i); | |
1717 | @@ -1035,6 +1040,7 @@ | |
1718 | ||
1719 | /* Set some defaults */ | |
1720 | pdev->vsnapshot = 0; | |
1721 | + | |
1722 | /* Start iso pipe for video; first try the last used video size | |
1723 | (or the default one); if that fails try QCIF/10 or QSIF/10; | |
1724 | it that fails too, give up. | |
1725 | @@ -1088,7 +1094,7 @@ | |
1726 | ||
1727 | /* Dump statistics, but only if a reasonable amount of frames were | |
1728 | processed (to prevent endless log-entries in case of snap-shot | |
1729 | - programs) | |
1730 | + programs) | |
1731 | */ | |
1732 | if (pdev->vframe_count > 20) | |
1733 | Info("Closing video device: %d frames received, dumped %d frames, %d frames with errors.\n", pdev->vframe_count, pdev->vframes_dumped, pdev->vframes_error); | |
1734 | @@ -1109,7 +1115,7 @@ | |
1735 | Info("Failed to set LED on/off time.\n"); | |
1736 | if (power_save) { | |
1737 | i = pwc_camera_power(pdev, 0); | |
1738 | - if (i < 0) | |
1739 | + if (i < 0) | |
1740 | Err("Failed to power down camera (%d)\n", i); | |
1741 | } | |
1742 | } | |
1743 | @@ -1118,9 +1124,9 @@ | |
1744 | return 0; | |
1745 | } | |
1746 | ||
1747 | -static int pwc_video_release(struct video_device *vfd) | |
1748 | +static void pwc_video_release(struct video_device *vfd) | |
1749 | { | |
1750 | - Trace(TRACE_OPEN, "pwc_video_release() called. Now what?\n"); | |
1751 | + Trace(TRACE_OPEN, "pwc_video_release() called. Nothing to do here. Honestly.\n"); | |
1752 | } | |
1753 | ||
1754 | ||
1755 | @@ -1143,6 +1149,7 @@ | |
1756 | struct pwc_device *pdev; | |
1757 | int noblock = file->f_flags & O_NONBLOCK; | |
1758 | DECLARE_WAITQUEUE(wait, current); | |
1759 | + int bytes_to_read; | |
1760 | ||
1761 | Trace(TRACE_READ, "video_read(0x%p, %p, %d) called.\n", vdev, buf, count); | |
1762 | if (vdev == NULL) | |
1763 | @@ -1179,20 +1186,25 @@ | |
1764 | } | |
1765 | remove_wait_queue(&pdev->frameq, &wait); | |
1766 | set_current_state(TASK_RUNNING); | |
1767 | - | |
1768 | + | |
1769 | /* Decompress and release frame */ | |
1770 | if (pwc_handle_frame(pdev)) | |
1771 | return -EFAULT; | |
1772 | } | |
1773 | ||
1774 | Trace(TRACE_READ, "Copying data to user space.\n"); | |
1775 | + if (pdev->vpalette == VIDEO_PALETTE_RAW) | |
1776 | + bytes_to_read = pdev->frame_size; | |
1777 | + else | |
1778 | + bytes_to_read = pdev->view.size; | |
1779 | + | |
1780 | /* copy bytes to user space; we allow for partial reads */ | |
1781 | - if (count + pdev->image_read_pos > pdev->view.size) | |
1782 | - count = pdev->view.size - pdev->image_read_pos; | |
1783 | + if (count + pdev->image_read_pos > bytes_to_read) | |
1784 | + count = bytes_to_read - pdev->image_read_pos; | |
1785 | if (copy_to_user(buf, pdev->image_ptr[pdev->fill_image] + pdev->image_read_pos, count)) | |
1786 | return -EFAULT; | |
1787 | pdev->image_read_pos += count; | |
1788 | - if (pdev->image_read_pos >= pdev->view.size) { /* All data has been read */ | |
1789 | + if (pdev->image_read_pos >= bytes_to_read) { /* All data has been read */ | |
1790 | pdev->image_read_pos = 0; | |
1791 | pwc_next_image(pdev); | |
1792 | } | |
1793 | @@ -1264,7 +1276,7 @@ | |
1794 | } | |
1795 | ||
1796 | case VIDIOCSCHAN: | |
1797 | - { | |
1798 | + { | |
1799 | /* The spec says the argument is an integer, but | |
1800 | the bttv driver uses a video_channel arg, which | |
1801 | makes sense becasue it also has the norm flag. | |
1802 | @@ -1282,8 +1294,6 @@ | |
1803 | struct video_picture *p = arg; | |
1804 | int val; | |
1805 | ||
1806 | - p->colour = 0x8000; | |
1807 | - p->hue = 0x8000; | |
1808 | val = pwc_get_brightness(pdev); | |
1809 | if (val >= 0) | |
1810 | p->brightness = val; | |
1811 | @@ -1306,11 +1316,11 @@ | |
1812 | else | |
1813 | p->colour = 0xffff; | |
1814 | p->depth = 24; | |
1815 | - p->palette = VIDEO_PALETTE_YUV420P; | |
1816 | + p->palette = pdev->vpalette; | |
1817 | p->hue = 0xFFFF; /* N/A */ | |
1818 | break; | |
1819 | } | |
1820 | - | |
1821 | + | |
1822 | case VIDIOCSPICT: | |
1823 | { | |
1824 | struct video_picture *p = arg; | |
1825 | @@ -1322,13 +1332,22 @@ | |
1826 | is used exactly once in the uncompress | |
1827 | routine. | |
1828 | */ | |
1829 | - if (p->palette && p->palette != VIDEO_PALETTE_YUV420P) { | |
1830 | - return -EINVAL; | |
1831 | - } | |
1832 | pwc_set_brightness(pdev, p->brightness); | |
1833 | pwc_set_contrast(pdev, p->contrast); | |
1834 | pwc_set_gamma(pdev, p->whiteness); | |
1835 | pwc_set_saturation(pdev, p->colour); | |
1836 | + if (p->palette && p->palette != pdev->vpalette) { | |
1837 | + switch (p->palette) { | |
1838 | + case VIDEO_PALETTE_YUV420P: | |
1839 | + case VIDEO_PALETTE_RAW: | |
1840 | + pdev->vpalette = p->palette; | |
1841 | + return pwc_try_video_mode(pdev, pdev->image.x, pdev->image.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot); | |
1842 | + break; | |
1843 | + default: | |
1844 | + return -EINVAL; | |
1845 | + break; | |
1846 | + } | |
1847 | + } | |
1848 | break; | |
1849 | } | |
1850 | ||
1851 | @@ -1402,13 +1421,23 @@ | |
1852 | various palettes... The driver doesn't support | |
1853 | such small images, so I'm working around it. | |
1854 | */ | |
1855 | - if (vm->format && vm->format != VIDEO_PALETTE_YUV420P) | |
1856 | - return -EINVAL; | |
1857 | - | |
1858 | + if (vm->format) | |
1859 | + { | |
1860 | + switch (vm->format) | |
1861 | + { | |
1862 | + case VIDEO_PALETTE_YUV420P: | |
1863 | + case VIDEO_PALETTE_RAW: | |
1864 | + break; | |
1865 | + default: | |
1866 | + return -EINVAL; | |
1867 | + break; | |
1868 | + } | |
1869 | + } | |
1870 | + | |
1871 | if ((vm->width != pdev->view.x || vm->height != pdev->view.y) && | |
1872 | (vm->width >= pdev->view_min.x && vm->height >= pdev->view_min.y)) { | |
1873 | int ret; | |
1874 | - | |
1875 | + | |
1876 | Trace(TRACE_OPEN, "VIDIOCMCAPTURE: changing size to please xawtv :-(.\n"); | |
1877 | ret = pwc_try_video_mode(pdev, vm->width, vm->height, pdev->vframes, pdev->vcompression, pdev->vsnapshot); | |
1878 | if (ret) | |
1879 | @@ -1640,12 +1669,12 @@ | |
1880 | type_id = 690; | |
1881 | break; | |
1882 | case 0x0310: | |
1883 | - Info("Philips PCVC730K (ToUCam Fun) USB webcam detected.\n"); | |
1884 | + Info("Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) USB webcam detected.\n"); | |
1885 | name = "Philips 730 webcam"; | |
1886 | type_id = 730; | |
1887 | break; | |
1888 | case 0x0311: | |
1889 | - Info("Philips PCVC740K (ToUCam Pro) USB webcam detected.\n"); | |
1890 | + Info("Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) USB webcam detected.\n"); | |
1891 | name = "Philips 740 webcam"; | |
1892 | type_id = 740; | |
1893 | break; | |
1894 | @@ -1759,18 +1788,45 @@ | |
1895 | break; | |
1896 | } | |
1897 | } | |
1898 | - else if (vendor_id == 0x04cc) { | |
1899 | + else if (vendor_id == 0x04cc) { | |
1900 | switch(product_id) { | |
1901 | case 0x8116: | |
1902 | Info("Sotec Afina Eye USB webcam detected.\n"); | |
1903 | name = "Sotec Afina Eye"; | |
1904 | type_id = 730; | |
1905 | - break; | |
1906 | + break; | |
1907 | default: | |
1908 | return -ENODEV; | |
1909 | break; | |
1910 | } | |
1911 | } | |
1912 | + else if (vendor_id == 0x06be) { | |
1913 | + switch(product_id) { | |
1914 | + case 0x8116: | |
1915 | + /* Basicly the same as the Sotec Afina Eye */ | |
1916 | + Info("AME CU-001 USB webcam detected.\n"); | |
1917 | + name = "AME CU-001"; | |
1918 | + type_id = 730; | |
1919 | + break; | |
1920 | + default: | |
1921 | + return -ENODEV; | |
1922 | + break; | |
1923 | + } | |
1924 | + } | |
1925 | + else if (vendor_id == 0x06be) { | |
1926 | + switch(product_id) { | |
1927 | + case 0x8116: | |
1928 | + /* This is essentially the same cam as the Sotec Afina Eye */ | |
1929 | + Info("AME Co. Afina Eye USB webcam detected.\n"); | |
1930 | + name = "AME Co. Afina Eye"; | |
1931 | + type_id = 750; | |
1932 | + break; | |
1933 | + default: | |
1934 | + return -ENODEV; | |
1935 | + break; | |
1936 | + } | |
1937 | + | |
1938 | + } | |
1939 | else if (vendor_id == 0x0d81) { | |
1940 | switch(product_id) { | |
1941 | case 0x1900: | |
1942 | @@ -1819,8 +1875,6 @@ | |
1943 | pdev->angle_range.pan_max = 7000; | |
1944 | pdev->angle_range.tilt_min = -3000; | |
1945 | pdev->angle_range.tilt_max = 2500; | |
1946 | - pdev->angle_range.zoom_min = -1; | |
1947 | - pdev->angle_range.zoom_max = -1; | |
1948 | } | |
1949 | ||
1950 | init_MUTEX(&pdev->modlock); | |
1951 | @@ -1834,7 +1888,7 @@ | |
1952 | strcpy(pdev->vdev.name, name); | |
1953 | pdev->vdev.owner = THIS_MODULE; | |
1954 | pdev->vdev.priv = pdev; | |
1955 | - | |
1956 | + | |
1957 | pdev->release = udev->descriptor.bcdDevice; | |
1958 | Trace(TRACE_PROBE, "Release: %04x\n", pdev->release); | |
1959 | ||
1960 | @@ -1898,14 +1952,14 @@ | |
1961 | Err("pwc_disconnect() Magic number failed. Consult your scrolls and try again.\n"); | |
1962 | goto disconnect_out; | |
1963 | } | |
1964 | -#endif | |
1965 | +#endif | |
1966 | ||
1967 | /* We got unplugged; this is signalled by an EPIPE error code */ | |
1968 | if (pdev->vopen) { | |
1969 | Info("Disconnected while webcam is in use!\n"); | |
1970 | pdev->error_status = EPIPE; | |
1971 | } | |
1972 | - | |
1973 | + | |
1974 | /* Alert waiting processes */ | |
1975 | wake_up_interruptible(&pdev->frameq); | |
1976 | /* Wait until device is closed */ | |
1977 | @@ -1913,7 +1967,7 @@ | |
1978 | schedule(); | |
1979 | /* Device is now closed, so we can safely unregister it */ | |
1980 | Trace(TRACE_PROBE, "Unregistering video device in disconnect().\n"); | |
1981 | - video_unregister_device(&pdev->vdev); | |
1982 | + video_unregister_device(&pdev->vdev); | |
1983 | ||
1984 | /* Free memory (don't set pdev to 0 just yet) */ | |
1985 | kfree(pdev); | |
1986 | @@ -1932,7 +1986,7 @@ | |
1987 | static int pwc_atoi(const char *s) | |
1988 | { | |
1989 | int k = 0; | |
1990 | - | |
1991 | + | |
1992 | k = 0; | |
1993 | while (*s != '\0' && *s >= '0' && *s <= '9') { | |
1994 | k = 10 * k + (*s - '0'); | |
1995 | @@ -1975,7 +2029,7 @@ | |
1996 | MODULE_PARM_DESC(dev_hint, "Device node hints"); | |
1997 | ||
1998 | MODULE_DESCRIPTION("Philips & OEM USB webcam driver"); | |
1999 | -MODULE_AUTHOR("Nemosoft Unv. <nemosoft@smcc.demon.nl>"); | |
2000 | +MODULE_AUTHOR("Nemosoft Unv. <webcam@smcc.demon.nl>"); | |
2001 | MODULE_LICENSE("GPL"); | |
2002 | ||
2003 | static int __init usb_pwc_init(void) | |
2004 | @@ -1983,9 +2037,10 @@ | |
2005 | int i, sz; | |
2006 | char *sizenames[PSZ_MAX] = { "sqcif", "qsif", "qcif", "sif", "cif", "vga" }; | |
2007 | ||
2008 | - Info("Philips PCA645/646 + PCVC675/680/690 + PCVC730/740/750 webcam module version " PWC_VERSION " loaded.\n"); | |
2009 | - Info("Also supports the Askey VC010, various Logitech QuickCams, Samsung MPC-C10 and MPC-C30,\n"); | |
2010 | - Info("the Creative WebCam 5, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n"); | |
2011 | + Info("Philips webcam module version " PWC_VERSION " loaded.\n"); | |
2012 | + Info("Supports Philips PCA645/646, PCVC675/680/690, PCVC720[40]/730/740/750 & PCVC830/840.\n"); | |
2013 | + Info("Also supports the Askey VC010, various Logitech Quickcams, Samsung MPC-C10 and MPC-C30,\n"); | |
2014 | + Info("the Creative WebCam 5 & Pro Ex, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n"); | |
2015 | ||
2016 | if (fps) { | |
2017 | if (fps < 4 || fps > 30) { | |
2018 | @@ -1995,7 +2050,7 @@ | |
2019 | default_fps = fps; | |
2020 | Info("Default framerate set to %d.\n", default_fps); | |
2021 | } | |
2022 | - | |
2023 | + | |
2024 | if (size) { | |
2025 | /* string; try matching with array */ | |
2026 | for (sz = 0; sz < PSZ_MAX; sz++) { | |
2027 | @@ -2045,12 +2100,12 @@ | |
2028 | if (leds[1] >= 0) | |
2029 | led_off = leds[1]; | |
2030 | ||
2031 | - /* Big device node whoopla. Basically, it allows you to assign a | |
2032 | - device node (/dev/videoX) to a camera, based on its type | |
2033 | + /* Big device node whoopla. Basicly, it allows you to assign a | |
2034 | + device node (/dev/videoX) to a camera, based on its type | |
2035 | & serial number. The format is [type[.serialnumber]:]node. | |
2036 | ||
2037 | - Any camera that isn't matched by these rules gets the next | |
2038 | - available free device node. | |
2039 | + Any camera that isn't matched by these rules gets the next | |
2040 | + available free device node. | |
2041 | */ | |
2042 | for (i = 0; i < MAX_DEV_HINTS; i++) { | |
2043 | char *s, *colon, *dot; | |
2044 | diff -Nur --exclude '*.orig' linux-2.6.6.org/drivers/usb/media/pwc-ioctl.h linux-2.6.6/drivers/usb/media/pwc-ioctl.h | |
2045 | --- linux-2.6.6.org/drivers/usb/media/pwc-ioctl.h 2004-05-10 04:32:29.000000000 +0200 | |
2046 | +++ linux-2.6.6/drivers/usb/media/pwc-ioctl.h 2004-05-07 00:52:23.000000000 +0200 | |
2047 | @@ -1,8 +1,8 @@ | |
2048 | #ifndef PWC_IOCTL_H | |
2049 | #define PWC_IOCTL_H | |
2050 | ||
2051 | -/* (C) 2001-2003 Nemosoft Unv. webcam@smcc.demon.nl | |
2052 | - | |
2053 | +/* (C) 2001-2004 Nemosoft Unv. webcam@smcc.demon.nl | |
2054 | + | |
2055 | This program is free software; you can redistribute it and/or modify | |
2056 | it under the terms of the GNU General Public License as published by | |
2057 | the Free Software Foundation; either version 2 of the License, or | |
2058 | @@ -18,19 +18,24 @@ | |
2059 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
2060 | */ | |
2061 | ||
2062 | -/* This is pwc-ioctl.h belonging to PWC 8.10 */ | |
2063 | +/* This is pwc-ioctl.h belonging to PWC 8.12.1 | |
2064 | + It contains structures and defines to communicate from user space | |
2065 | + directly to the driver. | |
2066 | + */ | |
2067 | ||
2068 | -/* | |
2069 | +/* | |
2070 | Changes | |
2071 | - 2001/08/03 Alvarado Added ioctl constants to access methods for | |
2072 | + 2001/08/03 Alvarado Added ioctl constants to access methods for | |
2073 | changing white balance and red/blue gains | |
2074 | 2002/12/15 G. H. Fernandez-Toribio VIDIOCGREALSIZE | |
2075 | + 2003/12/13 Nemosft Unv. Some modifications to make interfacing to | |
2076 | + PWCX easier | |
2077 | */ | |
2078 | ||
2079 | /* These are private ioctl() commands, specific for the Philips webcams. | |
2080 | They contain functions not found in other webcams, and settings not | |
2081 | - specified in the Video4Linux API. | |
2082 | - | |
2083 | + specified in the Video4Linux API. | |
2084 | + | |
2085 | The #define names are built up like follows: | |
2086 | VIDIOC VIDeo IOCtl prefix | |
2087 | PWC Philps WebCam | |
2088 | @@ -40,13 +45,21 @@ | |
2089 | */ | |
2090 | ||
2091 | ||
2092 | + /* Enumeration of image sizes */ | |
2093 | +#define PSZ_SQCIF 0x00 | |
2094 | +#define PSZ_QSIF 0x01 | |
2095 | +#define PSZ_QCIF 0x02 | |
2096 | +#define PSZ_SIF 0x03 | |
2097 | +#define PSZ_CIF 0x04 | |
2098 | +#define PSZ_VGA 0x05 | |
2099 | +#define PSZ_MAX 6 | |
2100 | ||
2101 | ||
2102 | /* The frame rate is encoded in the video_window.flags parameter using | |
2103 | the upper 16 bits, since some flags are defined nowadays. The following | |
2104 | defines provide a mask and shift to filter out this value. | |
2105 | - | |
2106 | - In 'Snapshot' mode the camera freezes its automatic exposure and colour | |
2107 | + | |
2108 | + In 'Snapshot' mode the camera freezes its automatic exposure and colour | |
2109 | balance controls. | |
2110 | */ | |
2111 | #define PWC_FPS_SHIFT 16 | |
2112 | @@ -55,7 +68,15 @@ | |
2113 | #define PWC_FPS_SNAPSHOT 0x00400000 | |
2114 | ||
2115 | ||
2116 | +/* structure for transfering x & y coordinates */ | |
2117 | +struct pwc_coord | |
2118 | +{ | |
2119 | + int x, y; /* guess what */ | |
2120 | + int size; /* size, or offset */ | |
2121 | +}; | |
2122 | + | |
2123 | ||
2124 | +/* Used with VIDIOCPWCPROBE */ | |
2125 | struct pwc_probe | |
2126 | { | |
2127 | char name[32]; | |
2128 | @@ -78,7 +99,6 @@ | |
2129 | otherwise undefined. | |
2130 | 'read_red' and 'read_blue' are read-only. | |
2131 | */ | |
2132 | - | |
2133 | struct pwc_whitebalance | |
2134 | { | |
2135 | int mode; | |
2136 | @@ -117,7 +137,7 @@ | |
2137 | #define PWC_MPT_TILT 0x02 | |
2138 | #define PWC_MPT_TIMEOUT 0x04 /* for status */ | |
2139 | ||
2140 | -/* Set angles; when absolute = 1, the angle is absolute and the | |
2141 | +/* Set angles; when absolute != 0, the angle is absolute and the | |
2142 | driver calculates the relative offset for you. This can only | |
2143 | be used with VIDIOCPWCSANGLE; VIDIOCPWCGANGLE always returns | |
2144 | absolute angles. | |
2145 | @@ -127,18 +147,14 @@ | |
2146 | int absolute; /* write-only */ | |
2147 | int pan; /* degrees * 100 */ | |
2148 | int tilt; /* degress * 100 */ | |
2149 | - int zoom; /* N/A, set to -1 */ | |
2150 | }; | |
2151 | ||
2152 | /* Range of angles of the camera, both horizontally and vertically. | |
2153 | - The zoom is not used, maybe in the future... | |
2154 | - | |
2155 | */ | |
2156 | struct pwc_mpt_range | |
2157 | { | |
2158 | int pan_min, pan_max; /* degrees * 100 */ | |
2159 | int tilt_min, tilt_max; | |
2160 | - int zoom_min, zoom_max; /* -1, -1 */ | |
2161 | }; | |
2162 | ||
2163 | struct pwc_mpt_status | |
2164 | @@ -149,6 +165,30 @@ | |
2165 | }; | |
2166 | ||
2167 | ||
2168 | +/* This is used for out-of-kernel decompression. With it, you can get | |
2169 | + all the necessary information to initialize and use the decompressor | |
2170 | + routines in standalone applications. | |
2171 | + */ | |
2172 | +struct pwc_video_command | |
2173 | +{ | |
2174 | + int type; /* camera type (645, 675, 730, etc.) */ | |
2175 | + int release; /* release number */ | |
2176 | + | |
2177 | + int size; /* one of PSZ_* */ | |
2178 | + int alternate; | |
2179 | + int command_len; /* length of USB video command */ | |
2180 | + unsigned char command_buf[13]; /* Actual USB video command */ | |
2181 | + int bandlength; /* >0 = compressed */ | |
2182 | + int frame_size; /* Size of one (un)compressed frame */ | |
2183 | +}; | |
2184 | + | |
2185 | +/* Flags for PWCX subroutines. Not all modules honour all flags. */ | |
2186 | +#define PWCX_FLAG_PLANAR 0x0001 | |
2187 | +#define PWCX_FLAG_BAYER 0x0008 | |
2188 | + | |
2189 | + | |
2190 | +/* IOCTL definitions */ | |
2191 | + | |
2192 | /* Restore user settings */ | |
2193 | #define VIDIOCPWCRUSER _IO('v', 192) | |
2194 | /* Save user settings */ | |
2195 | @@ -172,13 +212,13 @@ | |
2196 | /* This is a probe function; since so many devices are supported, it | |
2197 | becomes difficult to include all the names in programs that want to | |
2198 | check for the enhanced Philips stuff. So in stead, try this PROBE; | |
2199 | - it returns a structure with the original name, and the corresponding | |
2200 | + it returns a structure with the original name, and the corresponding | |
2201 | Philips type. | |
2202 | To use, fill the structure with zeroes, call PROBE and if that succeeds, | |
2203 | compare the name with that returned from VIDIOCGCAP; they should be the | |
2204 | same. If so, you can be assured it is a Philips (OEM) cam and the type | |
2205 | is valid. | |
2206 | - */ | |
2207 | + */ | |
2208 | #define VIDIOCPWCPROBE _IOR('v', 199, struct pwc_probe) | |
2209 | ||
2210 | /* Set AGC (Automatic Gain Control); int < 0 = auto, 0..65535 = fixed */ | |
2211 | @@ -225,5 +265,8 @@ | |
2212 | #define VIDIOCPWCMPTSANGLE _IOW('v', 212, struct pwc_mpt_angles) | |
2213 | #define VIDIOCPWCMPTGANGLE _IOR('v', 212, struct pwc_mpt_angles) | |
2214 | #define VIDIOCPWCMPTSTATUS _IOR('v', 213, struct pwc_mpt_status) | |
2215 | - | |
2216 | + | |
2217 | + /* Get the USB set-video command; needed for initializing libpwcx */ | |
2218 | +#define VIDIOCPWCGVIDCMD _IOR('v', 215, struct pwc_video_command) | |
2219 | + | |
2220 | #endif | |
2221 | diff -Nur --exclude '*.orig' linux-2.6.6.org/drivers/usb/media/pwc-misc.c linux-2.6.6/drivers/usb/media/pwc-misc.c | |
2222 | --- linux-2.6.6.org/drivers/usb/media/pwc-misc.c 2004-05-10 04:32:28.000000000 +0200 | |
2223 | +++ linux-2.6.6/drivers/usb/media/pwc-misc.c 2004-05-07 00:52:23.000000000 +0200 | |
2224 | @@ -15,13 +15,13 @@ | |
2225 | You should have received a copy of the GNU General Public License | |
2226 | along with this program; if not, write to the Free Software | |
2227 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
2228 | -*/ | |
2229 | +*/ | |
2230 | ||
2231 | #include <linux/slab.h> | |
2232 | ||
2233 | #include "pwc.h" | |
2234 | ||
2235 | -struct pwc_coord pwc_image_sizes[PSZ_MAX] = | |
2236 | +struct pwc_coord pwc_image_sizes[PSZ_MAX] = | |
2237 | { | |
2238 | { 128, 96, 0 }, | |
2239 | { 160, 120, 0 }, | |
2240 | @@ -36,11 +36,30 @@ | |
2241 | { | |
2242 | int i, find; | |
2243 | ||
2244 | - /* Make sure we don't go beyond our max size */ | |
2245 | - if (width > pdev->view_max.x || height > pdev->view_max.y) | |
2246 | - return -1; | |
2247 | + /* Make sure we don't go beyond our max size. | |
2248 | + NB: we have different limits for RAW and normal modes. In case | |
2249 | + you don't have the decompressor loaded or use RAW mode, | |
2250 | + the maximum viewable size is smaller. | |
2251 | + */ | |
2252 | + if (pdev->vpalette == VIDEO_PALETTE_RAW) | |
2253 | + { | |
2254 | + if (width > pdev->abs_max.x || height > pdev->abs_max.y) | |
2255 | + { | |
2256 | + Debug("VIDEO_PALETTE_RAW: going beyond abs_max.\n"); | |
2257 | + return -1; | |
2258 | + } | |
2259 | + } | |
2260 | + else | |
2261 | + { | |
2262 | + if (width > pdev->view_max.x || height > pdev->view_max.y) | |
2263 | + { | |
2264 | + Debug("VIDEO_PALETTE_ not RAW: going beyond view_max.\n"); | |
2265 | + return -1; | |
2266 | + } | |
2267 | + } | |
2268 | + | |
2269 | /* Find the largest size supported by the camera that fits into the | |
2270 | - requested size. | |
2271 | + requested size. | |
2272 | */ | |
2273 | find = -1; | |
2274 | for (i = 0; i < PSZ_MAX; i++) { | |
2275 | @@ -62,6 +81,8 @@ | |
2276 | pdev->view_min.y = 96; | |
2277 | pdev->view_max.x = 352; | |
2278 | pdev->view_max.y = 288; | |
2279 | + pdev->abs_max.x = 352; | |
2280 | + pdev->abs_max.y = 288; | |
2281 | pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QCIF | 1 << PSZ_CIF; | |
2282 | pdev->vcinterface = 2; | |
2283 | pdev->vendpoint = 4; | |
2284 | @@ -77,13 +98,14 @@ | |
2285 | if (pdev->decompressor != NULL) { | |
2286 | pdev->view_max.x = 640; | |
2287 | pdev->view_max.y = 480; | |
2288 | - pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF | 1 << PSZ_VGA; | |
2289 | } | |
2290 | else { | |
2291 | pdev->view_max.x = 352; | |
2292 | pdev->view_max.y = 288; | |
2293 | - pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF; | |
2294 | } | |
2295 | + pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF | 1 << PSZ_VGA; | |
2296 | + pdev->abs_max.x = 640; | |
2297 | + pdev->abs_max.y = 480; | |
2298 | pdev->vcinterface = 3; | |
2299 | pdev->vendpoint = 4; | |
2300 | pdev->frame_header_size = 0; | |
2301 | @@ -99,24 +121,26 @@ | |
2302 | if (pdev->decompressor != NULL) { | |
2303 | pdev->view_max.x = 640; | |
2304 | pdev->view_max.y = 480; | |
2305 | - pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA; | |
2306 | } | |
2307 | else { | |
2308 | - /* Tell CIF, even though SIF really is the maximum, but some tools really need CIF */ | |
2309 | + /* We use CIF, not SIF since some tools really need CIF. So we cheat a bit. */ | |
2310 | pdev->view_max.x = 352; | |
2311 | pdev->view_max.y = 288; | |
2312 | - pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF; | |
2313 | } | |
2314 | + pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA; | |
2315 | + pdev->abs_max.x = 640; | |
2316 | + pdev->abs_max.y = 480; | |
2317 | pdev->vcinterface = 3; | |
2318 | pdev->vendpoint = 5; | |
2319 | pdev->frame_header_size = TOUCAM_HEADER_SIZE; | |
2320 | pdev->frame_trailer_size = TOUCAM_TRAILER_SIZE; | |
2321 | break; | |
2322 | } | |
2323 | + pdev->vpalette = VIDEO_PALETTE_YUV420P; /* default */ | |
2324 | pdev->view_min.size = pdev->view_min.x * pdev->view_min.y; | |
2325 | pdev->view_max.size = pdev->view_max.x * pdev->view_max.y; | |
2326 | - /* length of image, in YUV format */ | |
2327 | - pdev->len_per_image = (pdev->view_max.size * 3) / 2; | |
2328 | + /* length of image, in YUV format; always allocate enough memory. */ | |
2329 | + pdev->len_per_image = (pdev->abs_max.x * pdev->abs_max.y * 3) / 2; | |
2330 | } | |
2331 | ||
2332 | ||
2333 | diff -Nur --exclude '*.orig' linux-2.6.6.org/drivers/usb/media/pwc-uncompress.c linux-2.6.6/drivers/usb/media/pwc-uncompress.c | |
2334 | --- linux-2.6.6.org/drivers/usb/media/pwc-uncompress.c 2004-05-10 04:32:37.000000000 +0200 | |
2335 | +++ linux-2.6.6/drivers/usb/media/pwc-uncompress.c 2004-05-07 00:52:23.000000000 +0200 | |
2336 | @@ -1,4 +1,4 @@ | |
2337 | -/* Linux driver for Philips webcam | |
2338 | +/* Linux driver for Philips webcam | |
2339 | Decompression frontend. | |
2340 | (C) 1999-2003 Nemosoft Unv. (webcam@smcc.demon.nl) | |
2341 | ||
2342 | @@ -21,7 +21,9 @@ | |
2343 | themselves. It also has a decompressor wrapper function. | |
2344 | */ | |
2345 | ||
2346 | +#include <asm/current.h> | |
2347 | #include <asm/types.h> | |
2348 | +// #include <linux/sched.h> | |
2349 | ||
2350 | #include "pwc.h" | |
2351 | #include "pwc-uncompress.h" | |
2352 | @@ -81,7 +83,6 @@ | |
2353 | u16 *src; | |
2354 | u16 *dsty, *dstu, *dstv; | |
2355 | ||
2356 | - | |
2357 | if (pdev == NULL) | |
2358 | return -EFAULT; | |
2359 | #if defined(__KERNEL__) && defined(PWC_MAGIC) | |
2360 | @@ -97,16 +98,24 @@ | |
2361 | image = pdev->image_ptr[pdev->fill_image]; | |
2362 | if (!image) | |
2363 | return -EFAULT; | |
2364 | - | |
2365 | + | |
2366 | yuv = fbuf->data + pdev->frame_header_size; /* Skip header */ | |
2367 | - if (pdev->vbandlength == 0) { | |
2368 | + | |
2369 | + /* Raw format; that's easy... */ | |
2370 | + if (pdev->vpalette == VIDEO_PALETTE_RAW) | |
2371 | + { | |
2372 | + memcpy(image, yuv, pdev->frame_size); | |
2373 | + return 0; | |
2374 | + } | |
2375 | + | |
2376 | + if (pdev->vbandlength == 0) { | |
2377 | /* Uncompressed mode. We copy the data into the output buffer, | |
2378 | using the viewport size (which may be larger than the image | |
2379 | size). Unfortunately we have to do a bit of byte stuffing | |
2380 | to get the desired output format/size. | |
2381 | */ | |
2382 | - /* | |
2383 | - * We do some byte shuffling here to go from the | |
2384 | + /* | |
2385 | + * We do some byte shuffling here to go from the | |
2386 | * native format to YUV420P. | |
2387 | */ | |
2388 | src = (u16 *)yuv; | |
2389 | @@ -140,15 +149,21 @@ | |
2390 | dstu += (stride >> 1); | |
2391 | } | |
2392 | } | |
2393 | - else { | |
2394 | - /* Compressed; the decompressor routines will write the data | |
2395 | + else { | |
2396 | + /* Compressed; the decompressor routines will write the data | |
2397 | in planar format immediately. | |
2398 | */ | |
2399 | + int flags; | |
2400 | + | |
2401 | + flags = PWCX_FLAG_PLANAR; | |
2402 | + if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot) | |
2403 | + flags |= PWCX_FLAG_BAYER; | |
2404 | + | |
2405 | if (pdev->decompressor) | |
2406 | pdev->decompressor->decompress( | |
2407 | &pdev->image, &pdev->view, &pdev->offset, | |
2408 | yuv, image, | |
2409 | - 1, | |
2410 | + flags, | |
2411 | pdev->decompress_data, pdev->vbandlength); | |
2412 | else | |
2413 | return -ENXIO; /* No such device or address: missing decompressor */ | |
2414 | diff -Nur --exclude '*.orig' linux-2.6.6.org/drivers/usb/media/pwc-uncompress.h linux-2.6.6/drivers/usb/media/pwc-uncompress.h | |
2415 | --- linux-2.6.6.org/drivers/usb/media/pwc-uncompress.h 2004-05-10 04:32:27.000000000 +0200 | |
2416 | +++ linux-2.6.6/drivers/usb/media/pwc-uncompress.h 2004-05-07 00:52:23.000000000 +0200 | |
2417 | @@ -24,10 +24,16 @@ | |
2418 | #define PWC_UNCOMPRESS_H | |
2419 | ||
2420 | #include <linux/config.h> | |
2421 | +#include <linux/linkage.h> | |
2422 | #include <linux/list.h> | |
2423 | ||
2424 | #include "pwc.h" | |
2425 | ||
2426 | +/* from pwc-dec.h */ | |
2427 | +#define PWCX_FLAG_PLANAR 0x0001 | |
2428 | +/* */ | |
2429 | + | |
2430 | + | |
2431 | #ifdef __cplusplus | |
2432 | extern "C" { | |
2433 | #endif | |
2434 | @@ -42,10 +48,10 @@ | |
2435 | int type; /* type of camera (645, 680, etc) */ | |
2436 | int table_size; /* memory needed */ | |
2437 | ||
2438 | - void (* init)(int release, void *buffer, void *table); /* Initialization routine; should be called after each set_video_mode */ | |
2439 | - void (* exit)(void); /* Cleanup routine */ | |
2440 | - void (* decompress)(struct pwc_coord *image, struct pwc_coord *view, struct pwc_coord *offset, | |
2441 | - void *src, void *dst, int planar, | |
2442 | + asmlinkage void (* init)(int type, int release, void *buffer, void *table); /* Initialization routine; should be called after each set_video_mode */ | |
2443 | + asmlinkage void (* exit)(void); /* Cleanup routine */ | |
2444 | + asmlinkage void (* decompress)(struct pwc_coord *image, struct pwc_coord *view, struct pwc_coord *offset, | |
2445 | + void *src, void *dst, int flags, | |
2446 | void *table, int bandlength); | |
2447 | void (* lock)(void); /* make sure module cannot be unloaded */ | |
2448 | void (* unlock)(void); /* release lock on module */ | |
2449 | diff -Nur --exclude '*.orig' linux-2.6.6.org/drivers/usb/media/pwc.h linux-2.6.6/drivers/usb/media/pwc.h | |
2450 | --- linux-2.6.6.org/drivers/usb/media/pwc.h 2004-05-10 04:32:51.000000000 +0200 | |
2451 | +++ linux-2.6.6/drivers/usb/media/pwc.h 2004-05-07 00:52:23.000000000 +0200 | |
2452 | @@ -22,12 +22,11 @@ | |
2453 | ||
2454 | #include <linux/config.h> | |
2455 | #include <linux/module.h> | |
2456 | -#include <linux/smp_lock.h> | |
2457 | -#include <linux/spinlock.h> | |
2458 | #include <linux/usb.h> | |
2459 | +#include <linux/spinlock.h> | |
2460 | #include <linux/videodev.h> | |
2461 | #include <linux/wait.h> | |
2462 | - | |
2463 | +#include <linux/smp_lock.h> | |
2464 | #include <asm/semaphore.h> | |
2465 | #include <asm/errno.h> | |
2466 | ||
2467 | @@ -65,9 +64,9 @@ | |
2468 | #define FEATURE_MOTOR_PANTILT 0x0001 | |
2469 | ||
2470 | /* Version block */ | |
2471 | -#define PWC_MAJOR 8 | |
2472 | -#define PWC_MINOR 12 | |
2473 | -#define PWC_VERSION "8.12" | |
2474 | +#define PWC_MAJOR 9 | |
2475 | +#define PWC_MINOR 0 | |
2476 | +#define PWC_VERSION "9.0-BETA-2" | |
2477 | #define PWC_NAME "pwc" | |
2478 | ||
2479 | /* Turn certain features on/off */ | |
2480 | @@ -90,12 +89,6 @@ | |
2481 | /* Absolute maximum number of buffers available for mmap() */ | |
2482 | #define MAX_IMAGES 10 | |
2483 | ||
2484 | -struct pwc_coord | |
2485 | -{ | |
2486 | - int x, y; /* guess what */ | |
2487 | - int size; /* size, or offset */ | |
2488 | -}; | |
2489 | - | |
2490 | /* The following structures were based on cpia.h. Why reinvent the wheel? :-) */ | |
2491 | struct pwc_iso_buf | |
2492 | { | |
2493 | @@ -137,6 +130,7 @@ | |
2494 | int vcinterface; /* video control interface */ | |
2495 | int valternate; /* alternate interface needed */ | |
2496 | int vframes, vsize; /* frames-per-second & size (see PSZ_*) */ | |
2497 | + int vpalette; /* palette: 420P, RAW or RGBBAYER */ | |
2498 | int vframe_count; /* received frames */ | |
2499 | int vframes_dumped; /* counter for dumped frames */ | |
2500 | int vframes_error; /* frames received in error */ | |
2501 | @@ -148,6 +142,9 @@ | |
2502 | char vsnapshot; /* snapshot mode */ | |
2503 | char vsync; /* used by isoc handler */ | |
2504 | char vmirror; /* for ToUCaM series */ | |
2505 | + | |
2506 | + int cmd_len; | |
2507 | + unsigned char cmd_buf[13]; | |
2508 | ||
2509 | /* The image acquisition requires 3 to 4 steps: | |
2510 | 1. data is gathered in short packets from the USB controller | |
2511 | @@ -169,8 +166,9 @@ | |
2512 | struct pwc_frame_buf *full_frames, *full_frames_tail; /* all filled frames */ | |
2513 | struct pwc_frame_buf *fill_frame; /* frame currently being filled */ | |
2514 | struct pwc_frame_buf *read_frame; /* frame currently read by user process */ | |
2515 | - int frame_size; | |
2516 | int frame_header_size, frame_trailer_size; | |
2517 | + int frame_size; | |
2518 | + int frame_total_size; /* including header & trailer */ | |
2519 | int drop_frames; | |
2520 | #if PWC_DEBUG | |
2521 | int sequence; /* Debugging aid */ | |
2522 | @@ -187,7 +185,8 @@ | |
2523 | a gray or black border. view_min <= image <= view <= view_max; | |
2524 | */ | |
2525 | int image_mask; /* bitmask of supported sizes */ | |
2526 | - struct pwc_coord view_min, view_max; /* minimum and maximum sizes */ | |
2527 | + struct pwc_coord view_min, view_max; /* minimum and maximum viewable sizes */ | |
2528 | + struct pwc_coord abs_max; /* maximum supported size with compression */ | |
2529 | struct pwc_coord image, view; /* image and viewport size */ | |
2530 | struct pwc_coord offset; /* offset within the viewport */ | |
2531 | ||
2532 | @@ -213,16 +212,6 @@ | |
2533 | #endif | |
2534 | }; | |
2535 | ||
2536 | -/* Enumeration of image sizes */ | |
2537 | -#define PSZ_SQCIF 0x00 | |
2538 | -#define PSZ_QSIF 0x01 | |
2539 | -#define PSZ_QCIF 0x02 | |
2540 | -#define PSZ_SIF 0x03 | |
2541 | -#define PSZ_CIF 0x04 | |
2542 | -#define PSZ_VGA 0x05 | |
2543 | -#define PSZ_MAX 6 | |
2544 | - | |
2545 | - | |
2546 | ||
2547 | #ifdef __cplusplus | |
2548 | extern "C" { | |
2549 | @@ -259,7 +248,7 @@ | |
2550 | extern int pwc_set_saturation(struct pwc_device *pdev, int value); | |
2551 | extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value); | |
2552 | extern int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value); | |
2553 | -extern int pwc_get_cmos_sensor(struct pwc_device *pdev); | |
2554 | +extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor); | |
2555 | ||
2556 | /* Power down or up the camera; not supported by all models */ | |
2557 | extern int pwc_camera_power(struct pwc_device *pdev, int power); | |
2558 | diff -Nur --exclude '*.orig' linux-2.6.6.org/drivers/usb/media/pwcx-glue.c linux-2.6.6/drivers/usb/media/pwcx-glue.c | |
2559 | --- linux-2.6.6.org/drivers/usb/media/pwcx-glue.c 1970-01-01 01:00:00.000000000 +0100 | |
2560 | +++ linux-2.6.6/drivers/usb/media/pwcx-glue.c 2004-05-07 01:10:43.000000000 +0200 | |
2561 | @@ -0,0 +1,193 @@ | |
2562 | +/* PWCX module glue code. */ | |
2563 | + | |
2564 | +#include <linux/config.h> | |
2565 | + | |
2566 | +#include "pwc.h" | |
2567 | +#include "pwcx.h" | |
2568 | +#include "pwc-uncompress.h" | |
2569 | + | |
2570 | +#define PWCX_MAJOR 9 | |
2571 | +#define PWCX_MINOR 0 | |
2572 | + | |
2573 | +#ifdef CONFIG_USB_PWCX_MODULE | |
2574 | +#include <linux/init.h> | |
2575 | +#include <linux/module.h> | |
2576 | +#include <linux/version.h> | |
2577 | + | |
2578 | +MODULE_DESCRIPTION("Philips webcam decompressor routines"); | |
2579 | +MODULE_AUTHOR("Nemosoft Unv. <webcam@smcc.demon.nl>"); | |
2580 | +MODULE_LICENSE("Proprietary. See http://www.smcc.demon.nl/webcam/tainting.html"); | |
2581 | + | |
2582 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) | |
2583 | +EXPORT_NO_SYMBOLS; | |
2584 | +#endif | |
2585 | + | |
2586 | +static void lock_pwcx(void) | |
2587 | +{ | |
2588 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) | |
2589 | + MOD_INC_USE_COUNT; | |
2590 | +#endif | |
2591 | +} | |
2592 | + | |
2593 | +static void unlock_pwcx(void) | |
2594 | +{ | |
2595 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) | |
2596 | + MOD_DEC_USE_COUNT; | |
2597 | +#endif | |
2598 | +} | |
2599 | + | |
2600 | +#else | |
2601 | + | |
2602 | +static void lock_pwcx(void) | |
2603 | +{ | |
2604 | +} | |
2605 | + | |
2606 | +static void unlock_pwcx(void) | |
2607 | +{ | |
2608 | +} | |
2609 | + | |
2610 | +#endif | |
2611 | + | |
2612 | +static struct pwc_decompressor Nala[2] = | |
2613 | +{ | |
2614 | + { | |
2615 | + 645, | |
2616 | + 5000, | |
2617 | + pwcx_init_decompress_Nala, | |
2618 | + pwcx_exit_decompress_Nala, | |
2619 | + pwcx_decompress_Nala, | |
2620 | + lock_pwcx, | |
2621 | + unlock_pwcx, | |
2622 | + }, | |
2623 | + { | |
2624 | + 646, | |
2625 | + 5000, | |
2626 | + pwcx_init_decompress_Nala, | |
2627 | + pwcx_exit_decompress_Nala, | |
2628 | + pwcx_decompress_Nala, | |
2629 | + lock_pwcx, | |
2630 | + unlock_pwcx, | |
2631 | + }, | |
2632 | +}; | |
2633 | + | |
2634 | +static struct pwc_decompressor Timon[3] = | |
2635 | +{ | |
2636 | + { | |
2637 | + 675, | |
2638 | + 60000, | |
2639 | + pwcx_init_decompress_Timon, | |
2640 | + pwcx_exit_decompress_Timon, | |
2641 | + pwcx_decompress_Timon, | |
2642 | + lock_pwcx, | |
2643 | + unlock_pwcx, | |
2644 | + }, | |
2645 | + { | |
2646 | + 680, | |
2647 | + 60000, | |
2648 | + pwcx_init_decompress_Timon, | |
2649 | + pwcx_exit_decompress_Timon, | |
2650 | + pwcx_decompress_Timon, | |
2651 | + lock_pwcx, | |
2652 | + unlock_pwcx, | |
2653 | + }, | |
2654 | + { | |
2655 | + 690, | |
2656 | + 60000, | |
2657 | + pwcx_init_decompress_Timon, | |
2658 | + pwcx_exit_decompress_Timon, | |
2659 | + pwcx_decompress_Timon, | |
2660 | + lock_pwcx, | |
2661 | + unlock_pwcx, | |
2662 | + }, | |
2663 | +}; | |
2664 | + | |
2665 | +static struct pwc_decompressor Kiara[4] = | |
2666 | +{ | |
2667 | + { | |
2668 | + 720, | |
2669 | + 60000, | |
2670 | + pwcx_init_decompress_Kiara, | |
2671 | + pwcx_exit_decompress_Kiara, | |
2672 | + pwcx_decompress_Kiara, | |
2673 | + lock_pwcx, | |
2674 | + unlock_pwcx, | |
2675 | + }, | |
2676 | + { | |
2677 | + 730, | |
2678 | + 60000, | |
2679 | + pwcx_init_decompress_Kiara, | |
2680 | + pwcx_exit_decompress_Kiara, | |
2681 | + pwcx_decompress_Kiara, | |
2682 | + lock_pwcx, | |
2683 | + unlock_pwcx, | |
2684 | + }, | |
2685 | + { | |
2686 | + 740, | |
2687 | + 60000, | |
2688 | + pwcx_init_decompress_Kiara, | |
2689 | + pwcx_exit_decompress_Kiara, | |
2690 | + pwcx_decompress_Kiara, | |
2691 | + lock_pwcx, | |
2692 | + unlock_pwcx, | |
2693 | + }, | |
2694 | + { | |
2695 | + 750, | |
2696 | + 60000, | |
2697 | + pwcx_init_decompress_Kiara, | |
2698 | + pwcx_exit_decompress_Kiara, | |
2699 | + pwcx_decompress_Kiara, | |
2700 | + lock_pwcx, | |
2701 | + unlock_pwcx, | |
2702 | + }, | |
2703 | +}; | |
2704 | + | |
2705 | +#ifdef CONFIG_USB_PWCX_MODULE | |
2706 | +static int __init usb_pwcx_init(void) | |
2707 | +#else | |
2708 | +int usb_pwcx_init(void) | |
2709 | +#endif | |
2710 | +{ | |
2711 | + Info("Philips webcam decompressor routines version %d.%d-BETA-2\n", PWCX_MAJOR, PWCX_MINOR); | |
2712 | + Info("Supports all cameras supported by the main module (pwc).\n"); | |
2713 | + | |
2714 | + /* register decompression modules */ | |
2715 | + if (pwc_decompressor_version != PWCX_MAJOR) { | |
2716 | + Err("Version mismatch! These decompression routines are version %d.*, while the\n" | |
2717 | + "main module expects version %d.*. Please consult the Philips webcam Linux\n" | |
2718 | + "driver page for the correct version and downloads.\n", PWCX_MAJOR, pwc_decompressor_version); | |
2719 | + return -EINVAL; | |
2720 | + } | |
2721 | + pwc_register_decompressor(&Nala[0]); | |
2722 | + pwc_register_decompressor(&Nala[1]); | |
2723 | + pwc_register_decompressor(&Timon[0]); | |
2724 | + pwc_register_decompressor(&Timon[1]); | |
2725 | + pwc_register_decompressor(&Timon[2]); | |
2726 | + pwc_register_decompressor(&Kiara[0]); | |
2727 | + pwc_register_decompressor(&Kiara[1]); | |
2728 | + pwc_register_decompressor(&Kiara[2]); | |
2729 | + pwc_register_decompressor(&Kiara[3]); | |
2730 | + return 0; | |
2731 | +} | |
2732 | + | |
2733 | +#ifdef CONFIG_USB_PWCX_MODULE | |
2734 | +static void __exit usb_pwcx_exit(void) | |
2735 | +#else | |
2736 | +void usb_pwcx_exit(void) | |
2737 | +#endif | |
2738 | +{ | |
2739 | + pwc_unregister_decompressor(Nala[0].type); | |
2740 | + pwc_unregister_decompressor(Nala[1].type); | |
2741 | + pwc_unregister_decompressor(Timon[0].type); | |
2742 | + pwc_unregister_decompressor(Timon[1].type); | |
2743 | + pwc_unregister_decompressor(Timon[2].type); | |
2744 | + pwc_unregister_decompressor(Kiara[0].type); | |
2745 | + pwc_unregister_decompressor(Kiara[1].type); | |
2746 | + pwc_unregister_decompressor(Kiara[2].type); | |
2747 | + pwc_unregister_decompressor(Kiara[3].type); | |
2748 | + Info("Philips webcam decompressor routines removed.\n"); | |
2749 | +} | |
2750 | + | |
2751 | +#ifdef CONFIG_USB_PWCX_MODULE | |
2752 | +module_init(usb_pwcx_init); | |
2753 | +module_exit(usb_pwcx_exit); | |
2754 | +#endif | |
2755 | diff -Nur --exclude '*.orig' linux-2.6.6.org/drivers/usb/media/pwcx.h linux-2.6.6/drivers/usb/media/pwcx.h | |
2756 | --- linux-2.6.6.org/drivers/usb/media/pwcx.h 1970-01-01 01:00:00.000000000 +0100 | |
2757 | +++ linux-2.6.6/drivers/usb/media/pwcx.h 2004-05-07 01:10:43.000000000 +0200 | |
2758 | @@ -0,0 +1,28 @@ | |
2759 | +#ifndef PWCX_H | |
2760 | +#define PWCX_H | |
2761 | + | |
2762 | +#include <linux/linkage.h> | |
2763 | +#include "pwc-ioctl.h" | |
2764 | + | |
2765 | +#ifdef __cplusplus | |
2766 | +extern "C"{ | |
2767 | +#endif | |
2768 | + | |
2769 | +/** functions **/ | |
2770 | +extern asmlinkage void pwcx_init_decompress_Nala(int type, int release, void *mode, void *table); | |
2771 | +extern asmlinkage void pwcx_exit_decompress_Nala(void); | |
2772 | +extern asmlinkage void pwcx_decompress_Nala(struct pwc_coord *image, struct pwc_coord *view, struct pwc_coord *offset, void *src, void *dst, int flags, void *table, int bandlength); | |
2773 | + | |
2774 | +extern asmlinkage void pwcx_init_decompress_Timon(int type, int release, void *mode, void *table); | |
2775 | +extern asmlinkage void pwcx_exit_decompress_Timon(void); | |
2776 | +extern asmlinkage void pwcx_decompress_Timon(struct pwc_coord *image, struct pwc_coord *view, struct pwc_coord *offset, void *src, void *dst, int flags, void *table, int bandlength); | |
2777 | + | |
2778 | +extern asmlinkage void pwcx_init_decompress_Kiara(int type, int release, void *mode, void *table); | |
2779 | +extern asmlinkage void pwcx_exit_decompress_Kiara(void); | |
2780 | +extern asmlinkage void pwcx_decompress_Kiara(struct pwc_coord *image, struct pwc_coord *view, struct pwc_coord *offset, void *src, void *dst, int flags, void *table, int bandlength); | |
2781 | + | |
2782 | +#ifdef __cplusplus | |
2783 | +} | |
2784 | +#endif | |
2785 | + | |
2786 | +#endif |