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