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