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
6 * Philips PCA645, PCA646
7 * Philips PCVC675, PCVC680, PCVC690
8 - * Philips PCVC720/40, PCVC730, PCVC740, PCVC750
9 + * Philips PCVC720/40 PCVC730, PCVC740, PCVC750
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
19 + * SOTEC Afina Eye / AME Optimedia CU-001
20 * Visionite VCS-UC300, VCS-UM100
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
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
37 To compile this driver as a module, choose M here: the
38 module will be called pwc.
41 + tristate "PWCX decompressor module"
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
53 pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o
54 +pwcx-objs := pwcx-glue.o libpwcx.a_
56 obj-$(CONFIG_USB_DABUSB) += dabusb.o
57 obj-$(CONFIG_USB_DSBR) += dsbr100.o
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
70 #include <asm/uaccess.h>
72 #include <asm/errno.h>
73 +#include <linux/version.h>
76 #include "pwc-ioctl.h"
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.
85 - There are 6 * 4 * 4 entries:
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
92 - When an uncompressed mode is not available, the next available compressed mode
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.
98 -struct Timon_table_entry
99 +struct Timon_table_entry
101 char alternate; /* USB alternate interface */
102 unsigned short packetsize; /* Normal packet size */
104 unsigned char mode[13]; /* precomputed mode settings for cam */
107 -static struct Timon_table_entry Timon_table[PSZ_MAX][6][4] =
108 +static struct Timon_table_entry Timon_table[PSZ_MAX][6][4] =
110 #include "pwc_timon.h"
118 s = (unsigned char *)p;
122 unsigned char buf[3];
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 */
131 Debug("Failed to send video command... %d\n", ret);
134 - if (pEntry->compressed && pdev->decompressor != NULL)
135 - pdev->decompressor->init(pdev->release, buf, pdev->decompress_data);
137 + if (pEntry->compressed && pdev->decompressor != 0 && pdev->vpalette != VIDEO_PALETTE_RAW)
138 + pdev->decompressor->init(pdev->type, pdev->release, buf, pdev->decompress_data);
141 + memcpy(pdev->cmd_buf, buf, 3);
143 /* Set various parameters */
144 pdev->vframes = frames;
146 @@ -303,13 +307,13 @@
147 if (size == PSZ_VGA && frames > 15)
149 fps = (frames / 5) - 1;
152 /* Find a supported framerate with progressively higher compression ratios
153 if the preferred ratio is not available.
156 if (pdev->decompressor == NULL) {
159 Debug("Trying to find uncompressed mode.\n");
161 pChoose = &Timon_table[size][fps][0];
163 pChoose = &Timon_table[size][fps][compression];
164 if (pChoose->alternate != 0)
170 if (pChoose == NULL || pChoose->alternate == 0)
175 - if (pChoose->bandlength > 0)
176 - pdev->decompressor->init(pdev->release, buf, pdev->decompress_data);
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);
181 + pdev->cmd_len = 13;
182 + memcpy(pdev->cmd_buf, buf, 13);
184 /* Set various parameters */
185 pdev->vframes = frames;
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;
195 pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8;
196 @@ -352,33 +359,54 @@
198 static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, int compression, int snapshot)
200 - struct Kiara_table_entry *pChoose;
201 + struct Kiara_table_entry *pChoose = 0;
203 unsigned char buf[12];
205 + struct Kiara_table_entry RawEntry = {6, 773, 1272, {0xAD, 0xF4, 0x10, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x03, 0x80}};
207 if (size >= PSZ_MAX || frames < 5 || frames > 30 || compression < 0 || compression > 3)
209 if (size == PSZ_VGA && frames > 15)
211 fps = (frames / 5) - 1;
213 - /* Find a supported framerate with progressively higher compression ratios
214 - if the preferred ratio is not available.
217 - if (pdev->decompressor == NULL) {
219 - Debug("Trying to find uncompressed mode.\n");
221 - pChoose = &Kiara_table[size][fps][0];
223 + /* special case: VGA @ 5 fps and snapshot is raw bayer mode */
224 + if (size == PSZ_VGA && frames == 5 && snapshot)
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
230 + if (pdev->vpalette == VIDEO_PALETTE_RAW || pdev->decompressor != NULL)
232 + Info("Choosing VGA/5 BAYER mode (%d).\n", pdev->vpalette);
233 + pChoose = &RawEntry;
237 + Info("VGA/5 BAYER mode _must_ have a decompressor available, or use RAW palette.\n");
241 - while (compression <= 3) {
242 - pChoose = &Kiara_table[size][fps][compression];
243 - if (pChoose->alternate != 0)
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.
252 + if (pdev->decompressor == NULL && pdev->vpalette != VIDEO_PALETTE_RAW) {
254 + Debug("Trying to find uncompressed mode.\n");
256 + pChoose = &Kiara_table[size][fps][0];
259 + while (compression <= 3) {
260 + pChoose = &Kiara_table[size][fps][compression];
261 + if (pChoose->alternate != 0)
267 if (pChoose == NULL || pChoose->alternate == 0)
268 return -ENOENT; /* Not supported. */
273 - if (pChoose->bandlength > 0)
274 - pdev->decompressor->init(pdev->release, buf, pdev->decompress_data);
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);
279 + pdev->cmd_len = 12;
280 + memcpy(pdev->cmd_buf, buf, 12);
282 pdev->vframes = frames;
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;
291 + if (pdev->vbandlength > 0)
292 + pdev->frame_size = (pdev->vbandlength * pdev->image.y) / 4;
294 pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8;
295 - pdev->frame_size += (pdev->frame_header_size + pdev->frame_trailer_size);
302 @pdev: device structure
303 @width: viewport width
304 @@ -422,14 +452,18 @@
306 int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot)
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);
316 Debug("Could not find suitable size.\n");
320 + Debug("decode_size = %d.\n", size);
328 ret = set_video_mode_Timon(pdev, size, frames, compression, snapshot);
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);
343 @@ -467,23 +502,33 @@
345 void pwc_set_image_buffer_size(struct pwc_device *pdev)
347 - int factor, i, filler = 0;
348 + int i, factor = 0, filler = 0;
352 + /* for PALETTE_YUV420P */
353 + switch(pdev->vpalette)
355 + case VIDEO_PALETTE_YUV420P:
359 + case VIDEO_PALETTE_RAW:
360 + factor = 6; /* can be uncompressed YUV420P */
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;
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
375 pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC;
376 pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE;
379 /* Fill buffers with gray or black */
380 for (i = 0; i < MAX_IMAGES; i++) {
381 if (pdev->image_ptr[i] != NULL)
387 - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
389 - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
390 - BRIGHTNESS_FORMATTER,
394 + ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1);
401 buf = (value >> 9) & 0x7f;
402 - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
404 - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
405 - BRIGHTNESS_FORMATTER,
408 + return SendControlMsg(SET_LUM_CTL, BRIGHTNESS_FORMATTER, 1);
417 - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
419 - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
420 - CONTRAST_FORMATTER,
424 + ret = RecvControlMsg(GET_LUM_CTL, CONTRAST_FORMATTER, 1);
431 buf = (value >> 10) & 0x3f;
432 - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
434 - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
435 - CONTRAST_FORMATTER,
438 + return SendControlMsg(SET_LUM_CTL, CONTRAST_FORMATTER, 1);
446 - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
448 - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
452 + ret = RecvControlMsg(GET_LUM_CTL, GAMMA_FORMATTER, 1);
459 buf = (value >> 11) & 0x1f;
460 - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
462 - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
466 + return SendControlMsg(SET_LUM_CTL, GAMMA_FORMATTER, 1);
472 if (pdev->type < 675)
474 - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
476 - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
477 - pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1,
480 + ret = RecvControlMsg(GET_CHROM_CTL, pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, 1);
483 return 32768 + buf * 327;
486 /* saturation ranges from -100 to +100 */
487 buf = (value - 32768) / 327;
488 - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
490 - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
491 - pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1,
494 + return SendControlMsg(SET_CHROM_CTL, pdev->type < 730 ? SATURATION_MODE_FORMATTER2 : SATURATION_MODE_FORMATTER1, 1);
500 buf = 0xff; /* fixed */
502 - ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
504 - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
505 - AGC_MODE_FORMATTER,
508 + ret = SendControlMsg(SET_LUM_CTL, AGC_MODE_FORMATTER, 1);
510 if (!mode && ret >= 0) {
515 buf = (value >> 10) & 0x3F;
516 - ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
518 - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
519 - PRESET_AGC_FORMATTER,
522 + ret = SendControlMsg(SET_LUM_CTL, PRESET_AGC_FORMATTER, 1);
526 @@ -681,22 +676,12 @@
530 - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
532 - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
533 - AGC_MODE_FORMATTER,
536 + ret = RecvControlMsg(GET_LUM_CTL, AGC_MODE_FORMATTER, 1);
540 if (buf != 0) { /* fixed */
541 - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
543 - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
544 - PRESET_AGC_FORMATTER,
547 + ret = RecvControlMsg(GET_LUM_CTL, PRESET_AGC_FORMATTER, 1);
552 *value = (buf << 10);
555 - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
557 - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
558 - READ_AGC_FORMATTER,
561 + ret = RecvControlMsg(GET_STATUS_CTL, READ_AGC_FORMATTER, 1);
564 /* Gah... this value ranges from 0x00 ... 0x9F */
567 buf[0] = 0xff; /* fixed */
569 - ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
571 - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
572 - SHUTTER_MODE_FORMATTER,
575 + ret = SendControlMsg(SET_LUM_CTL, SHUTTER_MODE_FORMATTER, 1);
577 if (!mode && ret >= 0) {
583 - ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
585 - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
586 - PRESET_SHUTTER_FORMATTER,
589 + ret = SendControlMsg(SET_LUM_CTL, PRESET_SHUTTER_FORMATTER, 2);
594 buf = 0x00; /* active */
596 buf = 0xFF; /* power save */
597 - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
599 - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
600 - SET_POWER_SAVE_MODE_FORMATTER,
603 + return SendControlMsg(SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER, 1);
607 @@ -801,32 +766,20 @@
609 static inline int pwc_restore_user(struct pwc_device *pdev)
611 - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
613 - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
614 - RESTORE_USER_DEFAULTS_FORMATTER,
617 + char buf; /* dummy */
618 + return SendControlMsg(SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, 0);
621 static inline int pwc_save_user(struct pwc_device *pdev)
623 - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
625 - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
626 - SAVE_USER_DEFAULTS_FORMATTER,
629 + char buf; /* dummy */
630 + return SendControlMsg(SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, 0);
633 static inline int pwc_restore_factory(struct pwc_device *pdev)
635 - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
637 - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
638 - RESTORE_FACTORY_DEFAULTS_FORMATTER,
641 + char buf; /* dummy */
642 + return SendControlMsg(SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, 0);
645 /* ************************************************* */
648 buf = mode & 0x07; /* just the lowest three bits */
650 - ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
652 - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
656 + ret = SendControlMsg(SET_CHROM_CTL, WB_MODE_FORMATTER, 1);
664 - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
666 - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
670 + ret = RecvControlMsg(GET_CHROM_CTL, WB_MODE_FORMATTER, 1);
674 @@ -891,34 +834,21 @@
679 - /* only the msb are considered */
680 + /* only the msb is considered */
683 - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
685 - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
686 - PRESET_MANUAL_RED_GAIN_FORMATTER,
689 + return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1);
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)
698 - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
700 - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
701 - PRESET_MANUAL_RED_GAIN_FORMATTER,
705 + ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1);
715 @@ -930,34 +860,21 @@
720 - /* linear mapping of 0..0xffff to -0x80..0x7f */
721 - buf = (value >> 8);
723 - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
725 - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
726 - PRESET_MANUAL_BLUE_GAIN_FORMATTER,
729 + /* only the msb is considered */
731 + return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1);
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)
740 - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
742 - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
743 - PRESET_MANUAL_BLUE_GAIN_FORMATTER,
747 + ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1);
757 @@ -965,40 +882,28 @@
758 internal red/blue gains, which may be different from the manual
759 gains set or read above.
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)
767 - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
769 - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
770 - READ_RED_GAIN_FORMATTER,
774 + ret = RecvControlMsg(GET_STATUS_CTL, READ_RED_GAIN_FORMATTER, 1);
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)
789 - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
791 - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
792 - READ_BLUE_GAIN_FORMATTER,
796 + ret = RecvControlMsg(GET_STATUS_CTL, READ_BLUE_GAIN_FORMATTER, 1);
806 @@ -1008,28 +913,19 @@
808 /* useful range is 0x01..0x20 */
810 - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
812 - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
813 - AWB_CONTROL_SPEED_FORMATTER,
816 + return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
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)
825 - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
827 - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
828 - AWB_CONTROL_SPEED_FORMATTER,
831 + ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
834 - return (buf * 0x7f0);
835 + *value = buf * 0x7f0;
840 @@ -1039,28 +935,19 @@
842 /* useful range is 0x01..0x3F */
844 - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
846 - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
847 - AWB_CONTROL_DELAY_FORMATTER,
850 + return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
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)
859 - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
861 - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
862 - AWB_CONTROL_DELAY_FORMATTER,
865 + ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
868 - return (buf << 10);
869 + *value = buf << 10;
874 @@ -1115,12 +1002,7 @@
875 buf = 0xff; /* auto contour on */
877 buf = 0x0; /* auto contour off */
878 - ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
880 - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
881 - AUTO_CONTOUR_FORMATTER,
884 + ret = SendControlMsg(SET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1);
888 @@ -1130,12 +1012,7 @@
891 buf = (contour >> 10); /* contour preset is [0..3f] */
892 - ret = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
894 - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
895 - PRESET_CONTOUR_FORMATTER,
898 + ret = SendControlMsg(SET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1);
902 @@ -1146,26 +1023,16 @@
906 - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
908 - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
909 - AUTO_CONTOUR_FORMATTER,
912 + ret = RecvControlMsg(GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1);
917 /* auto mode off, query current preset value */
918 - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
920 - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
921 - PRESET_CONTOUR_FORMATTER,
924 + ret = RecvControlMsg(GET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1);
927 - *contour = (buf << 10);
928 + *contour = buf << 10;
932 @@ -1181,28 +1048,19 @@
936 - return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
938 - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
939 - BACK_LIGHT_COMPENSATION_FORMATTER,
942 + return SendControlMsg(SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
945 -static inline int pwc_get_backlight(struct pwc_device *pdev)
946 +static inline int pwc_get_backlight(struct pwc_device *pdev, int *backlight)
951 - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
953 - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
954 - BACK_LIGHT_COMPENSATION_FORMATTER,
957 + ret = RecvControlMsg(GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
966 @@ -1217,7 +1075,7 @@
967 return SendControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
970 -static inline int pwc_get_flicker(struct pwc_device *pdev)
971 +static inline int pwc_get_flicker(struct pwc_device *pdev, int *flicker)
975 @@ -1225,7 +1083,8 @@
976 ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
985 @@ -1241,7 +1100,7 @@
986 return SendControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
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)
994 @@ -1249,14 +1108,15 @@
995 ret = RecvControlMsg(GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
1003 int pwc_mpt_reset(struct pwc_device *pdev, int flags)
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);
1012 @@ -1293,7 +1153,7 @@
1016 -int pwc_get_cmos_sensor(struct pwc_device *pdev)
1017 +int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
1020 int ret = -1, request;
1021 @@ -1305,24 +1165,60 @@
1023 request = SENSOR_TYPE_FORMATTER2;
1025 - ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
1027 - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1029 - pdev->vcinterface,
1031 + ret = RecvControlMsg(GET_STATUS_CTL, request, 1);
1034 if (pdev->type < 675)
1035 - return buf | 0x100;
1036 + *sensor = buf | 0x100;
1044 /* End of Add-Ons */
1045 /* ************************************************* */
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.
1054 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
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 */
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))) {\
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))) {\
1087 int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1090 @@ -1351,225 +1247,245 @@
1092 case VIDIOCPWCSCQUAL:
1095 + ARG_DEF(int, qual)
1097 - if (*qual < 0 || *qual > 3)
1099 + if (ARGR(qual) < 0 || ARGR(qual) > 3)
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);
1105 - pdev->vcompression = *qual;
1106 + pdev->vcompression = ARGR(qual);
1110 case VIDIOCPWCGCQUAL:
1113 + ARG_DEF(int, qual)
1115 - *qual = pdev->vcompression;
1116 + ARGR(qual) = pdev->vcompression;
1121 case VIDIOCPWCPROBE:
1123 - struct pwc_probe *probe = arg;
1124 + ARG_DEF(struct pwc_probe, probe)
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;
1139 - if (pwc_set_agc(pdev, *agc < 0 ? 1 : 0, *agc))
1141 + if (pwc_set_agc(pdev, ARGR(agc) < 0 ? 1 : 0, ARGR(agc)))
1151 - if (pwc_get_agc(pdev, agc))
1152 + if (pwc_get_agc(pdev, ARGA(agc)))
1158 case VIDIOCPWCSSHUTTER:
1160 - int *shutter_speed = arg;
1161 + ARG_DEF(int, shutter_speed)
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));
1171 - struct pwc_whitebalance *wb = arg;
1172 + ARG_DEF(struct pwc_whitebalance, wb)
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);
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);
1189 - struct pwc_whitebalance *wb = arg;
1190 + ARG_DEF(struct pwc_whitebalance, wb)
1192 - memset(wb, 0, sizeof(*wb));
1193 - wb->mode = pwc_get_awb(pdev);
1195 + memset(ARGA(wb), 0, sizeof(struct pwc_whitebalance));
1196 + ARGR(wb).mode = pwc_get_awb(pdev);
1197 + if (ARGR(wb).mode < 0)
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);
1207 + ret = pwc_get_blue_gain(pdev, &ARGR(wb).manual_blue);
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);
1218 + ret =pwc_read_blue_gain(pdev, &ARGR(wb).read_blue);
1227 case VIDIOCPWCSAWBSPEED:
1229 - struct pwc_wb_speed *wbs = arg;
1230 + ARG_DEF(struct pwc_wb_speed, wbs)
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);
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);
1245 case VIDIOCPWCGAWBSPEED:
1247 - struct pwc_wb_speed *wbs = arg;
1248 + ARG_DEF(struct pwc_wb_speed, wbs)
1250 - ret = pwc_get_wb_speed(pdev);
1251 + ret = pwc_get_wb_speed(pdev, &ARGR(wbs).control_speed);
1254 - wbs->control_speed = ret;
1255 - ret = pwc_get_wb_delay(pdev);
1256 + ret = pwc_get_wb_delay(pdev, &ARGR(wbs).control_delay);
1259 - wbs->control_delay = ret;
1266 - struct pwc_leds *leds = arg;
1267 + ARG_DEF(struct pwc_leds, leds)
1269 - ret = pwc_set_leds(pdev, leds->led_on, leds->led_off);
1271 + ret = pwc_set_leds(pdev, ARGR(leds).led_on, ARGR(leds).led_off);
1278 - struct pwc_leds *leds = arg;
1279 + ARG_DEF(struct pwc_leds, leds)
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);
1287 case VIDIOCPWCSCONTOUR:
1289 - int *contour = arg;
1290 + ARG_DEF(int, contour)
1292 - ret = pwc_set_contour(pdev, *contour);
1294 + ret = pwc_set_contour(pdev, ARGR(contour));
1298 case VIDIOCPWCGCONTOUR:
1300 - int *contour = arg;
1301 + ARG_DEF(int, contour)
1303 - ret = pwc_get_contour(pdev, contour);
1304 + ret = pwc_get_contour(pdev, ARGA(contour));
1309 case VIDIOCPWCSBACKLIGHT:
1311 - int *backlight = arg;
1312 + ARG_DEF(int, backlight)
1314 - ret = pwc_set_backlight(pdev, *backlight);
1316 + ret = pwc_set_backlight(pdev, ARGR(backlight));
1320 case VIDIOCPWCGBACKLIGHT:
1322 - int *backlight = arg;
1323 + ARG_DEF(int, backlight)
1325 - ret = pwc_get_backlight(pdev);
1328 + ret = pwc_get_backlight(pdev, ARGA(backlight));
1329 + ARG_OUT(backlight)
1333 case VIDIOCPWCSFLICKER:
1335 - int *flicker = arg;
1336 + ARG_DEF(int, flicker)
1338 - ret = pwc_set_flicker(pdev, *flicker);
1340 + ret = pwc_set_flicker(pdev, ARGR(flicker));
1344 case VIDIOCPWCGFLICKER:
1346 - int *flicker = arg;
1347 + ARG_DEF(int, flicker)
1349 - ret = pwc_get_flicker(pdev);
1352 + ret = pwc_get_flicker(pdev, ARGA(flicker));
1357 case VIDIOCPWCSDYNNOISE:
1359 - int *dynnoise = arg;
1360 + ARG_DEF(int, dynnoise)
1362 - ret = pwc_set_dynamic_noise(pdev, *dynnoise);
1364 + ret = pwc_set_dynamic_noise(pdev, ARGR(dynnoise));
1368 case VIDIOCPWCGDYNNOISE:
1370 - int *dynnoise = arg;
1371 + ARG_DEF(int, dynnoise)
1373 - ret = pwc_get_dynamic_noise(pdev);
1377 + ret = pwc_get_dynamic_noise(pdev, ARGA(dynnoise));
1378 + ARG_OUT(dynnoise);
1382 case VIDIOCPWCGREALSIZE:
1384 - struct pwc_imagesize *size = arg;
1385 + ARG_DEF(struct pwc_imagesize, size)
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;
1395 case VIDIOCPWCMPTRESET:
1399 if (pdev->features & FEATURE_MOTOR_PANTILT)
1401 - ret = pwc_mpt_reset(pdev, *flags);
1402 + ARG_DEF(int, flags)
1405 + ret = pwc_mpt_reset(pdev, ARGR(flags));
1408 pdev->pan_angle = 0;
1409 @@ -1582,11 +1498,15 @@
1414 case VIDIOCPWCMPTGRANGE:
1416 if (pdev->features & FEATURE_MOTOR_PANTILT)
1418 - memcpy(arg, &pdev->angle_range, sizeof(struct pwc_mpt_range));
1419 + ARG_DEF(struct pwc_mpt_range, range)
1421 + ARGR(range) = pdev->angle_range;
1426 @@ -1597,23 +1517,25 @@
1428 case VIDIOCPWCMPTSANGLE:
1430 - struct pwc_mpt_angles *angles = arg;
1431 int new_pan, new_tilt;
1433 if (pdev->features & FEATURE_MOTOR_PANTILT)
1435 + ARG_DEF(struct pwc_mpt_angles, angles)
1438 /* The camera can only set relative angles, so
1439 do some calculations when getting an absolute angle .
1441 - if (angles->absolute)
1442 + if (ARGR(angles).absolute)
1444 - new_pan = angles->pan;
1445 - new_tilt = angles->tilt;
1446 + new_pan = ARGR(angles).pan;
1447 + new_tilt = ARGR(angles).tilt;
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;
1456 /* check absolute ranges */
1457 if (new_pan < pdev->angle_range.pan_min ||
1458 @@ -1649,17 +1571,19 @@
1466 case VIDIOCPWCMPTGANGLE:
1468 - struct pwc_mpt_angles *angles = arg;
1470 if (pdev->features & FEATURE_MOTOR_PANTILT)
1472 - angles->absolute = 1;
1473 - angles->pan = pdev->pan_angle;
1474 - angles->tilt = pdev->tilt_angle;
1475 + ARG_DEF(struct pwc_mpt_angles, angles)
1477 + ARGR(angles).absolute = 1;
1478 + ARGR(angles).pan = pdev->pan_angle;
1479 + ARGR(angles).tilt = pdev->tilt_angle;
1484 @@ -1670,19 +1594,34 @@
1486 case VIDIOCPWCMPTSTATUS:
1488 - struct pwc_mpt_status *status = arg;
1490 if (pdev->features & FEATURE_MOTOR_PANTILT)
1492 - ret = pwc_mpt_get_status(pdev, status);
1493 + ARG_DEF(struct pwc_mpt_status, status)
1495 + ret = pwc_mpt_get_status(pdev, ARGA(status));
1508 + case VIDIOCPWCGVIDCMD:
1510 + ARG_DEF(struct pwc_video_command, cmd);
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;
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
1529 -/* Linux driver for Philips webcam
1530 +/* Linux driver for Philips webcam
1531 USB and Video4Linux interface part.
1532 (C) 1999-2003 Nemosoft Unv.
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
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) },
1555 - /* Allocate Isochronous pipe buffers */
1556 + /* Allocate Isochronuous pipe buffers */
1557 for (i = 0; i < MAX_ISO_BUFS; i++) {
1558 if (pdev->sbuf[i].data == NULL) {
1559 kbuf = kmalloc(ISO_BUFFER_SIZE, GFP_KERNEL);
1563 unsigned long flags;
1567 spin_lock_irqsave(&pdev->ptrlock, flags);
1568 if (pdev->fill_frame != NULL) {
1572 \brief Reset all buffers, pointers and lists, except for the image_used[] buffer.
1575 If the image_used[] buffer is cleared too, mmap()/VIDIOCSYNC will run into trouble.
1577 static void pwc_reset_buffers(struct pwc_device *pdev)
1581 unsigned long flags;
1584 spin_lock_irqsave(&pdev->ptrlock, flags);
1585 /* First grab our read_frame; this is removed from all lists, so
1586 we can release the lock after this without problems */
1588 Trace(TRACE_SEQUENCE, "Decompressing frame %d\n", pdev->read_frame->sequence);
1590 /* Decompression is a lenghty process, so it's outside of the lock.
1591 - This gives the isoc_handler the opportunity to fill more frames
1592 + This gives the isoc_handler the opportunity to fill more frames
1595 spin_unlock_irqrestore(&pdev->ptrlock, flags);
1598 fillptr = fbuf->data + fbuf->filled;
1602 /* Reset ISOC error counter. We did get here, after all. */
1603 pdev->visoc_errors = 0;
1608 /* ...copy data to frame buffer, if possible */
1609 - if (flen + fbuf->filled > pdev->frame_size) {
1610 - Trace(TRACE_FLOW, "Frame buffer overflow (flen = %d, frame_size = %d).\n", flen, pdev->frame_size);
1611 + if (flen + fbuf->filled > pdev->frame_total_size) {
1612 + Trace(TRACE_FLOW, "Frame buffer overflow (flen = %d, frame_total_size = %d).\n", flen, pdev->frame_total_size);
1613 pdev->vsync = 0; /* Hmm, let's wait for an EOF (end-of-frame) */
1614 pdev->vframes_error++;
1617 pdev->drop_frames--;
1619 /* Check for underflow first */
1620 - if (fbuf->filled < pdev->frame_size) {
1621 + if (fbuf->filled < pdev->frame_total_size) {
1622 Trace(TRACE_FLOW, "Frame buffer underflow (%d bytes); discarded.\n", fbuf->filled);
1623 pdev->vframes_error++;
1627 if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) {
1628 Err("Failed to find packet size for video endpoint in current alternate setting.\n");
1629 - return -ENFILE; /* Odd error, that should be noticeable */
1630 + return -ENFILE; /* Odd error, that should be noticable */
1633 /* Set alternate interface */
1636 Err("isoc_init() submit_urb %d failed with error %d\n", i, ret);
1638 - Trace(TRACE_OPEN, "URB 0x%p submitted.\n", pdev->sbuf[i].urb);
1639 + Trace(TRACE_MEMORY, "URB 0x%p submitted.\n", pdev->sbuf[i].urb);
1642 /* All is done... */
1644 static void pwc_isoc_cleanup(struct pwc_device *pdev)
1649 Trace(TRACE_OPEN, ">> pwc_isoc_cleanup()\n");
1653 Trace(TRACE_FLOW, "pwc_set_video_mode attempt 2 failed.\n");
1659 - if (pwc_isoc_init(pdev) < 0)
1660 + if (pwc_isoc_init(pdev) < 0)
1662 Info("Failed to restart ISOC transfers in pwc_try_video_mode.\n");
1663 ret = -EAGAIN; /* let's try again, who knows if it works a second time */
1664 @@ -970,24 +971,28 @@
1665 Trace(TRACE_OPEN, "Doing first time initialization.\n");
1668 - if (pwc_trace & TRACE_OPEN) {
1669 + if (pwc_trace & TRACE_OPEN)
1671 /* Query sensor type */
1672 const char *sensor_type = NULL;
1675 - i = pwc_get_cmos_sensor(pdev);
1677 - case -1: /* Unknown, show nothing */; break;
1678 - case 0x00: sensor_type = "Hyundai CMOS sensor"; break;
1679 - case 0x20: sensor_type = "Sony CCD sensor + TDA8787"; break;
1680 - case 0x2E: sensor_type = "Sony CCD sensor + Exas 98L59"; break;
1681 - case 0x2F: sensor_type = "Sony CCD sensor + ADI 9804"; break;
1682 - case 0x30: sensor_type = "Sharp CCD sensor + TDA8787"; break;
1683 - case 0x3E: sensor_type = "Sharp CCD sensor + Exas 98L59"; break;
1684 - case 0x3F: sensor_type = "Sharp CCD sensor + ADI 9804"; break;
1685 - case 0x40: sensor_type = "UPA 1021 sensor"; break;
1686 - case 0x100: sensor_type = "VGA sensor"; break;
1687 - case 0x101: sensor_type = "PAL MR sensor"; break;
1688 - default: sensor_type = "unknown type of sensor"; break;
1689 + ret = pwc_get_cmos_sensor(pdev, &i);
1693 + case 0x00: sensor_type = "Hyundai CMOS sensor"; break;
1694 + case 0x20: sensor_type = "Sony CCD sensor + TDA8787"; break;
1695 + case 0x2E: sensor_type = "Sony CCD sensor + Exas 98L59"; break;
1696 + case 0x2F: sensor_type = "Sony CCD sensor + ADI 9804"; break;
1697 + case 0x30: sensor_type = "Sharp CCD sensor + TDA8787"; break;
1698 + case 0x3E: sensor_type = "Sharp CCD sensor + Exas 98L59"; break;
1699 + case 0x3F: sensor_type = "Sharp CCD sensor + ADI 9804"; break;
1700 + case 0x40: sensor_type = "UPA 1021 sensor"; break;
1701 + case 0x100: sensor_type = "VGA sensor"; break;
1702 + case 0x101: sensor_type = "PAL MR sensor"; break;
1703 + default: sensor_type = "unknown type of sensor"; break;
1706 if (sensor_type != NULL)
1707 Info("This %s camera is equipped with a %s (%d).\n", pdev->vdev.name, sensor_type, i);
1708 @@ -1035,6 +1040,7 @@
1710 /* Set some defaults */
1711 pdev->vsnapshot = 0;
1713 /* Start iso pipe for video; first try the last used video size
1714 (or the default one); if that fails try QCIF/10 or QSIF/10;
1715 it that fails too, give up.
1716 @@ -1088,7 +1094,7 @@
1718 /* Dump statistics, but only if a reasonable amount of frames were
1719 processed (to prevent endless log-entries in case of snap-shot
1723 if (pdev->vframe_count > 20)
1724 Info("Closing video device: %d frames received, dumped %d frames, %d frames with errors.\n", pdev->vframe_count, pdev->vframes_dumped, pdev->vframes_error);
1725 @@ -1109,7 +1115,7 @@
1726 Info("Failed to set LED on/off time.\n");
1728 i = pwc_camera_power(pdev, 0);
1731 Err("Failed to power down camera (%d)\n", i);
1734 @@ -1143,6 +1149,7 @@
1735 struct pwc_device *pdev;
1736 int noblock = file->f_flags & O_NONBLOCK;
1737 DECLARE_WAITQUEUE(wait, current);
1738 + int bytes_to_read;
1740 Trace(TRACE_READ, "video_read(0x%p, %p, %d) called.\n", vdev, buf, count);
1742 @@ -1179,20 +1186,25 @@
1744 remove_wait_queue(&pdev->frameq, &wait);
1745 set_current_state(TASK_RUNNING);
1748 /* Decompress and release frame */
1749 if (pwc_handle_frame(pdev))
1753 Trace(TRACE_READ, "Copying data to user space.\n");
1754 + if (pdev->vpalette == VIDEO_PALETTE_RAW)
1755 + bytes_to_read = pdev->frame_size;
1757 + bytes_to_read = pdev->view.size;
1759 /* copy bytes to user space; we allow for partial reads */
1760 - if (count + pdev->image_read_pos > pdev->view.size)
1761 - count = pdev->view.size - pdev->image_read_pos;
1762 + if (count + pdev->image_read_pos > bytes_to_read)
1763 + count = bytes_to_read - pdev->image_read_pos;
1764 if (copy_to_user(buf, pdev->image_ptr[pdev->fill_image] + pdev->image_read_pos, count))
1766 pdev->image_read_pos += count;
1767 - if (pdev->image_read_pos >= pdev->view.size) { /* All data has been read */
1768 + if (pdev->image_read_pos >= bytes_to_read) { /* All data has been read */
1769 pdev->image_read_pos = 0;
1770 pwc_next_image(pdev);
1772 @@ -1264,7 +1276,7 @@
1778 /* The spec says the argument is an integer, but
1779 the bttv driver uses a video_channel arg, which
1780 makes sense becasue it also has the norm flag.
1781 @@ -1282,8 +1294,6 @@
1782 struct video_picture *p = arg;
1785 - p->colour = 0x8000;
1787 val = pwc_get_brightness(pdev);
1789 p->brightness = val;
1790 @@ -1306,11 +1316,11 @@
1794 - p->palette = VIDEO_PALETTE_YUV420P;
1795 + p->palette = pdev->vpalette;
1796 p->hue = 0xFFFF; /* N/A */
1803 struct video_picture *p = arg;
1804 @@ -1322,13 +1332,22 @@
1805 is used exactly once in the uncompress
1808 - if (p->palette && p->palette != VIDEO_PALETTE_YUV420P) {
1811 pwc_set_brightness(pdev, p->brightness);
1812 pwc_set_contrast(pdev, p->contrast);
1813 pwc_set_gamma(pdev, p->whiteness);
1814 pwc_set_saturation(pdev, p->colour);
1815 + if (p->palette && p->palette != pdev->vpalette) {
1816 + switch (p->palette) {
1817 + case VIDEO_PALETTE_YUV420P:
1818 + case VIDEO_PALETTE_RAW:
1819 + pdev->vpalette = p->palette;
1820 + return pwc_try_video_mode(pdev, pdev->image.x, pdev->image.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
1830 @@ -1402,13 +1421,23 @@
1831 various palettes... The driver doesn't support
1832 such small images, so I'm working around it.
1834 - if (vm->format && vm->format != VIDEO_PALETTE_YUV420P)
1839 + switch (vm->format)
1841 + case VIDEO_PALETTE_YUV420P:
1842 + case VIDEO_PALETTE_RAW:
1850 if ((vm->width != pdev->view.x || vm->height != pdev->view.y) &&
1851 (vm->width >= pdev->view_min.x && vm->height >= pdev->view_min.y)) {
1855 Trace(TRACE_OPEN, "VIDIOCMCAPTURE: changing size to please xawtv :-(.\n");
1856 ret = pwc_try_video_mode(pdev, vm->width, vm->height, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
1858 @@ -1640,12 +1669,12 @@
1862 - Info("Philips PCVC730K (ToUCam Fun) USB webcam detected.\n");
1863 + Info("Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) USB webcam detected.\n");
1864 name = "Philips 730 webcam";
1868 - Info("Philips PCVC740K (ToUCam Pro) USB webcam detected.\n");
1869 + Info("Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) USB webcam detected.\n");
1870 name = "Philips 740 webcam";
1873 @@ -1759,18 +1788,45 @@
1877 - else if (vendor_id == 0x04cc) {
1878 + else if (vendor_id == 0x04cc) {
1879 switch(product_id) {
1881 Info("Sotec Afina Eye USB webcam detected.\n");
1882 name = "Sotec Afina Eye";
1891 + else if (vendor_id == 0x06be) {
1892 + switch(product_id) {
1894 + /* Basicly the same as the Sotec Afina Eye */
1895 + Info("AME CU-001 USB webcam detected.\n");
1896 + name = "AME CU-001";
1904 + else if (vendor_id == 0x06be) {
1905 + switch(product_id) {
1907 + /* This is essentially the same cam as the Sotec Afina Eye */
1908 + Info("AME Co. Afina Eye USB webcam detected.\n");
1909 + name = "AME Co. Afina Eye";
1918 else if (vendor_id == 0x0d81) {
1919 switch(product_id) {
1921 @@ -1819,8 +1875,6 @@
1922 pdev->angle_range.pan_max = 7000;
1923 pdev->angle_range.tilt_min = -3000;
1924 pdev->angle_range.tilt_max = 2500;
1925 - pdev->angle_range.zoom_min = -1;
1926 - pdev->angle_range.zoom_max = -1;
1929 init_MUTEX(&pdev->modlock);
1930 @@ -1834,7 +1888,7 @@
1931 strcpy(pdev->vdev.name, name);
1932 pdev->vdev.owner = THIS_MODULE;
1933 pdev->vdev.priv = pdev;
1936 pdev->release = udev->descriptor.bcdDevice;
1937 Trace(TRACE_PROBE, "Release: %04x\n", pdev->release);
1939 @@ -1898,14 +1952,14 @@
1940 Err("pwc_disconnect() Magic number failed. Consult your scrolls and try again.\n");
1941 goto disconnect_out;
1946 /* We got unplugged; this is signalled by an EPIPE error code */
1948 Info("Disconnected while webcam is in use!\n");
1949 pdev->error_status = EPIPE;
1953 /* Alert waiting processes */
1954 wake_up_interruptible(&pdev->frameq);
1955 /* Wait until device is closed */
1956 @@ -1913,7 +1967,7 @@
1958 /* Device is now closed, so we can safely unregister it */
1959 Trace(TRACE_PROBE, "Unregistering video device in disconnect().\n");
1960 - video_unregister_device(&pdev->vdev);
1961 + video_unregister_device(&pdev->vdev);
1963 /* Free memory (don't set pdev to 0 just yet) */
1965 @@ -1932,7 +1986,7 @@
1966 static int pwc_atoi(const char *s)
1972 while (*s != '\0' && *s >= '0' && *s <= '9') {
1973 k = 10 * k + (*s - '0');
1974 @@ -1975,7 +2029,7 @@
1975 MODULE_PARM_DESC(dev_hint, "Device node hints");
1977 MODULE_DESCRIPTION("Philips & OEM USB webcam driver");
1978 -MODULE_AUTHOR("Nemosoft Unv. <nemosoft@smcc.demon.nl>");
1979 +MODULE_AUTHOR("Nemosoft Unv. <webcam@smcc.demon.nl>");
1980 MODULE_LICENSE("GPL");
1982 static int __init usb_pwc_init(void)
1983 @@ -1983,9 +2037,10 @@
1985 char *sizenames[PSZ_MAX] = { "sqcif", "qsif", "qcif", "sif", "cif", "vga" };
1987 - Info("Philips PCA645/646 + PCVC675/680/690 + PCVC730/740/750 webcam module version " PWC_VERSION " loaded.\n");
1988 - Info("Also supports the Askey VC010, various Logitech QuickCams, Samsung MPC-C10 and MPC-C30,\n");
1989 - Info("the Creative WebCam 5, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n");
1990 + Info("Philips webcam module version " PWC_VERSION " loaded.\n");
1991 + Info("Supports Philips PCA645/646, PCVC675/680/690, PCVC720[40]/730/740/750 & PCVC830/840.\n");
1992 + Info("Also supports the Askey VC010, various Logitech Quickcams, Samsung MPC-C10 and MPC-C30,\n");
1993 + Info("the Creative WebCam 5 & Pro Ex, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n");
1996 if (fps < 4 || fps > 30) {
1997 @@ -1995,7 +2050,7 @@
1999 Info("Default framerate set to %d.\n", default_fps);
2004 /* string; try matching with array */
2005 for (sz = 0; sz < PSZ_MAX; sz++) {
2006 @@ -2045,12 +2100,12 @@
2010 - /* Big device node whoopla. Basically, it allows you to assign a
2011 - device node (/dev/videoX) to a camera, based on its type
2012 + /* Big device node whoopla. Basicly, it allows you to assign a
2013 + device node (/dev/videoX) to a camera, based on its type
2014 & serial number. The format is [type[.serialnumber]:]node.
2016 - Any camera that isn't matched by these rules gets the next
2017 - available free device node.
2018 + Any camera that isn't matched by these rules gets the next
2019 + available free device node.
2021 for (i = 0; i < MAX_DEV_HINTS; i++) {
2022 char *s, *colon, *dot;
2023 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
2024 --- linux-2.6.6.org/drivers/usb/media/pwc-ioctl.h 2004-05-10 04:32:29.000000000 +0200
2025 +++ linux-2.6.6/drivers/usb/media/pwc-ioctl.h 2004-05-07 00:52:23.000000000 +0200
2030 -/* (C) 2001-2003 Nemosoft Unv. webcam@smcc.demon.nl
2032 +/* (C) 2001-2004 Nemosoft Unv. webcam@smcc.demon.nl
2034 This program is free software; you can redistribute it and/or modify
2035 it under the terms of the GNU General Public License as published by
2036 the Free Software Foundation; either version 2 of the License, or
2038 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2041 -/* This is pwc-ioctl.h belonging to PWC 8.10 */
2042 +/* This is pwc-ioctl.h belonging to PWC 8.12.1
2043 + It contains structures and defines to communicate from user space
2044 + directly to the driver.
2050 - 2001/08/03 Alvarado Added ioctl constants to access methods for
2051 + 2001/08/03 Alvarado Added ioctl constants to access methods for
2052 changing white balance and red/blue gains
2053 2002/12/15 G. H. Fernandez-Toribio VIDIOCGREALSIZE
2054 + 2003/12/13 Nemosft Unv. Some modifications to make interfacing to
2058 /* These are private ioctl() commands, specific for the Philips webcams.
2059 They contain functions not found in other webcams, and settings not
2060 - specified in the Video4Linux API.
2062 + specified in the Video4Linux API.
2064 The #define names are built up like follows:
2065 VIDIOC VIDeo IOCtl prefix
2071 + /* Enumeration of image sizes */
2072 +#define PSZ_SQCIF 0x00
2073 +#define PSZ_QSIF 0x01
2074 +#define PSZ_QCIF 0x02
2075 +#define PSZ_SIF 0x03
2076 +#define PSZ_CIF 0x04
2077 +#define PSZ_VGA 0x05
2081 /* The frame rate is encoded in the video_window.flags parameter using
2082 the upper 16 bits, since some flags are defined nowadays. The following
2083 defines provide a mask and shift to filter out this value.
2085 - In 'Snapshot' mode the camera freezes its automatic exposure and colour
2087 + In 'Snapshot' mode the camera freezes its automatic exposure and colour
2090 #define PWC_FPS_SHIFT 16
2092 #define PWC_FPS_SNAPSHOT 0x00400000
2095 +/* structure for transfering x & y coordinates */
2098 + int x, y; /* guess what */
2099 + int size; /* size, or offset */
2103 +/* Used with VIDIOCPWCPROBE */
2108 otherwise undefined.
2109 'read_red' and 'read_blue' are read-only.
2112 struct pwc_whitebalance
2116 #define PWC_MPT_TILT 0x02
2117 #define PWC_MPT_TIMEOUT 0x04 /* for status */
2119 -/* Set angles; when absolute = 1, the angle is absolute and the
2120 +/* Set angles; when absolute != 0, the angle is absolute and the
2121 driver calculates the relative offset for you. This can only
2122 be used with VIDIOCPWCSANGLE; VIDIOCPWCGANGLE always returns
2124 @@ -127,18 +147,14 @@
2125 int absolute; /* write-only */
2126 int pan; /* degrees * 100 */
2127 int tilt; /* degress * 100 */
2128 - int zoom; /* N/A, set to -1 */
2131 /* Range of angles of the camera, both horizontally and vertically.
2132 - The zoom is not used, maybe in the future...
2135 struct pwc_mpt_range
2137 int pan_min, pan_max; /* degrees * 100 */
2138 int tilt_min, tilt_max;
2139 - int zoom_min, zoom_max; /* -1, -1 */
2142 struct pwc_mpt_status
2143 @@ -149,6 +165,30 @@
2147 +/* This is used for out-of-kernel decompression. With it, you can get
2148 + all the necessary information to initialize and use the decompressor
2149 + routines in standalone applications.
2151 +struct pwc_video_command
2153 + int type; /* camera type (645, 675, 730, etc.) */
2154 + int release; /* release number */
2156 + int size; /* one of PSZ_* */
2158 + int command_len; /* length of USB video command */
2159 + unsigned char command_buf[13]; /* Actual USB video command */
2160 + int bandlength; /* >0 = compressed */
2161 + int frame_size; /* Size of one (un)compressed frame */
2164 +/* Flags for PWCX subroutines. Not all modules honour all flags. */
2165 +#define PWCX_FLAG_PLANAR 0x0001
2166 +#define PWCX_FLAG_BAYER 0x0008
2169 +/* IOCTL definitions */
2171 /* Restore user settings */
2172 #define VIDIOCPWCRUSER _IO('v', 192)
2173 /* Save user settings */
2174 @@ -172,13 +212,13 @@
2175 /* This is a probe function; since so many devices are supported, it
2176 becomes difficult to include all the names in programs that want to
2177 check for the enhanced Philips stuff. So in stead, try this PROBE;
2178 - it returns a structure with the original name, and the corresponding
2179 + it returns a structure with the original name, and the corresponding
2181 To use, fill the structure with zeroes, call PROBE and if that succeeds,
2182 compare the name with that returned from VIDIOCGCAP; they should be the
2183 same. If so, you can be assured it is a Philips (OEM) cam and the type
2187 #define VIDIOCPWCPROBE _IOR('v', 199, struct pwc_probe)
2189 /* Set AGC (Automatic Gain Control); int < 0 = auto, 0..65535 = fixed */
2191 #define VIDIOCPWCMPTSANGLE _IOW('v', 212, struct pwc_mpt_angles)
2192 #define VIDIOCPWCMPTGANGLE _IOR('v', 212, struct pwc_mpt_angles)
2193 #define VIDIOCPWCMPTSTATUS _IOR('v', 213, struct pwc_mpt_status)
2196 + /* Get the USB set-video command; needed for initializing libpwcx */
2197 +#define VIDIOCPWCGVIDCMD _IOR('v', 215, struct pwc_video_command)
2200 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
2201 --- linux-2.6.6.org/drivers/usb/media/pwc-misc.c 2004-05-10 04:32:28.000000000 +0200
2202 +++ linux-2.6.6/drivers/usb/media/pwc-misc.c 2004-05-07 00:52:23.000000000 +0200
2204 You should have received a copy of the GNU General Public License
2205 along with this program; if not, write to the Free Software
2206 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2210 #include <linux/slab.h>
2214 -struct pwc_coord pwc_image_sizes[PSZ_MAX] =
2215 +struct pwc_coord pwc_image_sizes[PSZ_MAX] =
2223 - /* Make sure we don't go beyond our max size */
2224 - if (width > pdev->view_max.x || height > pdev->view_max.y)
2226 + /* Make sure we don't go beyond our max size.
2227 + NB: we have different limits for RAW and normal modes. In case
2228 + you don't have the decompressor loaded or use RAW mode,
2229 + the maximum viewable size is smaller.
2231 + if (pdev->vpalette == VIDEO_PALETTE_RAW)
2233 + if (width > pdev->abs_max.x || height > pdev->abs_max.y)
2235 + Debug("VIDEO_PALETTE_RAW: going beyond abs_max.\n");
2241 + if (width > pdev->view_max.x || height > pdev->view_max.y)
2243 + Debug("VIDEO_PALETTE_ not RAW: going beyond view_max.\n");
2248 /* Find the largest size supported by the camera that fits into the
2253 for (i = 0; i < PSZ_MAX; i++) {
2255 pdev->view_min.y = 96;
2256 pdev->view_max.x = 352;
2257 pdev->view_max.y = 288;
2258 + pdev->abs_max.x = 352;
2259 + pdev->abs_max.y = 288;
2260 pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QCIF | 1 << PSZ_CIF;
2261 pdev->vcinterface = 2;
2262 pdev->vendpoint = 4;
2264 if (pdev->decompressor != NULL) {
2265 pdev->view_max.x = 640;
2266 pdev->view_max.y = 480;
2267 - pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF | 1 << PSZ_VGA;
2270 pdev->view_max.x = 352;
2271 pdev->view_max.y = 288;
2272 - pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF;
2274 + pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF | 1 << PSZ_VGA;
2275 + pdev->abs_max.x = 640;
2276 + pdev->abs_max.y = 480;
2277 pdev->vcinterface = 3;
2278 pdev->vendpoint = 4;
2279 pdev->frame_header_size = 0;
2280 @@ -99,24 +121,26 @@
2281 if (pdev->decompressor != NULL) {
2282 pdev->view_max.x = 640;
2283 pdev->view_max.y = 480;
2284 - pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA;
2287 - /* Tell CIF, even though SIF really is the maximum, but some tools really need CIF */
2288 + /* We use CIF, not SIF since some tools really need CIF. So we cheat a bit. */
2289 pdev->view_max.x = 352;
2290 pdev->view_max.y = 288;
2291 - pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF;
2293 + pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA;
2294 + pdev->abs_max.x = 640;
2295 + pdev->abs_max.y = 480;
2296 pdev->vcinterface = 3;
2297 pdev->vendpoint = 5;
2298 pdev->frame_header_size = TOUCAM_HEADER_SIZE;
2299 pdev->frame_trailer_size = TOUCAM_TRAILER_SIZE;
2302 + pdev->vpalette = VIDEO_PALETTE_YUV420P; /* default */
2303 pdev->view_min.size = pdev->view_min.x * pdev->view_min.y;
2304 pdev->view_max.size = pdev->view_max.x * pdev->view_max.y;
2305 - /* length of image, in YUV format */
2306 - pdev->len_per_image = (pdev->view_max.size * 3) / 2;
2307 + /* length of image, in YUV format; always allocate enough memory. */
2308 + pdev->len_per_image = (pdev->abs_max.x * pdev->abs_max.y * 3) / 2;
2312 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
2313 --- linux-2.6.6.org/drivers/usb/media/pwc-uncompress.c 2004-05-10 04:32:37.000000000 +0200
2314 +++ linux-2.6.6/drivers/usb/media/pwc-uncompress.c 2004-05-07 00:52:23.000000000 +0200
2316 -/* Linux driver for Philips webcam
2317 +/* Linux driver for Philips webcam
2318 Decompression frontend.
2319 (C) 1999-2003 Nemosoft Unv. (webcam@smcc.demon.nl)
2322 themselves. It also has a decompressor wrapper function.
2325 +#include <asm/current.h>
2326 #include <asm/types.h>
2327 +// #include <linux/sched.h>
2330 #include "pwc-uncompress.h"
2333 u16 *dsty, *dstu, *dstv;
2338 #if defined(__KERNEL__) && defined(PWC_MAGIC)
2340 image = pdev->image_ptr[pdev->fill_image];
2345 yuv = fbuf->data + pdev->frame_header_size; /* Skip header */
2346 - if (pdev->vbandlength == 0) {
2348 + /* Raw format; that's easy... */
2349 + if (pdev->vpalette == VIDEO_PALETTE_RAW)
2351 + memcpy(image, yuv, pdev->frame_size);
2355 + if (pdev->vbandlength == 0) {
2356 /* Uncompressed mode. We copy the data into the output buffer,
2357 using the viewport size (which may be larger than the image
2358 size). Unfortunately we have to do a bit of byte stuffing
2359 to get the desired output format/size.
2362 - * We do some byte shuffling here to go from the
2364 + * We do some byte shuffling here to go from the
2365 * native format to YUV420P.
2368 @@ -140,15 +149,21 @@
2369 dstu += (stride >> 1);
2373 - /* Compressed; the decompressor routines will write the data
2375 + /* Compressed; the decompressor routines will write the data
2376 in planar format immediately.
2380 + flags = PWCX_FLAG_PLANAR;
2381 + if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot)
2382 + flags |= PWCX_FLAG_BAYER;
2384 if (pdev->decompressor)
2385 pdev->decompressor->decompress(
2386 &pdev->image, &pdev->view, &pdev->offset,
2390 pdev->decompress_data, pdev->vbandlength);
2392 return -ENXIO; /* No such device or address: missing decompressor */
2393 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
2394 --- linux-2.6.6.org/drivers/usb/media/pwc-uncompress.h 2004-05-10 04:32:27.000000000 +0200
2395 +++ linux-2.6.6/drivers/usb/media/pwc-uncompress.h 2004-05-07 00:52:23.000000000 +0200
2397 #define PWC_UNCOMPRESS_H
2399 #include <linux/config.h>
2400 +#include <linux/linkage.h>
2401 #include <linux/list.h>
2405 +/* from pwc-dec.h */
2406 +#define PWCX_FLAG_PLANAR 0x0001
2414 int type; /* type of camera (645, 680, etc) */
2415 int table_size; /* memory needed */
2417 - void (* init)(int release, void *buffer, void *table); /* Initialization routine; should be called after each set_video_mode */
2418 - void (* exit)(void); /* Cleanup routine */
2419 - void (* decompress)(struct pwc_coord *image, struct pwc_coord *view, struct pwc_coord *offset,
2420 - void *src, void *dst, int planar,
2421 + asmlinkage void (* init)(int type, int release, void *buffer, void *table); /* Initialization routine; should be called after each set_video_mode */
2422 + asmlinkage void (* exit)(void); /* Cleanup routine */
2423 + asmlinkage void (* decompress)(struct pwc_coord *image, struct pwc_coord *view, struct pwc_coord *offset,
2424 + void *src, void *dst, int flags,
2425 void *table, int bandlength);
2426 void (* lock)(void); /* make sure module cannot be unloaded */
2427 void (* unlock)(void); /* release lock on module */
2428 diff -Nur --exclude '*.orig' linux-2.6.6.org/drivers/usb/media/pwc.h linux-2.6.6/drivers/usb/media/pwc.h
2429 --- linux-2.6.6.org/drivers/usb/media/pwc.h 2004-05-10 04:32:51.000000000 +0200
2430 +++ linux-2.6.6/drivers/usb/media/pwc.h 2004-05-07 00:52:23.000000000 +0200
2433 #include <linux/config.h>
2434 #include <linux/module.h>
2435 -#include <linux/smp_lock.h>
2436 -#include <linux/spinlock.h>
2437 #include <linux/usb.h>
2438 +#include <linux/spinlock.h>
2439 #include <linux/videodev.h>
2440 #include <linux/wait.h>
2442 +#include <linux/smp_lock.h>
2443 #include <asm/semaphore.h>
2444 #include <asm/errno.h>
2447 #define FEATURE_MOTOR_PANTILT 0x0001
2450 -#define PWC_MAJOR 8
2451 -#define PWC_MINOR 12
2452 -#define PWC_VERSION "8.12"
2453 +#define PWC_MAJOR 9
2454 +#define PWC_MINOR 0
2455 +#define PWC_VERSION "9.0-BETA-2"
2456 #define PWC_NAME "pwc"
2458 /* Turn certain features on/off */
2460 /* Absolute maximum number of buffers available for mmap() */
2461 #define MAX_IMAGES 10
2465 - int x, y; /* guess what */
2466 - int size; /* size, or offset */
2469 /* The following structures were based on cpia.h. Why reinvent the wheel? :-) */
2473 int vcinterface; /* video control interface */
2474 int valternate; /* alternate interface needed */
2475 int vframes, vsize; /* frames-per-second & size (see PSZ_*) */
2476 + int vpalette; /* palette: 420P, RAW or RGBBAYER */
2477 int vframe_count; /* received frames */
2478 int vframes_dumped; /* counter for dumped frames */
2479 int vframes_error; /* frames received in error */
2481 char vsnapshot; /* snapshot mode */
2482 char vsync; /* used by isoc handler */
2483 char vmirror; /* for ToUCaM series */
2486 + unsigned char cmd_buf[13];
2488 /* The image acquisition requires 3 to 4 steps:
2489 1. data is gathered in short packets from the USB controller
2491 struct pwc_frame_buf *full_frames, *full_frames_tail; /* all filled frames */
2492 struct pwc_frame_buf *fill_frame; /* frame currently being filled */
2493 struct pwc_frame_buf *read_frame; /* frame currently read by user process */
2495 int frame_header_size, frame_trailer_size;
2497 + int frame_total_size; /* including header & trailer */
2500 int sequence; /* Debugging aid */
2502 a gray or black border. view_min <= image <= view <= view_max;
2504 int image_mask; /* bitmask of supported sizes */
2505 - struct pwc_coord view_min, view_max; /* minimum and maximum sizes */
2506 + struct pwc_coord view_min, view_max; /* minimum and maximum viewable sizes */
2507 + struct pwc_coord abs_max; /* maximum supported size with compression */
2508 struct pwc_coord image, view; /* image and viewport size */
2509 struct pwc_coord offset; /* offset within the viewport */
2511 @@ -213,16 +212,6 @@
2515 -/* Enumeration of image sizes */
2516 -#define PSZ_SQCIF 0x00
2517 -#define PSZ_QSIF 0x01
2518 -#define PSZ_QCIF 0x02
2519 -#define PSZ_SIF 0x03
2520 -#define PSZ_CIF 0x04
2521 -#define PSZ_VGA 0x05
2529 extern int pwc_set_saturation(struct pwc_device *pdev, int value);
2530 extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value);
2531 extern int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value);
2532 -extern int pwc_get_cmos_sensor(struct pwc_device *pdev);
2533 +extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor);
2535 /* Power down or up the camera; not supported by all models */
2536 extern int pwc_camera_power(struct pwc_device *pdev, int power);
2537 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
2538 --- linux-2.6.6.org/drivers/usb/media/pwcx-glue.c 1970-01-01 01:00:00.000000000 +0100
2539 +++ linux-2.6.6/drivers/usb/media/pwcx-glue.c 2004-05-07 01:10:43.000000000 +0200
2541 +/* PWCX module glue code. */
2543 +#include <linux/config.h>
2547 +#include "pwc-uncompress.h"
2549 +#define PWCX_MAJOR 9
2550 +#define PWCX_MINOR 0
2552 +#ifdef CONFIG_USB_PWCX_MODULE
2553 +#include <linux/init.h>
2554 +#include <linux/module.h>
2555 +#include <linux/version.h>
2557 +MODULE_DESCRIPTION("Philips webcam decompressor routines");
2558 +MODULE_AUTHOR("Nemosoft Unv. <webcam@smcc.demon.nl>");
2559 +MODULE_LICENSE("Proprietary. See http://www.smcc.demon.nl/webcam/tainting.html");
2561 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
2565 +static void lock_pwcx(void)
2567 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
2568 + MOD_INC_USE_COUNT;
2572 +static void unlock_pwcx(void)
2574 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
2575 + MOD_DEC_USE_COUNT;
2581 +static void lock_pwcx(void)
2585 +static void unlock_pwcx(void)
2591 +static struct pwc_decompressor Nala[2] =
2596 + pwcx_init_decompress_Nala,
2597 + pwcx_exit_decompress_Nala,
2598 + pwcx_decompress_Nala,
2605 + pwcx_init_decompress_Nala,
2606 + pwcx_exit_decompress_Nala,
2607 + pwcx_decompress_Nala,
2613 +static struct pwc_decompressor Timon[3] =
2618 + pwcx_init_decompress_Timon,
2619 + pwcx_exit_decompress_Timon,
2620 + pwcx_decompress_Timon,
2627 + pwcx_init_decompress_Timon,
2628 + pwcx_exit_decompress_Timon,
2629 + pwcx_decompress_Timon,
2636 + pwcx_init_decompress_Timon,
2637 + pwcx_exit_decompress_Timon,
2638 + pwcx_decompress_Timon,
2644 +static struct pwc_decompressor Kiara[4] =
2649 + pwcx_init_decompress_Kiara,
2650 + pwcx_exit_decompress_Kiara,
2651 + pwcx_decompress_Kiara,
2658 + pwcx_init_decompress_Kiara,
2659 + pwcx_exit_decompress_Kiara,
2660 + pwcx_decompress_Kiara,
2667 + pwcx_init_decompress_Kiara,
2668 + pwcx_exit_decompress_Kiara,
2669 + pwcx_decompress_Kiara,
2676 + pwcx_init_decompress_Kiara,
2677 + pwcx_exit_decompress_Kiara,
2678 + pwcx_decompress_Kiara,
2684 +#ifdef CONFIG_USB_PWCX_MODULE
2685 +static int __init usb_pwcx_init(void)
2687 +int usb_pwcx_init(void)
2690 + Info("Philips webcam decompressor routines version %d.%d-BETA-2\n", PWCX_MAJOR, PWCX_MINOR);
2691 + Info("Supports all cameras supported by the main module (pwc).\n");
2693 + /* register decompression modules */
2694 + if (pwc_decompressor_version != PWCX_MAJOR) {
2695 + Err("Version mismatch! These decompression routines are version %d.*, while the\n"
2696 + "main module expects version %d.*. Please consult the Philips webcam Linux\n"
2697 + "driver page for the correct version and downloads.\n", PWCX_MAJOR, pwc_decompressor_version);
2700 + pwc_register_decompressor(&Nala[0]);
2701 + pwc_register_decompressor(&Nala[1]);
2702 + pwc_register_decompressor(&Timon[0]);
2703 + pwc_register_decompressor(&Timon[1]);
2704 + pwc_register_decompressor(&Timon[2]);
2705 + pwc_register_decompressor(&Kiara[0]);
2706 + pwc_register_decompressor(&Kiara[1]);
2707 + pwc_register_decompressor(&Kiara[2]);
2708 + pwc_register_decompressor(&Kiara[3]);
2712 +#ifdef CONFIG_USB_PWCX_MODULE
2713 +static void __exit usb_pwcx_exit(void)
2715 +void usb_pwcx_exit(void)
2718 + pwc_unregister_decompressor(Nala[0].type);
2719 + pwc_unregister_decompressor(Nala[1].type);
2720 + pwc_unregister_decompressor(Timon[0].type);
2721 + pwc_unregister_decompressor(Timon[1].type);
2722 + pwc_unregister_decompressor(Timon[2].type);
2723 + pwc_unregister_decompressor(Kiara[0].type);
2724 + pwc_unregister_decompressor(Kiara[1].type);
2725 + pwc_unregister_decompressor(Kiara[2].type);
2726 + pwc_unregister_decompressor(Kiara[3].type);
2727 + Info("Philips webcam decompressor routines removed.\n");
2730 +#ifdef CONFIG_USB_PWCX_MODULE
2731 +module_init(usb_pwcx_init);
2732 +module_exit(usb_pwcx_exit);
2734 diff -Nur --exclude '*.orig' linux-2.6.6.org/drivers/usb/media/pwcx.h linux-2.6.6/drivers/usb/media/pwcx.h
2735 --- linux-2.6.6.org/drivers/usb/media/pwcx.h 1970-01-01 01:00:00.000000000 +0100
2736 +++ linux-2.6.6/drivers/usb/media/pwcx.h 2004-05-07 01:10:43.000000000 +0200
2741 +#include <linux/linkage.h>
2742 +#include "pwc-ioctl.h"
2749 +extern asmlinkage void pwcx_init_decompress_Nala(int type, int release, void *mode, void *table);
2750 +extern asmlinkage void pwcx_exit_decompress_Nala(void);
2751 +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);
2753 +extern asmlinkage void pwcx_init_decompress_Timon(int type, int release, void *mode, void *table);
2754 +extern asmlinkage void pwcx_exit_decompress_Timon(void);
2755 +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);
2757 +extern asmlinkage void pwcx_init_decompress_Kiara(int type, int release, void *mode, void *table);
2758 +extern asmlinkage void pwcx_exit_decompress_Kiara(void);
2759 +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);