SyntekUSBVideoCamera

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/version.h>
00038 #include <linux/errno.h>
00039 #include <linux/slab.h>
00040 #include <linux/kref.h>
00041 #include <linux/vmalloc.h>
00042 #include <linux/mm.h>
00043 #include <linux/videodev.h>
00044 
00045 
00046 #include <linux/usb.h>
00047 #include <media/v4l2-common.h>
00048 #include <media/v4l2-ioctl.h>
00049 
00050 #include "stk11xx.h"
00051 
00052 
00053 static struct v4l2_file_operations v4l_stk11xx_fops;
00054 
00055 
00060 const struct stk11xx_coord stk11xx_image_sizes[STK11XX_NBR_SIZES] = {
00061     {   80,   60 },
00062     {  128,   96 },
00063     {  160,  120 },
00064     {  213,  160 },
00065     {  320,  240 },
00066     {  640,  480 },
00067     {  800,  600 },
00068     { 1024,  768 },
00069     { 1280, 1024 }
00070 };
00071 
00072 
00078 static struct v4l2_queryctrl stk11xx_controls[] = {
00079     {
00080         .id      = V4L2_CID_BRIGHTNESS,
00081         .type    = V4L2_CTRL_TYPE_INTEGER,
00082         .name    = "Brightness",
00083         .minimum = 0,
00084         .maximum = 0xff00,
00085         .step    = 1,
00086         .default_value = 0x7f00,
00087     },
00088     {
00089         .id      = V4L2_CID_WHITENESS,
00090         .type    = V4L2_CTRL_TYPE_INTEGER,
00091         .name    = "Whiteness",
00092         .minimum = 0,
00093         .maximum = 0xff00,
00094         .step    = 1,
00095         .default_value = 0x7f00,
00096     },
00097     {
00098         .id      = V4L2_CID_SATURATION,
00099         .type    = V4L2_CTRL_TYPE_INTEGER,
00100         .name    = "Saturation",
00101         .minimum = 0,
00102         .maximum = 0xff00,
00103         .step    = 1,
00104         .default_value = 0x7f00,
00105     },
00106     {
00107         .id      = V4L2_CID_CONTRAST,
00108         .type    = V4L2_CTRL_TYPE_INTEGER,
00109         .name    = "Contrast",
00110         .minimum = 0,
00111         .maximum = 0xff00,
00112         .step    = 1,
00113         .default_value = 0x7f00,
00114     },
00115     {
00116         .id = V4L2_CID_HFLIP,
00117         .type   = V4L2_CTRL_TYPE_BOOLEAN,
00118         .name   = "Flip Horizontally",
00119         .minimum        = 0,
00120                 .maximum        = 1,
00121                 .step           = 1,
00122                 .default_value  = 0, // will be actually set later
00123     },
00124     {
00125         .id = V4L2_CID_VFLIP,
00126         .type   = V4L2_CTRL_TYPE_BOOLEAN,
00127         .name   = "Flip Vertically",
00128         .minimum        = 0,
00129                 .maximum        = 1,
00130                 .step           = 1,
00131                 .default_value  = 0, // will be actually set later
00132     }
00133 };
00134 
00135 
00147 int v4l_stk11xx_select_video_mode(struct usb_stk11xx *dev, int width, int height)
00148 {
00149     int i;
00150     int find;
00151 
00152 
00153     // Check width and height
00154     // Notice : this test is usefull for the Kopete application !
00155 
00156     // Driver can't build an image smaller than the minimal resolution !
00157     if ((width < stk11xx_image_sizes[0].x)
00158             || (height < stk11xx_image_sizes[0].y)) {
00159         width = stk11xx_image_sizes[0].x;
00160         height = stk11xx_image_sizes[0].y;
00161     }
00162 
00163     // Driver can't build an image bigger than the maximal resolution !
00164     switch (dev->webcam_type) {
00165         case STK11XX_SXGA:
00166             if ((width > stk11xx_image_sizes[STK11XX_NBR_SIZES-1].x)
00167                 || (height > stk11xx_image_sizes[STK11XX_NBR_SIZES-1].y)) {
00168                 width = stk11xx_image_sizes[STK11XX_NBR_SIZES-1].x;
00169                 height = stk11xx_image_sizes[STK11XX_NBR_SIZES-1].y;
00170             }
00171             break;
00172 
00173         case STK11XX_VGA:
00174             if ((width > stk11xx_image_sizes[STK11XX_NBR_SIZES-3-1].x)
00175                 || (height > stk11xx_image_sizes[STK11XX_NBR_SIZES-3-1].y)) {
00176                 width = stk11xx_image_sizes[STK11XX_NBR_SIZES-3-1].x;
00177                 height = stk11xx_image_sizes[STK11XX_NBR_SIZES-3-1].y;
00178             }
00179             break;
00180 
00181         default:
00182             return -1;
00183     }
00184 
00185 
00186     // Seek the best resolution
00187     switch (dev->webcam_type) {
00188         case STK11XX_SXGA:
00189             for (i=0, find=0; i<STK11XX_NBR_SIZES; i++) {
00190                 if (stk11xx_image_sizes[i].x <= width && stk11xx_image_sizes[i].y <= height)
00191                     find = i;
00192             }
00193             break;
00194 
00195         case STK11XX_VGA:
00196             for (i=0, find=0; i<STK11XX_NBR_SIZES-3; i++) {
00197                 if (stk11xx_image_sizes[i].x <= width && stk11xx_image_sizes[i].y <= height)
00198                     find = i;
00199             }
00200             break;
00201 
00202         default:
00203             return -1;
00204     }
00205 
00206     // Save the new resolution
00207     dev->resolution = find;
00208 
00209     STK_DEBUG("Set mode %d [%dx%d]\n", dev->resolution,
00210             stk11xx_image_sizes[dev->resolution].x, stk11xx_image_sizes[dev->resolution].y);
00211 
00212     // Save the new size
00213     dev->view.x = width;
00214     dev->view.y = height;
00215 
00216 
00217     // Calculate the frame size
00218     switch (dev->resolution) {
00219         case STK11XX_80x60:
00220         case STK11XX_128x96:
00221         case STK11XX_160x120:
00222         case STK11XX_213x160:
00223         case STK11XX_320x240:
00224         case STK11XX_640x480:
00225             dev->image.x = stk11xx_image_sizes[STK11XX_640x480].x;
00226             dev->image.y = stk11xx_image_sizes[STK11XX_640x480].y;
00227             dev->frame_size = dev->image.x * dev->image.y;
00228             break;
00229 
00230         case STK11XX_800x600:
00231         case STK11XX_1024x768:
00232         case STK11XX_1280x1024:
00233             dev->image.x = stk11xx_image_sizes[STK11XX_1280x1024].x;
00234             dev->image.y = stk11xx_image_sizes[STK11XX_1280x1024].y;
00235             dev->frame_size = dev->image.x * dev->image.y;
00236             break;
00237     }
00238 
00239 
00240     // Calculate the image size
00241         switch (dev->vsettings.palette) {
00242         case STK11XX_PALETTE_RGB24:
00243         case STK11XX_PALETTE_BGR24:
00244             dev->view_size = 3 * dev->view.x * dev->view.y;
00245             dev->image_size = 3 * dev->frame_size;
00246             break;
00247 
00248         case STK11XX_PALETTE_RGB32:
00249         case STK11XX_PALETTE_BGR32:
00250             dev->view_size = 3 * dev->view.x * dev->view.y;
00251             dev->image_size = 4 * dev->frame_size;
00252             break;
00253 
00254         case STK11XX_PALETTE_UYVY:
00255         case STK11XX_PALETTE_YUYV:
00256             dev->view_size = 2 * dev->view.x * dev->view.y;
00257             dev->image_size = 2 * dev->frame_size;
00258             break;
00259     }
00260 
00261     return 0;
00262 }
00263 
00264 
00274 static int v4l_stk11xx_open(struct file *fp)
00275 {
00276     int err;
00277 
00278     struct usb_stk11xx *dev;
00279     struct video_device *vdev;
00280     
00281     vdev = video_devdata(fp);
00282     dev = video_get_drvdata(video_devdata(fp));
00283 
00284     if (dev == NULL) {
00285         STK_ERROR("Device not initialized !!!\n");
00286         BUG();
00287     }
00288     mutex_lock(&dev->modlock);
00289 
00290     if (dev->vopen) {
00291         STK_DEBUG("Device is busy, someone is using the device\n");
00292         mutex_unlock(&dev->modlock);
00293         return -EBUSY;
00294     }
00295 
00296 
00297     // Allocate memory
00298     err = stk11xx_allocate_buffers(dev);
00299 
00300     if (err < 0) {
00301         STK_ERROR("Failed to allocate buffer memory !\n");
00302         mutex_unlock(&dev->modlock);
00303         return err;
00304     }
00305     
00306     // Reset buffers and parameters
00307     stk11xx_reset_buffers(dev);
00308 
00309     // Settings
00310     dev->error_status = 0;
00311     dev->visoc_errors = 0;
00312     dev->vframes_error = 0;
00313     dev->vframes_dumped = 0;
00314     dev->vsettings.hue = 0xffff;
00315     dev->vsettings.depth = 24;
00316     dev->vsettings.palette = STK11XX_PALETTE_BGR24;
00317 
00318     // Select the resolution by default
00319     v4l_stk11xx_select_video_mode(dev, 640, 480);
00320 
00321     // Initialize the device
00322     dev_stk11xx_init_camera(dev);
00323     dev_stk11xx_camera_on(dev);
00324     dev_stk11xx_reconf_camera(dev);
00325 
00326     // Init Isoc and URB
00327     err = usb_stk11xx_isoc_init(dev);
00328 
00329     if (err) {
00330         STK_ERROR("Failed to init ISOC stuff !\n");
00331         usb_stk11xx_isoc_cleanup(dev);
00332         stk11xx_free_buffers(dev);
00333         mutex_unlock(&dev->modlock);
00334         return err;
00335     }
00336 
00337     // Start the video stream
00338     dev_stk11xx_start_stream(dev);
00339 
00340     // Video settings
00341     dev_stk11xx_camera_settings(dev);
00342 
00343     // Register interface on power management
00344     usb_autopm_get_interface(dev->interface);
00345 
00346     dev->vopen++;
00347     fp->private_data = vdev;
00348 
00349     mutex_unlock(&dev->modlock);
00350 
00351     return 0;
00352 }
00353 
00354 
00364 static int v4l_stk11xx_release(struct file *fp)
00365 {
00366     struct usb_stk11xx *dev;
00367     struct video_device *vdev;
00368     
00369     vdev = video_devdata(fp);
00370     dev = video_get_drvdata(video_devdata(fp));
00371 
00372     if (dev->vopen == 0)
00373         STK_ERROR("v4l_release called on closed device\n");
00374 
00375     // Stop the video stream
00376     dev_stk11xx_stop_stream(dev);
00377 
00378     // ISOC and URB cleanup
00379     usb_stk11xx_isoc_cleanup(dev);
00380 
00381     // Free memory
00382     stk11xx_free_buffers(dev);
00383 
00384     // Switch off the camera
00385     dev_stk11xx_camera_off(dev);
00386 
00387     dev_stk11xx_camera_asleep(dev);
00388 
00389     // Unregister interface on power management
00390     usb_autopm_put_interface(dev->interface);
00391 
00392     dev->vopen--;
00393 
00394     return 0;
00395 }
00396 
00397 
00411 static ssize_t v4l_stk11xx_read(struct file *fp, char __user *buf,
00412         size_t count, loff_t *f_pos)
00413 {
00414     int noblock = fp->f_flags & O_NONBLOCK;
00415 
00416     struct usb_stk11xx *dev;
00417     struct video_device *vdev;
00418 
00419     int bytes_to_read;
00420     void *image_buffer_addr;
00421     
00422     DECLARE_WAITQUEUE(wait, current);
00423 
00424     vdev = video_devdata(fp);
00425     dev = video_get_drvdata(video_devdata(fp));
00426 
00427     STK_STREAM("Read vdev=0x%p, buf=0x%p, count=%zd\n", vdev, buf, count);
00428 
00429     if (dev == NULL)
00430         return -EFAULT;
00431 
00432     if (vdev == NULL)
00433         return -EFAULT;
00434 
00435     mutex_lock(&dev->modlock);
00436 
00437     if (dev->image_read_pos == 0) {
00438         add_wait_queue(&dev->wait_frame, &wait);
00439 
00440         while (dev->full_frames == NULL) {
00441             if (dev->error_status) {
00442                 remove_wait_queue(&dev->wait_frame, &wait);
00443                 set_current_state(TASK_RUNNING);
00444                 mutex_unlock(&dev->modlock);
00445                 return -dev->error_status ;
00446             }
00447 
00448             if (noblock) {
00449                 remove_wait_queue(&dev->wait_frame, &wait);
00450                 set_current_state(TASK_RUNNING);
00451                 mutex_unlock(&dev->modlock);
00452                 return -EWOULDBLOCK;
00453             }
00454 
00455             if (signal_pending(current)) {
00456                 remove_wait_queue(&dev->wait_frame, &wait);
00457                 set_current_state(TASK_RUNNING);
00458                 mutex_unlock(&dev->modlock);
00459                 return -ERESTARTSYS;
00460             }
00461 
00462             schedule();
00463             set_current_state(TASK_INTERRUPTIBLE);
00464         }
00465 
00466         remove_wait_queue(&dev->wait_frame, &wait);
00467         set_current_state(TASK_RUNNING);
00468 
00469         if (stk11xx_handle_frame(dev)) {
00470             mutex_unlock(&dev->modlock);
00471             return -EFAULT;
00472         }
00473     }
00474 
00475     bytes_to_read = dev->view_size;
00476 
00477     if (count + dev->image_read_pos > bytes_to_read)
00478         count = bytes_to_read - dev->image_read_pos;
00479 
00480     image_buffer_addr = dev->image_data;
00481     image_buffer_addr += dev->images[dev->fill_image].offset;
00482     image_buffer_addr += dev->image_read_pos;
00483 
00484     if (copy_to_user(buf, image_buffer_addr, count)) {
00485         mutex_unlock(&dev->modlock);
00486         return -EFAULT;
00487     }
00488     
00489     dev->image_read_pos += count;
00490     
00491     if (dev->image_read_pos >= bytes_to_read) {
00492         dev->image_read_pos = 0;
00493         stk11xx_next_image(dev);
00494     }
00495 
00496     mutex_unlock(&dev->modlock);
00497 
00498     return count;
00499 }
00500 
00501 
00510 static unsigned int v4l_stk11xx_poll(struct file *fp, poll_table *wait)
00511 {
00512     struct usb_stk11xx *dev;
00513     struct video_device *vdev;
00514     
00515     vdev = video_devdata(fp);
00516     dev = video_get_drvdata(video_devdata(fp));
00517 
00518     STK_STREAM("Poll\n");
00519 
00520     if (vdev == NULL)
00521         return -EFAULT;
00522 
00523     if (dev == NULL)
00524         return -EFAULT;
00525 
00526     poll_wait(fp, &dev->wait_frame, wait);
00527 
00528     if (dev->error_status)
00529         return POLLERR;
00530 
00531     if (dev->full_frames != NULL)
00532         return (POLLIN | POLLRDNORM);
00533 
00534     return 0;
00535 }
00536 
00537 
00548 static int v4l_stk11xx_mmap(struct file *fp, struct vm_area_struct *vma)
00549 {
00550     unsigned int i;
00551 
00552     unsigned long size;
00553     unsigned long start;
00554     unsigned long pos;
00555     unsigned long page;
00556 
00557     struct usb_stk11xx *dev;
00558 
00559     struct video_device *vdev;
00560     
00561     vdev = video_devdata(fp);
00562     dev = video_get_drvdata(video_devdata(fp));
00563 
00564     STK_STREAM("mmap\n");
00565 
00566     start = vma->vm_start;
00567     size = vma->vm_end - vma->vm_start;
00568 
00569     // Find the buffer for this mapping...
00570     for (i=0; i<dev->nbuffers; i++) {
00571         pos = dev->images[i].offset;
00572 
00573         if ((pos >> PAGE_SHIFT) == vma->vm_pgoff)
00574             break;
00575     }
00576 
00577     // If no buffer found !
00578     if (i == STK11XX_MAX_IMAGES) {
00579         STK_ERROR("mmap no buffer found !\n");
00580         return -EINVAL;
00581     }
00582 
00583     if (i == 0) {
00584         unsigned long total_size;
00585 
00586         total_size = dev->nbuffers * dev->len_per_image;
00587 
00588         if (size != dev->len_per_image && size != total_size) {
00589             STK_ERROR("Wrong size (%lu) needed to be len_per_image=%d or total_size=%lu\n",
00590                 size, dev->len_per_image, total_size);
00591                 
00592             return -EINVAL;
00593         }
00594     }
00595     else if (size > dev->len_per_image)
00596         return -EINVAL;
00597 
00598     vma->vm_flags |= VM_IO;
00599 
00600     pos = (unsigned long) dev->image_data;
00601 
00602     while (size > 0) {
00603         page = vmalloc_to_pfn((void *) pos);
00604 
00605         if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
00606             return -EAGAIN;
00607 
00608         start += PAGE_SIZE;
00609         pos += PAGE_SIZE;
00610 
00611         if (size > PAGE_SIZE)
00612             size -= PAGE_SIZE;
00613         else
00614             size = 0;
00615     }
00616 
00617     return 0;
00618 }
00619 
00620 
00632 static long v4l_stk11xx_do_ioctl(struct file *fp,
00633         unsigned int cmd, void __user *arg)
00634 {
00635     struct usb_stk11xx *dev;
00636     struct video_device *vdev;
00637 
00638     DECLARE_WAITQUEUE(wait, current);
00639     
00640     vdev = video_devdata(fp);
00641     dev = video_get_drvdata(video_devdata(fp));
00642 
00643 #if (CONFIG_STK11XX_DEBUG == 1)
00644     v4l_printk_ioctl(cmd);
00645 #endif
00646 
00647     switch (cmd) {
00648         // Video 4 Linux v1
00649 
00650         case VIDIOCGCAP:
00651             {
00652                 struct video_capability *cap = arg;
00653 
00654                 STK_DEBUG("VIDIOCGCAP\n");
00655 
00656                 memset(cap, 0, sizeof(*cap));
00657                 strlcpy(cap->name, "stk11xx", sizeof(cap->name));
00658                 cap->type = VID_TYPE_CAPTURE;
00659                 cap->channels = 1;
00660                 cap->audios = 0;
00661 
00662                 switch (dev->webcam_type) {
00663                     case STK11XX_SXGA:
00664                         cap->minwidth = stk11xx_image_sizes[STK11XX_80x60].x;
00665                         cap->minheight = stk11xx_image_sizes[STK11XX_80x60].y;
00666                         cap->maxwidth = stk11xx_image_sizes[STK11XX_1280x1024].x;
00667                         cap->maxheight = stk11xx_image_sizes[STK11XX_1280x1024].y;
00668                         break;
00669 
00670                     case STK11XX_VGA:
00671                         cap->minwidth = stk11xx_image_sizes[STK11XX_80x60].x;
00672                         cap->minheight = stk11xx_image_sizes[STK11XX_80x60].y;
00673                         cap->maxwidth = stk11xx_image_sizes[STK11XX_640x480].x;
00674                         cap->maxheight = stk11xx_image_sizes[STK11XX_640x480].y;
00675                         break;
00676                 }
00677             }
00678             break;
00679     
00680         case VIDIOCGCHAN:
00681             {
00682                 struct video_channel *v = arg;
00683 
00684                 STK_DEBUG("VIDIOCGCHAN\n");
00685 
00686                 if (v->channel != 0)
00687                     return -EINVAL;
00688             
00689                 v->flags = 0;
00690                 v->tuners = 0;
00691                 v->type = VIDEO_TYPE_CAMERA;
00692                 strcpy(v->name, "Webcam");
00693             }
00694             break;
00695 
00696         case VIDIOCSCHAN:
00697             {
00698                 struct video_channel *v = arg;
00699 
00700                 STK_DEBUG("VIDIOCSCHAN\n");
00701 
00702                 if (v->channel != 0)
00703                     return -EINVAL;
00704             }
00705             break;
00706 
00707         case VIDIOCGPICT:
00708             {
00709                 struct video_picture *p = arg;
00710 
00711                 STK_DEBUG("VIDIOCGPICT\n");
00712 
00713                 p->brightness = dev->vsettings.brightness;
00714                 p->contrast = dev->vsettings.contrast;
00715                 p->whiteness = dev->vsettings.whiteness;
00716                 p->colour = dev->vsettings.colour;
00717                 p->depth = dev->vsettings.depth;
00718                 p->palette = dev->vsettings.palette;
00719                 p->hue = dev->vsettings.hue;
00720 
00721                 switch (dev->vsettings.palette) {
00722                     case STK11XX_PALETTE_BGR24:
00723                         p->palette = VIDEO_PALETTE_RGB24;
00724                         break;
00725 
00726                     case STK11XX_PALETTE_BGR32:
00727                                                 p->palette = VIDEO_PALETTE_RGB32;
00728                         break;
00729 
00730                     case STK11XX_PALETTE_UYVY:
00731                         p->palette = VIDEO_PALETTE_UYVY;
00732                         break;
00733 
00734                     case STK11XX_PALETTE_YUYV:
00735                         p->palette = VIDEO_PALETTE_YUYV;
00736                         break;
00737                 }
00738             }
00739             break;
00740 
00741         case VIDIOCSPICT:
00742             {
00743                 struct video_picture *p = arg;
00744 
00745                 STK_DEBUG("VIDIOCSPICT\n");
00746 
00747                 dev->vsettings.brightness = p->brightness;
00748                 dev->vsettings.contrast = p->contrast;
00749                 dev->vsettings.whiteness = p->whiteness;
00750                 dev->vsettings.colour = p->colour;
00751                 dev->vsettings.hue = p->hue;
00752                 
00753                 if (p->palette && p->palette != dev->vsettings.palette) {
00754                     switch (p->palette) {
00755                         case VIDEO_PALETTE_RGB24:
00756                             dev->vsettings.depth = 24;
00757                             dev->vsettings.palette = STK11XX_PALETTE_BGR24;
00758                             break;
00759 
00760                         case VIDEO_PALETTE_RGB32:
00761                             dev->vsettings.depth = 32;
00762                             dev->vsettings.palette = STK11XX_PALETTE_BGR32;
00763                             break;
00764 
00765                         case VIDEO_PALETTE_UYVY:
00766                             dev->vsettings.depth = 16;
00767                             dev->vsettings.palette = STK11XX_PALETTE_UYVY;
00768                             break;
00769 
00770                         case VIDEO_PALETTE_YUYV:
00771                             dev->vsettings.depth = 16;
00772                             dev->vsettings.palette = STK11XX_PALETTE_YUYV;
00773                             break;
00774 
00775                         default:
00776                             return -EINVAL;
00777                     }
00778                 }
00779 
00780                 dev_stk11xx_camera_settings(dev);
00781 
00782                 STK_DEBUG("VIDIOCSPICT done\n");
00783             }
00784             break;
00785 
00786         case VIDIOCGWIN:
00787             {
00788                 struct video_window *vw = arg;
00789 
00790                 STK_DEBUG("VIDIOCGWIN\n");
00791 
00792                 vw->x = 0;
00793                 vw->y = 0;
00794                 vw->width = dev->view.x;
00795                 vw->height = dev->view.y;
00796                 vw->chromakey = 0;
00797             }
00798             break;
00799 
00800         case VIDIOCSWIN:
00801             {
00802                 struct video_window *vw = arg;
00803 
00804                 STK_DEBUG("VIDIOCSWIN\n");
00805 
00806                 STK_DEBUG("Set x=%d, y=%d\n", vw->x, vw->y);
00807                 STK_DEBUG("Set width=%d, height=%d\n", vw->width, vw->height);
00808                 STK_DEBUG("Flags = %X\n", vw->flags);
00809 
00810                 // Stop the video stream
00811                 dev_stk11xx_stop_stream(dev);
00812             
00813                 // ISOC and URB cleanup
00814                 usb_stk11xx_isoc_cleanup(dev);
00815 
00816                 // Switch off the camera
00817                 dev_stk11xx_camera_off(dev);
00818 
00819                 dev_stk11xx_camera_asleep(dev);
00820 
00821                 // Select the new video mode
00822                 if (v4l_stk11xx_select_video_mode(dev, vw->width, vw->height)) {
00823                     STK_ERROR("Select video mode failed !\n");
00824                     return -EAGAIN;
00825                 }
00826 
00827                 // Clear the buffers
00828                 stk11xx_clear_buffers(dev);
00829 
00830                 // Initialize the device
00831                 dev_stk11xx_init_camera(dev);
00832                 dev_stk11xx_camera_on(dev);
00833                 dev_stk11xx_reconf_camera(dev);
00834 
00835                 // ISOC and URB init
00836                 usb_stk11xx_isoc_init(dev);
00837 
00838                 // Re-start the stream
00839                 dev_stk11xx_start_stream(dev);
00840 
00841                 // Video settings
00842                 dev_stk11xx_camera_settings(dev);
00843             }
00844             break;
00845 
00846         case VIDIOCGFBUF:
00847             {
00848                 struct video_buffer *vb = arg;
00849 
00850                 STK_DEBUG("VIDIOCGFBUF\n");
00851 
00852                 memset(vb, 0, sizeof(*vb));
00853             }
00854             break;
00855 
00856         case VIDIOCGMBUF:
00857             {
00858                 int i;
00859                 struct video_mbuf *vm = arg;
00860 
00861                 STK_DEBUG("VIDIOCGMBUF\n");
00862 
00863                 memset(vm, 0, sizeof(*vm));
00864 
00865                 vm->size = dev->nbuffers * dev->len_per_image;
00866                 vm->frames = dev->nbuffers;
00867 
00868                 for (i=0; i<dev->nbuffers; i++)
00869                     vm->offsets[i] = i * dev->len_per_image;
00870             }
00871             break;
00872 
00873         case VIDIOCMCAPTURE:
00874             {
00875                 struct video_mmap *vm = arg;
00876 
00877                 STK_DEBUG("VIDIOCMCAPTURE format=%d\n", vm->format);
00878 
00879                 if (vm->frame < 0 || vm->frame >= dev->nbuffers)
00880                     return -EINVAL;
00881 
00882                 if (vm->format) {
00883                     switch (vm->format) {
00884                         case VIDEO_PALETTE_RGB32:
00885                             break;
00886 
00887                         case VIDEO_PALETTE_RGB24:
00888                             break;
00889 
00890                         case VIDEO_PALETTE_UYVY:
00891                             break;
00892 
00893                         case VIDEO_PALETTE_YUYV:
00894                             break;
00895 
00896                         default:
00897                             return -EINVAL;
00898                     }
00899                 }
00900 
00901                 if ((vm->width != dev->view.x) || (vm->height != dev->view.y)) 
00902                     return -EAGAIN;
00903 
00904                 if (dev->image_used[vm->frame])
00905                     return -EBUSY;
00906 
00907                 dev->image_used[vm->frame] = 1;
00908 
00909                 STK_DEBUG("VIDIOCMCAPTURE done\n");
00910             }
00911             break;
00912 
00913         case VIDIOCSYNC:
00914             {
00915                 int ret;
00916                 int *mbuf = arg;
00917 
00918                 STK_DEBUG("VIDIOCSYNC\n");
00919 
00920                 if (*mbuf < 0 || *mbuf >= dev->nbuffers)
00921                     return -EINVAL;
00922 
00923                 if (dev->image_used[*mbuf] == 0)
00924                     return -EINVAL;
00925 
00926                 add_wait_queue(&dev->wait_frame, &wait);
00927 
00928                 while (dev->full_frames == NULL) {
00929                     if (dev->error_status) {
00930                         remove_wait_queue(&dev->wait_frame, &wait);
00931                         set_current_state(TASK_RUNNING);
00932                         return -dev->error_status;
00933                     }
00934 
00935                     if (signal_pending(current)) {
00936                         remove_wait_queue(&dev->wait_frame, &wait);
00937                         set_current_state(TASK_RUNNING);
00938                         return -ERESTARTSYS;
00939                     }
00940 
00941                     schedule();
00942                     set_current_state(TASK_INTERRUPTIBLE);
00943                 }
00944 
00945                 remove_wait_queue(&dev->wait_frame, &wait);
00946                 set_current_state(TASK_RUNNING);
00947 
00948                 STK_DEBUG("VIDIOCSYNC: frame ready\n");
00949 
00950                 dev->fill_image = *mbuf;
00951 
00952                 ret = stk11xx_handle_frame(dev);
00953 
00954                 if (ret != 0)
00955                     STK_ERROR("VIDIOCSYNC error !\n");
00956 
00957                 dev->image_used[*mbuf] = 0;
00958             }
00959             break;
00960 
00961         case VIDIOCGAUDIO:
00962             STK_DEBUG("VIDIOCGAUDIO\n");
00963             return -EINVAL;
00964             break;
00965 
00966         case VIDIOCSAUDIO:
00967             STK_DEBUG("VIDIOCSAUDIO\n");
00968             return -EINVAL;
00969             break;
00970 
00971         case VIDIOCGUNIT:
00972             {
00973                 struct video_unit *vu = arg;
00974 
00975                 vu->video = dev->vdev->minor & 0x3f;
00976                 vu->audio = -1;
00977                 vu->vbi = -1;
00978                 vu->radio = -1;
00979                 vu->teletext = -1;
00980             }
00981             break;
00982 
00983 
00984         // Video 4 Linux v2
00985 
00986         case VIDIOC_QUERYCAP:
00987             {
00988                 struct v4l2_capability *cap = arg;
00989 
00990                 STK_DEBUG("VIDIOC_QUERYCAP\n");
00991 
00992                 memset(cap, 0, sizeof(*cap));
00993                 strlcpy(cap->driver, "stk11xx", sizeof(cap->driver));
00994 
00995                 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
00996                 cap->version = (__u32) DRIVER_VERSION_NUM, strlcpy(cap->card, dev->vdev->name, sizeof(cap->card));
00997             
00998                 if (usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)) < 0)
00999                     strlcpy(cap->bus_info, dev->vdev->name, sizeof(cap->bus_info));
01000             }
01001             break;
01002 
01003         case VIDIOC_ENUMINPUT:
01004             {
01005                 struct v4l2_input *i = arg;
01006 
01007                 STK_DEBUG("VIDIOC_ENUMINPUT %d\n", i->index);
01008 
01009                 if (i->index)
01010                     return -EINVAL;
01011 
01012                 strlcpy(i->name, "USB", sizeof(i->name));
01013                 i->type = V4L2_INPUT_TYPE_CAMERA;
01014             }
01015             break;
01016 
01017         case VIDIOC_G_INPUT:
01018             {
01019                 struct v4l2_input *i = arg;
01020 
01021                 STK_DEBUG("GET INPUT %d\n", i->index);
01022 
01023                 if (i->index)
01024                     return -EINVAL;
01025             }
01026             break;
01027 
01028         case VIDIOC_S_INPUT:
01029             {
01030                 struct v4l2_input *i = arg;
01031 
01032                 STK_DEBUG("SET INPUT %d\n", i->index);
01033 
01034                 if (i->index != 0)
01035                     return -EINVAL;
01036             }
01037             break;
01038 
01039         case VIDIOC_QUERYCTRL:
01040             {
01041                 int i;
01042                 int nbr;
01043                 struct v4l2_queryctrl *c = arg;
01044 
01045                 STK_DEBUG("VIDIOC_QUERYCTRL id = %d\n", c->id);
01046 
01047                 nbr = sizeof(stk11xx_controls)/sizeof(struct v4l2_queryctrl);
01048 
01049                 for (i=0; i<nbr; i++) {
01050                     if (stk11xx_controls[i].id == c->id) {
01051                         STK_DEBUG("VIDIOC_QUERYCTRL found\n");
01052                         memcpy(c, &stk11xx_controls[i], sizeof(struct v4l2_queryctrl));
01053                         switch(c->id)
01054                         {
01055                             case V4L2_CID_BRIGHTNESS:
01056                                 c->default_value = dev->vsettings.default_brightness;
01057                                 break;
01058                             case V4L2_CID_WHITENESS:
01059                                 c->default_value = dev->vsettings.default_whiteness;
01060                                 break;
01061                             case V4L2_CID_SATURATION:
01062                                 c->default_value = dev->vsettings.default_colour;
01063                                 break;
01064                             case V4L2_CID_CONTRAST:
01065                                 c->default_value = dev->vsettings.default_contrast;
01066                                 break;
01067                             case V4L2_CID_HFLIP:
01068                                 c->default_value = dev->vsettings.default_hflip;
01069                                 break;
01070                             case V4L2_CID_VFLIP:
01071                                 c->default_value = dev->vsettings.default_vflip;
01072                                 break;
01073                         }
01074                         break;
01075                     }
01076                 }
01077 
01078                 if (i >= nbr)
01079                     return -EINVAL;
01080             }
01081             break;
01082 
01083         case VIDIOC_G_CTRL:
01084             {
01085                 struct v4l2_control *c = arg;
01086 
01087                 STK_DEBUG("GET CTRL id=%d\n", c->id);
01088 
01089                 switch (c->id) {
01090                     case V4L2_CID_BRIGHTNESS:
01091                         c->value = dev->vsettings.brightness;
01092                         break;
01093 
01094                     case V4L2_CID_WHITENESS:
01095                         c->value = dev->vsettings.whiteness;
01096                         break;
01097 
01098                     case V4L2_CID_SATURATION:
01099                         c->value = dev->vsettings.colour;
01100                         break;
01101 
01102                     case V4L2_CID_CONTRAST:
01103                         c->value = dev->vsettings.contrast;
01104                         break;
01105 
01106                     case V4L2_CID_HFLIP:
01107                         c->value = dev->vsettings.hflip;
01108                         break;
01109 
01110                     case V4L2_CID_VFLIP:
01111                         c->value = dev->vsettings.vflip;
01112                         break;
01113 
01114                     default:
01115                         return -EINVAL;
01116                 }
01117             }
01118             break;
01119 
01120         case VIDIOC_S_CTRL:
01121             {
01122                 struct v4l2_control *c = arg;
01123 
01124                 STK_DEBUG("SET CTRL id=%d value=%d\n", c->id, c->value);
01125 
01126                 switch (c->id) {
01127                     case V4L2_CID_BRIGHTNESS:
01128                         dev->vsettings.brightness = (0xff00 & c->value);
01129                         break;
01130 
01131                     case V4L2_CID_WHITENESS:
01132                         dev->vsettings.whiteness = (0xff00 & c->value);
01133                         break;
01134 
01135                     case V4L2_CID_SATURATION:
01136                         dev->vsettings.colour = (0xff00 & c->value);
01137                         break;
01138 
01139                     case V4L2_CID_CONTRAST:
01140                         dev->vsettings.contrast = (0xff00 & c->value);
01141                         break;
01142 
01143                     case V4L2_CID_HFLIP:
01144                         dev->vsettings.hflip = c->value ? 1: 0;
01145                         break;
01146 
01147                     case V4L2_CID_VFLIP:
01148                         dev->vsettings.vflip = c->value ? 1: 0;
01149                         break;
01150 
01151                     default:
01152                         return -EINVAL;
01153                 }
01154 
01155                 dev_stk11xx_camera_settings(dev);
01156             }
01157             break;
01158 
01159         case VIDIOC_ENUM_FMT:
01160             {
01161                 int index;
01162                 struct v4l2_fmtdesc *fmtd = arg;
01163 
01164                 STK_DEBUG("VIDIOC_ENUM_FMT %d\n", fmtd->index);
01165 
01166                 if (fmtd->index != 0)
01167                     return -EINVAL;
01168 
01169                 index = fmtd->index;
01170 
01171                 memset(fmtd, 0, sizeof(*fmtd));
01172 
01173                 fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
01174                 fmtd->index = index;
01175 
01176                 switch (index) {
01177                     case 0:
01178                         fmtd->flags = 0;
01179                         fmtd->pixelformat = V4L2_PIX_FMT_RGB24;
01180 
01181                         strcpy(fmtd->description, "rgb24");
01182                         break;
01183 
01184                     case 1:
01185                         fmtd->flags = 0;
01186                         fmtd->pixelformat = V4L2_PIX_FMT_RGB32;
01187 
01188                         strcpy(fmtd->description, "rgb32");
01189                         break;
01190 
01191                     case 2:
01192                         fmtd->flags = 0;
01193                         fmtd->pixelformat = V4L2_PIX_FMT_BGR24;
01194 
01195                         strcpy(fmtd->description, "bgr24");
01196                         break;
01197 
01198                     case 3:
01199                         fmtd->flags = 0;
01200                         fmtd->pixelformat = V4L2_PIX_FMT_BGR32;
01201 
01202                         strcpy(fmtd->description, "bgr32");
01203                         break;
01204 
01205                     case 4:
01206                         fmtd->flags = 0;
01207                         fmtd->pixelformat = V4L2_PIX_FMT_UYVY;
01208 
01209                         strcpy(fmtd->description, "uyvy");
01210                         break;
01211 
01212                     case 5:
01213                         fmtd->flags = 0;
01214                         fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
01215 
01216                         strcpy(fmtd->description, "yuyv");
01217                         break;
01218 
01219                     default:
01220                         return -EINVAL;
01221                 }
01222             }
01223             break;
01224 
01225         case VIDIOC_G_FMT:
01226             {
01227                 struct v4l2_format *fmtd = arg;
01228                 struct v4l2_pix_format pix_format;
01229 
01230                 STK_DEBUG("GET FMT %d\n", fmtd->type);
01231 
01232                 if (fmtd->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
01233                     return -EINVAL;
01234 
01235                 pix_format.width = dev->view.x;
01236                 pix_format.height = dev->view.y;
01237                 pix_format.field = V4L2_FIELD_NONE;
01238                 pix_format.colorspace = V4L2_COLORSPACE_SRGB;
01239                 pix_format.priv = 0;
01240 
01241                                 switch (dev->vsettings.palette) {
01242                     case STK11XX_PALETTE_RGB24:
01243                         pix_format.pixelformat = V4L2_PIX_FMT_RGB24;
01244                         pix_format.sizeimage = pix_format.width * pix_format.height * 3;
01245                         pix_format.bytesperline = 3 * pix_format.width;
01246                         break;
01247 
01248                     case STK11XX_PALETTE_RGB32:
01249                         pix_format.pixelformat = V4L2_PIX_FMT_RGB32;
01250                         pix_format.sizeimage = pix_format.width * pix_format.height * 4;
01251                         pix_format.bytesperline = 4 * pix_format.width;
01252                         break;
01253 
01254                     case STK11XX_PALETTE_BGR24:
01255                         pix_format.pixelformat = V4L2_PIX_FMT_BGR24;
01256                         pix_format.sizeimage = pix_format.width * pix_format.height * 3;
01257                         pix_format.bytesperline = 3 * pix_format.width;
01258                         break;
01259 
01260                     case STK11XX_PALETTE_BGR32:
01261                         pix_format.pixelformat = V4L2_PIX_FMT_BGR32;
01262                         pix_format.sizeimage = pix_format.width * pix_format.height * 4;
01263                         pix_format.bytesperline = 4 * pix_format.width;
01264                         break;
01265 
01266                     case STK11XX_PALETTE_UYVY:
01267                         pix_format.pixelformat = V4L2_PIX_FMT_UYVY;
01268                         pix_format.sizeimage = pix_format.width * pix_format.height * 2;
01269                         pix_format.bytesperline = 2 * pix_format.width;
01270                         break;
01271 
01272                     case STK11XX_PALETTE_YUYV:
01273                         pix_format.pixelformat = V4L2_PIX_FMT_YUYV;
01274                         pix_format.sizeimage = pix_format.width * pix_format.height * 2;
01275                         pix_format.bytesperline = 2 * pix_format.width;
01276                         break;
01277                 }
01278 
01279                 memcpy(&(fmtd->fmt.pix), &pix_format, sizeof(pix_format));
01280             }
01281             break;
01282 
01283         case VIDIOC_TRY_FMT:
01284             {
01285                 struct v4l2_format *fmtd = arg;
01286 
01287                 STK_DEBUG("TRY FMT %d\n", fmtd->type);
01288 
01289                 if (fmtd->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
01290                     return -EINVAL;
01291 
01292 
01293                 switch (dev->webcam_type) {
01294                     case STK11XX_SXGA:
01295                         if (fmtd->fmt.pix.width > stk11xx_image_sizes[STK11XX_NBR_SIZES-1].x)
01296                             fmtd->fmt.pix.width = stk11xx_image_sizes[STK11XX_NBR_SIZES-1].x;
01297                         else if (fmtd->fmt.pix.width < stk11xx_image_sizes[0].x)
01298                             fmtd->fmt.pix.width = stk11xx_image_sizes[0].x;
01299     
01300                         if (fmtd->fmt.pix.height > stk11xx_image_sizes[STK11XX_NBR_SIZES-1].y)
01301                             fmtd->fmt.pix.height = stk11xx_image_sizes[STK11XX_NBR_SIZES-1].y;
01302                         else if (fmtd->fmt.pix.height < stk11xx_image_sizes[0].y)
01303                             fmtd->fmt.pix.height = stk11xx_image_sizes[0].y;
01304                         break;
01305 
01306                     case STK11XX_VGA:
01307                         if (fmtd->fmt.pix.width > stk11xx_image_sizes[STK11XX_NBR_SIZES-1-3].x)
01308                             fmtd->fmt.pix.width = stk11xx_image_sizes[STK11XX_NBR_SIZES-1-3].x;
01309                         else if (fmtd->fmt.pix.width < stk11xx_image_sizes[0].x)
01310                             fmtd->fmt.pix.width = stk11xx_image_sizes[0].x;
01311     
01312                         if (fmtd->fmt.pix.height > stk11xx_image_sizes[STK11XX_NBR_SIZES-1-3].y)
01313                             fmtd->fmt.pix.height = stk11xx_image_sizes[STK11XX_NBR_SIZES-1-3].y;
01314                         else if (fmtd->fmt.pix.height < stk11xx_image_sizes[0].y)
01315                             fmtd->fmt.pix.height = stk11xx_image_sizes[0].y;
01316                         break;
01317                 }
01318                                 fmtd->fmt.pix.field = V4L2_FIELD_NONE;
01319                                 fmtd->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
01320                                 fmtd->fmt.pix.priv = 0;
01321                 switch (fmtd->fmt.pix.pixelformat) {
01322                     case V4L2_PIX_FMT_RGB24:
01323                         dev->vsettings.depth = 24;
01324                                                 fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 3;
01325                                                 fmtd->fmt.pix.bytesperline = 3 * fmtd->fmt.pix.width;
01326 
01327                         break;
01328 
01329                     case V4L2_PIX_FMT_RGB32:
01330                         dev->vsettings.depth = 32;
01331                                                 fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 4;
01332                                                 fmtd->fmt.pix.bytesperline = 4 * fmtd->fmt.pix.width;
01333 
01334                         break;
01335 
01336                     case V4L2_PIX_FMT_BGR24:
01337                         dev->vsettings.depth = 24;
01338                                                 fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 3;
01339                                                 fmtd->fmt.pix.bytesperline = 3 * fmtd->fmt.pix.width;
01340 
01341                         break;
01342 
01343                     case V4L2_PIX_FMT_BGR32:
01344                         dev->vsettings.depth = 32;
01345                                                 fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 4;
01346                                                 fmtd->fmt.pix.bytesperline = 4 * fmtd->fmt.pix.width;
01347 
01348                         break;
01349 
01350                     case V4L2_PIX_FMT_UYVY:
01351                         dev->vsettings.depth = 16;
01352                                                 fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 2;
01353                                                 fmtd->fmt.pix.bytesperline = 2 * fmtd->fmt.pix.width;
01354 
01355                         break;
01356 
01357                     case V4L2_PIX_FMT_YUYV:
01358                         dev->vsettings.depth = 16;
01359                                                 fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 2;
01360                                                 fmtd->fmt.pix.bytesperline = 2 * fmtd->fmt.pix.width;
01361 
01362                         break;
01363 
01364                     default:
01365                         return -EINVAL;
01366                 }
01367 
01368             }
01369             break;
01370 
01371         case VIDIOC_S_FMT:
01372             {
01373                 struct v4l2_format *fmtd = arg;
01374 
01375                 STK_DEBUG("SET FMT %d : %d\n", fmtd->type, fmtd->fmt.pix.pixelformat);
01376 
01377                 if (fmtd->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
01378                     return -EINVAL;
01379 
01380                                 // need to also set the fields as in G_FMT, conform v4l2 specs
01381                                 fmtd->fmt.pix.field = V4L2_FIELD_NONE;
01382                                 fmtd->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
01383                                 fmtd->fmt.pix.priv = 0;
01384 
01385 
01386                 switch (fmtd->fmt.pix.pixelformat) {
01387                     case V4L2_PIX_FMT_RGB24:
01388                         dev->vsettings.depth = 24;
01389                                                 dev->vsettings.palette = STK11XX_PALETTE_RGB24;
01390                                                 fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 3;
01391                                                 fmtd->fmt.pix.bytesperline = 3 * fmtd->fmt.pix.width;
01392 
01393                         break;
01394 
01395                     case V4L2_PIX_FMT_RGB32:
01396                         dev->vsettings.depth = 32;
01397                         dev->vsettings.palette = STK11XX_PALETTE_RGB32;
01398                                                 fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 4;
01399                                                 fmtd->fmt.pix.bytesperline = 4 * fmtd->fmt.pix.width;
01400 
01401                         break;
01402 
01403                     case V4L2_PIX_FMT_BGR24:
01404                         dev->vsettings.depth = 24;
01405                         dev->vsettings.palette = STK11XX_PALETTE_BGR24;
01406                                                 fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 3;
01407                                                 fmtd->fmt.pix.bytesperline = 3 * fmtd->fmt.pix.width;
01408 
01409                         break;
01410 
01411                     case V4L2_PIX_FMT_BGR32:
01412                         dev->vsettings.depth = 32;
01413                         dev->vsettings.palette = STK11XX_PALETTE_BGR32;
01414                                                 fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 4;
01415                                                 fmtd->fmt.pix.bytesperline = 4 * fmtd->fmt.pix.width;
01416 
01417                         break;
01418 
01419                     case V4L2_PIX_FMT_UYVY:
01420                         dev->vsettings.depth = 16;
01421                         dev->vsettings.palette = STK11XX_PALETTE_UYVY;
01422                                                 fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 2;
01423                                                 fmtd->fmt.pix.bytesperline = 2 * fmtd->fmt.pix.width;
01424 
01425                         break;
01426 
01427                     case V4L2_PIX_FMT_YUYV:
01428                         dev->vsettings.depth = 16;
01429                         dev->vsettings.palette = STK11XX_PALETTE_YUYV;
01430                                                 fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 2;
01431                                                 fmtd->fmt.pix.bytesperline = 2 * fmtd->fmt.pix.width;
01432 
01433                         break;
01434 
01435                     default:
01436                         return -EINVAL;
01437                 }
01438 
01439                 STK_DEBUG("Set width=%d, height=%d\n", fmtd->fmt.pix.width, fmtd->fmt.pix.height);
01440 
01441                 // Stop the video stream
01442                 dev_stk11xx_stop_stream(dev);
01443             
01444                 // ISOC and URB cleanup
01445                 usb_stk11xx_isoc_cleanup(dev);
01446 
01447                 // Switch off the camera
01448                 dev_stk11xx_camera_off(dev);
01449 
01450                 dev_stk11xx_camera_asleep(dev);
01451 
01452                 // Select the new video mode
01453                 if (v4l_stk11xx_select_video_mode(dev, fmtd->fmt.pix.width, fmtd->fmt.pix.height)) {
01454                     STK_ERROR("Select video mode failed !\n");
01455                     return -EAGAIN;
01456                 }
01457 
01458                 // Clear the buffers
01459                 stk11xx_clear_buffers(dev);
01460 
01461                 // Initialize the device
01462                 dev_stk11xx_init_camera(dev);
01463                 dev_stk11xx_camera_on(dev);
01464                 dev_stk11xx_reconf_camera(dev);
01465 
01466                 // ISOC and URB init
01467                 usb_stk11xx_isoc_init(dev);
01468 
01469                 // Re-start the stream
01470                 dev_stk11xx_start_stream(dev);
01471 
01472                 // Video settings
01473                 dev_stk11xx_camera_settings(dev);
01474             }
01475             break;
01476 
01477         case VIDIOC_QUERYSTD:
01478             {
01479                 STK_DEBUG("QUERY STD\n");
01480                 return -EINVAL;
01481             }
01482             break;
01483 
01484         case VIDIOC_G_STD:
01485             {
01486                 v4l2_std_id *std = arg;
01487 
01488                 STK_DEBUG("GET STD\n");
01489         
01490                 *std = V4L2_STD_UNKNOWN;
01491             }
01492             break;
01493 
01494         case VIDIOC_S_STD:
01495             {
01496                 v4l2_std_id *std = arg;
01497 
01498                 STK_DEBUG("SET STD\n");
01499                 
01500                 if (*std != V4L2_STD_UNKNOWN)
01501                     return -EINVAL;
01502             }
01503             break;
01504 
01505         case VIDIOC_ENUMSTD:
01506             {
01507                 struct v4l2_standard *std = arg;
01508 
01509                 STK_DEBUG("VIDIOC_ENUMSTD\n");
01510 
01511                 if (std->index != 0)
01512                     return -EINVAL;
01513 
01514                 std->id = V4L2_STD_UNKNOWN;
01515                 strncpy(std->name, "webcam", sizeof(std->name));
01516 
01517                 break;
01518             }
01519 
01520         case VIDIOC_REQBUFS:
01521             {
01522                 int nbuffers;
01523                 struct v4l2_requestbuffers *rb = arg;
01524 
01525                 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
01526                     return -EINVAL;
01527 
01528                 if (rb->memory != V4L2_MEMORY_MMAP)
01529                     return -EINVAL;
01530 
01531                 nbuffers = rb->count;
01532 
01533                 if (nbuffers < 2)
01534                     nbuffers = 2;
01535                 else if (nbuffers > dev->nbuffers)
01536                     nbuffers = dev->nbuffers;
01537 
01538                 rb->count = dev->nbuffers;
01539             }
01540             break;
01541 
01542         case VIDIOC_QUERYBUF:
01543             {
01544                 int index;
01545                 struct v4l2_buffer *buf = arg;
01546 
01547                 STK_DEBUG("QUERY BUFFERS %d %d\n", buf->index, dev->nbuffers);
01548 
01549                 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
01550                     return -EINVAL;
01551 
01552                 if (buf->memory != V4L2_MEMORY_MMAP) 
01553                     return -EINVAL;
01554 
01555                 index = buf->index;
01556 
01557                 if (index < 0 || index >= dev->nbuffers)
01558                     return -EINVAL;
01559 
01560                 memset(buf, 0, sizeof(struct v4l2_buffer));
01561 
01562                 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
01563                 buf->index = index;
01564                 buf->m.offset = index * dev->len_per_image;
01565                 buf->bytesused = dev->view_size;
01566                 buf->field = V4L2_FIELD_NONE;
01567                 buf->memory = V4L2_MEMORY_MMAP;
01568                 buf->length = dev->len_per_image;
01569             }
01570             break;
01571 
01572         case VIDIOC_QBUF:
01573             {
01574                 struct v4l2_buffer *buf = arg;
01575 
01576                 STK_DEBUG("VIDIOC_QBUF\n");
01577 
01578                 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
01579                     return -EINVAL;
01580 
01581                 if (buf->memory != V4L2_MEMORY_MMAP)
01582                     return -EINVAL;
01583 
01584                 if (buf->index < 0 || buf->index >= dev->nbuffers)
01585                     return -EINVAL;
01586 
01587                 buf->flags |= V4L2_BUF_FLAG_QUEUED;
01588                 buf->flags &= ~V4L2_BUF_FLAG_DONE;
01589             }
01590             break;
01591 
01592         case VIDIOC_DQBUF:
01593             {
01594                 int ret;
01595                 struct v4l2_buffer *buf = arg;
01596 
01597                 STK_DEBUG("VIDIOC_DQBUF\n");
01598                 
01599                 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
01600                     return -EINVAL;
01601 
01602                 add_wait_queue(&dev->wait_frame, &wait);
01603 
01604                 while (dev->full_frames == NULL) {
01605                     if (dev->error_status) {
01606                         remove_wait_queue(&dev->wait_frame, &wait);
01607                         set_current_state(TASK_RUNNING);
01608 
01609                         return -dev->error_status;
01610                     }
01611 
01612                     if (signal_pending(current)) {
01613                         remove_wait_queue(&dev->wait_frame, &wait);
01614                         set_current_state(TASK_RUNNING);
01615 
01616                         return -ERESTARTSYS;
01617                     }
01618 
01619                     schedule();
01620                     set_current_state(TASK_INTERRUPTIBLE);
01621                 }
01622 
01623                 remove_wait_queue(&dev->wait_frame, &wait);
01624                 set_current_state(TASK_RUNNING);
01625 
01626                 STK_DEBUG("VIDIOC_DQBUF : frame ready.\n");
01627 
01628                 ret = stk11xx_handle_frame(dev);
01629 
01630                 if (ret)
01631                     return -EFAULT;
01632 
01633                 buf->index = dev->fill_image;
01634                 buf->bytesused = dev->view_size;
01635                 buf->flags = V4L2_BUF_FLAG_MAPPED;
01636                 buf->field = V4L2_FIELD_NONE;
01637                 do_gettimeofday(&buf->timestamp);
01638                 buf->sequence = 0;
01639                 buf->memory = V4L2_MEMORY_MMAP;
01640                 buf->m.offset = dev->fill_image * dev->len_per_image;
01641                 buf->length = dev->len_per_image; //buf->bytesused;
01642 
01643                 stk11xx_next_image(dev);
01644             }
01645             break;
01646 
01647         case VIDIOC_STREAMON:
01648             {
01649                 STK_DEBUG("VIDIOC_STREAMON\n");
01650 
01651                 usb_stk11xx_isoc_init(dev);
01652             }
01653             break;
01654 
01655         case VIDIOC_STREAMOFF:
01656             {
01657                 STK_DEBUG("VIDIOC_STREAMOFF\n");
01658 
01659                 usb_stk11xx_isoc_cleanup(dev);
01660             }
01661             break;
01662 
01663         case VIDIOC_G_PARM:
01664             {
01665                 struct v4l2_streamparm *sp = arg;
01666 
01667                 STK_DEBUG("GET PARM %d\n", sp->type);
01668 
01669                 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
01670                     return -EINVAL;
01671 
01672                 sp->parm.capture.capability = 0;
01673                 sp->parm.capture.capturemode = 0;
01674                 sp->parm.capture.timeperframe.numerator = 1;
01675                 sp->parm.capture.timeperframe.denominator = 30;
01676                 sp->parm.capture.readbuffers = 2;
01677                 sp->parm.capture.extendedmode = 0;
01678             }
01679             break;
01680 
01681 
01682         case VIDIOC_G_AUDIO:
01683             STK_DEBUG("GET AUDIO\n");
01684             return -EINVAL;
01685             break;
01686 
01687         case VIDIOC_S_AUDIO:
01688             STK_DEBUG("SET AUDIO\n");
01689             return -EINVAL;
01690             break;
01691 
01692         case VIDIOC_S_TUNER:
01693             STK_DEBUG("SET TUNER\n");
01694             return -EINVAL;
01695             break;
01696 
01697         case VIDIOC_G_FBUF:
01698         case VIDIOC_S_FBUF:
01699         case VIDIOC_OVERLAY:
01700             return -EINVAL;
01701             break;
01702 
01703         case VIDIOC_G_TUNER:
01704         case VIDIOC_G_FREQUENCY:
01705         case VIDIOC_S_FREQUENCY:
01706             return -EINVAL;
01707             break;
01708 
01709         case VIDIOC_QUERYMENU:
01710             return -EINVAL;
01711             break;
01712 /*
01713         case VIDIOC_CROPCAP:
01714             {
01715                 struct v4l2_cropcap cc;
01716 
01717                 cc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
01718                 cc.pixelaspect.numerator = 1;
01719                 cc.pixelaspect.denominator = 1;
01720                 cc.bounds.top = 0;
01721                 cc.bounds.left = 0;
01722                 cc.bounds.width = 640;
01723                 cc.bounds.height = 480;
01724                 cc.defrect.top = 0;
01725                 cc.defrect.left = 0;
01726                 cc.defrect.width = 640;
01727                 cc.defrect.height = 480;
01728 
01729                 memcpy(arg, &cc, sizeof(cc));
01730             }
01731             break;
01732 */
01733         default:
01734             STK_DEBUG("IOCTL unknown !\n");
01735             return -ENOIOCTLCMD;
01736     }
01737 
01738     return 0;
01739 }
01740 
01741 
01753 static long v4l_stk11xx_ioctl(struct file *fp,
01754         unsigned int cmd, unsigned long arg)
01755 {
01756     long err;
01757     struct usb_stk11xx *dev;
01758     struct video_device *vdev;
01759     
01760     vdev = video_devdata(fp);
01761     dev = video_get_drvdata(video_devdata(fp));
01762 
01763     STK_DEBUG("v4l_stk11xx_ioctl %02X\n", (unsigned char) cmd);
01764 
01765     if (dev == NULL)
01766         return -EFAULT;
01767 
01768     if (vdev == NULL)
01769         return -EFAULT;
01770 
01771     mutex_lock(&dev->modlock); 
01772 
01773     err = video_usercopy(fp, cmd, arg, v4l_stk11xx_do_ioctl);
01774 
01775     mutex_unlock(&dev->modlock);
01776 
01777     return err;
01778 }
01779 
01780 
01790 int v4l_stk11xx_register_video_device(struct usb_stk11xx *dev)
01791 {
01792     int err;
01793 
01794     strcpy(dev->vdev->name, DRIVER_DESC);
01795 
01796     dev->vdev->dev = dev->interface->dev;
01797     dev->vdev->fops = &v4l_stk11xx_fops;
01798     dev->vdev->release = video_device_release;
01799     dev->vdev->minor = -1;
01800 
01801     video_set_drvdata(dev->vdev, dev);
01802 
01803     err = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1);
01804 
01805     if (err)
01806         STK_ERROR("Video register fail !\n");
01807     else
01808         STK_INFO("Syntek USB2.0 Camera is now controlling video device /dev/video%d\n", dev->vdev->minor);
01809 
01810     return err;
01811 }
01812 
01813 
01823 int v4l_stk11xx_unregister_video_device(struct usb_stk11xx *dev)
01824 {
01825     STK_INFO("Syntek USB2.0 Camera release resources video device /dev/video%d\n", dev->vdev->minor);
01826 
01827     video_set_drvdata(dev->vdev, NULL);
01828     video_unregister_device(dev->vdev);
01829 
01830     return 0;
01831 }
01832 
01833 
01839 static struct v4l2_file_operations v4l_stk11xx_fops = {
01840     .owner = THIS_MODULE,
01841     .open = v4l_stk11xx_open,
01842     .release = v4l_stk11xx_release,
01843     .read = v4l_stk11xx_read,
01844     .poll = v4l_stk11xx_poll,
01845     .mmap = v4l_stk11xx_mmap,
01846     .ioctl = v4l_stk11xx_ioctl,
01847 };
01848