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 #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