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