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

Generated on Tue Oct 30 13:32:13 2007 for SyntekUSBVideoCamera by  doxygen 1.5.3