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