]> git.pld-linux.org Git - packages/kernel.git/blob - 2.6.6-pwcx.patch
- obsolete
[packages/kernel.git] / 2.6.6-pwcx.patch
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
This page took 0.358361 seconds and 3 git commands to generate.