]> git.pld-linux.org Git - packages/kernel.git/blame - linux-2.4.19-pre8-konicawc.patch
- obsolete
[packages/kernel.git] / linux-2.4.19-pre8-konicawc.patch
CommitLineData
f512433a 1diff -urN -X /home/spse/dontdiff linux-2.4.19-pre8/Documentation/Configure.help linux-2.4.19-pre8-konicawc/Documentation/Configure.help
2--- linux-2.4.19-pre8/Documentation/Configure.help Sat May 11 01:02:03 2002
3+++ linux-2.4.19-pre8-konicawc/Documentation/Configure.help Sat May 11 01:19:34 2002
4@@ -13685,6 +13685,21 @@
5 The module will be called vicam.o. If you want to compile it as a
6 module, say M here and read <file:Documentation/modules.txt>.
7
8+Konica based Webcam
9+CONFIG_USB_KONICAWC
10+ Say Y here if you want support for webcams based on a Konica
11+ chipset. This is known to work with the Intel YC76 webcam.
12+
13+ This driver uses the Video For Linux API. You must enable
14+ (Y or M in config) Video For Linux (under Character Devices)
15+ to use this driver. Information on this API and pointers to
16+ "v4l" programs may be found on the WWW at
17+ <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
18+
19+ This code is also available as a module ( = code which can be
20+ inserted in and removed from the running kernel whenever you want).
21+ The module will be called konicawc.o. If you want to compile it as
22+ a module, say M here and read <file:Documentation/modules.txt>.
23
24 Pegasus/Pegasus II based USB-Ethernet device support
25 CONFIG_USB_PEGASUS
26diff -urN -X /home/spse/dontdiff linux-2.4.19-pre8/drivers/usb/Config.in linux-2.4.19-pre8-konicawc/drivers/usb/Config.in
27--- linux-2.4.19-pre8/drivers/usb/Config.in Sat May 11 01:02:11 2002
28+++ linux-2.4.19-pre8-konicawc/drivers/usb/Config.in Sat May 11 01:18:02 2002
29@@ -80,6 +80,7 @@
30 dep_tristate ' USB 3com HomeConnect (aka vicam) support (EXPERIMENTAL)' CONFIG_USB_VICAM $CONFIG_USB $CONFIG_VIDEO_DEV $CONFIG_EXPERIMENTAL
31 dep_tristate ' D-Link USB FM radio support (EXPERIMENTAL)' CONFIG_USB_DSBR $CONFIG_USB $CONFIG_VIDEO_DEV $CONFIG_EXPERIMENTAL
32 dep_tristate ' DABUSB driver' CONFIG_USB_DABUSB $CONFIG_USB
33+ dep_tristate ' USB Konica Webcam support' CONFIG_USB_KONICAWC $CONFIG_USB $CONFIG_VIDEO_DEV
34 fi
35
36 comment 'USB Network adaptors'
37diff -urN -X /home/spse/dontdiff linux-2.4.19-pre8/drivers/usb/Makefile linux-2.4.19-pre8-konicawc/drivers/usb/Makefile
38--- linux-2.4.19-pre8/drivers/usb/Makefile Sat May 11 01:02:11 2002
39+++ linux-2.4.19-pre8-konicawc/drivers/usb/Makefile Sat May 11 01:36:40 2002
40@@ -10,7 +10,7 @@
41
42 # Objects that export symbols.
43
44-export-objs := hcd.o usb.o ov511.o pwc-uncompress.o
45+export-objs := hcd.o usb.o ov511.o pwc-uncompress.o usbvideo.o
46
47 # Multipart objects.
48
49@@ -71,6 +71,7 @@
50 obj-$(CONFIG_USB_AUDIO) += audio.o
51 obj-$(CONFIG_USB_EMI26) += emi26.o
52 obj-$(CONFIG_USB_IBMCAM) += ibmcam.o usbvideo.o ultracam.o
53+obj-$(CONFIG_USB_KONICAWC) += konicawc.o usbvideo.o
54 obj-$(CONFIG_USB_PWC) += pwc.o
55 obj-$(CONFIG_USB_DC2XX) += dc2xx.o
56 obj-$(CONFIG_USB_MDC800) += mdc800.o
57diff -urN -X /home/spse/dontdiff linux-2.4.19-pre8/drivers/usb/ibmcam.c linux-2.4.19-pre8-konicawc/drivers/usb/ibmcam.c
58--- linux-2.4.19-pre8/drivers/usb/ibmcam.c Sat May 11 01:02:11 2002
59+++ linux-2.4.19-pre8-konicawc/drivers/usb/ibmcam.c Sat May 11 01:34:30 2002
60@@ -3899,6 +3899,17 @@
61 return uvd;
62 }
63
64+
65+static struct usb_device_id id_table[] = {
66+ { USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x0002, 0x0002) }, /* Model 1 */
67+ { USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 2 */
68+ { USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x0301, 0x0301) }, /* Model 3 */
69+ { USB_DEVICE_VER(IBMCAM_VENDOR_ID, NETCAM_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 4 */
70+ { USB_DEVICE_VER(IBMCAM_VENDOR_ID, VEO_800C_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 2 */
71+ { USB_DEVICE_VER(IBMCAM_VENDOR_ID, VEO_800D_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 4 */
72+ { } /* Terminating entry */
73+};
74+
75 /*
76 * ibmcam_init()
77 *
78@@ -3926,7 +3937,8 @@
79 sizeof(ibmcam_t),
80 "ibmcam",
81 &cbTbl,
82- THIS_MODULE);
83+ THIS_MODULE,
84+ id_table);
85 }
86
87 static void __exit ibmcam_cleanup(void)
88@@ -3934,15 +3946,6 @@
89 usbvideo_Deregister(&cams);
90 }
91
92-static __devinitdata struct usb_device_id id_table[] = {
93- { USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x0002, 0x0002) }, /* Model 1 */
94- { USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 2 */
95- { USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x0301, 0x0301) }, /* Model 3 */
96- { USB_DEVICE_VER(IBMCAM_VENDOR_ID, NETCAM_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 4 */
97- { USB_DEVICE_VER(IBMCAM_VENDOR_ID, VEO_800C_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 2 */
98- { USB_DEVICE_VER(IBMCAM_VENDOR_ID, VEO_800D_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 4 */
99- { } /* Terminating entry */
100-};
101 MODULE_DEVICE_TABLE(usb, id_table);
102
103 module_init(ibmcam_init);
104diff -urN -X /home/spse/dontdiff linux-2.4.19-pre8/drivers/usb/konicawc.c linux-2.4.19-pre8-konicawc/drivers/usb/konicawc.c
105--- linux-2.4.19-pre8/drivers/usb/konicawc.c Thu Jan 1 01:00:00 1970
106+++ linux-2.4.19-pre8-konicawc/drivers/usb/konicawc.c Sat May 11 03:18:42 2002
107@@ -0,0 +1,936 @@
108+/*
109+ * konicawc.c - konica webcam driver
110+ *
111+ * Author: Simon Evans <spse@secret.org.uk>
112+ *
113+ * Copyright (C) 2002 Simon Evans
114+ *
115+ * Licence: GPL
116+ *
117+ * Driver for USB webcams based on Konica chipset. This
118+ * chipset is used in Intel YC76 camera.
119+ *
120+ */
121+
122+#include <linux/kernel.h>
123+#include <linux/module.h>
124+#include <linux/init.h>
125+
126+//#define DEBUG
127+
128+#include "usbvideo.h"
129+
130+#define MAX_BRIGHTNESS 108
131+#define MAX_CONTRAST 108
132+#define MAX_SATURATION 108
133+#define MAX_SHARPNESS 108
134+#define MAX_WHITEBAL 372
135+#define MAX_SPEED 6
136+
137+
138+#define MAX_CAMERAS 1
139+
140+#define DRIVER_VERSION "v1.3"
141+#define DRIVER_DESC "Konica Webcam driver"
142+
143+enum ctrl_req {
144+ SetWhitebal = 0x01,
145+ SetBrightness = 0x02,
146+ SetSharpness = 0x03,
147+ SetContrast = 0x04,
148+ SetSaturation = 0x05,
149+};
150+
151+
152+enum frame_sizes {
153+ SIZE_160X120 = 0,
154+ SIZE_160X136 = 1,
155+ SIZE_176X144 = 2,
156+ SIZE_320X240 = 3,
157+
158+};
159+
160+#define MAX_FRAME_SIZE SIZE_320X240
161+
162+static usbvideo_t *cams;
163+
164+/* Some default values for inital camera settings,
165+ can be set by modprobe */
166+
167+static int debug;
168+static enum frame_sizes size;
169+static int speed = 6; /* Speed (fps) 0 (slowest) to 6 (fastest) */
170+static int brightness = MAX_BRIGHTNESS/2;
171+static int contrast = MAX_CONTRAST/2;
172+static int saturation = MAX_SATURATION/2;
173+static int sharpness = MAX_SHARPNESS/2;
174+static int whitebal = 3*(MAX_WHITEBAL/4);
175+
176+static int spd_to_iface[] = { 1, 0, 3, 2, 4, 5, 6 };
177+
178+/* These FPS speeds are from the windows config box. They are
179+ * indexed on size (0-2) and speed (0-6). Divide by 3 to get the
180+ * real fps.
181+ */
182+
183+static int spd_to_fps[][7] = { { 24, 40, 48, 60, 72, 80, 100 },
184+ { 24, 40, 48, 60, 72, 80, 100 },
185+ { 18, 30, 36, 45, 54, 60, 75 },
186+ { 6, 10, 12, 15, 18, 21, 25 } };
187+
188+struct cam_size {
189+ u16 width;
190+ u16 height;
191+ u8 cmd;
192+};
193+
194+static struct cam_size camera_sizes[] = { { 160, 120, 0x7 },
195+ { 160, 136, 0xa },
196+ { 176, 144, 0x4 },
197+ { 320, 240, 0x5 } };
198+
199+struct konicawc {
200+ u8 brightness; /* camera uses 0 - 9, x11 for real value */
201+ u8 contrast; /* as above */
202+ u8 saturation; /* as above */
203+ u8 sharpness; /* as above */
204+ u8 white_bal; /* 0 - 33, x11 for real value */
205+ u8 speed; /* Stored as 0 - 6, used as index in spd_to_* (above) */
206+ u8 size; /* Frame Size */
207+ int height;
208+ int width;
209+ struct urb *sts_urb[USBVIDEO_NUMSBUF];
210+ u8 sts_buf[USBVIDEO_NUMSBUF][FRAMES_PER_DESC];
211+ struct urb *last_data_urb;
212+ int lastframe;
213+ int cur_frame_size; /* number of bytes in current frame size */
214+ int maxline; /* number of lines per frame */
215+ int yplanesz; /* Number of bytes in the Y plane */
216+ unsigned int skip_frame:2;
217+ unsigned int buttonsts:1;
218+};
219+
220+
221+#define konicawc_set_misc(uvd, req, value, index) konicawc_ctrl_msg(uvd, USB_DIR_OUT, req, value, index, NULL, 0)
222+#define konicawc_get_misc(uvd, req, value, index, buf, sz) konicawc_ctrl_msg(uvd, USB_DIR_IN, req, value, index, buf, sz)
223+#define konicawc_set_value(uvd, value, index) konicawc_ctrl_msg(uvd, USB_DIR_OUT, 2, value, index, NULL, 0)
224+
225+
226+static int konicawc_ctrl_msg(uvd_t *uvd, u8 dir, u8 request, u16 value, u16 index, void *buf, int len)
227+{
228+ int retval = usb_control_msg(uvd->dev,
229+ dir ? usb_rcvctrlpipe(uvd->dev, 0) : usb_sndctrlpipe(uvd->dev, 0),
230+ request, 0x40 | dir, value, index, buf, len, HZ);
231+ return retval < 0 ? retval : 0;
232+}
233+
234+
235+static void konicawc_set_camera_size(uvd_t *uvd)
236+{
237+ struct konicawc *cam = (struct konicawc *)uvd->user_data;
238+
239+ konicawc_set_misc(uvd, 0x2, camera_sizes[cam->size].cmd, 0x08);
240+ cam->width = camera_sizes[cam->size].width;
241+ cam->height = camera_sizes[cam->size].height;
242+ cam->yplanesz = cam->height * cam->width;
243+ cam->cur_frame_size = (cam->yplanesz * 3) / 2;
244+ cam->maxline = cam->yplanesz / 256;
245+ uvd->videosize = VIDEOSIZE(cam->width, cam->height);
246+}
247+
248+
249+static int konicawc_setup_on_open(uvd_t *uvd)
250+{
251+ struct konicawc *cam = (struct konicawc *)uvd->user_data;
252+
253+ konicawc_set_misc(uvd, 0x2, 0, 0x0b);
254+ dbg("setting brightness to %d (%d)", cam->brightness,
255+ cam->brightness * 11);
256+ konicawc_set_value(uvd, cam->brightness, SetBrightness);
257+ dbg("setting white balance to %d (%d)", cam->white_bal,
258+ cam->white_bal * 11);
259+ konicawc_set_value(uvd, cam->white_bal, SetWhitebal);
260+ dbg("setting contrast to %d (%d)", cam->contrast,
261+ cam->contrast * 11);
262+ konicawc_set_value(uvd, cam->contrast, SetContrast);
263+ dbg("setting saturation to %d (%d)", cam->saturation,
264+ cam->saturation * 11);
265+ konicawc_set_value(uvd, cam->saturation, SetSaturation);
266+ dbg("setting sharpness to %d (%d)", cam->sharpness,
267+ cam->sharpness * 11);
268+ konicawc_set_value(uvd, cam->sharpness, SetSharpness);
269+ konicawc_set_camera_size(uvd);
270+ konicawc_set_misc(uvd, 0x2, 1, 0x0b);
271+ cam->lastframe = -1;
272+ cam->skip_frame = 2;
273+ cam->buttonsts = 0;
274+ return 0;
275+}
276+
277+
278+static void konicawc_adjust_picture(uvd_t *uvd)
279+{
280+ struct konicawc *cam = (struct konicawc *)uvd->user_data;
281+
282+ konicawc_set_misc(uvd, 0x2, 0, 0x0b);
283+ dbg("new brightness: %d", uvd->vpic.brightness);
284+ uvd->vpic.brightness = (uvd->vpic.brightness > MAX_BRIGHTNESS) ? MAX_BRIGHTNESS : uvd->vpic.brightness;
285+ if(cam->brightness != uvd->vpic.brightness / 11) {
286+ cam->brightness = uvd->vpic.brightness / 11;
287+ dbg("setting brightness to %d (%d)", cam->brightness,
288+ cam->brightness * 11);
289+ konicawc_set_value(uvd, cam->brightness, SetBrightness);
290+ }
291+
292+ dbg("new contrast: %d", uvd->vpic.contrast);
293+ uvd->vpic.contrast = (uvd->vpic.contrast > MAX_CONTRAST) ? MAX_CONTRAST : uvd->vpic.contrast;
294+ if(cam->contrast != uvd->vpic.contrast / 11) {
295+ cam->contrast = uvd->vpic.contrast / 11;
296+ dbg("setting contrast to %d (%d)", cam->contrast,
297+ cam->contrast * 11);
298+ konicawc_set_value(uvd, cam->contrast, SetContrast);
299+ }
300+ konicawc_set_misc(uvd, 0x2, 1, 0x0b);
301+}
302+
303+
304+static int konicawc_compress_iso(uvd_t *uvd, struct urb *dataurb, struct urb *stsurb)
305+{
306+ char *cdata;
307+ int i, totlen = 0;
308+ unsigned char *status = stsurb->transfer_buffer;
309+ int keep = 0, discard = 0, bad = 0;
310+ struct konicawc *cam = (struct konicawc *)uvd->user_data;
311+
312+ for (i = 0; i < dataurb->number_of_packets; i++) {
313+ int button = cam->buttonsts;
314+ unsigned char sts;
315+ int n = dataurb->iso_frame_desc[i].actual_length;
316+ int st = dataurb->iso_frame_desc[i].status;
317+ cdata = dataurb->transfer_buffer +
318+ dataurb->iso_frame_desc[i].offset;
319+
320+ /* Detect and ignore errored packets */
321+ if (st < 0) {
322+ if (debug >= 1)
323+ err("Data error: packet=%d. len=%d. status=%d.",
324+ i, n, st);
325+ uvd->stats.iso_err_count++;
326+ continue;
327+ }
328+
329+ /* Detect and ignore empty packets */
330+ if (n <= 0) {
331+ uvd->stats.iso_skip_count++;
332+ continue;
333+ }
334+
335+ /* See what the status data said about the packet */
336+ sts = *(status+stsurb->iso_frame_desc[i].offset);
337+
338+ /* sts: 0x80-0xff: frame start with frame number (ie 0-7f)
339+ * otherwise:
340+ * bit 0 0: keep packet
341+ * 1: drop packet (padding data)
342+ *
343+ * bit 4 0 button not clicked
344+ * 1 button clicked
345+ * button is used to `take a picture' (in software)
346+ */
347+
348+ if(sts < 0x80) {
349+ button = sts & 0x40;
350+ sts &= ~0x40;
351+ }
352+
353+ /* work out the button status, but dont do
354+ anything with it for now */
355+
356+ if(button != cam->buttonsts) {
357+ dbg("button: %sclicked", button ? "" : "un");
358+ cam->buttonsts = button;
359+ }
360+
361+ if(sts == 0x01) { /* drop frame */
362+ discard++;
363+ continue;
364+ }
365+
366+ if((sts > 0x01) && (sts < 0x80)) {
367+ info("unknown status %2.2x", sts);
368+ bad++;
369+ continue;
370+ }
371+
372+ keep++;
373+ if(sts & 0x80) { /* frame start */
374+ unsigned char marker[] = { 0, 0xff, 0, 0x00 };
375+
376+ if(cam->skip_frame == 2) {
377+ cam->skip_frame--;
378+ continue;
379+ }
380+
381+ /* Do we have enough space for this frame? */
382+#if 0
383+ dbg("RingQueue: need %d have %d", cam->cur_frame_size + 4, RingQueue_GetFreeSpace(&uvd->dp));
384+ if(RingQueue_GetFreeSpace(&uvd->dp) < cam->cur_frame_size + 4) {
385+ info("Dropping frame");
386+ cam->skip_frame = 1;
387+ continue;
388+ } else {
389+ cam->skip_frame = 0;
390+ }
391+#endif
392+ cam->skip_frame = 0;
393+
394+ if(debug > 1)
395+ dbg("Adding Marker packet = %d, frame = %2.2x",
396+ i, *(status+i));
397+ marker[3] = sts & 0x7F;
398+ if(RingQueue_GetFreeSpace(&uvd->dp) < (4+n)) {
399+ err("RingQueue Full! (cant add header) - Dropping frame");
400+ cam->skip_frame = 1;
401+ } else {
402+ RingQueue_Enqueue(&uvd->dp, marker, 4);
403+ }
404+
405+ totlen += 4;
406+ }
407+ if(cam->skip_frame)
408+ continue;
409+
410+ totlen += n; /* Little local accounting */
411+ if(debug > 5)
412+ dbg("Adding packet %d, bytes = %d", i, n);
413+ if(RingQueue_GetFreeSpace(&uvd->dp) < n) {
414+ err("RingQueue Full! (want %d got %d) - Dropping frame", n,
415+ RingQueue_GetFreeSpace(&uvd->dp));
416+ cam->skip_frame = 1;
417+ } else {
418+ RingQueue_Enqueue(&uvd->dp, cdata, n);
419+ }
420+ }
421+ if(debug > 8) {
422+ dbg("finished: keep = %d discard = %d bad = %d added %d bytes",
423+ keep, discard, bad, totlen);
424+ }
425+ return totlen;
426+}
427+
428+
429+static void konicawc_isoc_irq(struct urb *urb)
430+{
431+ int i, len = 0;
432+ uvd_t *uvd = urb->context;
433+ struct konicawc *cam = (struct konicawc *)uvd->user_data;
434+
435+ /* We don't want to do anything if we are about to be removed! */
436+ if (!CAMERA_IS_OPERATIONAL(uvd))
437+ return;
438+
439+ if(urb->status) {
440+ if(urb->status == -EOVERFLOW) {
441+ dbg("isoc_irq: got babble");
442+ } else if(urb->status == -ENOENT || urb->status == -EINPROGRESS) {
443+ dbg("isoc_irq: URB unlinked");
444+ } else {
445+ dbg("isoc_irq: status %d", urb->status);
446+ }
447+ return;
448+ }
449+
450+ if (urb->actual_length > 32) {
451+ cam->last_data_urb = urb;
452+ return;
453+ }
454+
455+ if (!uvd->streaming) {
456+ if (debug >= 1)
457+ info("Not streaming, but interrupt!");
458+ return;
459+ }
460+
461+ uvd->stats.urb_count++;
462+ if (urb->actual_length <= 0)
463+ goto urb_done_with;
464+
465+ /* Copy the data received into ring queue */
466+ if(cam->last_data_urb) {
467+ len = konicawc_compress_iso(uvd, cam->last_data_urb, urb);
468+ for (i = 0; i < FRAMES_PER_DESC; i++) {
469+ cam->last_data_urb->iso_frame_desc[i].status = 0;
470+ cam->last_data_urb->iso_frame_desc[i].actual_length = 0;
471+ }
472+ cam->last_data_urb = NULL;
473+ }
474+ uvd->stats.urb_length = len;
475+ uvd->stats.data_count += len;
476+
477+ if(RingQueue_GetLength(&uvd->dp) >= 384)
478+ RingQueue_WakeUpInterruptible(&uvd->dp);
479+
480+urb_done_with:
481+
482+ for (i = 0; i < FRAMES_PER_DESC; i++) {
483+ urb->iso_frame_desc[i].status = 0;
484+ urb->iso_frame_desc[i].actual_length = 0;
485+ }
486+ return;
487+}
488+
489+
490+static int konicawc_start_data(uvd_t *uvd)
491+{
492+ struct usb_device *dev = uvd->dev;
493+ int i, errFlag;
494+ struct konicawc *cam = (struct konicawc *)uvd->user_data;
495+ int pktsz;
496+ struct usb_interface_descriptor *interface;
497+
498+ interface = &dev->actconfig->interface[uvd->iface].altsetting[spd_to_iface[cam->speed]];
499+ pktsz = interface->endpoint[1].wMaxPacketSize;
500+ dbg("pktsz = %d", pktsz);
501+ if (!CAMERA_IS_OPERATIONAL(uvd)) {
502+ err("Camera is not operational");
503+ return -EFAULT;
504+ }
505+ uvd->curframe = -1;
506+
507+ /* Alternate interface 1 is is the biggest frame size */
508+ i = usb_set_interface(dev, uvd->iface, uvd->ifaceAltActive);
509+ if (i < 0) {
510+ err("usb_set_interface error");
511+ uvd->last_error = i;
512+ return -EBUSY;
513+ }
514+
515+ /* We double buffer the Iso lists */
516+ for (i=0; i < USBVIDEO_NUMSBUF; i++) {
517+ int j, k;
518+ struct urb *urb = uvd->sbuf[i].urb;
519+ urb->dev = dev;
520+ urb->context = uvd;
521+ urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp);
522+ urb->transfer_flags = USB_ISO_ASAP;
523+ urb->transfer_buffer = uvd->sbuf[i].data;
524+ urb->complete = konicawc_isoc_irq;
525+ urb->number_of_packets = FRAMES_PER_DESC;
526+ urb->transfer_buffer_length = pktsz * FRAMES_PER_DESC;
527+ for (j=k=0; j < FRAMES_PER_DESC; j++, k += pktsz) {
528+ urb->iso_frame_desc[j].offset = k;
529+ urb->iso_frame_desc[j].length = pktsz;
530+ }
531+
532+ urb = cam->sts_urb[i];
533+ urb->dev = dev;
534+ urb->context = uvd;
535+ urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp-1);
536+ urb->transfer_flags = USB_ISO_ASAP;
537+ urb->transfer_buffer = cam->sts_buf[i];
538+ urb->complete = konicawc_isoc_irq;
539+ urb->number_of_packets = FRAMES_PER_DESC;
540+ urb->transfer_buffer_length = FRAMES_PER_DESC;
541+ for (j=0; j < FRAMES_PER_DESC; j++) {
542+ urb->iso_frame_desc[j].offset = j;
543+ urb->iso_frame_desc[j].length = 1;
544+ }
545+ }
546+
547+ cam->last_data_urb = NULL;
548+
549+ /* Link URBs into a ring so that they invoke each other infinitely */
550+ for (i=0; i < USBVIDEO_NUMSBUF; i++) {
551+ if ((i+1) < USBVIDEO_NUMSBUF) {
552+ cam->sts_urb[i]->next = uvd->sbuf[i].urb;
553+ uvd->sbuf[i].urb->next = cam->sts_urb[i+1];
554+ } else {
555+ cam->sts_urb[i]->next = uvd->sbuf[i].urb;
556+ uvd->sbuf[i].urb->next = cam->sts_urb[0];
557+ }
558+ }
559+
560+ /* Submit all URBs */
561+ for (i=0; i < USBVIDEO_NUMSBUF; i++) {
562+ errFlag = usb_submit_urb(uvd->sbuf[i].urb);
563+ if (errFlag)
564+ err ("usb_submit_isoc(%d) ret %d", i, errFlag);
565+
566+ errFlag = usb_submit_urb(cam->sts_urb[i]);
567+ if (errFlag)
568+ err("usb_submit_isoc(%d) ret %d", i, errFlag);
569+ }
570+
571+ uvd->streaming = 1;
572+ if (debug > 1)
573+ dbg("streaming=1 video_endp=$%02x", uvd->video_endp);
574+ return 0;
575+}
576+
577+
578+static void konicawc_stop_data(uvd_t *uvd)
579+{
580+ int i, j;
581+ struct konicawc *cam;
582+
583+ if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
584+ return;
585+
586+ cam = (struct konicawc *)uvd->user_data;
587+ cam->last_data_urb = NULL;
588+
589+ /* Unschedule all of the iso td's */
590+ for (i=0; i < USBVIDEO_NUMSBUF; i++) {
591+ j = usb_unlink_urb(uvd->sbuf[i].urb);
592+ if (j < 0)
593+ err("usb_unlink_urb() error %d.", j);
594+
595+ j = usb_unlink_urb(cam->sts_urb[i]);
596+ if (j < 0)
597+ err("usb_unlink_urb() error %d.", j);
598+ }
599+
600+ uvd->streaming = 0;
601+
602+ if (!uvd->remove_pending) {
603+ /* Set packet size to 0 */
604+ j = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltInactive);
605+ if (j < 0) {
606+ err("usb_set_interface() error %d.", j);
607+ uvd->last_error = j;
608+ }
609+ }
610+}
611+
612+
613+static void konicawc_process_isoc(uvd_t *uvd, usbvideo_frame_t *frame)
614+{
615+ struct konicawc *cam = (struct konicawc *)uvd->user_data;
616+ int maxline = cam->maxline;
617+ int yplanesz = cam->yplanesz;
618+
619+ assert(frame != NULL);
620+
621+ if(debug > 5)
622+ dbg("maxline = %d yplanesz = %d", maxline, yplanesz);
623+
624+ if(debug > 3)
625+ dbg("Frame state = %d", frame->scanstate);
626+
627+ if(frame->scanstate == ScanState_Scanning) {
628+ int drop = 0;
629+ int curframe;
630+ int fdrops = 0;
631+ if(debug > 3)
632+ dbg("Searching for marker, queue len = %d", RingQueue_GetLength(&uvd->dp));
633+ while(RingQueue_GetLength(&uvd->dp) >= 4) {
634+ if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
635+ (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) &&
636+ (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) &&
637+ (RING_QUEUE_PEEK(&uvd->dp, 3) < 0x80)) {
638+ curframe = RING_QUEUE_PEEK(&uvd->dp, 3);
639+ if(cam->lastframe != -1) {
640+ fdrops = (0x80 + curframe - cam->lastframe) & 0x7F;
641+ fdrops--;
642+ if(fdrops) {
643+ info("Dropped %d frames (%d -> %d)", fdrops,
644+ cam->lastframe, curframe);
645+ }
646+ }
647+ cam->lastframe = curframe;
648+ frame->curline = 0;
649+ frame->scanstate = ScanState_Lines;
650+ RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 4);
651+ break;
652+ }
653+ RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
654+ drop++;
655+ }
656+ if(drop)
657+ dbg("dropped %d bytes looking for new frame", drop);
658+ }
659+
660+ if(frame->scanstate == ScanState_Scanning)
661+ return;
662+
663+ /* Try to move data from queue into frame buffer
664+ * We get data in blocks of 384 bytes made up of:
665+ * 256 Y, 64 U, 64 V.
666+ * This needs to be written out as a Y plane, a U plane and a V plane.
667+ */
668+
669+ while ( frame->curline < maxline && (RingQueue_GetLength(&uvd->dp) >= 384)) {
670+ /* Y */
671+ RingQueue_Dequeue(&uvd->dp, frame->data + (frame->curline * 256), 256);
672+ /* U */
673+ RingQueue_Dequeue(&uvd->dp, frame->data + yplanesz + (frame->curline * 64), 64);
674+ /* V */
675+ RingQueue_Dequeue(&uvd->dp, frame->data + (5 * yplanesz)/4 + (frame->curline * 64), 64);
676+ frame->seqRead_Length += 384;
677+ frame->curline++;
678+ }
679+ /* See if we filled the frame */
680+ if (frame->curline == maxline) {
681+ if(debug > 5)
682+ dbg("got whole frame");
683+
684+ frame->frameState = FrameState_Done_Hold;
685+ frame->curline = 0;
686+ uvd->curframe = -1;
687+ uvd->stats.frame_num++;
688+ }
689+}
690+
691+
692+static int konicawc_find_fps(int size, int fps)
693+{
694+ int i;
695+
696+ fps *= 3;
697+ dbg("konica_find_fps: size = %d fps = %d", size, fps);
698+ if(fps <= spd_to_fps[size][0])
699+ return 0;
700+
701+ if(fps >= spd_to_fps[size][MAX_SPEED])
702+ return MAX_SPEED;
703+
704+ for(i = 0; i < MAX_SPEED; i++) {
705+ if((fps >= spd_to_fps[size][i]) && (fps <= spd_to_fps[size][i+1])) {
706+ dbg("fps %d between %d and %d", fps, i, i+1);
707+ if( (fps - spd_to_fps[size][i]) < (spd_to_fps[size][i+1] - fps))
708+ return i;
709+ else
710+ return i+1;
711+ }
712+ }
713+ return MAX_SPEED+1;
714+}
715+
716+
717+static int konicawc_set_video_mode(uvd_t *uvd, int x, int y, int fps)
718+{
719+ struct konicawc *cam = (struct konicawc *)uvd->user_data;
720+ int newspeed = cam->speed;
721+ int newsize;
722+
723+ if(x > 0 && y > 0) {
724+ if(debug >= 2)
725+ dbg("trying to find size %d,%d", x, y);
726+ for(newsize = 0; newsize <= MAX_FRAME_SIZE; newsize++) {
727+ if((camera_sizes[newsize].width == x) && (camera_sizes[newsize].height == y))
728+ break;
729+ }
730+ } else {
731+ newsize = cam->size;
732+ }
733+
734+ if(newsize > MAX_FRAME_SIZE) {
735+ dbg("couldnt find size %d,%d", x, y);
736+ return -EINVAL;
737+ }
738+
739+ if(fps > 0) {
740+ dbg("trying to set fps to %d", fps);
741+ newspeed = konicawc_find_fps(newsize, fps);
742+ dbg("find_fps returned %d (%d)", newspeed, spd_to_fps[newsize][newspeed]);
743+ }
744+
745+ if(newspeed > MAX_SPEED)
746+ return -EINVAL;
747+
748+ dbg("setting size to %d speed to %d", newsize, newspeed);
749+ if((newsize == cam->size) && (newspeed == cam->speed)) {
750+ dbg("Nothing to do");
751+ return 0;
752+ }
753+ info("setting to %dx%d @ %d fps", camera_sizes[newsize].width,
754+ camera_sizes[newsize].height, spd_to_fps[newsize][newspeed]/3);
755+
756+ konicawc_stop_data(uvd);
757+ konicawc_set_misc(uvd, 0x2, 0, 0x0b);
758+ uvd->ifaceAltActive = spd_to_iface[newspeed];
759+ dbg("new interface = %d", uvd->ifaceAltActive);
760+ cam->speed = newspeed;
761+
762+ if(cam->size != newsize) {
763+ cam->size = newsize;
764+ konicawc_set_camera_size(uvd);
765+ }
766+
767+ /* Flush the input queue and clear any current frame in progress */
768+
769+ RingQueue_Flush(&uvd->dp);
770+ cam->skip_frame = 2;
771+ cam->lastframe = -1;
772+ if(uvd->curframe != -1) {
773+ uvd->frame[uvd->curframe].curline = 0;
774+ uvd->frame[uvd->curframe].seqRead_Length = 0;
775+ uvd->frame[uvd->curframe].seqRead_Index = 0;
776+ }
777+
778+ konicawc_set_misc(uvd, 0x2, 1, 0x0b);
779+ konicawc_start_data(uvd);
780+ return 0;
781+}
782+
783+
784+static int konicawc_calculate_fps(uvd_t *uvd)
785+{
786+ struct konicawc *cam = uvd->user_data;
787+ return spd_to_fps[cam->size][cam->speed]/3;
788+}
789+
790+
791+static void konicawc_configure_video(uvd_t *uvd)
792+{
793+ struct konicawc *cam = (struct konicawc *)uvd->user_data;
794+ u8 buf[2];
795+
796+ memset(&uvd->vpic, 0, sizeof(uvd->vpic));
797+ memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
798+
799+ RESTRICT_TO_RANGE(brightness, 0, MAX_BRIGHTNESS);
800+ RESTRICT_TO_RANGE(contrast, 0, MAX_CONTRAST);
801+ RESTRICT_TO_RANGE(saturation, 0, MAX_SATURATION);
802+ RESTRICT_TO_RANGE(sharpness, 0, MAX_SHARPNESS);
803+ RESTRICT_TO_RANGE(whitebal, 0, MAX_WHITEBAL);
804+
805+ cam->brightness = brightness / 11;
806+ cam->contrast = contrast / 11;
807+ cam->saturation = saturation / 11;
808+ cam->sharpness = sharpness / 11;
809+ cam->white_bal = whitebal / 11;
810+
811+ uvd->vpic.colour = 108;
812+ uvd->vpic.hue = 108;
813+ uvd->vpic.brightness = brightness;
814+ uvd->vpic.contrast = contrast;
815+ uvd->vpic.whiteness = whitebal;
816+ uvd->vpic.depth = 6;
817+ uvd->vpic.palette = VIDEO_PALETTE_YUV420P;
818+
819+ memset(&uvd->vcap, 0, sizeof(uvd->vcap));
820+ strcpy(uvd->vcap.name, "Konica Webcam");
821+ uvd->vcap.type = VID_TYPE_CAPTURE;
822+ uvd->vcap.channels = 1;
823+ uvd->vcap.audios = 0;
824+ uvd->vcap.minwidth = camera_sizes[SIZE_160X120].width;
825+ uvd->vcap.minheight = camera_sizes[SIZE_160X120].height;
826+ uvd->vcap.maxwidth = camera_sizes[SIZE_320X240].width;
827+ uvd->vcap.maxheight = camera_sizes[SIZE_320X240].height;
828+
829+ memset(&uvd->vchan, 0, sizeof(uvd->vchan));
830+ uvd->vchan.flags = 0 ;
831+ uvd->vchan.tuners = 0;
832+ uvd->vchan.channel = 0;
833+ uvd->vchan.type = VIDEO_TYPE_CAMERA;
834+ strcpy(uvd->vchan.name, "Camera");
835+
836+ /* Talk to device */
837+ dbg("device init");
838+ if(!konicawc_get_misc(uvd, 0x3, 0, 0x10, buf, 2))
839+ dbg("3,10 -> %2.2x %2.2x", buf[0], buf[1]);
840+ if(!konicawc_get_misc(uvd, 0x3, 0, 0x10, buf, 2))
841+ dbg("3,10 -> %2.2x %2.2x", buf[0], buf[1]);
842+ if(konicawc_set_misc(uvd, 0x2, 0, 0xd))
843+ dbg("2,0,d failed");
844+ dbg("setting initial values");
845+}
846+
847+
848+static void *konicawc_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *devid)
849+{
850+ uvd_t *uvd = NULL;
851+ int i, nas;
852+ int actInterface=-1, inactInterface=-1, maxPS=0;
853+ unsigned char video_ep = 0;
854+
855+ if (debug >= 1)
856+ dbg("konicawc_probe(%p,%u.)", dev, ifnum);
857+
858+ /* We don't handle multi-config cameras */
859+ if (dev->descriptor.bNumConfigurations != 1)
860+ return NULL;
861+
862+ info("Konica Webcam (rev. 0x%04x)", dev->descriptor.bcdDevice);
863+ RESTRICT_TO_RANGE(speed, 0, MAX_SPEED);
864+
865+ /* Validate found interface: must have one ISO endpoint */
866+ nas = dev->actconfig->interface[ifnum].num_altsetting;
867+ if (nas != 8) {
868+ err("Incorrect number of alternate settings (%d) for this camera!", nas);
869+ return NULL;
870+ }
871+ /* Validate all alternate settings */
872+ for (i=0; i < nas; i++) {
873+ const struct usb_interface_descriptor *interface;
874+ const struct usb_endpoint_descriptor *endpoint;
875+
876+ interface = &dev->actconfig->interface[ifnum].altsetting[i];
877+ if (interface->bNumEndpoints != 2) {
878+ err("Interface %d. has %u. endpoints!",
879+ ifnum, (unsigned)(interface->bNumEndpoints));
880+ return NULL;
881+ }
882+ endpoint = &interface->endpoint[1];
883+ dbg("found endpoint: addr: 0x%2.2x maxps = 0x%4.4x",
884+ endpoint->bEndpointAddress, endpoint->wMaxPacketSize);
885+ if (video_ep == 0)
886+ video_ep = endpoint->bEndpointAddress;
887+ else if (video_ep != endpoint->bEndpointAddress) {
888+ err("Alternate settings have different endpoint addresses!");
889+ return NULL;
890+ }
891+ if ((endpoint->bmAttributes & 0x03) != 0x01) {
892+ err("Interface %d. has non-ISO endpoint!", ifnum);
893+ return NULL;
894+ }
895+ if ((endpoint->bEndpointAddress & 0x80) == 0) {
896+ err("Interface %d. has ISO OUT endpoint!", ifnum);
897+ return NULL;
898+ }
899+ if (endpoint->wMaxPacketSize == 0) {
900+ if (inactInterface < 0)
901+ inactInterface = i;
902+ else {
903+ err("More than one inactive alt. setting!");
904+ return NULL;
905+ }
906+ } else {
907+ if (i == spd_to_iface[speed]) {
908+ /* This one is the requested one */
909+ actInterface = i;
910+ }
911+ }
912+ if(endpoint->wMaxPacketSize > maxPS)
913+ maxPS = endpoint->wMaxPacketSize;
914+ }
915+ if(actInterface == -1) {
916+ err("Cant find required endpoint");
917+ return NULL;
918+ }
919+
920+ dbg("Selecting requested active setting=%d. maxPS=%d.", actInterface, maxPS);
921+
922+ /* Code below may sleep, need to lock module while we are here */
923+ MOD_INC_USE_COUNT;
924+ uvd = usbvideo_AllocateDevice(cams);
925+ if (uvd != NULL) {
926+ struct konicawc *cam = (struct konicawc *)(uvd->user_data);
927+ /* Here uvd is a fully allocated uvd_t object */
928+ for(i = 0; i < USBVIDEO_NUMSBUF; i++) {
929+ cam->sts_urb[i] = usb_alloc_urb(FRAMES_PER_DESC);
930+ if(cam->sts_urb[i] == NULL) {
931+ while(i--) {
932+ usb_free_urb(cam->sts_urb[i]);
933+ }
934+ err("cant allocate urbs");
935+ return NULL;
936+ }
937+ }
938+ cam->speed = speed;
939+ RESTRICT_TO_RANGE(size, SIZE_160X120, SIZE_320X240);
940+ cam->width = camera_sizes[size].width;
941+ cam->height = camera_sizes[size].height;
942+ cam->size = size;
943+
944+ uvd->flags = 0;
945+ uvd->debug = debug;
946+ uvd->dev = dev;
947+ uvd->iface = ifnum;
948+ uvd->ifaceAltInactive = inactInterface;
949+ uvd->ifaceAltActive = actInterface;
950+ uvd->video_endp = video_ep;
951+ uvd->iso_packet_len = maxPS;
952+ uvd->paletteBits = 1L << VIDEO_PALETTE_YUV420P;
953+ uvd->defaultPalette = VIDEO_PALETTE_YUV420P;
954+ uvd->canvas = VIDEOSIZE(320, 240);
955+ uvd->videosize = VIDEOSIZE(cam->width, cam->height);
956+
957+ /* Initialize konicawc specific data */
958+ konicawc_configure_video(uvd);
959+
960+ i = usbvideo_RegisterVideoDevice(uvd);
961+ uvd->max_frame_size = (320 * 240 * 3)/2;
962+ if (i != 0) {
963+ err("usbvideo_RegisterVideoDevice() failed.");
964+ uvd = NULL;
965+ }
966+ }
967+ MOD_DEC_USE_COUNT;
968+ return uvd;
969+}
970+
971+
972+static void konicawc_free_uvd(uvd_t *uvd)
973+{
974+ int i;
975+ struct konicawc *cam = (struct konicawc *)uvd->user_data;
976+
977+ for (i=0; i < USBVIDEO_NUMSBUF; i++) {
978+ usb_free_urb(cam->sts_urb[i]);
979+ cam->sts_urb[i] = NULL;
980+ }
981+}
982+
983+
984+static struct usb_device_id id_table[] = {
985+ { USB_DEVICE(0x04c8, 0x0720) }, /* Intel YC 76 */
986+ { } /* Terminating entry */
987+};
988+
989+
990+static int __init konicawc_init(void)
991+{
992+ usbvideo_cb_t cbTbl;
993+ info(DRIVER_DESC " " DRIVER_VERSION);
994+ memset(&cbTbl, 0, sizeof(cbTbl));
995+ cbTbl.probe = konicawc_probe;
996+ cbTbl.setupOnOpen = konicawc_setup_on_open;
997+ cbTbl.processData = konicawc_process_isoc;
998+ cbTbl.getFPS = konicawc_calculate_fps;
999+ cbTbl.setVideoMode = konicawc_set_video_mode;
1000+ cbTbl.startDataPump = konicawc_start_data;
1001+ cbTbl.stopDataPump = konicawc_stop_data;
1002+ cbTbl.adjustPicture = konicawc_adjust_picture;
1003+ cbTbl.userFree = konicawc_free_uvd;
1004+ return usbvideo_register(
1005+ &cams,
1006+ MAX_CAMERAS,
1007+ sizeof(struct konicawc),
1008+ "konicawc",
1009+ &cbTbl,
1010+ THIS_MODULE,
1011+ id_table);
1012+}
1013+
1014+
1015+static void __exit konicawc_cleanup(void)
1016+{
1017+ usbvideo_Deregister(&cams);
1018+}
1019+
1020+
1021+MODULE_DEVICE_TABLE(usb, id_table);
1022+
1023+MODULE_LICENSE("GPL");
1024+MODULE_AUTHOR("Simon Evans <spse@secret.org.uk>");
1025+MODULE_DESCRIPTION(DRIVER_DESC);
1026+MODULE_PARM(speed, "i");
1027+MODULE_PARM_DESC(speed, "Initial speed: 0 (slowest) - 6 (fastest)");
1028+MODULE_PARM(size, "i");
1029+MODULE_PARM_DESC(size, "Initial Size 0: 160x120 1: 160x136 2: 176x144 3: 320x240");
1030+MODULE_PARM(brightness, "i");
1031+MODULE_PARM_DESC(brightness, "Initial brightness 0 - 108");
1032+MODULE_PARM(contrast, "i");
1033+MODULE_PARM_DESC(contrast, "Initial contrast 0 - 108");
1034+MODULE_PARM(saturation, "i");
1035+MODULE_PARM_DESC(saturation, "Initial saturation 0 - 108");
1036+MODULE_PARM(sharpness, "i");
1037+MODULE_PARM_DESC(sharpness, "Initial brightness 0 - 108");
1038+MODULE_PARM(whitebal, "i");
1039+MODULE_PARM_DESC(whitebal, "Initial white balance 0 - 363");
1040+MODULE_PARM(debug, "i");
1041+MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
1042+module_init(konicawc_init);
1043+module_exit(konicawc_cleanup);
1044diff -urN -X /home/spse/dontdiff linux-2.4.19-pre8/drivers/usb/ultracam.c linux-2.4.19-pre8-konicawc/drivers/usb/ultracam.c
1045--- linux-2.4.19-pre8/drivers/usb/ultracam.c Wed Oct 17 22:34:06 2001
1046+++ linux-2.4.19-pre8-konicawc/drivers/usb/ultracam.c Sat May 11 01:34:30 2002
1047@@ -659,6 +659,12 @@
1048 return uvd;
1049 }
1050
1051+
1052+static struct usb_device_id id_table[] = {
1053+ { USB_DEVICE(ULTRACAM_VENDOR_ID, ULTRACAM_PRODUCT_ID) },
1054+ { } /* Terminating entry */
1055+};
1056+
1057 /*
1058 * ultracam_init()
1059 *
1060@@ -682,7 +688,8 @@
1061 sizeof(ultracam_t),
1062 "ultracam",
1063 &cbTbl,
1064- THIS_MODULE);
1065+ THIS_MODULE,
1066+ id_table);
1067 }
1068
1069 static void __exit ultracam_cleanup(void)
1070@@ -690,16 +697,7 @@
1071 usbvideo_Deregister(&cams);
1072 }
1073
1074-#if defined(usb_device_id_ver)
1075-
1076-static __devinitdata struct usb_device_id id_table[] = {
1077- { USB_DEVICE(ULTRACAM_VENDOR_ID, ULTRACAM_PRODUCT_ID) },
1078- { } /* Terminating entry */
1079-};
1080 MODULE_DEVICE_TABLE(usb, id_table);
1081-
1082-
1083-#endif /* defined(usb_device_id_ver) */
1084 MODULE_LICENSE("GPL");
1085
1086 module_init(ultracam_init);
1087diff -urN -X /home/spse/dontdiff linux-2.4.19-pre8/drivers/usb/usbvideo.c linux-2.4.19-pre8-konicawc/drivers/usb/usbvideo.c
1088--- linux-2.4.19-pre8/drivers/usb/usbvideo.c Thu Oct 11 07:42:46 2001
1089+++ linux-2.4.19-pre8-konicawc/drivers/usb/usbvideo.c Sat May 11 03:11:30 2002
1090@@ -159,9 +159,21 @@
1091
1092 void RingQueue_Allocate(RingQueue_t *rq, int rqLen)
1093 {
1094+ /* Make sure the requested size is a power of 2 and
1095+ round up if necessary. This allows index wrapping
1096+ using masks rather than modulo */
1097+
1098+ int i = 1;
1099 assert(rq != NULL);
1100 assert(rqLen > 0);
1101+
1102+ while(rqLen >> i)
1103+ i++;
1104+ if(rqLen != 1 << (i-1))
1105+ rqLen = 1 << i;
1106+
1107 rq->length = rqLen;
1108+ rq->ri = rq->wi = 0;
1109 rq->queue = usbvideo_rvmalloc(rq->length);
1110 assert(rq->queue != NULL);
1111 }
1112@@ -185,12 +197,33 @@
1113
1114 int RingQueue_Dequeue(RingQueue_t *rq, unsigned char *dst, int len)
1115 {
1116- int i;
1117+ int rql, toread;
1118+
1119 assert(rq != NULL);
1120 assert(dst != NULL);
1121- for (i=0; i < len; i++) {
1122- dst[i] = rq->queue[rq->ri];
1123- RING_QUEUE_DEQUEUE_BYTES(rq,1);
1124+
1125+
1126+ rql = RingQueue_GetLength(rq);
1127+ if(!rql)
1128+ return 0;
1129+
1130+ /* Clip requested length to available data */
1131+ if(len > rql)
1132+ len = rql;
1133+
1134+ toread = len;
1135+ if(rq->ri > rq->wi) {
1136+ /* Read data from tail */
1137+ int read = (toread < (rq->length - rq->ri)) ? toread : rq->length - rq->ri;
1138+ memcpy(dst, rq->queue + rq->ri, read);
1139+ toread -= read;
1140+ dst += read;
1141+ rq->ri = (rq->ri + read) & (rq->length-1);
1142+ }
1143+ if(toread) {
1144+ /* Read data from head */
1145+ memcpy(dst, rq->queue + rq->ri, toread);
1146+ rq->ri = (rq->ri + toread) & (rq->length-1);
1147 }
1148 return len;
1149 }
1150@@ -216,7 +249,7 @@
1151 if (m > q_avail)
1152 m = q_avail;
1153
1154- memmove(rq->queue + rq->wi, cdata, m);
1155+ memcpy(rq->queue + rq->wi, cdata, m);
1156 RING_QUEUE_ADVANCE_INDEX(rq, wi, m);
1157 cdata += m;
1158 enqueued += m;
1159@@ -225,22 +258,6 @@
1160 return enqueued;
1161 }
1162
1163-int RingQueue_GetLength(const RingQueue_t *rq)
1164-{
1165- int ri, wi;
1166-
1167- assert(rq != NULL);
1168-
1169- ri = rq->ri;
1170- wi = rq->wi;
1171- if (ri == wi)
1172- return 0;
1173- else if (ri < wi)
1174- return wi - ri;
1175- else
1176- return wi + (rq->length - ri);
1177-}
1178-
1179 void RingQueue_InterruptibleSleepOn(RingQueue_t *rq)
1180 {
1181 assert(rq != NULL);
1182@@ -254,6 +271,14 @@
1183 wake_up_interruptible(&rq->wqh);
1184 }
1185
1186+void RingQueue_Flush(RingQueue_t *rq)
1187+{
1188+ assert(rq != NULL);
1189+ rq->ri = 0;
1190+ rq->wi = 0;
1191+}
1192+
1193+
1194 /*
1195 * usbvideo_VideosizeToString()
1196 *
1197@@ -390,7 +415,7 @@
1198 q_used = RingQueue_GetLength(&uvd->dp);
1199 if ((uvd->dp.ri + q_used) >= uvd->dp.length) {
1200 u_hi = uvd->dp.length;
1201- u_lo = (q_used + uvd->dp.ri) % uvd->dp.length;
1202+ u_lo = (q_used + uvd->dp.ri) & (uvd->dp.length-1);
1203 } else {
1204 u_hi = (q_used + uvd->dp.ri);
1205 u_lo = -1;
1206@@ -757,7 +782,8 @@
1207 const int num_extra,
1208 const char *driverName,
1209 const usbvideo_cb_t *cbTbl,
1210- struct module *md )
1211+ struct module *md,
1212+ const struct usb_device_id *id_table)
1213 {
1214 static const char proc[] = "usbvideo_register";
1215 usbvideo_t *cams;
1216@@ -791,6 +817,10 @@
1217 cams->cb.getFrame = usbvideo_GetFrame;
1218 if (cams->cb.disconnect == NULL)
1219 cams->cb.disconnect = usbvideo_Disconnect;
1220+ if (cams->cb.startDataPump == NULL)
1221+ cams->cb.startDataPump = usbvideo_StartDataPump;
1222+ if (cams->cb.stopDataPump == NULL)
1223+ cams->cb.stopDataPump = usbvideo_StopDataPump;
1224 #if USES_PROC_FS
1225 /*
1226 * If both /proc fs callbacks are NULL then we assume that the driver
1227@@ -843,6 +873,7 @@
1228 cams->usbdrv.name = cams->drvName;
1229 cams->usbdrv.probe = cams->cb.probe;
1230 cams->usbdrv.disconnect = cams->cb.disconnect;
1231+ cams->usbdrv.id_table = id_table;
1232
1233 #if USES_PROC_FS
1234 if (cams->uses_procfs) {
1235@@ -963,7 +994,7 @@
1236 uvd->remove_pending = 1; /* Now all ISO data will be ignored */
1237
1238 /* At this time we ask to cancel outstanding URBs */
1239- usbvideo_StopDataPump(uvd);
1240+ GET_CALLBACK(uvd, stopDataPump)(uvd);
1241
1242 for (i=0; i < USBVIDEO_NUMSBUF; i++)
1243 usb_free_urb(uvd->sbuf[i].urb);
1244@@ -1192,8 +1223,7 @@
1245
1246 if (!CAMERA_IS_OPERATIONAL(uvd))
1247 return -EFAULT;
1248-
1249- if (size > (((2 * uvd->max_frame_size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
1250+ if (size > (((USBVIDEO_NUMFRAMES * uvd->max_frame_size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
1251 return -EINVAL;
1252
1253 pos = (unsigned long) uvd->fbuf;
1254@@ -1254,7 +1284,7 @@
1255 /* Allocate memory for the frame buffers */
1256 uvd->fbuf_size = USBVIDEO_NUMFRAMES * uvd->max_frame_size;
1257 uvd->fbuf = usbvideo_rvmalloc(uvd->fbuf_size);
1258- RingQueue_Allocate(&uvd->dp, 128*1024); /* FIXME #define */
1259+ RingQueue_Allocate(&uvd->dp, RING_QUEUE_SIZE);
1260 if ((uvd->fbuf == NULL) ||
1261 (!RingQueue_IsAllocated(&uvd->dp))) {
1262 err("%s: Failed to allocate fbuf or dp", proc);
1263@@ -1299,7 +1329,7 @@
1264 if (errCode == 0) {
1265 /* Start data pump if we have valid endpoint */
1266 if (uvd->video_endp != 0)
1267- errCode = usbvideo_StartDataPump(uvd);
1268+ errCode = GET_CALLBACK(uvd, startDataPump)(uvd);
1269 if (errCode == 0) {
1270 if (VALID_CALLBACK(uvd, setupOnOpen)) {
1271 if (uvd->debug > 1)
1272@@ -1350,7 +1380,7 @@
1273 info("%s($%p)", proc, dev);
1274
1275 down(&uvd->lock);
1276- usbvideo_StopDataPump(uvd);
1277+ GET_CALLBACK(uvd, stopDataPump)(uvd);
1278 usbvideo_rvfree(uvd->fbuf, uvd->fbuf_size);
1279 uvd->fbuf = NULL;
1280 RingQueue_Free(&uvd->dp);
1281@@ -1458,8 +1488,8 @@
1282
1283 vw.x = 0;
1284 vw.y = 0;
1285- vw.width = VIDEOSIZE_X(uvd->canvas);
1286- vw.height = VIDEOSIZE_Y(uvd->canvas);
1287+ vw.width = VIDEOSIZE_X(uvd->videosize);
1288+ vw.height = VIDEOSIZE_Y(uvd->videosize);
1289 vw.chromakey = 0;
1290 if (VALID_CALLBACK(uvd, getFPS))
1291 vw.flags = GET_CALLBACK(uvd, getFPS)(uvd);
1292@@ -1529,8 +1559,8 @@
1293 }
1294 return -EINVAL;
1295 }
1296- if ((vm.frame != 0) && (vm.frame != 1)) {
1297- err("VIDIOCMCAPTURE: vm.frame=%d. !E [0,1]", vm.frame);
1298+ if ((vm.frame < 0) && (vm.frame >= USBVIDEO_NUMFRAMES)) {
1299+ err("VIDIOCMCAPTURE: vm.frame=%d. !E [0-%d]", vm.frame, USBVIDEO_NUMFRAMES-1);
1300 return -EINVAL;
1301 }
1302 if (uvd->frame[vm.frame].frameState == FrameState_Grabbing) {
1303@@ -1629,7 +1659,7 @@
1304 {
1305 static const char proc[] = "usbvideo_v4l_read";
1306 uvd_t *uvd = (uvd_t *) dev;
1307- int frmx = -1;
1308+ int frmx = -1, i;
1309 usbvideo_frame_t *frame;
1310
1311 if (!CAMERA_IS_OPERATIONAL(uvd) || (buf == NULL))
1312@@ -1641,14 +1671,13 @@
1313 down(&uvd->lock);
1314
1315 /* See if a frame is completed, then use it. */
1316- if ((uvd->frame[0].frameState == FrameState_Done) ||
1317- (uvd->frame[0].frameState == FrameState_Done_Hold) ||
1318- (uvd->frame[0].frameState == FrameState_Error)) {
1319- frmx = 0;
1320- } else if ((uvd->frame[1].frameState >= FrameState_Done) ||
1321- (uvd->frame[1].frameState == FrameState_Done_Hold) ||
1322- (uvd->frame[1].frameState >= FrameState_Done)) {
1323- frmx = 1;
1324+ for(i = 0; i < USBVIDEO_NUMFRAMES; i++) {
1325+ if ((uvd->frame[i].frameState == FrameState_Done) ||
1326+ (uvd->frame[i].frameState == FrameState_Done_Hold) ||
1327+ (uvd->frame[i].frameState == FrameState_Error)) {
1328+ frmx = i;
1329+ break;
1330+ }
1331 }
1332
1333 /* FIXME: If we don't start a frame here then who ever does? */
1334@@ -1663,10 +1692,12 @@
1335 * We will need to wait until it becomes cooked, of course.
1336 */
1337 if (frmx == -1) {
1338- if (uvd->frame[0].frameState == FrameState_Grabbing)
1339- frmx = 0;
1340- else if (uvd->frame[1].frameState == FrameState_Grabbing)
1341- frmx = 1;
1342+ for(i = 0; i < USBVIDEO_NUMFRAMES; i++) {
1343+ if (uvd->frame[i].frameState == FrameState_Grabbing) {
1344+ frmx = i;
1345+ break;
1346+ }
1347+ }
1348 }
1349
1350 /*
1351@@ -1764,7 +1795,7 @@
1352
1353 /* Mark it as available to be used again. */
1354 uvd->frame[frmx].frameState = FrameState_Unused;
1355- if (usbvideo_NewFrame(uvd, frmx ? 0 : 1)) {
1356+ if (usbvideo_NewFrame(uvd, (frmx + 1) % USBVIDEO_NUMFRAMES)) {
1357 err("%s: usbvideo_NewFrame failed.", proc);
1358 }
1359 }
1360@@ -2001,7 +2032,7 @@
1361 uvd->settingsAdjusted = 1;
1362 }
1363
1364- n = (framenum - 1 + USBVIDEO_NUMFRAMES) % USBVIDEO_NUMFRAMES;
1365+ n = (framenum + 1) % USBVIDEO_NUMFRAMES;
1366 if (uvd->frame[n].frameState == FrameState_Ready)
1367 framenum = n;
1368
1369@@ -2033,7 +2064,8 @@
1370 */
1371 if (!(uvd->flags & FLAGS_SEPARATE_FRAMES)) {
1372 /* This copies previous frame into this one to mask losses */
1373- memmove(frame->data, uvd->frame[1-framenum].data, uvd->max_frame_size);
1374+ int prev = (framenum - 1 + USBVIDEO_NUMFRAMES) % USBVIDEO_NUMFRAMES;
1375+ memmove(frame->data, uvd->frame[prev].data, uvd->max_frame_size);
1376 } else {
1377 if (uvd->flags & FLAGS_CLEAN_FRAMES) {
1378 /* This provides a "clean" frame but slows things down */
1379diff -urN -X /home/spse/dontdiff linux-2.4.19-pre8/drivers/usb/usbvideo.h linux-2.4.19-pre8-konicawc/drivers/usb/usbvideo.h
1380--- linux-2.4.19-pre8/drivers/usb/usbvideo.h Thu Oct 11 07:42:46 2001
1381+++ linux-2.4.19-pre8-konicawc/drivers/usb/usbvideo.h Sat May 11 01:58:58 2002
1382@@ -113,9 +113,10 @@
1383 mr = LIMIT_RGB(mm_r); \
1384 }
1385
1386-#define RING_QUEUE_ADVANCE_INDEX(rq,ind,n) (rq)->ind = ((rq)->ind + (n)) % (rq)->length
1387+#define RING_QUEUE_SIZE (128*1024) /* Must be a power of 2 */
1388+#define RING_QUEUE_ADVANCE_INDEX(rq,ind,n) (rq)->ind = ((rq)->ind + (n)) & ((rq)->length-1)
1389 #define RING_QUEUE_DEQUEUE_BYTES(rq,n) RING_QUEUE_ADVANCE_INDEX(rq,ri,n)
1390-#define RING_QUEUE_PEEK(rq,ofs) ((rq)->queue[((ofs) + (rq)->ri) % (rq)->length])
1391+#define RING_QUEUE_PEEK(rq,ofs) ((rq)->queue[((ofs) + (rq)->ri) & ((rq)->length-1)])
1392
1393 typedef struct {
1394 unsigned char *queue; /* Data from the Isoc data pump */
1395@@ -269,6 +270,9 @@
1396 int (*getFrame)(uvd_t *, int);
1397 int (*procfs_read)(char *page,char **start,off_t off,int count,int *eof,void *data);
1398 int (*procfs_write)(struct file *file,const char *buffer,unsigned long count,void *data);
1399+ int (*startDataPump)(uvd_t *uvd);
1400+ void (*stopDataPump)(uvd_t *uvd);
1401+ int (*setVideoMode)(uvd_t *, int, int, int);
1402 } usbvideo_cb_t;
1403
1404 struct s_usbvideo_t {
1405@@ -302,15 +306,20 @@
1406 #define VALID_CALLBACK(uvd,cbName) ((((uvd) != NULL) && \
1407 ((uvd)->handle != NULL)) ? GET_CALLBACK(uvd,cbName) : NULL)
1408
1409-void RingQueue_Initialize(RingQueue_t *rq);
1410-void RingQueue_Allocate(RingQueue_t *rq, int rqLen);
1411-int RingQueue_IsAllocated(const RingQueue_t *rq);
1412-void RingQueue_Free(RingQueue_t *rq);
1413 int RingQueue_Dequeue(RingQueue_t *rq, unsigned char *dst, int len);
1414 int RingQueue_Enqueue(RingQueue_t *rq, const unsigned char *cdata, int n);
1415-int RingQueue_GetLength(const RingQueue_t *rq);
1416-void RingQueue_InterruptibleSleepOn(RingQueue_t *rq);
1417 void RingQueue_WakeUpInterruptible(RingQueue_t *rq);
1418+void RingQueue_Flush(RingQueue_t *rq);
1419+
1420+static inline int RingQueue_GetLength(const RingQueue_t *rq)
1421+{
1422+ return (rq->wi - rq->ri + rq->length) & (rq->length-1);
1423+}
1424+
1425+static inline int RingQueue_GetFreeSpace(const RingQueue_t *rq)
1426+{
1427+ return rq->length - RingQueue_GetLength(rq);
1428+}
1429
1430 void usbvideo_CollectRawData(uvd_t *uvd, usbvideo_frame_t *frame);
1431 void usbvideo_DrawLine(
1432@@ -339,7 +348,8 @@
1433 const int num_extra,
1434 const char *driverName,
1435 const usbvideo_cb_t *cbTable,
1436- struct module *md);
1437+ struct module *md,
1438+ const struct usb_device_id *id_table);
1439 uvd_t *usbvideo_AllocateDevice(usbvideo_t *cams);
1440 int usbvideo_RegisterVideoDevice(uvd_t *uvd);
1441 void usbvideo_Deregister(usbvideo_t **uvt);
This page took 0.383347 seconds and 4 git commands to generate.