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