Version:  2.0.40 2.2.26 2.4.37 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0

Linux/drivers/media/usb/pwc/pwc-if.c

  1 /* Linux driver for Philips webcam
  2    USB and Video4Linux interface part.
  3    (C) 1999-2004 Nemosoft Unv.
  4    (C) 2004-2006 Luc Saillard (luc@saillard.org)
  5    (C) 2011 Hans de Goede <hdegoede@redhat.com>
  6 
  7    NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
  8    driver and thus may have bugs that are not present in the original version.
  9    Please send bug reports and support requests to <luc@saillard.org>.
 10    The decompression routines have been implemented by reverse-engineering the
 11    Nemosoft binary pwcx module. Caveat emptor.
 12 
 13    This program is free software; you can redistribute it and/or modify
 14    it under the terms of the GNU General Public License as published by
 15    the Free Software Foundation; either version 2 of the License, or
 16    (at your option) any later version.
 17 
 18    This program is distributed in the hope that it will be useful,
 19    but WITHOUT ANY WARRANTY; without even the implied warranty of
 20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 21    GNU General Public License for more details.
 22 
 23    You should have received a copy of the GNU General Public License
 24    along with this program; if not, write to the Free Software
 25    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 26 
 27 */
 28 
 29 /*
 30    This code forms the interface between the USB layers and the Philips
 31    specific stuff. Some adanved stuff of the driver falls under an
 32    NDA, signed between me and Philips B.V., Eindhoven, the Netherlands, and
 33    is thus not distributed in source form. The binary pwcx.o module
 34    contains the code that falls under the NDA.
 35 
 36    In case you're wondering: 'pwc' stands for "Philips WebCam", but
 37    I really didn't want to type 'philips_web_cam' every time (I'm lazy as
 38    any Linux kernel hacker, but I don't like uncomprehensible abbreviations
 39    without explanation).
 40 
 41    Oh yes, convention: to disctinguish between all the various pointers to
 42    device-structures, I use these names for the pointer variables:
 43    udev: struct usb_device *
 44    vdev: struct video_device (member of pwc_dev)
 45    pdev: struct pwc_devive *
 46 */
 47 
 48 /* Contributors:
 49    - Alvarado: adding whitebalance code
 50    - Alistar Moire: QuickCam 3000 Pro device/product ID
 51    - Tony Hoyle: Creative Labs Webcam 5 device/product ID
 52    - Mark Burazin: solving hang in VIDIOCSYNC when camera gets unplugged
 53    - Jk Fang: Sotec Afina Eye ID
 54    - Xavier Roche: QuickCam Pro 4000 ID
 55    - Jens Knudsen: QuickCam Zoom ID
 56    - J. Debert: QuickCam for Notebooks ID
 57    - Pham Thanh Nam: webcam snapshot button as an event input device
 58 */
 59 
 60 #include <linux/errno.h>
 61 #include <linux/init.h>
 62 #include <linux/mm.h>
 63 #include <linux/module.h>
 64 #include <linux/poll.h>
 65 #include <linux/slab.h>
 66 #ifdef CONFIG_USB_PWC_INPUT_EVDEV
 67 #include <linux/usb/input.h>
 68 #endif
 69 #include <linux/vmalloc.h>
 70 #include <asm/io.h>
 71 #include <linux/kernel.h>               /* simple_strtol() */
 72 
 73 #include "pwc.h"
 74 #include "pwc-kiara.h"
 75 #include "pwc-timon.h"
 76 #include "pwc-dec23.h"
 77 #include "pwc-dec1.h"
 78 
 79 /* Function prototypes and driver templates */
 80 
 81 /* hotplug device table support */
 82 static const struct usb_device_id pwc_device_table [] = {
 83         { USB_DEVICE(0x0471, 0x0302) }, /* Philips models */
 84         { USB_DEVICE(0x0471, 0x0303) },
 85         { USB_DEVICE(0x0471, 0x0304) },
 86         { USB_DEVICE(0x0471, 0x0307) },
 87         { USB_DEVICE(0x0471, 0x0308) },
 88         { USB_DEVICE(0x0471, 0x030C) },
 89         { USB_DEVICE(0x0471, 0x0310) },
 90         { USB_DEVICE(0x0471, 0x0311) }, /* Philips ToUcam PRO II */
 91         { USB_DEVICE(0x0471, 0x0312) },
 92         { USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */
 93         { USB_DEVICE(0x0471, 0x0329) }, /* Philips SPC 900NC PC Camera */
 94         { USB_DEVICE(0x069A, 0x0001) }, /* Askey */
 95         { USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */
 96         { USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */
 97         { USB_DEVICE(0x046D, 0x08B2) }, /* Logitech QuickCam Pro 4000 */
 98         { USB_DEVICE(0x046D, 0x08B3) }, /* Logitech QuickCam Zoom (old model) */
 99         { USB_DEVICE(0x046D, 0x08B4) }, /* Logitech QuickCam Zoom (new model) */
100         { USB_DEVICE(0x046D, 0x08B5) }, /* Logitech QuickCam Orbit/Sphere */
101         { USB_DEVICE(0x046D, 0x08B6) }, /* Cisco VT Camera */
102         { USB_DEVICE(0x046D, 0x08B7) }, /* Logitech ViewPort AV 100 */
103         { USB_DEVICE(0x046D, 0x08B8) }, /* Logitech (reserved) */
104         { USB_DEVICE(0x055D, 0x9000) }, /* Samsung MPC-C10 */
105         { USB_DEVICE(0x055D, 0x9001) }, /* Samsung MPC-C30 */
106         { USB_DEVICE(0x055D, 0x9002) }, /* Samsung SNC-35E (Ver3.0) */
107         { USB_DEVICE(0x041E, 0x400C) }, /* Creative Webcam 5 */
108         { USB_DEVICE(0x041E, 0x4011) }, /* Creative Webcam Pro Ex */
109         { USB_DEVICE(0x04CC, 0x8116) }, /* Afina Eye */
110         { USB_DEVICE(0x06BE, 0x8116) }, /* new Afina Eye */
111         { USB_DEVICE(0x0d81, 0x1910) }, /* Visionite */
112         { USB_DEVICE(0x0d81, 0x1900) },
113         { }
114 };
115 MODULE_DEVICE_TABLE(usb, pwc_device_table);
116 
117 static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id);
118 static void usb_pwc_disconnect(struct usb_interface *intf);
119 static void pwc_isoc_cleanup(struct pwc_device *pdev);
120 
121 static struct usb_driver pwc_driver = {
122         .name =                 "Philips webcam",       /* name */
123         .id_table =             pwc_device_table,
124         .probe =                usb_pwc_probe,          /* probe() */
125         .disconnect =           usb_pwc_disconnect,     /* disconnect() */
126 };
127 
128 #define MAX_DEV_HINTS   20
129 #define MAX_ISOC_ERRORS 20
130 
131 #ifdef CONFIG_USB_PWC_DEBUG
132         int pwc_trace = PWC_DEBUG_LEVEL;
133 #endif
134 static int power_save = -1;
135 static int leds[2] = { 100, 0 };
136 
137 /***/
138 
139 static const struct v4l2_file_operations pwc_fops = {
140         .owner =        THIS_MODULE,
141         .open =         v4l2_fh_open,
142         .release =      vb2_fop_release,
143         .read =         vb2_fop_read,
144         .poll =         vb2_fop_poll,
145         .mmap =         vb2_fop_mmap,
146         .unlocked_ioctl = video_ioctl2,
147 };
148 static struct video_device pwc_template = {
149         .name =         "Philips Webcam",       /* Filled in later */
150         .release =      video_device_release_empty,
151         .fops =         &pwc_fops,
152         .ioctl_ops =    &pwc_ioctl_ops,
153 };
154 
155 /***************************************************************************/
156 /* Private functions */
157 
158 static struct pwc_frame_buf *pwc_get_next_fill_buf(struct pwc_device *pdev)
159 {
160         unsigned long flags = 0;
161         struct pwc_frame_buf *buf = NULL;
162 
163         spin_lock_irqsave(&pdev->queued_bufs_lock, flags);
164         if (list_empty(&pdev->queued_bufs))
165                 goto leave;
166 
167         buf = list_entry(pdev->queued_bufs.next, struct pwc_frame_buf, list);
168         list_del(&buf->list);
169 leave:
170         spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags);
171         return buf;
172 }
173 
174 static void pwc_snapshot_button(struct pwc_device *pdev, int down)
175 {
176         if (down) {
177                 PWC_TRACE("Snapshot button pressed.\n");
178         } else {
179                 PWC_TRACE("Snapshot button released.\n");
180         }
181 
182 #ifdef CONFIG_USB_PWC_INPUT_EVDEV
183         if (pdev->button_dev) {
184                 input_report_key(pdev->button_dev, KEY_CAMERA, down);
185                 input_sync(pdev->button_dev);
186         }
187 #endif
188 }
189 
190 static void pwc_frame_complete(struct pwc_device *pdev)
191 {
192         struct pwc_frame_buf *fbuf = pdev->fill_buf;
193 
194         /* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus
195            frames on the USB wire after an exposure change. This conditition is
196            however detected  in the cam and a bit is set in the header.
197            */
198         if (pdev->type == 730) {
199                 unsigned char *ptr = (unsigned char *)fbuf->data;
200 
201                 if (ptr[1] == 1 && ptr[0] & 0x10) {
202                         PWC_TRACE("Hyundai CMOS sensor bug. Dropping frame.\n");
203                         pdev->drop_frames += 2;
204                 }
205                 if ((ptr[0] ^ pdev->vmirror) & 0x01) {
206                         pwc_snapshot_button(pdev, ptr[0] & 0x01);
207                 }
208                 if ((ptr[0] ^ pdev->vmirror) & 0x02) {
209                         if (ptr[0] & 0x02)
210                                 PWC_TRACE("Image is mirrored.\n");
211                         else
212                                 PWC_TRACE("Image is normal.\n");
213                 }
214                 pdev->vmirror = ptr[0] & 0x03;
215                 /* Sometimes the trailer of the 730 is still sent as a 4 byte packet
216                    after a short frame; this condition is filtered out specifically. A 4 byte
217                    frame doesn't make sense anyway.
218                    So we get either this sequence:
219                    drop_bit set -> 4 byte frame -> short frame -> good frame
220                    Or this one:
221                    drop_bit set -> short frame -> good frame
222                    So we drop either 3 or 2 frames in all!
223                    */
224                 if (fbuf->filled == 4)
225                         pdev->drop_frames++;
226         } else if (pdev->type == 740 || pdev->type == 720) {
227                 unsigned char *ptr = (unsigned char *)fbuf->data;
228                 if ((ptr[0] ^ pdev->vmirror) & 0x01) {
229                         pwc_snapshot_button(pdev, ptr[0] & 0x01);
230                 }
231                 pdev->vmirror = ptr[0] & 0x03;
232         }
233 
234         /* In case we were instructed to drop the frame, do so silently. */
235         if (pdev->drop_frames > 0) {
236                 pdev->drop_frames--;
237         } else {
238                 /* Check for underflow first */
239                 if (fbuf->filled < pdev->frame_total_size) {
240                         PWC_DEBUG_FLOW("Frame buffer underflow (%d bytes);"
241                                        " discarded.\n", fbuf->filled);
242                 } else {
243                         fbuf->vb.v4l2_buf.field = V4L2_FIELD_NONE;
244                         fbuf->vb.v4l2_buf.sequence = pdev->vframe_count;
245                         vb2_buffer_done(&fbuf->vb, VB2_BUF_STATE_DONE);
246                         pdev->fill_buf = NULL;
247                         pdev->vsync = 0;
248                 }
249         } /* !drop_frames */
250         pdev->vframe_count++;
251 }
252 
253 /* This gets called for the Isochronous pipe (video). This is done in
254  * interrupt time, so it has to be fast, not crash, and not stall. Neat.
255  */
256 static void pwc_isoc_handler(struct urb *urb)
257 {
258         struct pwc_device *pdev = (struct pwc_device *)urb->context;
259         int i, fst, flen;
260         unsigned char *iso_buf = NULL;
261 
262         if (urb->status == -ENOENT || urb->status == -ECONNRESET ||
263             urb->status == -ESHUTDOWN) {
264                 PWC_DEBUG_OPEN("URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a");
265                 return;
266         }
267 
268         if (pdev->fill_buf == NULL)
269                 pdev->fill_buf = pwc_get_next_fill_buf(pdev);
270 
271         if (urb->status != 0) {
272                 const char *errmsg;
273 
274                 errmsg = "Unknown";
275                 switch(urb->status) {
276                         case -ENOSR:            errmsg = "Buffer error (overrun)"; break;
277                         case -EPIPE:            errmsg = "Stalled (device not responding)"; break;
278                         case -EOVERFLOW:        errmsg = "Babble (bad cable?)"; break;
279                         case -EPROTO:           errmsg = "Bit-stuff error (bad cable?)"; break;
280                         case -EILSEQ:           errmsg = "CRC/Timeout (could be anything)"; break;
281                         case -ETIME:            errmsg = "Device does not respond"; break;
282                 }
283                 PWC_ERROR("pwc_isoc_handler() called with status %d [%s].\n",
284                           urb->status, errmsg);
285                 /* Give up after a number of contiguous errors */
286                 if (++pdev->visoc_errors > MAX_ISOC_ERRORS)
287                 {
288                         PWC_ERROR("Too many ISOC errors, bailing out.\n");
289                         if (pdev->fill_buf) {
290                                 vb2_buffer_done(&pdev->fill_buf->vb,
291                                                 VB2_BUF_STATE_ERROR);
292                                 pdev->fill_buf = NULL;
293                         }
294                 }
295                 pdev->vsync = 0; /* Drop the current frame */
296                 goto handler_end;
297         }
298 
299         /* Reset ISOC error counter. We did get here, after all. */
300         pdev->visoc_errors = 0;
301 
302         /* vsync: 0 = don't copy data
303                   1 = sync-hunt
304                   2 = synched
305          */
306         /* Compact data */
307         for (i = 0; i < urb->number_of_packets; i++) {
308                 fst  = urb->iso_frame_desc[i].status;
309                 flen = urb->iso_frame_desc[i].actual_length;
310                 iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
311                 if (fst != 0) {
312                         PWC_ERROR("Iso frame %d has error %d\n", i, fst);
313                         continue;
314                 }
315                 if (flen > 0 && pdev->vsync) {
316                         struct pwc_frame_buf *fbuf = pdev->fill_buf;
317 
318                         if (pdev->vsync == 1) {
319                                 v4l2_get_timestamp(
320                                         &fbuf->vb.v4l2_buf.timestamp);
321                                 pdev->vsync = 2;
322                         }
323 
324                         if (flen + fbuf->filled > pdev->frame_total_size) {
325                                 PWC_ERROR("Frame overflow (%d > %d)\n",
326                                           flen + fbuf->filled,
327                                           pdev->frame_total_size);
328                                 pdev->vsync = 0; /* Let's wait for an EOF */
329                         } else {
330                                 memcpy(fbuf->data + fbuf->filled, iso_buf,
331                                        flen);
332                                 fbuf->filled += flen;
333                         }
334                 }
335                 if (flen < pdev->vlast_packet_size) {
336                         /* Shorter packet... end of frame */
337                         if (pdev->vsync == 2)
338                                 pwc_frame_complete(pdev);
339                         if (pdev->fill_buf == NULL)
340                                 pdev->fill_buf = pwc_get_next_fill_buf(pdev);
341                         if (pdev->fill_buf) {
342                                 pdev->fill_buf->filled = 0;
343                                 pdev->vsync = 1;
344                         }
345                 }
346                 pdev->vlast_packet_size = flen;
347         }
348 
349 handler_end:
350         i = usb_submit_urb(urb, GFP_ATOMIC);
351         if (i != 0)
352                 PWC_ERROR("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i);
353 }
354 
355 /* Both v4l2_lock and vb_queue_lock should be locked when calling this */
356 static int pwc_isoc_init(struct pwc_device *pdev)
357 {
358         struct usb_device *udev;
359         struct urb *urb;
360         int i, j, ret;
361         struct usb_interface *intf;
362         struct usb_host_interface *idesc = NULL;
363         int compression = 0; /* 0..3 = uncompressed..high */
364 
365         pdev->vsync = 0;
366         pdev->vlast_packet_size = 0;
367         pdev->fill_buf = NULL;
368         pdev->vframe_count = 0;
369         pdev->visoc_errors = 0;
370         udev = pdev->udev;
371 
372 retry:
373         /* We first try with low compression and then retry with a higher
374            compression setting if there is not enough bandwidth. */
375         ret = pwc_set_video_mode(pdev, pdev->width, pdev->height, pdev->pixfmt,
376                                  pdev->vframes, &compression, 1);
377 
378         /* Get the current alternate interface, adjust packet size */
379         intf = usb_ifnum_to_if(udev, 0);
380         if (intf)
381                 idesc = usb_altnum_to_altsetting(intf, pdev->valternate);
382         if (!idesc)
383                 return -EIO;
384 
385         /* Search video endpoint */
386         pdev->vmax_packet_size = -1;
387         for (i = 0; i < idesc->desc.bNumEndpoints; i++) {
388                 if ((idesc->endpoint[i].desc.bEndpointAddress & 0xF) == pdev->vendpoint) {
389                         pdev->vmax_packet_size = le16_to_cpu(idesc->endpoint[i].desc.wMaxPacketSize);
390                         break;
391                 }
392         }
393 
394         if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) {
395                 PWC_ERROR("Failed to find packet size for video endpoint in current alternate setting.\n");
396                 return -ENFILE; /* Odd error, that should be noticeable */
397         }
398 
399         /* Set alternate interface */
400         PWC_DEBUG_OPEN("Setting alternate interface %d\n", pdev->valternate);
401         ret = usb_set_interface(pdev->udev, 0, pdev->valternate);
402         if (ret == -ENOSPC && compression < 3) {
403                 compression++;
404                 goto retry;
405         }
406         if (ret < 0)
407                 return ret;
408 
409         /* Allocate and init Isochronuous urbs */
410         for (i = 0; i < MAX_ISO_BUFS; i++) {
411                 urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL);
412                 if (urb == NULL) {
413                         PWC_ERROR("Failed to allocate urb %d\n", i);
414                         pwc_isoc_cleanup(pdev);
415                         return -ENOMEM;
416                 }
417                 pdev->urbs[i] = urb;
418                 PWC_DEBUG_MEMORY("Allocated URB at 0x%p\n", urb);
419 
420                 urb->interval = 1; // devik
421                 urb->dev = udev;
422                 urb->pipe = usb_rcvisocpipe(udev, pdev->vendpoint);
423                 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
424                 urb->transfer_buffer = usb_alloc_coherent(udev,
425                                                           ISO_BUFFER_SIZE,
426                                                           GFP_KERNEL,
427                                                           &urb->transfer_dma);
428                 if (urb->transfer_buffer == NULL) {
429                         PWC_ERROR("Failed to allocate urb buffer %d\n", i);
430                         pwc_isoc_cleanup(pdev);
431                         return -ENOMEM;
432                 }
433                 urb->transfer_buffer_length = ISO_BUFFER_SIZE;
434                 urb->complete = pwc_isoc_handler;
435                 urb->context = pdev;
436                 urb->start_frame = 0;
437                 urb->number_of_packets = ISO_FRAMES_PER_DESC;
438                 for (j = 0; j < ISO_FRAMES_PER_DESC; j++) {
439                         urb->iso_frame_desc[j].offset = j * ISO_MAX_FRAME_SIZE;
440                         urb->iso_frame_desc[j].length = pdev->vmax_packet_size;
441                 }
442         }
443 
444         /* link */
445         for (i = 0; i < MAX_ISO_BUFS; i++) {
446                 ret = usb_submit_urb(pdev->urbs[i], GFP_KERNEL);
447                 if (ret == -ENOSPC && compression < 3) {
448                         compression++;
449                         pwc_isoc_cleanup(pdev);
450                         goto retry;
451                 }
452                 if (ret) {
453                         PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret);
454                         pwc_isoc_cleanup(pdev);
455                         return ret;
456                 }
457                 PWC_DEBUG_MEMORY("URB 0x%p submitted.\n", pdev->urbs[i]);
458         }
459 
460         /* All is done... */
461         PWC_DEBUG_OPEN("<< pwc_isoc_init()\n");
462         return 0;
463 }
464 
465 static void pwc_iso_stop(struct pwc_device *pdev)
466 {
467         int i;
468 
469         /* Unlinking ISOC buffers one by one */
470         for (i = 0; i < MAX_ISO_BUFS; i++) {
471                 if (pdev->urbs[i]) {
472                         PWC_DEBUG_MEMORY("Unlinking URB %p\n", pdev->urbs[i]);
473                         usb_kill_urb(pdev->urbs[i]);
474                 }
475         }
476 }
477 
478 static void pwc_iso_free(struct pwc_device *pdev)
479 {
480         int i;
481 
482         /* Freeing ISOC buffers one by one */
483         for (i = 0; i < MAX_ISO_BUFS; i++) {
484                 if (pdev->urbs[i]) {
485                         PWC_DEBUG_MEMORY("Freeing URB\n");
486                         if (pdev->urbs[i]->transfer_buffer) {
487                                 usb_free_coherent(pdev->udev,
488                                         pdev->urbs[i]->transfer_buffer_length,
489                                         pdev->urbs[i]->transfer_buffer,
490                                         pdev->urbs[i]->transfer_dma);
491                         }
492                         usb_free_urb(pdev->urbs[i]);
493                         pdev->urbs[i] = NULL;
494                 }
495         }
496 }
497 
498 /* Both v4l2_lock and vb_queue_lock should be locked when calling this */
499 static void pwc_isoc_cleanup(struct pwc_device *pdev)
500 {
501         PWC_DEBUG_OPEN(">> pwc_isoc_cleanup()\n");
502 
503         pwc_iso_stop(pdev);
504         pwc_iso_free(pdev);
505         usb_set_interface(pdev->udev, 0, 0);
506 
507         PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n");
508 }
509 
510 /* Must be called with vb_queue_lock hold */
511 static void pwc_cleanup_queued_bufs(struct pwc_device *pdev,
512                                     enum vb2_buffer_state state)
513 {
514         unsigned long flags = 0;
515 
516         spin_lock_irqsave(&pdev->queued_bufs_lock, flags);
517         while (!list_empty(&pdev->queued_bufs)) {
518                 struct pwc_frame_buf *buf;
519 
520                 buf = list_entry(pdev->queued_bufs.next, struct pwc_frame_buf,
521                                  list);
522                 list_del(&buf->list);
523                 vb2_buffer_done(&buf->vb, state);
524         }
525         spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags);
526 }
527 
528 #ifdef CONFIG_USB_PWC_DEBUG
529 static const char *pwc_sensor_type_to_string(unsigned int sensor_type)
530 {
531         switch(sensor_type) {
532                 case 0x00:
533                         return "Hyundai CMOS sensor";
534                 case 0x20:
535                         return "Sony CCD sensor + TDA8787";
536                 case 0x2E:
537                         return "Sony CCD sensor + Exas 98L59";
538                 case 0x2F:
539                         return "Sony CCD sensor + ADI 9804";
540                 case 0x30:
541                         return "Sharp CCD sensor + TDA8787";
542                 case 0x3E:
543                         return "Sharp CCD sensor + Exas 98L59";
544                 case 0x3F:
545                         return "Sharp CCD sensor + ADI 9804";
546                 case 0x40:
547                         return "UPA 1021 sensor";
548                 case 0x100:
549                         return "VGA sensor";
550                 case 0x101:
551                         return "PAL MR sensor";
552                 default:
553                         return "unknown type of sensor";
554         }
555 }
556 #endif
557 
558 /***************************************************************************/
559 /* Video4Linux functions */
560 
561 static void pwc_video_release(struct v4l2_device *v)
562 {
563         struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);
564 
565         v4l2_ctrl_handler_free(&pdev->ctrl_handler);
566         v4l2_device_unregister(&pdev->v4l2_dev);
567         kfree(pdev->ctrl_buf);
568         kfree(pdev);
569 }
570 
571 /***************************************************************************/
572 /* Videobuf2 operations */
573 
574 static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
575                                 unsigned int *nbuffers, unsigned int *nplanes,
576                                 unsigned int sizes[], void *alloc_ctxs[])
577 {
578         struct pwc_device *pdev = vb2_get_drv_priv(vq);
579         int size;
580 
581         if (*nbuffers < MIN_FRAMES)
582                 *nbuffers = MIN_FRAMES;
583         else if (*nbuffers > MAX_FRAMES)
584                 *nbuffers = MAX_FRAMES;
585 
586         *nplanes = 1;
587 
588         size = pwc_get_size(pdev, MAX_WIDTH, MAX_HEIGHT);
589         sizes[0] = PAGE_ALIGN(pwc_image_sizes[size][0] *
590                               pwc_image_sizes[size][1] * 3 / 2);
591 
592         return 0;
593 }
594 
595 static int buffer_init(struct vb2_buffer *vb)
596 {
597         struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
598 
599         /* need vmalloc since frame buffer > 128K */
600         buf->data = vzalloc(PWC_FRAME_SIZE);
601         if (buf->data == NULL)
602                 return -ENOMEM;
603 
604         return 0;
605 }
606 
607 static int buffer_prepare(struct vb2_buffer *vb)
608 {
609         struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue);
610 
611         /* Don't allow queing new buffers after device disconnection */
612         if (!pdev->udev)
613                 return -ENODEV;
614 
615         return 0;
616 }
617 
618 static void buffer_finish(struct vb2_buffer *vb)
619 {
620         struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue);
621         struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
622 
623         if (vb->state == VB2_BUF_STATE_DONE) {
624                 /*
625                  * Application has called dqbuf and is getting back a buffer
626                  * we've filled, take the pwc data we've stored in buf->data
627                  * and decompress it into a usable format, storing the result
628                  * in the vb2_buffer.
629                  */
630                 pwc_decompress(pdev, buf);
631         }
632 }
633 
634 static void buffer_cleanup(struct vb2_buffer *vb)
635 {
636         struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
637 
638         vfree(buf->data);
639 }
640 
641 static void buffer_queue(struct vb2_buffer *vb)
642 {
643         struct pwc_device *pdev = vb2_get_drv_priv(vb->vb2_queue);
644         struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
645         unsigned long flags = 0;
646 
647         /* Check the device has not disconnected between prep and queuing */
648         if (!pdev->udev) {
649                 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
650                 return;
651         }
652 
653         spin_lock_irqsave(&pdev->queued_bufs_lock, flags);
654         list_add_tail(&buf->list, &pdev->queued_bufs);
655         spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags);
656 }
657 
658 static int start_streaming(struct vb2_queue *vq, unsigned int count)
659 {
660         struct pwc_device *pdev = vb2_get_drv_priv(vq);
661         int r;
662 
663         if (!pdev->udev)
664                 return -ENODEV;
665 
666         if (mutex_lock_interruptible(&pdev->v4l2_lock))
667                 return -ERESTARTSYS;
668         /* Turn on camera and set LEDS on */
669         pwc_camera_power(pdev, 1);
670         pwc_set_leds(pdev, leds[0], leds[1]);
671 
672         r = pwc_isoc_init(pdev);
673         if (r) {
674                 /* If we failed turn camera and LEDS back off */
675                 pwc_set_leds(pdev, 0, 0);
676                 pwc_camera_power(pdev, 0);
677                 /* And cleanup any queued bufs!! */
678                 pwc_cleanup_queued_bufs(pdev, VB2_BUF_STATE_QUEUED);
679         }
680         mutex_unlock(&pdev->v4l2_lock);
681 
682         return r;
683 }
684 
685 static void stop_streaming(struct vb2_queue *vq)
686 {
687         struct pwc_device *pdev = vb2_get_drv_priv(vq);
688 
689         mutex_lock(&pdev->v4l2_lock);
690         if (pdev->udev) {
691                 pwc_set_leds(pdev, 0, 0);
692                 pwc_camera_power(pdev, 0);
693                 pwc_isoc_cleanup(pdev);
694         }
695 
696         pwc_cleanup_queued_bufs(pdev, VB2_BUF_STATE_ERROR);
697         if (pdev->fill_buf)
698                 vb2_buffer_done(&pdev->fill_buf->vb, VB2_BUF_STATE_ERROR);
699         mutex_unlock(&pdev->v4l2_lock);
700 }
701 
702 static struct vb2_ops pwc_vb_queue_ops = {
703         .queue_setup            = queue_setup,
704         .buf_init               = buffer_init,
705         .buf_prepare            = buffer_prepare,
706         .buf_finish             = buffer_finish,
707         .buf_cleanup            = buffer_cleanup,
708         .buf_queue              = buffer_queue,
709         .start_streaming        = start_streaming,
710         .stop_streaming         = stop_streaming,
711         .wait_prepare           = vb2_ops_wait_prepare,
712         .wait_finish            = vb2_ops_wait_finish,
713 };
714 
715 /***************************************************************************/
716 /* USB functions */
717 
718 /* This function gets called when a new device is plugged in or the usb core
719  * is loaded.
720  */
721 
722 static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id)
723 {
724         struct usb_device *udev = interface_to_usbdev(intf);
725         struct pwc_device *pdev = NULL;
726         int vendor_id, product_id, type_id;
727         int rc;
728         int features = 0;
729         int compression = 0;
730         int my_power_save = power_save;
731         char serial_number[30], *name;
732 
733         vendor_id = le16_to_cpu(udev->descriptor.idVendor);
734         product_id = le16_to_cpu(udev->descriptor.idProduct);
735 
736         /* Check if we can handle this device */
737         PWC_DEBUG_PROBE("probe() called [%04X %04X], if %d\n",
738                 vendor_id, product_id,
739                 intf->altsetting->desc.bInterfaceNumber);
740 
741         /* the interfaces are probed one by one. We are only interested in the
742            video interface (0) now.
743            Interface 1 is the Audio Control, and interface 2 Audio itself.
744          */
745         if (intf->altsetting->desc.bInterfaceNumber > 0)
746                 return -ENODEV;
747 
748         if (vendor_id == 0x0471) {
749                 switch (product_id) {
750                 case 0x0302:
751                         PWC_INFO("Philips PCA645VC USB webcam detected.\n");
752                         name = "Philips 645 webcam";
753                         type_id = 645;
754                         break;
755                 case 0x0303:
756                         PWC_INFO("Philips PCA646VC USB webcam detected.\n");
757                         name = "Philips 646 webcam";
758                         type_id = 646;
759                         break;
760                 case 0x0304:
761                         PWC_INFO("Askey VC010 type 2 USB webcam detected.\n");
762                         name = "Askey VC010 webcam";
763                         type_id = 646;
764                         break;
765                 case 0x0307:
766                         PWC_INFO("Philips PCVC675K (Vesta) USB webcam detected.\n");
767                         name = "Philips 675 webcam";
768                         type_id = 675;
769                         break;
770                 case 0x0308:
771                         PWC_INFO("Philips PCVC680K (Vesta Pro) USB webcam detected.\n");
772                         name = "Philips 680 webcam";
773                         type_id = 680;
774                         break;
775                 case 0x030C:
776                         PWC_INFO("Philips PCVC690K (Vesta Pro Scan) USB webcam detected.\n");
777                         name = "Philips 690 webcam";
778                         type_id = 690;
779                         break;
780                 case 0x0310:
781                         PWC_INFO("Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) USB webcam detected.\n");
782                         name = "Philips 730 webcam";
783                         type_id = 730;
784                         break;
785                 case 0x0311:
786                         PWC_INFO("Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) USB webcam detected.\n");
787                         name = "Philips 740 webcam";
788                         type_id = 740;
789                         break;
790                 case 0x0312:
791                         PWC_INFO("Philips PCVC750K (ToUCam Pro Scan) USB webcam detected.\n");
792                         name = "Philips 750 webcam";
793                         type_id = 750;
794                         break;
795                 case 0x0313:
796                         PWC_INFO("Philips PCVC720K/40 (ToUCam XS) USB webcam detected.\n");
797                         name = "Philips 720K/40 webcam";
798                         type_id = 720;
799                         break;
800                 case 0x0329:
801                         PWC_INFO("Philips SPC 900NC USB webcam detected.\n");
802                         name = "Philips SPC 900NC webcam";
803                         type_id = 740;
804                         break;
805                 default:
806                         return -ENODEV;
807                         break;
808                 }
809         }
810         else if (vendor_id == 0x069A) {
811                 switch(product_id) {
812                 case 0x0001:
813                         PWC_INFO("Askey VC010 type 1 USB webcam detected.\n");
814                         name = "Askey VC010 webcam";
815                         type_id = 645;
816                         break;
817                 default:
818                         return -ENODEV;
819                         break;
820                 }
821         }
822         else if (vendor_id == 0x046d) {
823                 switch(product_id) {
824                 case 0x08b0:
825                         PWC_INFO("Logitech QuickCam Pro 3000 USB webcam detected.\n");
826                         name = "Logitech QuickCam Pro 3000";
827                         type_id = 740; /* CCD sensor */
828                         break;
829                 case 0x08b1:
830                         PWC_INFO("Logitech QuickCam Notebook Pro USB webcam detected.\n");
831                         name = "Logitech QuickCam Notebook Pro";
832                         type_id = 740; /* CCD sensor */
833                         break;
834                 case 0x08b2:
835                         PWC_INFO("Logitech QuickCam 4000 Pro USB webcam detected.\n");
836                         name = "Logitech QuickCam Pro 4000";
837                         type_id = 740; /* CCD sensor */
838                         if (my_power_save == -1)
839                                 my_power_save = 1;
840                         break;
841                 case 0x08b3:
842                         PWC_INFO("Logitech QuickCam Zoom USB webcam detected.\n");
843                         name = "Logitech QuickCam Zoom";
844                         type_id = 740; /* CCD sensor */
845                         break;
846                 case 0x08B4:
847                         PWC_INFO("Logitech QuickCam Zoom (new model) USB webcam detected.\n");
848                         name = "Logitech QuickCam Zoom";
849                         type_id = 740; /* CCD sensor */
850                         if (my_power_save == -1)
851                                 my_power_save = 1;
852                         break;
853                 case 0x08b5:
854                         PWC_INFO("Logitech QuickCam Orbit/Sphere USB webcam detected.\n");
855                         name = "Logitech QuickCam Orbit";
856                         type_id = 740; /* CCD sensor */
857                         if (my_power_save == -1)
858                                 my_power_save = 1;
859                         features |= FEATURE_MOTOR_PANTILT;
860                         break;
861                 case 0x08b6:
862                         PWC_INFO("Logitech/Cisco VT Camera webcam detected.\n");
863                         name = "Cisco VT Camera";
864                         type_id = 740; /* CCD sensor */
865                         break;
866                 case 0x08b7:
867                         PWC_INFO("Logitech ViewPort AV 100 webcam detected.\n");
868                         name = "Logitech ViewPort AV 100";
869                         type_id = 740; /* CCD sensor */
870                         break;
871                 case 0x08b8: /* Where this released? */
872                         PWC_INFO("Logitech QuickCam detected (reserved ID).\n");
873                         name = "Logitech QuickCam (res.)";
874                         type_id = 730; /* Assuming CMOS */
875                         break;
876                 default:
877                         return -ENODEV;
878                         break;
879                 }
880         }
881         else if (vendor_id == 0x055d) {
882                 /* I don't know the difference between the C10 and the C30;
883                    I suppose the difference is the sensor, but both cameras
884                    work equally well with a type_id of 675
885                  */
886                 switch(product_id) {
887                 case 0x9000:
888                         PWC_INFO("Samsung MPC-C10 USB webcam detected.\n");
889                         name = "Samsung MPC-C10";
890                         type_id = 675;
891                         break;
892                 case 0x9001:
893                         PWC_INFO("Samsung MPC-C30 USB webcam detected.\n");
894                         name = "Samsung MPC-C30";
895                         type_id = 675;
896                         break;
897                 case 0x9002:
898                         PWC_INFO("Samsung SNC-35E (v3.0) USB webcam detected.\n");
899                         name = "Samsung MPC-C30";
900                         type_id = 740;
901                         break;
902                 default:
903                         return -ENODEV;
904                         break;
905                 }
906         }
907         else if (vendor_id == 0x041e) {
908                 switch(product_id) {
909                 case 0x400c:
910                         PWC_INFO("Creative Labs Webcam 5 detected.\n");
911                         name = "Creative Labs Webcam 5";
912                         type_id = 730;
913                         if (my_power_save == -1)
914                                 my_power_save = 1;
915                         break;
916                 case 0x4011:
917                         PWC_INFO("Creative Labs Webcam Pro Ex detected.\n");
918                         name = "Creative Labs Webcam Pro Ex";
919                         type_id = 740;
920                         break;
921                 default:
922                         return -ENODEV;
923                         break;
924                 }
925         }
926         else if (vendor_id == 0x04cc) {
927                 switch(product_id) {
928                 case 0x8116:
929                         PWC_INFO("Sotec Afina Eye USB webcam detected.\n");
930                         name = "Sotec Afina Eye";
931                         type_id = 730;
932                         break;
933                 default:
934                         return -ENODEV;
935                         break;
936                 }
937         }
938         else if (vendor_id == 0x06be) {
939                 switch(product_id) {
940                 case 0x8116:
941                         /* This is essentially the same cam as the Sotec Afina Eye */
942                         PWC_INFO("AME Co. Afina Eye USB webcam detected.\n");
943                         name = "AME Co. Afina Eye";
944                         type_id = 750;
945                         break;
946                 default:
947                         return -ENODEV;
948                         break;
949                 }
950 
951         }
952         else if (vendor_id == 0x0d81) {
953                 switch(product_id) {
954                 case 0x1900:
955                         PWC_INFO("Visionite VCS-UC300 USB webcam detected.\n");
956                         name = "Visionite VCS-UC300";
957                         type_id = 740; /* CCD sensor */
958                         break;
959                 case 0x1910:
960                         PWC_INFO("Visionite VCS-UM100 USB webcam detected.\n");
961                         name = "Visionite VCS-UM100";
962                         type_id = 730; /* CMOS sensor */
963                         break;
964                 default:
965                         return -ENODEV;
966                         break;
967                 }
968         }
969         else
970                 return -ENODEV; /* Not any of the know types; but the list keeps growing. */
971 
972         if (my_power_save == -1)
973                 my_power_save = 0;
974 
975         memset(serial_number, 0, 30);
976         usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29);
977         PWC_DEBUG_PROBE("Device serial number is %s\n", serial_number);
978 
979         if (udev->descriptor.bNumConfigurations > 1)
980                 PWC_WARNING("Warning: more than 1 configuration available.\n");
981 
982         /* Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device */
983         pdev = kzalloc(sizeof(struct pwc_device), GFP_KERNEL);
984         if (pdev == NULL) {
985                 PWC_ERROR("Oops, could not allocate memory for pwc_device.\n");
986                 return -ENOMEM;
987         }
988         pdev->type = type_id;
989         pdev->features = features;
990         pwc_construct(pdev); /* set min/max sizes correct */
991 
992         mutex_init(&pdev->v4l2_lock);
993         mutex_init(&pdev->vb_queue_lock);
994         spin_lock_init(&pdev->queued_bufs_lock);
995         INIT_LIST_HEAD(&pdev->queued_bufs);
996 
997         pdev->udev = udev;
998         pdev->power_save = my_power_save;
999 
1000         /* Init videobuf2 queue structure */
1001         pdev->vb_queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1002         pdev->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
1003         pdev->vb_queue.drv_priv = pdev;
1004         pdev->vb_queue.buf_struct_size = sizeof(struct pwc_frame_buf);
1005         pdev->vb_queue.ops = &pwc_vb_queue_ops;
1006         pdev->vb_queue.mem_ops = &vb2_vmalloc_memops;
1007         pdev->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1008         rc = vb2_queue_init(&pdev->vb_queue);
1009         if (rc < 0) {
1010                 PWC_ERROR("Oops, could not initialize vb2 queue.\n");
1011                 goto err_free_mem;
1012         }
1013 
1014         /* Init video_device structure */
1015         pdev->vdev = pwc_template;
1016         strcpy(pdev->vdev.name, name);
1017         pdev->vdev.queue = &pdev->vb_queue;
1018         pdev->vdev.queue->lock = &pdev->vb_queue_lock;
1019         video_set_drvdata(&pdev->vdev, pdev);
1020 
1021         pdev->release = le16_to_cpu(udev->descriptor.bcdDevice);
1022         PWC_DEBUG_PROBE("Release: %04x\n", pdev->release);
1023 
1024         /* Allocate USB command buffers */
1025         pdev->ctrl_buf = kmalloc(sizeof(pdev->cmd_buf), GFP_KERNEL);
1026         if (!pdev->ctrl_buf) {
1027                 PWC_ERROR("Oops, could not allocate memory for pwc_device.\n");
1028                 rc = -ENOMEM;
1029                 goto err_free_mem;
1030         }
1031 
1032 #ifdef CONFIG_USB_PWC_DEBUG
1033         /* Query sensor type */
1034         if (pwc_get_cmos_sensor(pdev, &rc) >= 0) {
1035                 PWC_DEBUG_OPEN("This %s camera is equipped with a %s (%d).\n",
1036                                 pdev->vdev.name,
1037                                 pwc_sensor_type_to_string(rc), rc);
1038         }
1039 #endif
1040 
1041         /* Set the leds off */
1042         pwc_set_leds(pdev, 0, 0);
1043 
1044         /* Setup initial videomode */
1045         rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT,
1046                                 V4L2_PIX_FMT_YUV420, 30, &compression, 1);
1047         if (rc)
1048                 goto err_free_mem;
1049 
1050         /* Register controls (and read default values from camera */
1051         rc = pwc_init_controls(pdev);
1052         if (rc) {
1053                 PWC_ERROR("Failed to register v4l2 controls (%d).\n", rc);
1054                 goto err_free_mem;
1055         }
1056 
1057         /* And powerdown the camera until streaming starts */
1058         pwc_camera_power(pdev, 0);
1059 
1060         /* Register the v4l2_device structure */
1061         pdev->v4l2_dev.release = pwc_video_release;
1062         rc = v4l2_device_register(&intf->dev, &pdev->v4l2_dev);
1063         if (rc) {
1064                 PWC_ERROR("Failed to register v4l2-device (%d).\n", rc);
1065                 goto err_free_controls;
1066         }
1067 
1068         pdev->v4l2_dev.ctrl_handler = &pdev->ctrl_handler;
1069         pdev->vdev.v4l2_dev = &pdev->v4l2_dev;
1070         pdev->vdev.lock = &pdev->v4l2_lock;
1071 
1072         rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, -1);
1073         if (rc < 0) {
1074                 PWC_ERROR("Failed to register as video device (%d).\n", rc);
1075                 goto err_unregister_v4l2_dev;
1076         }
1077         PWC_INFO("Registered as %s.\n", video_device_node_name(&pdev->vdev));
1078 
1079 #ifdef CONFIG_USB_PWC_INPUT_EVDEV
1080         /* register webcam snapshot button input device */
1081         pdev->button_dev = input_allocate_device();
1082         if (!pdev->button_dev) {
1083                 rc = -ENOMEM;
1084                 goto err_video_unreg;
1085         }
1086 
1087         usb_make_path(udev, pdev->button_phys, sizeof(pdev->button_phys));
1088         strlcat(pdev->button_phys, "/input0", sizeof(pdev->button_phys));
1089 
1090         pdev->button_dev->name = "PWC snapshot button";
1091         pdev->button_dev->phys = pdev->button_phys;
1092         usb_to_input_id(pdev->udev, &pdev->button_dev->id);
1093         pdev->button_dev->dev.parent = &pdev->udev->dev;
1094         pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY);
1095         pdev->button_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);
1096 
1097         rc = input_register_device(pdev->button_dev);
1098         if (rc) {
1099                 input_free_device(pdev->button_dev);
1100                 pdev->button_dev = NULL;
1101                 goto err_video_unreg;
1102         }
1103 #endif
1104 
1105         return 0;
1106 
1107 err_video_unreg:
1108         video_unregister_device(&pdev->vdev);
1109 err_unregister_v4l2_dev:
1110         v4l2_device_unregister(&pdev->v4l2_dev);
1111 err_free_controls:
1112         v4l2_ctrl_handler_free(&pdev->ctrl_handler);
1113 err_free_mem:
1114         kfree(pdev->ctrl_buf);
1115         kfree(pdev);
1116         return rc;
1117 }
1118 
1119 /* The user yanked out the cable... */
1120 static void usb_pwc_disconnect(struct usb_interface *intf)
1121 {
1122         struct v4l2_device *v = usb_get_intfdata(intf);
1123         struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);
1124 
1125         mutex_lock(&pdev->vb_queue_lock);
1126         mutex_lock(&pdev->v4l2_lock);
1127         /* No need to keep the urbs around after disconnection */
1128         if (pdev->vb_queue.streaming)
1129                 pwc_isoc_cleanup(pdev);
1130         pdev->udev = NULL;
1131 
1132         v4l2_device_disconnect(&pdev->v4l2_dev);
1133         video_unregister_device(&pdev->vdev);
1134         mutex_unlock(&pdev->v4l2_lock);
1135         mutex_unlock(&pdev->vb_queue_lock);
1136 
1137 #ifdef CONFIG_USB_PWC_INPUT_EVDEV
1138         if (pdev->button_dev)
1139                 input_unregister_device(pdev->button_dev);
1140 #endif
1141 
1142         v4l2_device_put(&pdev->v4l2_dev);
1143 }
1144 
1145 
1146 /*
1147  * Initialization code & module stuff
1148  */
1149 
1150 static unsigned int leds_nargs;
1151 
1152 #ifdef CONFIG_USB_PWC_DEBUG
1153 module_param_named(trace, pwc_trace, int, 0644);
1154 #endif
1155 module_param(power_save, int, 0644);
1156 module_param_array(leds, int, &leds_nargs, 0444);
1157 
1158 #ifdef CONFIG_USB_PWC_DEBUG
1159 MODULE_PARM_DESC(trace, "For debugging purposes");
1160 #endif
1161 MODULE_PARM_DESC(power_save, "Turn power saving for new cameras on or off");
1162 MODULE_PARM_DESC(leds, "LED on,off time in milliseconds");
1163 
1164 MODULE_DESCRIPTION("Philips & OEM USB webcam driver");
1165 MODULE_AUTHOR("Luc Saillard <luc@saillard.org>");
1166 MODULE_LICENSE("GPL");
1167 MODULE_ALIAS("pwcx");
1168 MODULE_VERSION( PWC_VERSION );
1169 
1170 module_usb_driver(pwc_driver);
1171 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us