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