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