stk11xx-v4l.c

Go to the documentation of this file.
00001 
00034 #include <linux/module.h>
00035 #include <linux/init.h>
00036 #include <linux/kernel.h>
00037 #include <linux/errno.h>
00038 #include <linux/slab.h>
00039 #include <linux/kref.h>
00040 #include <linux/vmalloc.h>
00041 
00042 #include <linux/usb.h>
00043 //#include <linux/videodev2.h>
00044 #include <media/v4l2-common.h>
00045 //#include <media/pwc-ioctl.h>
00046 
00047 #include "stk11xx.h"
00048 
00049 
00054 #define STK11XX_PERCENT(x,y) ( ((int)x * (int)y) / 100)
00055 
00056 
00057 static struct file_operations v4l_stk11xx_fops;
00058 
00059 
00064 const struct stk11xx_coord stk11xx_image_sizes[STK11XX_NBR_SIZES] = {
00065     {   80,   60 },
00066     {  128,   96 },
00067     {  160,  120 },
00068     {  213,  160 },
00069     {  320,  240 },
00070     {  640,  480 },
00071     {  800,  600 },
00072     { 1024,  768 },
00073     { 1280, 1024 }
00074 };
00075 
00076 
00081 static struct v4l2_queryctrl stk11xx_controls[] = {
00082     {
00083         .id      = V4L2_CID_BRIGHTNESS,
00084         .type    = V4L2_CTRL_TYPE_INTEGER,
00085         .name    = "Brightness",
00086         .minimum = 0,
00087         .maximum = 0xFFFF,
00088         .step    = 1,
00089         .default_value = 0xFF00,
00090     },
00091     {
00092         .id      = V4L2_CID_CONTRAST,
00093         .type    = V4L2_CTRL_TYPE_INTEGER,
00094         .name    = "Contrast",
00095         .minimum = 0,
00096         .maximum = 0xFFFF,
00097         .step    = 1,
00098         .default_value = 0xFF00,
00099     },
00100 };
00101 
00102 
00114 int v4l_stk11xx_select_video_mode(struct usb_stk11xx *dev, int width, int height)
00115 {
00116     int i;
00117     int find;
00118 
00119 
00120     // Check width and height
00121     // Driver can't build an image more little than the minimal resolution !
00122     if ((width < stk11xx_image_sizes[0].x)
00123             || (height < stk11xx_image_sizes[0].y))
00124         return -1;
00125 
00126     // Seek the best resolution
00127     switch (dev->webcam_type) {
00128         case STK11XX_SXGA:
00129             for (i=0, find=0; i<STK11XX_NBR_SIZES; i++) {
00130                 if (stk11xx_image_sizes[i].x <= width && stk11xx_image_sizes[i].y <= height)
00131                     find = i;
00132             }
00133             break;
00134 
00135         case STK11XX_VGA:
00136             for (i=0, find=0; i<STK11XX_NBR_SIZES-3; i++) {
00137                 if (stk11xx_image_sizes[i].x <= width && stk11xx_image_sizes[i].y <= height)
00138                     find = i;
00139             }
00140             break;
00141 
00142         default:
00143             return -1;
00144     }
00145 
00146     // Save the new resolution
00147     dev->resolution = find;
00148 
00149     STK_DEBUG("Set mode %d [%dx%d]\n", dev->resolution,
00150             stk11xx_image_sizes[dev->resolution].x, stk11xx_image_sizes[dev->resolution].y);
00151 
00152     // Save the new size
00153     dev->view.x = width;
00154     dev->view.y = height;
00155 
00156 
00157     // Calculate the frame size
00158     switch (dev->resolution) {
00159         case STK11XX_80x60:
00160         case STK11XX_128x96:
00161         case STK11XX_160x120:
00162         case STK11XX_213x160:
00163         case STK11XX_320x240:
00164         case STK11XX_640x480:
00165             dev->image.x = stk11xx_image_sizes[STK11XX_640x480].x;
00166             dev->image.y = stk11xx_image_sizes[STK11XX_640x480].y;
00167             dev->frame_size = dev->image.x * dev->image.y;
00168             break;
00169 
00170         case STK11XX_800x600:
00171         case STK11XX_1024x768:
00172         case STK11XX_1280x1024:
00173             dev->image.x = stk11xx_image_sizes[STK11XX_1280x1024].x;
00174             dev->image.y = stk11xx_image_sizes[STK11XX_1280x1024].y;
00175             dev->frame_size = dev->image.x * dev->image.y;
00176             break;
00177     }
00178 
00179 
00180     // Calculate the image size
00181     switch (dev->vsettings.palette) {
00182         case STK11XX_PALETTE_RGB24:
00183         case STK11XX_PALETTE_BGR24:
00184             dev->image_size = 3 * dev->frame_size;
00185             break;
00186 
00187         case STK11XX_PALETTE_RGB32:
00188         case STK11XX_PALETTE_BGR32:
00189             dev->image_size = 4 * dev->frame_size;
00190             break;
00191     }
00192 
00193     return 0;
00194 }
00195 
00196 
00207 static int v4l_stk11xx_open(struct inode *inode, struct file *fp)
00208 {
00209     int err;
00210 
00211     struct usb_stk11xx *dev;
00212     struct video_device *vdev;
00213     
00214     vdev = video_devdata(fp);
00215     dev = video_get_drvdata(video_devdata(fp));
00216 
00217     if (dev == NULL) {
00218         STK_ERROR("Device not initialized !!!\n");
00219         BUG();
00220     }
00221 
00222     if (dev->vopen) {
00223         STK_DEBUG("Device is busy, someone is using the device\n");
00224         return -EBUSY;
00225     }
00226 
00227     // Allocate memory
00228     err = stk11xx_allocate_buffers(dev);
00229 
00230     if (err < 0) {
00231         STK_ERROR("Failed to allocate buffer memory !\n");
00232         return err;
00233     }
00234     
00235     // Reset buffers and parameters
00236     stk11xx_reset_buffers(dev);
00237 
00238     // Settings
00239     dev->error_status = 0;
00240     dev->visoc_errors = 0;
00241     dev->vframes_error = 0;
00242     dev->vframes_dumped = 0;
00243     dev->vsettings.brightness = STK11XX_PERCENT(50, 0xFFFF); // 0x6400;
00244     dev->vsettings.contrast = STK11XX_PERCENT(50, 0xFFFF); //0xF800;
00245     dev->vsettings.whiteness = STK11XX_PERCENT(50, 0xFFFF); //0x1000;
00246     dev->vsettings.colour = 0xFFFF;
00247     dev->vsettings.depth = 24;
00248     dev->vsettings.palette = STK11XX_PALETTE_BGR24;
00249     dev->vsettings.hue = STK11XX_PERCENT(50, 0xFFFF);
00250 
00251     // Select the resolution by default
00252     v4l_stk11xx_select_video_mode(dev, 640, 480);
00253 
00254     // Initialize the device
00255     dev_stk11xx_init_camera(dev);
00256     dev_stk11xx_camera_on(dev);
00257     dev_stk11xx_reconf_camera(dev);
00258 
00259     // Init Isoc and URB
00260     err = usb_stk11xx_isoc_init(dev);
00261 
00262     if (err) {
00263         STK_ERROR("Failed to init ISOC stuff !\n");
00264         usb_stk11xx_isoc_cleanup(dev);
00265         stk11xx_free_buffers(dev);
00266         return err;
00267     }
00268 
00269     // Start the video stream
00270     dev_stk11xx_start_stream(dev);
00271 
00272     // Video settings
00273     dev_stk11xx_camera_settings(dev);
00274 
00275     dev->vopen++;
00276     fp->private_data = vdev;
00277 
00278     return 0;
00279 }
00280 
00281 
00292 static int v4l_stk11xx_release(struct inode *inode, struct file *fp)
00293 {
00294     struct usb_stk11xx *dev;
00295     struct video_device *vdev;
00296     
00297     vdev = video_devdata(fp);
00298     dev = video_get_drvdata(video_devdata(fp));
00299 
00300     if (dev->vopen == 0)
00301         STK_ERROR("v4l_release called on closed device\n");
00302 
00303     // Stop the video stream
00304     dev_stk11xx_stop_stream(dev);
00305 
00306     // ISOC and URB cleanup
00307     usb_stk11xx_isoc_cleanup(dev);
00308 
00309     // Free memory
00310     stk11xx_free_buffers(dev);
00311 
00312     // Switch off the camera
00313     dev_stk11xx_camera_off(dev);
00314 
00315     dev_stk11xx_camera_asleep(dev);
00316 
00317     dev->vopen--;
00318 
00319     return 0;
00320 }
00321 
00322 
00336 static ssize_t v4l_stk11xx_read(struct file *fp, char __user *buf,
00337         size_t count, loff_t *f_pos)
00338 {
00339     int noblock = fp->f_flags & O_NONBLOCK;
00340 
00341     struct usb_stk11xx *dev;
00342     struct video_device *vdev;
00343 
00344     int bytes_to_read;
00345     void *image_buffer_addr;
00346     
00347     DECLARE_WAITQUEUE(wait, current);
00348 
00349     vdev = video_devdata(fp);
00350     dev = video_get_drvdata(video_devdata(fp));
00351 
00352     STK_STREAM("Read vdev=0x%p, buf=0x%p, count=%zd\n", vdev, buf, count);
00353 
00354     if (dev == NULL)
00355         return -EFAULT;
00356 
00357     if (vdev == NULL)
00358         return -EFAULT;
00359 
00360     if (dev->image_read_pos == 0) {
00361         add_wait_queue(&dev->wait_frame, &wait);
00362 
00363         while (dev->full_frames == NULL) {
00364             if (dev->error_status) {
00365                 remove_wait_queue(&dev->wait_frame, &wait);
00366                 set_current_state(TASK_RUNNING);
00367                 return -dev->error_status ;
00368             }
00369 
00370             if (noblock) {
00371                 remove_wait_queue(&dev->wait_frame, &wait);
00372                 set_current_state(TASK_RUNNING);
00373                 return -EWOULDBLOCK;
00374             }
00375 
00376             if (signal_pending(current)) {
00377                 remove_wait_queue(&dev->wait_frame, &wait);
00378                 set_current_state(TASK_RUNNING);
00379                 return -ERESTARTSYS;
00380             }
00381 
00382             schedule();
00383             set_current_state(TASK_INTERRUPTIBLE);
00384         }
00385 
00386         remove_wait_queue(&dev->wait_frame, &wait);
00387         set_current_state(TASK_RUNNING);
00388 
00389         if (stk11xx_handle_frame(dev))
00390             return -EFAULT;
00391     }
00392 
00393     bytes_to_read = dev->image_size;
00394 
00395     if (count + dev->image_read_pos > bytes_to_read)
00396         count = bytes_to_read - dev->image_read_pos;
00397 
00398     image_buffer_addr = dev->image_data;
00399     image_buffer_addr += dev->images[dev->fill_image].offset;
00400     image_buffer_addr += dev->image_read_pos;
00401 
00402     if (copy_to_user(buf, image_buffer_addr, count))
00403         return -EFAULT;
00404     
00405     dev->image_read_pos += count;
00406     
00407     if (dev->image_read_pos >= bytes_to_read) {
00408         dev->image_read_pos = 0;
00409         stk11xx_next_image(dev);
00410     }
00411 
00412     return count;
00413 }
00414 
00415 
00424 static unsigned int v4l_stk11xx_poll(struct file *fp, poll_table *wait)
00425 {
00426     struct usb_stk11xx *dev;
00427     struct video_device *vdev;
00428     
00429     vdev = video_devdata(fp);
00430     dev = video_get_drvdata(video_devdata(fp));
00431 
00432     STK_STREAM("Poll\n");
00433 
00434     if (vdev == NULL)
00435         return -EFAULT;
00436 
00437     if (dev == NULL)
00438         return -EFAULT;
00439 
00440     poll_wait(fp, &dev->wait_frame, wait);
00441 
00442     if (dev->error_status)
00443         return POLLERR;
00444 
00445     if (dev->full_frames != NULL)
00446         return (POLLIN | POLLRDNORM);
00447 
00448     return 0;
00449 }
00450 
00451 
00462 static int v4l_stk11xx_mmap(struct file *fp, struct vm_area_struct *vma)
00463 {
00464     unsigned int i;
00465 
00466     unsigned long size;
00467     unsigned long start;
00468     unsigned long pos;
00469     unsigned long page;
00470 
00471     struct usb_stk11xx *dev;
00472 
00473     struct video_device *vdev;
00474     
00475     vdev = video_devdata(fp);
00476     dev = video_get_drvdata(video_devdata(fp));
00477 
00478     STK_STREAM("mmap\n");
00479 
00480     start = vma->vm_start;
00481     size = vma->vm_end - vma->vm_start;
00482 
00483     // Find the buffer for this mapping...
00484     for (i=0; i<dev->nbuffers; i++) {
00485         pos = dev->images[i].offset;
00486 
00487         if ((pos >> PAGE_SHIFT) == vma->vm_pgoff)
00488             break;
00489     }
00490 
00491     // If no buffer found !
00492     if (i == STK11XX_MAX_IMAGES) {
00493         STK_ERROR("mmap no buffer found !\n");
00494         return -EINVAL;
00495     }
00496 
00497     if (i == 0) {
00498         unsigned long total_size;
00499 
00500         total_size = dev->nbuffers * dev->len_per_image;
00501 
00502         if (size != dev->len_per_image && size != total_size)
00503             return -EINVAL;
00504     }
00505     else if (size > dev->len_per_image)
00506         return -EINVAL;
00507 
00508     vma->vm_flags |= VM_IO;
00509 
00510     pos = (unsigned long) dev->image_data;
00511 
00512     while (size > 0) {
00513         page = vmalloc_to_pfn((void *) pos);
00514 
00515         if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
00516             return -EAGAIN;
00517 
00518         start += PAGE_SIZE;
00519         pos += PAGE_SIZE;
00520 
00521         if (size > PAGE_SIZE)
00522             size -= PAGE_SIZE;
00523         else
00524             size = 0;
00525     }
00526 
00527     return 0;
00528 }
00529 
00530 
00543 static int v4l_stk11xx_do_ioctl(struct inode *inode, struct file *fp,
00544         unsigned int cmd, void __user *arg)
00545 {
00546     struct usb_stk11xx *dev;
00547     struct video_device *vdev;
00548 
00549     DECLARE_WAITQUEUE(wait, current);
00550     
00551     vdev = video_devdata(fp);
00552     dev = video_get_drvdata(video_devdata(fp));
00553 
00554     switch (cmd) {
00555         // Video 4 Linux v1
00556 
00557         case VIDIOCGCAP:
00558             {
00559                 struct video_capability *cap = arg;
00560 
00561                 STK_DEBUG("VIDIOCGCAP\n");
00562 
00563                 memset(cap, 0, sizeof(*cap));
00564                 strlcpy(cap->name, "stk11xx", sizeof(cap->name));
00565                 cap->type = VID_TYPE_CAPTURE;
00566                 cap->channels = 1;
00567                 cap->audios = 0;
00568 
00569                 switch (dev->webcam_type) {
00570                     case STK11XX_SXGA:
00571                         cap->minwidth = stk11xx_image_sizes[STK11XX_80x60].x;
00572                         cap->minheight = stk11xx_image_sizes[STK11XX_80x60].y;
00573                         cap->maxwidth = stk11xx_image_sizes[STK11XX_1280x1024].x;
00574                         cap->maxheight = stk11xx_image_sizes[STK11XX_1280x1024].y;
00575                         break;
00576 
00577                     case STK11XX_VGA:
00578                         cap->minwidth = stk11xx_image_sizes[STK11XX_80x60].x;
00579                         cap->minheight = stk11xx_image_sizes[STK11XX_80x60].y;
00580                         cap->maxwidth = stk11xx_image_sizes[STK11XX_640x480].x;
00581                         cap->maxheight = stk11xx_image_sizes[STK11XX_640x480].y;
00582                         break;
00583                 }
00584             }
00585             break;
00586     
00587         case VIDIOCGCHAN:
00588             {
00589                 struct video_channel *v = arg;
00590 
00591                 STK_DEBUG("VIDIOCGCHAN\n");
00592 
00593                 if (v->channel != 0)
00594                     return -EINVAL;
00595             
00596                 v->flags = 0;
00597                 v->tuners = 0;
00598                 v->type = VIDEO_TYPE_CAMERA;
00599                 strcpy(v->name, "Webcam");
00600             }
00601             break;
00602 
00603         case VIDIOCSCHAN:
00604             {
00605                 struct video_channel *v = arg;
00606 
00607                 STK_DEBUG("VIDIOCSCHAN\n");
00608 
00609                 if (v->channel != 0)
00610                     return -EINVAL;
00611             }
00612             break;
00613 
00614         case VIDIOCGPICT:
00615             {
00616                 struct video_picture *p = arg;
00617 
00618                 STK_DEBUG("VIDIOCGPICT\n");
00619 
00620                 p->brightness = dev->vsettings.brightness;
00621                 p->contrast = dev->vsettings.contrast;
00622                 p->whiteness = dev->vsettings.whiteness;
00623                 p->colour = dev->vsettings.colour;
00624                 p->depth = dev->vsettings.depth;
00625                 p->palette = dev->vsettings.palette;
00626                 p->hue = dev->vsettings.hue;
00627 
00628                 switch (dev->vsettings.palette) {
00629                     case STK11XX_PALETTE_BGR24:
00630                         p->palette = VIDEO_PALETTE_RGB24;
00631                         break;
00632 
00633                     case STK11XX_PALETTE_BGR32:
00634                         p->palette = VIDEO_PALETTE_RGB32;
00635                         break;
00636                 }
00637             }
00638             break;
00639 
00640         case VIDIOCSPICT:
00641             {
00642                 struct video_picture *p = arg;
00643 
00644                 STK_DEBUG("VIDIOCSPICT\n");
00645 
00646                 dev->vsettings.brightness = p->brightness;
00647                 dev->vsettings.contrast = p->contrast;
00648                 dev->vsettings.whiteness = p->whiteness;
00649                 dev->vsettings.colour = p->colour;
00650                 dev->vsettings.hue = p->hue;
00651                 
00652                 if (p->palette && p->palette != dev->vsettings.palette) {
00653                     switch (p->palette) {
00654                         case VIDEO_PALETTE_RGB24:
00655                             dev->vsettings.depth = 24;
00656                             dev->vsettings.palette = STK11XX_PALETTE_BGR24;
00657                             break;
00658 
00659                         case VIDEO_PALETTE_RGB32:
00660                             dev->vsettings.depth = 32;
00661                             dev->vsettings.palette = STK11XX_PALETTE_BGR32;
00662                             break;
00663 
00664                         default:
00665                             return -EINVAL;
00666                     }
00667                 }
00668 
00669                 dev_stk11xx_camera_settings(dev);
00670 
00671                 STK_DEBUG("VIDIOCSPICT done\n");
00672             }
00673             break;
00674 
00675         case VIDIOCGWIN:
00676             {
00677                 struct video_window *vw = arg;
00678 
00679                 STK_DEBUG("VIDIOCGWIN\n");
00680 
00681                 vw->x = 0;
00682                 vw->y = 0;
00683                 vw->width = dev->view.x;
00684                 vw->height = dev->view.y;
00685                 vw->chromakey = 0;
00686             }
00687             break;
00688 
00689         case VIDIOCSWIN:
00690             {
00691                 struct video_window *vw = arg;
00692 
00693                 STK_DEBUG("VIDIOCSWIN\n");
00694 
00695                 STK_DEBUG("Set x=%d, y=%d\n", vw->x, vw->y);
00696                 STK_DEBUG("Set width=%d, height=%d\n", vw->width, vw->height);
00697                 STK_DEBUG("Flags = %X\n", vw->flags);
00698 
00699                 // Stop the video stream
00700                 dev_stk11xx_stop_stream(dev);
00701             
00702                 // ISOC and URB cleanup
00703                 usb_stk11xx_isoc_cleanup(dev);
00704 
00705                 // Switch off the camera
00706                 dev_stk11xx_camera_off(dev);
00707 
00708                 dev_stk11xx_camera_asleep(dev);
00709 
00710                 // Select the new video mode
00711                 if (v4l_stk11xx_select_video_mode(dev, vw->width, vw->height)) {
00712                     STK_ERROR("Select video mode failed !\n");
00713                     return -EAGAIN;
00714                 }
00715 
00716                 // Clear the buffers
00717                 stk11xx_clear_buffers(dev);
00718 
00719                 // Initialize the device
00720                 dev_stk11xx_init_camera(dev);
00721                 dev_stk11xx_camera_on(dev);
00722                 dev_stk11xx_reconf_camera(dev);
00723 
00724                 // ISOC and URB init
00725                 usb_stk11xx_isoc_init(dev);
00726 
00727                 // Re-start the stream
00728                 dev_stk11xx_start_stream(dev);
00729 
00730                 // Video settings
00731                 dev_stk11xx_camera_settings(dev);
00732             }
00733             break;
00734 
00735         case VIDIOCGFBUF:
00736             {
00737                 struct video_buffer *vb = arg;
00738 
00739                 STK_DEBUG("VIDIOCGFBUF\n");
00740 
00741                 memset(vb, 0, sizeof(*vb));
00742             }
00743             break;
00744 
00745         case VIDIOCGMBUF:
00746             {
00747                 int i;
00748                 struct video_mbuf *vm = arg;
00749 
00750                 STK_DEBUG("VIDIOCGMBUF\n");
00751 
00752                 memset(vm, 0, sizeof(*vm));
00753 
00754                 vm->size = dev->nbuffers * dev->len_per_image;
00755                 vm->frames = dev->nbuffers;
00756 
00757                 for (i=0; i<dev->nbuffers; i++)
00758                     vm->offsets[i] = i * dev->len_per_image;
00759             }
00760             break;
00761 
00762         case VIDIOCMCAPTURE:
00763             {
00764                 struct video_mmap *vm = arg;
00765 
00766                 STK_DEBUG("VIDIOCMCAPTURE\n");
00767 
00768                 if (vm->frame < 0 || vm->frame >= dev->nbuffers)
00769                     return -EINVAL;
00770 
00771                 if (vm->format) {
00772                     switch (vm->format) {
00773                         case VIDEO_PALETTE_RGB32:
00774                             break;
00775 
00776                         case VIDEO_PALETTE_RGB24:
00777                             break;
00778 
00779                         default:
00780                             return -EINVAL;
00781                     }
00782                 }
00783 
00784                 if ((vm->width != dev->view.x) || (vm->height != dev->view.y)) 
00785                     return -EAGAIN;
00786 
00787                 if (dev->image_used[vm->frame])
00788                     return -EBUSY;
00789 
00790                 dev->image_used[vm->frame] = 1;
00791 
00792                 STK_DEBUG("VIDIOCMCAPTURE done\n");
00793             }
00794             break;
00795 
00796         case VIDIOCSYNC:
00797             {
00798                 int ret;
00799                 int *mbuf = arg;
00800 
00801                 STK_DEBUG("VIDIOCSYNC\n");
00802 
00803                 if (*mbuf < 0 || *mbuf >= dev->nbuffers)
00804                     return -EINVAL;
00805 
00806                 if (dev->image_used[*mbuf] == 0)
00807                     return -EINVAL;
00808 
00809                 add_wait_queue(&dev->wait_frame, &wait);
00810 
00811                 while (dev->full_frames == NULL) {
00812                     if (dev->error_status) {
00813                         remove_wait_queue(&dev->wait_frame, &wait);
00814                         set_current_state(TASK_RUNNING);
00815                         return -dev->error_status;
00816                     }
00817 
00818                     if (signal_pending(current)) {
00819                         remove_wait_queue(&dev->wait_frame, &wait);
00820                         set_current_state(TASK_RUNNING);
00821                         return -ERESTARTSYS;
00822                     }
00823 
00824                     schedule();
00825                     set_current_state(TASK_INTERRUPTIBLE);
00826                 }
00827 
00828                 remove_wait_queue(&dev->wait_frame, &wait);
00829                 set_current_state(TASK_RUNNING);
00830 
00831                 STK_DEBUG("VIDIOCSYNC: frame ready\n");
00832 
00833                 dev->fill_image = *mbuf;
00834 
00835                 ret = stk11xx_handle_frame(dev);
00836 
00837                 if (ret != 0)
00838                     STK_ERROR("VIDIOCSYNC error !\n");
00839 
00840                 dev->image_used[*mbuf] = 0;
00841             }
00842             break;
00843 
00844         case VIDIOCGAUDIO:
00845             STK_DEBUG("VIDIOCGAUDIO\n");
00846             return -EINVAL;
00847             break;
00848 
00849         case VIDIOCSAUDIO:
00850             STK_DEBUG("VIDIOCSAUDIO\n");
00851             return -EINVAL;
00852             break;
00853 
00854         case VIDIOCGUNIT:
00855             {
00856                 struct video_unit *vu = arg;
00857 
00858                 vu->video = dev->vdev->minor & 0x3F;
00859                 vu->audio = -1;
00860                 vu->vbi = -1;
00861                 vu->radio = -1;
00862                 vu->teletext = -1;
00863             }
00864             break;
00865 
00866 
00867         // Video 4 Linux v2
00868 
00869         case VIDIOC_QUERYCAP:
00870             {
00871                 struct v4l2_capability *cap = arg;
00872 
00873                 STK_DEBUG("VIDIOC_QUERYCAP\n");
00874 
00875                 memset(cap, 0, sizeof(*cap));
00876                 strlcpy(cap->driver, "stk11xx", sizeof(cap->driver));
00877 
00878                 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
00879                 cap->version = (__u32) DRIVER_VERSION_NUM, strlcpy(cap->card, dev->vdev->name, sizeof(cap->card));
00880             
00881                 if (usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)) < 0)
00882                     strlcpy(cap->bus_info, dev->vdev->name, sizeof(cap->bus_info));
00883             }
00884             break;
00885 
00886         case VIDIOC_ENUMINPUT:
00887             {
00888                 struct v4l2_input *i = arg;
00889 
00890                 STK_DEBUG("VIDIOC_ENUMINPUT %d\n", i->index);
00891 
00892                 if (i->index)
00893                     return -EINVAL;
00894 
00895                 strlcpy(i->name, "USB", sizeof(i->name));
00896                 i->type = V4L2_INPUT_TYPE_CAMERA;
00897             }
00898             break;
00899 
00900         case VIDIOC_G_INPUT:
00901             {
00902                 struct v4l2_input *i = arg;
00903 
00904                 STK_DEBUG("GET INPUT %d\n", i->index);
00905 
00906                 if (i->index)
00907                     return -EINVAL;
00908             }
00909             break;
00910 
00911         case VIDIOC_S_INPUT:
00912             {
00913                 struct v4l2_input *i = arg;
00914 
00915                 STK_DEBUG("SET INPUT %d\n", i->index);
00916 
00917                 if (i->index != 0)
00918                     return -EINVAL;
00919             }
00920             break;
00921 
00922         case VIDIOC_QUERYCTRL:
00923             {
00924                 int i;
00925                 int nbr;
00926                 struct v4l2_queryctrl *c = arg;
00927 
00928                 STK_DEBUG("VIDIOC_QUERYCTRL id = %d\n", c->id);
00929 
00930                 nbr = sizeof(stk11xx_controls)/sizeof(struct v4l2_queryctrl);
00931 
00932                 for (i=0; i<nbr; i++) {
00933                     if (stk11xx_controls[i].id == c->id) {
00934                         STK_DEBUG("VIDIOC_QUERYCTRL found\n");
00935                         memcpy(c, &stk11xx_controls[i], sizeof(struct v4l2_queryctrl));
00936                         break;
00937                     }
00938                 }
00939 
00940                 if (i >= nbr)
00941                     return -EINVAL;
00942             }
00943             break;
00944 
00945         case VIDIOC_G_CTRL:
00946             {
00947                 struct v4l2_control *c = arg;
00948 
00949                 STK_DEBUG("GET CTRL id=%d\n", c->id);
00950 
00951                 switch (c->id) {
00952                     case V4L2_CID_BRIGHTNESS:
00953                         c->value = dev->vsettings.brightness;
00954                         break;
00955 
00956                     case V4L2_CID_CONTRAST:
00957                         c->value = dev->vsettings.contrast;
00958                         break;
00959 
00960                     default:
00961                         return -EINVAL;
00962                 }
00963             }
00964             break;
00965 
00966         case VIDIOC_S_CTRL:
00967             {
00968                 struct v4l2_control *c = arg;
00969 
00970                 STK_DEBUG("SET CTRL id=%d value=%d\n", c->id, c->value);
00971 
00972                 switch (c->id) {
00973                     case V4L2_CID_BRIGHTNESS:
00974                         dev->vsettings.brightness = c->value;
00975                         break;
00976 
00977                     case V4L2_CID_CONTRAST:
00978                         dev->vsettings.contrast = c->value;
00979                         break;
00980 
00981                     default:
00982                         return -EINVAL;
00983                 }
00984 
00985                 dev_stk11xx_camera_settings(dev);
00986             }
00987             break;
00988 
00989         case VIDIOC_ENUM_FMT:
00990             {
00991                 int index;
00992                 struct v4l2_fmtdesc *fmtd = arg;
00993 
00994                 STK_DEBUG("VIDIOC_ENUM_FMT %d\n", fmtd->index);
00995 
00996                 if (fmtd->index != 0)
00997                     return -EINVAL;
00998 
00999                 index = fmtd->index;
01000 
01001                 memset(fmtd, 0, sizeof(*fmtd));
01002 
01003                 fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
01004                 fmtd->index = index;
01005 
01006                 switch (index) {
01007                     case 0:
01008                         fmtd->flags = 0;
01009                         fmtd->pixelformat = V4L2_PIX_FMT_RGB24;
01010 
01011                         strcpy(fmtd->description, "rgb24");
01012                         break;
01013 
01014                     case 1:
01015                         fmtd->flags = 0;
01016                         fmtd->pixelformat = V4L2_PIX_FMT_RGB32;
01017 
01018                         strcpy(fmtd->description, "rgb32");
01019                         break;
01020 
01021                     case 2:
01022                         fmtd->flags = 0;
01023                         fmtd->pixelformat = V4L2_PIX_FMT_BGR24;
01024 
01025                         strcpy(fmtd->description, "bgr24");
01026                         break;
01027 
01028                     case 3:
01029                         fmtd->flags = 0;
01030                         fmtd->pixelformat = V4L2_PIX_FMT_BGR32;
01031 
01032                         strcpy(fmtd->description, "bgr32");
01033                         break;
01034 
01035                     default:
01036                         return -EINVAL;
01037                 }
01038             }
01039             break;
01040 
01041         case VIDIOC_G_FMT:
01042             {
01043                 struct v4l2_format *fmtd = arg;
01044                 struct v4l2_pix_format pix_format;
01045 
01046                 STK_DEBUG("GET FMT %d\n", fmtd->type);
01047 
01048                 if (fmtd->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
01049                     return -EINVAL;
01050 
01051                 pix_format.width = dev->view.x;
01052                 pix_format.height = dev->view.y;
01053                 pix_format.field = V4L2_FIELD_NONE;
01054                 pix_format.colorspace = V4L2_COLORSPACE_SRGB;
01055                 pix_format.priv = 0;
01056 
01057                 switch (dev->vsettings.palette) {
01058                     case STK11XX_PALETTE_RGB24:
01059                         pix_format.pixelformat = V4L2_PIX_FMT_RGB24;
01060                         pix_format.sizeimage = pix_format.width * pix_format.height * 3;
01061                         pix_format.bytesperline = 3 * pix_format.width;
01062                         break;
01063 
01064                     case STK11XX_PALETTE_RGB32:
01065                         pix_format.pixelformat = V4L2_PIX_FMT_RGB32;
01066                         pix_format.sizeimage = pix_format.width * pix_format.height * 4;
01067                         pix_format.bytesperline = 4 * pix_format.width;
01068                         break;
01069 
01070                     case STK11XX_PALETTE_BGR24:
01071                         pix_format.pixelformat = V4L2_PIX_FMT_BGR24;
01072                         pix_format.sizeimage = pix_format.width * pix_format.height * 3;
01073                         pix_format.bytesperline = 3 * pix_format.width;
01074                         break;
01075 
01076                     case STK11XX_PALETTE_BGR32:
01077                         pix_format.pixelformat = V4L2_PIX_FMT_BGR32;
01078                         pix_format.sizeimage = pix_format.width * pix_format.height * 4;
01079                         pix_format.bytesperline = 4 * pix_format.width;
01080                         break;
01081                 }
01082 
01083                 memcpy(&(fmtd->fmt.pix), &pix_format, sizeof(pix_format));
01084             }
01085             break;
01086 
01087         case VIDIOC_TRY_FMT:
01088             {
01089                 struct v4l2_format *fmtd = arg;
01090 
01091                 STK_DEBUG("TRY FMT %d\n", fmtd->type);
01092 
01093                 if (fmtd->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
01094                     return -EINVAL;
01095 
01096                 switch (fmtd->fmt.pix.pixelformat) {
01097                     case V4L2_PIX_FMT_RGB24:
01098                     case V4L2_PIX_FMT_BGR24:
01099                         dev->vsettings.depth = 24;
01100                         break;
01101 
01102                     case V4L2_PIX_FMT_RGB32:
01103                     case V4L2_PIX_FMT_BGR32:
01104                         dev->vsettings.depth = 32;
01105                         break;
01106 
01107                     default:
01108                         return -EINVAL;
01109                 }
01110 
01111                 switch (dev->webcam_type) {
01112                     case STK11XX_SXGA:
01113                         if (fmtd->fmt.pix.width > stk11xx_image_sizes[STK11XX_NBR_SIZES-1].x)
01114                             fmtd->fmt.pix.width = stk11xx_image_sizes[STK11XX_NBR_SIZES-1].x;
01115                         else if (fmtd->fmt.pix.width < stk11xx_image_sizes[0].x)
01116                             fmtd->fmt.pix.width = stk11xx_image_sizes[0].x;
01117     
01118                         if (fmtd->fmt.pix.height > stk11xx_image_sizes[STK11XX_NBR_SIZES-1].y)
01119                             fmtd->fmt.pix.height = stk11xx_image_sizes[STK11XX_NBR_SIZES-1].y;
01120                         else if (fmtd->fmt.pix.height < stk11xx_image_sizes[0].y)
01121                             fmtd->fmt.pix.height = stk11xx_image_sizes[0].y;
01122                         break;
01123 
01124                     case STK11XX_VGA:
01125                         if (fmtd->fmt.pix.width > stk11xx_image_sizes[STK11XX_NBR_SIZES-1-3].x)
01126                             fmtd->fmt.pix.width = stk11xx_image_sizes[STK11XX_NBR_SIZES-1-3].x;
01127                         else if (fmtd->fmt.pix.width < stk11xx_image_sizes[0].x)
01128                             fmtd->fmt.pix.width = stk11xx_image_sizes[0].x;
01129     
01130                         if (fmtd->fmt.pix.height > stk11xx_image_sizes[STK11XX_NBR_SIZES-1-3].y)
01131                             fmtd->fmt.pix.height = stk11xx_image_sizes[STK11XX_NBR_SIZES-1-3].y;
01132                         else if (fmtd->fmt.pix.height < stk11xx_image_sizes[0].y)
01133                             fmtd->fmt.pix.height = stk11xx_image_sizes[0].y;
01134                         break;
01135                 }
01136 
01137             }
01138             break;
01139 
01140         case VIDIOC_S_FMT:
01141             {
01142                 struct v4l2_format *fmtd = arg;
01143 
01144                 STK_DEBUG("SET FMT %d\n", fmtd->type);
01145 
01146                 if (fmtd->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
01147                     return -EINVAL;
01148 
01149                 switch (fmtd->fmt.pix.pixelformat) {
01150                     case V4L2_PIX_FMT_RGB24:
01151                         dev->vsettings.depth = 24;
01152                         dev->vsettings.palette = STK11XX_PALETTE_RGB24;
01153                         break;
01154 
01155                     case V4L2_PIX_FMT_RGB32:
01156                         dev->vsettings.depth = 32;
01157                         dev->vsettings.palette = STK11XX_PALETTE_RGB32;
01158                         break;
01159 
01160                     case V4L2_PIX_FMT_BGR24:
01161                         dev->vsettings.depth = 24;
01162                         dev->vsettings.palette = STK11XX_PALETTE_BGR24;
01163                         break;
01164 
01165                     case V4L2_PIX_FMT_BGR32:
01166                         dev->vsettings.depth = 32;
01167                         dev->vsettings.palette = STK11XX_PALETTE_BGR32;
01168                         break;
01169 
01170                     default:
01171                         return -EINVAL;
01172                 }
01173 
01174                 STK_DEBUG("Set width=%d, height=%d\n", fmtd->fmt.pix.width, fmtd->fmt.pix.height);
01175 
01176                 // Stop the video stream
01177                 dev_stk11xx_stop_stream(dev);
01178             
01179                 // ISOC and URB cleanup
01180                 usb_stk11xx_isoc_cleanup(dev);
01181 
01182                 // Switch off the camera
01183                 dev_stk11xx_camera_off(dev);
01184 
01185                 dev_stk11xx_camera_asleep(dev);
01186 
01187                 // Select the new video mode
01188                 if (v4l_stk11xx_select_video_mode(dev, fmtd->fmt.pix.width, fmtd->fmt.pix.height)) {
01189                     STK_ERROR("Select video mode failed !\n");
01190                     return -EAGAIN;
01191                 }
01192 
01193                 // Clear the buffers
01194                 stk11xx_clear_buffers(dev);
01195 
01196                 // Initialize the device
01197                 dev_stk11xx_init_camera(dev);
01198                 dev_stk11xx_camera_on(dev);
01199                 dev_stk11xx_reconf_camera(dev);
01200 
01201                 // ISOC and URB init
01202                 usb_stk11xx_isoc_init(dev);
01203 
01204                 // Re-start the stream
01205                 dev_stk11xx_start_stream(dev);
01206 
01207                 // Video settings
01208                 dev_stk11xx_camera_settings(dev);
01209             }
01210             break;
01211 
01212         case VIDIOC_QUERYSTD:
01213             {
01214                 STK_DEBUG("QUERY STD\n");
01215                 return -EINVAL;
01216             }
01217             break;
01218 
01219         case VIDIOC_G_STD:
01220             {
01221                 v4l2_std_id *std = arg;
01222 
01223                 STK_DEBUG("GET STD\n");
01224         
01225                 *std = V4L2_STD_UNKNOWN;
01226             }
01227             break;
01228 
01229         case VIDIOC_S_STD:
01230             {
01231                 v4l2_std_id *std = arg;
01232 
01233                 STK_DEBUG("SET STD\n");
01234                 
01235                 if (*std != V4L2_STD_UNKNOWN)
01236                     return -EINVAL;
01237             }
01238             break;
01239 
01240         case VIDIOC_ENUMSTD:
01241             {
01242                 struct v4l2_standard *std = arg;
01243 
01244                 STK_DEBUG("VIDIOC_ENUMSTD\n");
01245 
01246                 if (std->index != 0)
01247                     return -EINVAL;
01248 
01249                 std->id = V4L2_STD_UNKNOWN;
01250                 strncpy(std->name, "webcam", sizeof(std->name));
01251 
01252                 break;
01253             }
01254 
01255         case VIDIOC_REQBUFS:
01256             {
01257                 int nbuffers;
01258                 struct v4l2_requestbuffers *rb = arg;
01259 
01260                 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
01261                     return -EINVAL;
01262 
01263                 if (rb->memory != V4L2_MEMORY_MMAP)
01264                     return -EINVAL;
01265 
01266                 nbuffers = rb->count;
01267 
01268                 if (nbuffers < 2)
01269                     nbuffers = 2;
01270                 else if (nbuffers > dev->nbuffers)
01271                     nbuffers = dev->nbuffers;
01272 
01273                 rb->count = dev->nbuffers;
01274             }
01275             break;
01276 
01277         case VIDIOC_QUERYBUF:
01278             {
01279                 int index;
01280                 struct v4l2_buffer *buf = arg;
01281 
01282                 STK_DEBUG("QUERY BUFFERS %d %d\n", buf->index, dev->nbuffers);
01283 
01284                 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
01285                     return -EINVAL;
01286 
01287                 if (buf->memory != V4L2_MEMORY_MMAP) 
01288                     return -EINVAL;
01289 
01290                 index = buf->index;
01291 
01292                 if (index < 0 || index >= dev->nbuffers)
01293                     return -EINVAL;
01294 
01295                 memset(buf, 0, sizeof(struct v4l2_buffer));
01296 
01297                 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
01298                 buf->index = index;
01299                 buf->m.offset = index * dev->len_per_image;
01300                 buf->bytesused = dev->image_size;
01301                 buf->field = V4L2_FIELD_NONE;
01302                 buf->memory = V4L2_MEMORY_MMAP;
01303                 buf->length = dev->len_per_image;
01304             }
01305             break;
01306 
01307         case VIDIOC_QBUF:
01308             {
01309                 struct v4l2_buffer *buf = arg;
01310 
01311                 STK_DEBUG("VIDIOC_QBUF\n");
01312 
01313                 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
01314                     return -EINVAL;
01315 
01316                 if (buf->memory != V4L2_MEMORY_MMAP)
01317                     return -EINVAL;
01318 
01319                 if (buf->index < 0 || buf->index >= dev->nbuffers)
01320                     return -EINVAL;
01321 
01322                 buf->flags |= V4L2_BUF_FLAG_QUEUED;
01323                 buf->flags &= ~V4L2_BUF_FLAG_DONE;
01324             }
01325             break;
01326 
01327         case VIDIOC_DQBUF:
01328             {
01329                 int ret;
01330                 struct v4l2_buffer *buf = arg;
01331 
01332                 STK_DEBUG("VIDIOC_DQBUF\n");
01333                 
01334                 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
01335                     return -EINVAL;
01336 
01337                 add_wait_queue(&dev->wait_frame, &wait);
01338 
01339                 while (dev->full_frames == NULL) {
01340                     if (dev->error_status) {
01341                         remove_wait_queue(&dev->wait_frame, &wait);
01342                         set_current_state(TASK_RUNNING);
01343 
01344                         return -dev->error_status;
01345                     }
01346 
01347                     if (signal_pending(current)) {
01348                         remove_wait_queue(&dev->wait_frame, &wait);
01349                         set_current_state(TASK_RUNNING);
01350 
01351                         return -ERESTARTSYS;
01352                     }
01353 
01354                     schedule();
01355                     set_current_state(TASK_INTERRUPTIBLE);
01356                 }
01357 
01358                 remove_wait_queue(&dev->wait_frame, &wait);
01359                 set_current_state(TASK_RUNNING);
01360 
01361                 STK_DEBUG("VIDIOC_DQBUF : frame ready.\n");
01362 
01363                 ret = stk11xx_handle_frame(dev);
01364 
01365                 if (ret)
01366                     return -EFAULT;
01367 
01368                 buf->index = dev->fill_image;
01369                 buf->bytesused = dev->image_size;
01370                 buf->flags = V4L2_BUF_FLAG_MAPPED;
01371                 buf->field = V4L2_FIELD_NONE;
01372                 do_gettimeofday(&buf->timestamp);
01373                 buf->sequence = 0;
01374                 buf->memory = V4L2_MEMORY_MMAP;
01375                 buf->m.offset = dev->fill_image * dev->len_per_image;
01376                 buf->length = buf->bytesused;
01377 
01378                 stk11xx_next_image(dev);
01379             }
01380             break;
01381 
01382         case VIDIOC_STREAMON:
01383             {
01384                 STK_DEBUG("VIDIOC_STREAMON\n");
01385 
01386                 usb_stk11xx_isoc_init(dev);
01387             }
01388             break;
01389 
01390         case VIDIOC_STREAMOFF:
01391             {
01392                 STK_DEBUG("VIDIOC_STREAMOFF\n");
01393 
01394                 usb_stk11xx_isoc_cleanup(dev);
01395             }
01396             break;
01397 
01398         case VIDIOC_G_PARM:
01399             {
01400                 struct v4l2_streamparm *sp = arg;
01401 
01402                 STK_DEBUG("GET PARM %d\n", sp->type);
01403 
01404                 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
01405                     return -EINVAL;
01406 
01407                 sp->parm.capture.capability = 0;
01408                 sp->parm.capture.capturemode = 0;
01409                 sp->parm.capture.timeperframe.numerator = 1;
01410                 sp->parm.capture.timeperframe.denominator = 30;
01411                 sp->parm.capture.readbuffers = 2;
01412                 sp->parm.capture.extendedmode = 0;
01413             }
01414             break;
01415 
01416 
01417         case VIDIOC_G_AUDIO:
01418             STK_DEBUG("GET AUDIO\n");
01419             return -EINVAL;
01420             break;
01421 
01422         case VIDIOC_S_AUDIO:
01423             STK_DEBUG("SET AUDIO\n");
01424             return -EINVAL;
01425             break;
01426 
01427         case VIDIOC_S_TUNER:
01428             STK_DEBUG("SET TUNER\n");
01429             return -EINVAL;
01430             break;
01431 
01432         case VIDIOC_G_FBUF:
01433         case VIDIOC_S_FBUF:
01434         case VIDIOC_OVERLAY:
01435             return -EINVAL;
01436             break;
01437 
01438         case VIDIOC_G_TUNER:
01439         case VIDIOC_G_FREQUENCY:
01440         case VIDIOC_S_FREQUENCY:
01441             return -EINVAL;
01442             break;
01443 
01444         case VIDIOC_QUERYMENU:
01445             return -EINVAL;
01446             break;
01447 /*
01448         case VIDIOC_CROPCAP:
01449             {
01450                 struct v4l2_cropcap cc;
01451 
01452                 cc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
01453                 cc.pixelaspect.numerator = 1;
01454                 cc.pixelaspect.denominator = 1;
01455                 cc.bounds.top = 0;
01456                 cc.bounds.left = 0;
01457                 cc.bounds.width = 640;
01458                 cc.bounds.height = 480;
01459                 cc.defrect.top = 0;
01460                 cc.defrect.left = 0;
01461                 cc.defrect.width = 640;
01462                 cc.defrect.height = 480;
01463 
01464                 memcpy(arg, &cc, sizeof(cc));
01465             }
01466             break;
01467 */
01468         default:
01469             STK_DEBUG("IOCTL unknown !\n");
01470             return -ENOIOCTLCMD;
01471     }
01472 
01473     return 0;
01474 }
01475 
01476 
01489 static int v4l_stk11xx_ioctl(struct inode *inode, struct file *fp,
01490         unsigned int cmd, unsigned long arg)
01491 {
01492     int err;
01493     struct usb_stk11xx *dev;
01494     struct video_device *vdev;
01495     
01496     vdev = video_devdata(fp);
01497     dev = video_get_drvdata(video_devdata(fp));
01498 
01499     STK_DEBUG("v4l_stk11xx_ioctl %02X\n", (unsigned char) cmd);
01500 
01501     if (dev == NULL)
01502         return -EFAULT;
01503 
01504     if (vdev == NULL)
01505         return -EFAULT;
01506 
01507 //  v4l_printk_ioctl(cmd);
01508 
01509     err = v4l_stk11xx_do_ioctl(inode, fp, cmd, (void __user *) arg);
01510 
01511     return err;
01512 }
01513 
01514 
01524 int v4l_stk11xx_register_video_device(struct usb_stk11xx *dev)
01525 {
01526     int err;
01527 
01528     strcpy(dev->vdev->name, DRIVER_DESC);
01529 
01530     dev->vdev->owner = THIS_MODULE;
01531     dev->vdev->type = VID_TYPE_CAPTURE;
01532     dev->vdev->hardware = VID_HARDWARE_STK11XX;
01533     dev->vdev->fops = &v4l_stk11xx_fops;
01534     dev->vdev->release = video_device_release;
01535     dev->vdev->minor = -1;
01536 
01537     video_set_drvdata(dev->vdev, dev);
01538 
01539     err = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1);
01540 
01541     if (err)
01542         STK_ERROR("Video register fail !\n");
01543     else
01544         STK_INFO("Syntek USB2.0 Camera is now controlling video device /dev/video%d\n", dev->vdev->minor);
01545 
01546     return err;
01547 }
01548 
01549 
01559 int v4l_stk11xx_unregister_video_device(struct usb_stk11xx *dev)
01560 {
01561     STK_INFO("Syntek USB2.0 Camera release resources video device /dev/video%d\n", dev->vdev->minor);
01562 
01563     video_set_drvdata(dev->vdev, NULL);
01564     video_unregister_device(dev->vdev);
01565 
01566     return 0;
01567 }
01568 
01569 
01575 static struct file_operations v4l_stk11xx_fops = {
01576     .owner = THIS_MODULE,
01577     .open = v4l_stk11xx_open,
01578     .release = v4l_stk11xx_release,
01579     .read = v4l_stk11xx_read,
01580     .poll = v4l_stk11xx_poll,
01581     .mmap = v4l_stk11xx_mmap,
01582     .ioctl = v4l_stk11xx_ioctl,
01583     .llseek = no_llseek
01584 };
01585 

Generated on Tue Oct 2 06:18:12 2007 for SyntekUSBVideoCamera by  doxygen 1.5.3