]> git.pld-linux.org Git - packages/kernel.git/blame - 2.6.6-pwcx.patch
- ported from linux-2.4.25-atmdd.patch
[packages/kernel.git] / 2.6.6-pwcx.patch
CommitLineData
8bce5f09 1diff -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
47diff -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
66diff -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;
1525diff -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;
2044diff -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
2221diff -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
2333diff -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 */
2414diff -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 */
2449diff -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);
2558diff -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
2755diff -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
This page took 0.340649 seconds and 4 git commands to generate.