[PATCH] 2.5.12 - make usbvideo_register take a usb_device_id table
[opensuse:kernel.git] / drivers / usb / media / konicawc.c
1 /*
2  * $Id$
3  *
4  * konicawc.c - konica webcam driver
5  *
6  * Author: Simon Evans <spse@secret.org.uk>
7  *
8  * Copyright (C) 2002 Simon Evans
9  *
10  * Licence: GPL
11  * 
12  * Driver for USB webcams based on Konica chipset. This
13  * chipset is used in Intel YC76 camera.
14  *
15  */
16
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/init.h>
20
21 #include "usbvideo.h"
22
23 #define MAX_BRIGHTNESS  108
24 #define MAX_CONTRAST    108
25 #define MAX_SATURATION  108
26 #define MAX_SHARPNESS   108
27 #define MAX_WHITEBAL    372
28 #define MAX_SPEED       6
29 #define MAX_CAMERAS     1
30
31 #define DRIVER_VERSION  "v1.1"
32 #define DRIVER_DESC     "Konica Webcam driver"
33
34 enum ctrl_req {
35         SetWhitebal     = 0x01,
36         SetBrightness   = 0x02,
37         SetSharpness    = 0x03,
38         SetContrast     = 0x04,
39         SetSaturation   = 0x05,
40 };
41
42
43 enum frame_sizes {
44         SIZE_160X136    = 0,
45         SIZE_176X144    = 1,
46         SIZE_320X240    = 2,
47 };
48
49
50 static usbvideo_t *cams;
51
52 /* Some default values for inital camera settings,
53    can be set by modprobe */
54
55 static int debug;
56 static enum frame_sizes size;   
57 static int speed = 6;           /* Speed (fps) 0 (slowest) to 6 (fastest) */
58 static int brightness = MAX_BRIGHTNESS/2;
59 static int contrast =   MAX_CONTRAST/2;
60 static int saturation = MAX_SATURATION/2;
61 static int sharpness =  MAX_SHARPNESS/2;
62 static int whitebal =   3*(MAX_WHITEBAL/4);
63
64 static int speed_to_interface[] = { 1, 0, 3, 2, 4, 5, 6 };
65
66 /* These FPS speeds are from the windows config box. They are
67  * indexed on size (0-2) and speed (0-6). Divide by 3 to get the
68  * real fps.
69  */
70
71 static int speed_to_fps[3][7] = { { 24, 40, 48, 60, 72, 80, 100 },
72                                   { 18, 30, 36, 45, 54, 60, 75  },
73                                   { 6,  10, 12, 15, 18, 20, 25  } };
74
75
76 static int camera_sizes[][2] = { { 160, 136 },
77                                  { 176, 144 },
78                                  { 320, 240 },
79                                  { } /* List terminator */
80 };
81
82 struct konicawc {
83         u8 brightness;          /* camera uses 0 - 9, x11 for real value */
84         u8 contrast;            /* as above */
85         u8 saturation;          /* as above */
86         u8 sharpness;           /* as above */
87         u8 white_bal;           /* 0 - 33, x11 for real value */
88         u8 speed;               /* Stored as 0 - 6, used as index in speed_to_* (above) */
89         u8 size;                /* Frame Size */
90         int height;
91         int width;
92         struct urb *sts_urb[USBVIDEO_NUMSBUF];
93         u8 sts_buf[USBVIDEO_NUMSBUF][FRAMES_PER_DESC];
94         struct urb *last_data_urb;
95         int lastframe;
96 };
97
98
99 #define konicawc_set_misc(uvd, req, value, index)               konicawc_ctrl_msg(uvd, USB_DIR_OUT, req, value, index, NULL, 0)
100 #define konicawc_get_misc(uvd, req, value, index, buf, sz)      konicawc_ctrl_msg(uvd, USB_DIR_IN, req, value, index, buf, sz)
101 #define konicawc_set_value(uvd, value, index)                   konicawc_ctrl_msg(uvd, USB_DIR_OUT, 2, value, index, NULL, 0)
102
103
104 static int konicawc_ctrl_msg(uvd_t *uvd, u8 dir, u8 request, u16 value, u16 index, void *buf, int len)
105 {
106         int retval = usb_control_msg(uvd->dev,
107                 dir ? usb_rcvctrlpipe(uvd->dev, 0) : usb_sndctrlpipe(uvd->dev, 0),
108                     request, 0x40 | dir, value, index, buf, len, HZ);
109         return retval < 0 ? retval : 0;
110 }
111
112
113 static int konicawc_setup_on_open(uvd_t *uvd)
114 {
115         struct konicawc *cam = (struct konicawc *)uvd->user_data;
116
117         konicawc_set_misc(uvd, 0x2, 0, 0x0b);
118         dbg("setting brightness to %d (%d)", cam->brightness,
119             cam->brightness * 11);
120         konicawc_set_value(uvd, cam->brightness, SetBrightness);
121         dbg("setting white balance to %d (%d)", cam->white_bal,
122             cam->white_bal * 11);
123         konicawc_set_value(uvd, cam->white_bal, SetWhitebal);
124         dbg("setting contrast to %d (%d)", cam->contrast,
125             cam->contrast * 11);
126         konicawc_set_value(uvd, cam->contrast, SetContrast);
127         dbg("setting saturation to %d (%d)", cam->saturation,
128             cam->saturation * 11);
129         konicawc_set_value(uvd, cam->saturation, SetSaturation);
130         dbg("setting sharpness to %d (%d)", cam->sharpness,
131             cam->sharpness * 11);
132         konicawc_set_value(uvd, cam->sharpness, SetSharpness);
133         dbg("setting size %d", cam->size);
134         switch(cam->size) {
135         case 0:
136                 konicawc_set_misc(uvd, 0x2, 0xa, 0x08);
137                 break;
138
139         case 1:
140                 konicawc_set_misc(uvd, 0x2, 4, 0x08);
141                 break;
142
143         case 2:
144                 konicawc_set_misc(uvd, 0x2, 5, 0x08);
145                 break;
146         }
147         konicawc_set_misc(uvd, 0x2, 1, 0x0b);
148         cam->lastframe = -1;
149         return 0;
150 }
151
152
153 static void konicawc_adjust_picture(uvd_t *uvd)
154 {
155         struct konicawc *cam = (struct konicawc *)uvd->user_data;
156
157         dbg("new brightness: %d", uvd->vpic.brightness);
158         uvd->vpic.brightness = (uvd->vpic.brightness > MAX_BRIGHTNESS) ? MAX_BRIGHTNESS : uvd->vpic.brightness;
159         if(cam->brightness != uvd->vpic.brightness / 11) {
160            cam->brightness = uvd->vpic.brightness / 11;
161            dbg("setting brightness to %d (%d)", cam->brightness,
162                cam->brightness * 11);
163            konicawc_set_value(uvd, cam->brightness, SetBrightness);
164         }
165
166         dbg("new contrast: %d", uvd->vpic.contrast);
167         uvd->vpic.contrast = (uvd->vpic.contrast > MAX_CONTRAST) ? MAX_CONTRAST : uvd->vpic.contrast;
168         if(cam->contrast != uvd->vpic.contrast / 11) {
169                 cam->contrast = uvd->vpic.contrast / 11;
170                 dbg("setting contrast to %d (%d)", cam->contrast,
171                     cam->contrast * 11);
172                 konicawc_set_value(uvd, cam->contrast, SetContrast);
173         }
174 }
175
176
177 static int konicawc_compress_iso(uvd_t *uvd, struct urb *dataurb, struct urb *stsurb)
178 {
179         char *cdata;
180         int i, totlen = 0;
181         unsigned char *status = stsurb->transfer_buffer;
182         int keep = 0, discard = 0, bad = 0;
183         static int buttonsts = 0;
184
185         for (i = 0; i < dataurb->number_of_packets; i++) {
186                 int button = buttonsts;
187                 unsigned char sts;
188                 int n = dataurb->iso_frame_desc[i].actual_length;
189                 int st = dataurb->iso_frame_desc[i].status;
190                 cdata = dataurb->transfer_buffer + 
191                         dataurb->iso_frame_desc[i].offset;
192
193                 /* Detect and ignore errored packets */
194                 if (st < 0) {
195                         if (debug >= 1)
196                                 err("Data error: packet=%d. len=%d. status=%d.",
197                                     i, n, st);
198                         uvd->stats.iso_err_count++;
199                         continue;
200                 }
201
202                 /* Detect and ignore empty packets */
203                 if (n <= 0) {
204                         uvd->stats.iso_skip_count++;
205                         continue;
206                 }
207
208                 /* See what the status data said about the packet */
209                 sts = *(status+stsurb->iso_frame_desc[i].offset);
210
211                 /* sts: 0x80-0xff: frame start with frame number (ie 0-7f)
212                  * otherwise:
213                  * bit 0 0:drop packet (padding data)
214                  *       1 keep packet
215                  *
216                  * bit 4 0 button not clicked
217                  *       1 button clicked
218                  * button is used to `take a picture' (in software)
219                  */
220
221                 if(sts < 0x80) {
222                         button = sts & 0x40;
223                         sts &= ~0x40;
224                 }
225                 
226                 /* work out the button status, but dont do
227                    anything with it for now */
228                    
229                 if(button != buttonsts) {
230                         dbg("button: %sclicked", button ? "" : "un");
231                         buttonsts = button;
232                 }
233
234                 if(sts == 0x01) { /* drop frame */
235                         discard++;
236                         continue;
237                 }
238                 
239                 if((sts > 0x01) && (sts < 0x80)) {
240                         info("unknown status %2.2x", sts);
241                         bad++;
242                         continue;
243                 }
244
245                 keep++;
246                 if(*(status+i) & 0x80) { /* frame start */
247                         unsigned char marker[] = { 0, 0xff, 0, 0x00 };
248                         if(debug > 1)
249                                 dbg("Adding Marker packet = %d, frame = %2.2x",
250                                     i, *(status+i));
251                         marker[3] = *(status+i) - 0x80;
252                         RingQueue_Enqueue(&uvd->dp, marker, 4);                 
253                         totlen += 4;
254                 }
255                 totlen += n;    /* Little local accounting */
256                 if(debug > 5)
257                         dbg("Adding packet %d, bytes = %d", i, n);
258                 RingQueue_Enqueue(&uvd->dp, cdata, n);
259
260         }
261         if(debug > 8) {
262                 dbg("finished: keep = %d discard = %d bad = %d added %d bytes",
263                     keep, discard, bad, totlen);
264         }
265         return totlen;
266 }
267
268
269 static void konicawc_isoc_irq(struct urb *urb)
270 {
271         int i, len = 0;
272         uvd_t *uvd = urb->context;
273         struct konicawc *cam = (struct konicawc *)uvd->user_data;
274
275         /* We don't want to do anything if we are about to be removed! */
276         if (!CAMERA_IS_OPERATIONAL(uvd))
277                 return;
278
279         if (urb->actual_length > 32) {
280                 cam->last_data_urb = urb;
281                 return;
282         }
283
284         if (!uvd->streaming) {
285                 if (debug >= 1)
286                         info("Not streaming, but interrupt!");
287                 return;
288         }
289
290         uvd->stats.urb_count++;
291         if (urb->actual_length <= 0)
292                 goto urb_done_with;
293
294         /* Copy the data received into ring queue */
295         if(cam->last_data_urb) {
296                 len = konicawc_compress_iso(uvd, cam->last_data_urb, urb);
297                 for (i = 0; i < FRAMES_PER_DESC; i++) {
298                         cam->last_data_urb->iso_frame_desc[i].status = 0;
299                         cam->last_data_urb->iso_frame_desc[i].actual_length = 0;
300                 }
301                 cam->last_data_urb = NULL;
302         }
303         uvd->stats.urb_length = len;
304         if (len <= 0) {
305                 goto urb_done_with;
306         }
307
308         /* Here we got some data */
309         uvd->stats.data_count += len;
310         RingQueue_WakeUpInterruptible(&uvd->dp);
311
312 urb_done_with:
313
314         for (i = 0; i < FRAMES_PER_DESC; i++) {
315                 urb->iso_frame_desc[i].status = 0;
316                 urb->iso_frame_desc[i].actual_length = 0;
317         }
318         return;
319 }
320
321
322 static int konicawc_start_data(uvd_t *uvd)
323 {
324         struct usb_device *dev = uvd->dev;
325         int i, errFlag;
326         struct konicawc *cam = (struct konicawc *)uvd->user_data;
327
328         if (!CAMERA_IS_OPERATIONAL(uvd)) {
329                 err("Camera is not operational");
330                 return -EFAULT;
331         }
332         uvd->curframe = -1;
333
334         /* Alternate interface 1 is is the biggest frame size */
335         i = usb_set_interface(dev, uvd->iface, uvd->ifaceAltActive);
336         if (i < 0) {
337                 err("usb_set_interface error");
338                 uvd->last_error = i;
339                 return -EBUSY;
340         }
341
342         /* We double buffer the Iso lists */
343         for (i=0; i < USBVIDEO_NUMSBUF; i++) {
344                 int j, k;
345                 struct urb *urb = uvd->sbuf[i].urb;
346                 urb->dev = dev;
347                 urb->context = uvd;
348                 urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp);
349                 urb->transfer_flags = USB_ISO_ASAP;
350                 urb->transfer_buffer = uvd->sbuf[i].data;
351                 urb->complete = konicawc_isoc_irq;
352                 urb->number_of_packets = FRAMES_PER_DESC;
353                 urb->transfer_buffer_length = uvd->iso_packet_len * FRAMES_PER_DESC;
354                 for (j=k=0; j < FRAMES_PER_DESC; j++, k += uvd->iso_packet_len) {
355                         urb->iso_frame_desc[j].offset = k;
356                         urb->iso_frame_desc[j].length = uvd->iso_packet_len;
357                 }
358
359                 urb = cam->sts_urb[i];
360                 urb->dev = dev;
361                 urb->context = uvd;
362                 urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp-1);
363                 urb->transfer_flags = USB_ISO_ASAP;
364                 urb->transfer_buffer = cam->sts_buf[i];
365                 urb->complete = konicawc_isoc_irq;
366                 urb->number_of_packets = FRAMES_PER_DESC;
367                 urb->transfer_buffer_length = FRAMES_PER_DESC;
368                 for (j=0; j < FRAMES_PER_DESC; j++) {
369                         urb->iso_frame_desc[j].offset = j;
370                         urb->iso_frame_desc[j].length = 1;
371                 }
372         }
373
374         cam->last_data_urb = NULL;
375         
376         /* Link URBs into a ring so that they invoke each other infinitely */
377         for (i=0; i < USBVIDEO_NUMSBUF; i++) {
378                 if ((i+1) < USBVIDEO_NUMSBUF) {
379                         cam->sts_urb[i]->next = uvd->sbuf[i].urb;
380                         uvd->sbuf[i].urb->next = cam->sts_urb[i+1];
381                 } else {
382                         cam->sts_urb[i]->next = uvd->sbuf[i].urb;
383                         uvd->sbuf[i].urb->next = cam->sts_urb[0];
384                 }
385         }
386
387         /* Submit all URBs */
388         for (i=0; i < USBVIDEO_NUMSBUF; i++) {
389                 errFlag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL);
390                 if (errFlag)
391                         err ("usb_submit_isoc(%d) ret %d", i, errFlag);
392
393                 errFlag = usb_submit_urb(cam->sts_urb[i], GFP_KERNEL);
394                 if (errFlag)
395                         err("usb_submit_isoc(%d) ret %d", i, errFlag);
396         }
397
398         uvd->streaming = 1;
399         if (debug > 1)
400                 dbg("streaming=1 video_endp=$%02x", uvd->video_endp);
401         return 0;
402 }
403
404
405 static void konicawc_stop_data(uvd_t *uvd)
406 {
407         int i, j;
408         struct konicawc *cam;
409
410         if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
411                 return;
412
413         cam = (struct konicawc *)uvd->user_data;
414         cam->last_data_urb = NULL;
415
416         /* Unschedule all of the iso td's */
417         for (i=0; i < USBVIDEO_NUMSBUF; i++) {
418                 j = usb_unlink_urb(uvd->sbuf[i].urb);
419                 if (j < 0)
420                         err("usb_unlink_urb() error %d.", j);
421
422                 j = usb_unlink_urb(cam->sts_urb[i]);
423                 if (j < 0)
424                         err("usb_unlink_urb() error %d.", j);
425         }
426
427         uvd->streaming = 0;
428
429         if (!uvd->remove_pending) {
430                 /* Set packet size to 0 */
431                 j = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltInactive);
432                 if (j < 0) {
433                         err("usb_set_interface() error %d.", j);
434                         uvd->last_error = j;
435                 }
436         }
437 }
438
439
440 static void konicawc_process_isoc(uvd_t *uvd, usbvideo_frame_t *frame)
441 {       
442         int n;
443         int maxline, yplanesz;
444         struct konicawc *cam = (struct konicawc *)uvd->user_data;
445         assert(uvd != NULL);
446         assert(frame != NULL);
447
448         maxline = (cam->height * cam->width * 3) / (2 * 384);
449         yplanesz = cam->height * cam->width;
450         if(debug > 5)
451                 dbg("maxline = %d yplanesz = %d", maxline, yplanesz);
452         
453         if(debug > 3)
454                 dbg("Frame state = %d", frame->scanstate);
455
456         if(frame->scanstate == ScanState_Scanning) {
457                 int drop = 0;
458                 int curframe;
459                 int fdrops = 0;
460                 if(debug > 3)
461                         dbg("Searching for marker, queue len = %d", RingQueue_GetLength(&uvd->dp));
462                 while(RingQueue_GetLength(&uvd->dp) >= 4) {
463                         if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
464                             (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) &&
465                             (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) &&
466                             (RING_QUEUE_PEEK(&uvd->dp, 3) < 0x80)) {
467                                 curframe = RING_QUEUE_PEEK(&uvd->dp, 3);
468                                 if(cam->lastframe != -1) {
469                                         if(curframe < cam->lastframe) {
470                                                 fdrops = (curframe + 0x80) - cam->lastframe;
471                                         } else {
472                                                 fdrops = curframe - cam->lastframe;
473                                         }
474                                         fdrops--;
475                                         if(fdrops)
476                                                 info("Dropped %d frames (%d -> %d)", fdrops,
477                                                      cam->lastframe, curframe);
478                                 }
479                                 cam->lastframe = curframe;
480                                 frame->curline = 0;
481                                 frame->scanstate = ScanState_Lines;
482                                 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 4);
483                                 break;
484                         }
485                         RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
486                         drop++;
487                 }
488         }
489
490         if(frame->scanstate == ScanState_Scanning)
491                 return;
492                 
493         /* Try to move data from queue into frame buffer 
494          * We get data in blocks of 384 bytes made up of:
495          * 256 Y, 64 U, 64 V.
496          * This needs to be written out as a Y plane, a U plane and a V plane.
497          */
498                 
499         while ( frame->curline < maxline && (n = RingQueue_GetLength(&uvd->dp)) >= 384) {
500                 /* Y */
501                 RingQueue_Dequeue(&uvd->dp, frame->data + (frame->curline * 256), 256);
502                 /* U */
503                 RingQueue_Dequeue(&uvd->dp, frame->data + yplanesz + (frame->curline * 64), 64);
504                 /* V */
505                 RingQueue_Dequeue(&uvd->dp, frame->data + (5 * yplanesz)/4 + (frame->curline * 64), 64);
506                 frame->seqRead_Length += 384;
507                 frame->curline++;
508         }
509         /* See if we filled the frame */
510         if (frame->curline == maxline) {
511                 if(debug > 5)
512                         dbg("got whole frame");
513
514                 frame->frameState = FrameState_Done_Hold;
515                 frame->curline = 0;
516                 uvd->curframe = -1;
517                 uvd->stats.frame_num++;
518         }
519 }
520
521
522 static int konicawc_calculate_fps(uvd_t *uvd)
523 {
524         struct konicawc *t = uvd->user_data;
525         dbg("fps = %d", speed_to_fps[t->size][t->speed]/3);
526
527         return speed_to_fps[t->size][t->speed]/3;
528 }
529
530
531 static void konicawc_configure_video(uvd_t *uvd)
532 {
533         struct konicawc *cam = (struct konicawc *)uvd->user_data;
534         u8 buf[2];
535
536         memset(&uvd->vpic, 0, sizeof(uvd->vpic));
537         memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
538
539         RESTRICT_TO_RANGE(brightness, 0, MAX_BRIGHTNESS);
540         RESTRICT_TO_RANGE(contrast, 0, MAX_CONTRAST);
541         RESTRICT_TO_RANGE(saturation, 0, MAX_SATURATION);
542         RESTRICT_TO_RANGE(sharpness, 0, MAX_SHARPNESS);
543         RESTRICT_TO_RANGE(whitebal, 0, MAX_WHITEBAL);
544
545         cam->brightness = brightness / 11;
546         cam->contrast = contrast / 11;
547         cam->saturation = saturation / 11;
548         cam->sharpness = sharpness / 11;
549         cam->white_bal = whitebal / 11;
550
551         uvd->vpic.colour = 108;
552         uvd->vpic.hue = 108;
553         uvd->vpic.brightness = brightness;
554         uvd->vpic.contrast = contrast;
555         uvd->vpic.whiteness = whitebal;
556         uvd->vpic.depth = 6;
557         uvd->vpic.palette = VIDEO_PALETTE_YUV420P;
558
559         memset(&uvd->vcap, 0, sizeof(uvd->vcap));
560         strcpy(uvd->vcap.name, "Konica Webcam");
561         uvd->vcap.type = VID_TYPE_CAPTURE;
562         uvd->vcap.channels = 1;
563         uvd->vcap.audios = 0;
564         uvd->vcap.minwidth = camera_sizes[cam->size][0];
565         uvd->vcap.minheight = camera_sizes[cam->size][1];
566         uvd->vcap.maxwidth = camera_sizes[cam->size][0];
567         uvd->vcap.maxheight = camera_sizes[cam->size][1];
568
569         memset(&uvd->vchan, 0, sizeof(uvd->vchan));
570         uvd->vchan.flags = 0 ;
571         uvd->vchan.tuners = 0;
572         uvd->vchan.channel = 0;
573         uvd->vchan.type = VIDEO_TYPE_CAMERA;
574         strcpy(uvd->vchan.name, "Camera");
575
576         /* Talk to device */
577         dbg("device init");
578         if(!konicawc_get_misc(uvd, 0x3, 0, 0x10, buf, 2))
579                 dbg("3,10 -> %2.2x %2.2x", buf[0], buf[1]);
580         if(!konicawc_get_misc(uvd, 0x3, 0, 0x10, buf, 2))
581                 dbg("3,10 -> %2.2x %2.2x", buf[0], buf[1]);
582         if(konicawc_set_misc(uvd, 0x2, 0, 0xd))
583                 dbg("2,0,d failed");
584         dbg("setting initial values");
585
586 }
587
588
589 static void *konicawc_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *devid)
590 {
591         uvd_t *uvd = NULL;
592         int i, nas;
593         int actInterface=-1, inactInterface=-1, maxPS=0;
594         unsigned char video_ep = 0;
595         
596         if (debug >= 1)
597                 dbg("konicawc_probe(%p,%u.)", dev, ifnum);
598
599         /* We don't handle multi-config cameras */
600         if (dev->descriptor.bNumConfigurations != 1)
601                 return NULL;
602
603         info("Konica Webcam (rev. 0x%04x)", dev->descriptor.bcdDevice);
604         RESTRICT_TO_RANGE(speed, 0, MAX_SPEED);
605
606         /* Validate found interface: must have one ISO endpoint */
607         nas = dev->actconfig->interface[ifnum].num_altsetting;
608         if (debug > 0)
609                 info("Number of alternate settings=%d.", nas);
610         if (nas < 8) {
611                 err("Too few alternate settings for this camera!");
612                 return NULL;
613         }
614         /* Validate all alternate settings */
615         for (i=0; i < nas; i++) {
616                 const struct usb_interface_descriptor *interface;
617                 const struct usb_endpoint_descriptor *endpoint;
618
619                 interface = &dev->actconfig->interface[ifnum].altsetting[i];
620                 if (interface->bNumEndpoints != 2) {
621                         err("Interface %d. has %u. endpoints!",
622                             ifnum, (unsigned)(interface->bNumEndpoints));
623                         return NULL;
624                 }
625                 endpoint = &interface->endpoint[1];
626                 dbg("found endpoint: addr: 0x%2.2x maxps = 0x%4.4x",
627                     endpoint->bEndpointAddress, endpoint->wMaxPacketSize);
628                 if (video_ep == 0)
629                         video_ep = endpoint->bEndpointAddress;
630                 else if (video_ep != endpoint->bEndpointAddress) {
631                         err("Alternate settings have different endpoint addresses!");
632                         return NULL;
633                 }
634                 if ((endpoint->bmAttributes & 0x03) != 0x01) {
635                         err("Interface %d. has non-ISO endpoint!", ifnum);
636                         return NULL;
637                 }
638                 if ((endpoint->bEndpointAddress & 0x80) == 0) {
639                         err("Interface %d. has ISO OUT endpoint!", ifnum);
640                         return NULL;
641                 }
642                 if (endpoint->wMaxPacketSize == 0) {
643                         if (inactInterface < 0)
644                                 inactInterface = i;
645                         else {
646                                 err("More than one inactive alt. setting!");
647                                 return NULL;
648                         }
649                 } else {
650                         if (i == speed_to_interface[speed]) {
651                                 /* This one is the requested one */
652                                 actInterface = i;
653                                 maxPS = endpoint->wMaxPacketSize;
654                                 if (debug > 0) {
655                                         info("Selecting requested active setting=%d. maxPS=%d.",
656                                              i, maxPS);
657                                 }
658                         }
659                 }
660         }
661         if(actInterface == -1) {
662                 err("Cant find required endpoint");
663                 return NULL;
664         }
665
666
667         /* Code below may sleep, need to lock module while we are here */
668         MOD_INC_USE_COUNT;
669         uvd = usbvideo_AllocateDevice(cams);
670         if (uvd != NULL) {
671                 struct konicawc *cam = (struct konicawc *)(uvd->user_data);
672                 /* Here uvd is a fully allocated uvd_t object */
673                 for(i = 0; i < USBVIDEO_NUMSBUF; i++) {
674                         cam->sts_urb[i] = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
675                         if(cam->sts_urb[i] == NULL) {
676                                 while(i--) {
677                                         usb_free_urb(cam->sts_urb[i]);
678                                 }
679                                 err("cant allocate urbs");
680                                 return NULL;
681                         }
682                 }
683                 cam->speed = speed;
684                 switch(size) {
685                 case SIZE_160X136:
686                 default:
687                         cam->height = 136;
688                         cam->width = 160;
689                         cam->size = SIZE_160X136;
690                         break;
691
692                 case SIZE_176X144:
693                         cam->height = 144;
694                         cam->width = 176;
695                         cam->size = SIZE_176X144;
696                         break;
697
698                 case SIZE_320X240:
699                         cam->height = 240;
700                         cam->width = 320;
701                         cam->size = SIZE_320X240;
702                         break;
703                 }
704
705                 uvd->flags = 0;
706                 uvd->debug = debug;
707                 uvd->dev = dev;
708                 uvd->iface = ifnum;
709                 uvd->ifaceAltInactive = inactInterface;
710                 uvd->ifaceAltActive = actInterface;
711                 uvd->video_endp = video_ep;
712                 uvd->iso_packet_len = maxPS;
713                 uvd->paletteBits = 1L << VIDEO_PALETTE_YUV420P;
714                 uvd->defaultPalette = VIDEO_PALETTE_YUV420P;
715                 uvd->canvas = VIDEOSIZE(cam->width, cam->height);
716                 uvd->videosize = uvd->canvas;
717
718                 /* Initialize konicawc specific data */
719                 konicawc_configure_video(uvd);
720
721                 i = usbvideo_RegisterVideoDevice(uvd);
722                 uvd->max_frame_size = (cam->width * cam->height * 3)/2;
723                 if (i != 0) {
724                         err("usbvideo_RegisterVideoDevice() failed.");
725                         uvd = NULL;
726                 }
727         }
728         MOD_DEC_USE_COUNT;
729         return uvd;
730 }
731
732
733 static void konicawc_free_uvd(uvd_t *uvd)
734 {
735         int i;
736         struct konicawc *cam = (struct konicawc *)uvd->user_data;
737
738         for (i=0; i < USBVIDEO_NUMSBUF; i++) {
739                 usb_free_urb(cam->sts_urb[i]);
740                 cam->sts_urb[i] = NULL;
741         }
742 }
743
744
745 static struct usb_device_id id_table[] = {
746         { USB_DEVICE(0x04c8, 0x0720) }, /* Intel YC 76 */
747         { }  /* Terminating entry */
748 };
749
750
751 static int __init konicawc_init(void)
752 {
753         usbvideo_cb_t cbTbl;
754         info(DRIVER_DESC " " DRIVER_VERSION);
755         memset(&cbTbl, 0, sizeof(cbTbl));
756         cbTbl.probe = konicawc_probe;
757         cbTbl.setupOnOpen = konicawc_setup_on_open;
758         cbTbl.processData = konicawc_process_isoc;
759         cbTbl.getFPS = konicawc_calculate_fps;
760         cbTbl.startDataPump = konicawc_start_data;
761         cbTbl.stopDataPump = konicawc_stop_data;
762         cbTbl.adjustPicture = konicawc_adjust_picture;
763         cbTbl.userFree = konicawc_free_uvd;
764         return usbvideo_register(
765                 &cams,
766                 MAX_CAMERAS,
767                 sizeof(struct konicawc),
768                 "konicawc",
769                 &cbTbl,
770                 THIS_MODULE,
771                 id_table);
772 }
773
774
775 static void __exit konicawc_cleanup(void)
776 {
777         usbvideo_Deregister(&cams);
778 }
779
780
781 MODULE_DEVICE_TABLE(usb, id_table);
782
783 MODULE_LICENSE("GPL");
784 MODULE_AUTHOR("Simon Evans <spse@secret.org.uk>");
785 MODULE_DESCRIPTION(DRIVER_DESC);
786 MODULE_PARM(speed, "i");
787 MODULE_PARM_DESC(speed, "FPS speed: 0 (slowest) - 6 (fastest)");
788 MODULE_PARM(size, "i");
789 MODULE_PARM_DESC(size, "Frame Size 0: 160x136 1: 176x144 2: 320x240");
790 MODULE_PARM(brightness, "i");
791 MODULE_PARM_DESC(brightness, "Initial brightness 0 - 108");
792 MODULE_PARM(contrast, "i");
793 MODULE_PARM_DESC(contrast, "Initial contrast 0 - 108");
794 MODULE_PARM(saturation, "i");
795 MODULE_PARM_DESC(saturation, "Initial saturation 0 - 108");
796 MODULE_PARM(sharpness, "i");
797 MODULE_PARM_DESC(sharpness, "Initial brightness 0 - 108");
798 MODULE_PARM(whitebal, "i");
799 MODULE_PARM_DESC(whitebal, "Initial white balance 0 - 363");
800 MODULE_PARM(debug, "i");
801 MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
802 module_init(konicawc_init);
803 module_exit(konicawc_cleanup);