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