Syntek USB Video Camera
stk11xx-v4l.c
Go to the documentation of this file.
1
34#include <linux/module.h>
35#include <linux/init.h>
36#include <linux/kernel.h>
37#include <linux/version.h>
38#include <linux/errno.h>
39#include <linux/slab.h>
40#include <linux/kref.h>
41#include <linux/vmalloc.h>
42#include <linux/mm.h>
43
44
45#include <linux/usb.h>
46#include <media/v4l2-common.h>
47#include <media/v4l2-ioctl.h>
48
49#include "stk11xx.h"
50
51
53
54
59const struct stk11xx_coord stk11xx_image_sizes[STK11XX_NBR_SIZES] = {
60 { 80, 60 },
61 { 128, 96 },
62 { 160, 120 },
63 { 213, 160 },
64 { 320, 240 },
65 { 640, 480 },
66 { 720, 576 },
67 { 800, 600 },
68 { 1024, 768 },
69 { 1280, 1024 }
70};
71
72
79 {
82 .name = "Brightness",
83 .minimum = 0,
84 .maximum = 0xff00,
85 .step = 1,
86 .default_value = 0x7f00,
87 },
88 {
91 .name = "Whiteness",
92 .minimum = 0,
93 .maximum = 0xff00,
94 .step = 1,
95 .default_value = 0x7f00,
96 },
97 {
100 .name = "Saturation",
101 .minimum = 0,
102 .maximum = 0xff00,
103 .step = 1,
104 .default_value = 0x7f00,
105 },
106 {
107 .id = V4L2_CID_CONTRAST,
109 .name = "Contrast",
110 .minimum = 0,
111 .maximum = 0xff00,
112 .step = 1,
113 .default_value = 0x7f00,
114 },
115 {
116 .id = V4L2_CID_HUE,
118 .name = "Hue",
119 .minimum = 0,
120 .maximum = 0xff00,
121 .step = 1,
122 .default_value = 0x7f00,
123 },
124 {
125 .id = V4L2_CID_HFLIP,
127 .name = "Flip Horizontally",
128 .minimum = 0,
129 .maximum = 1,
130 .step = 1,
131 .default_value = 0, // will be actually set later
132 },
133 {
134 .id = V4L2_CID_VFLIP,
136 .name = "Flip Vertically",
137 .minimum = 0,
138 .maximum = 1,
139 .step = 1,
140 .default_value = 0, // will be actually set later
141 }
142};
143
144
157{
158 int i;
159 int find;
160
161
162 // Check width and height
163 // Notice : this test is usefull for the Kopete application !
164
165 // Driver can't build an image smaller than the minimal resolution !
166 if ((width < stk11xx_image_sizes[0].x)
167 || (height < stk11xx_image_sizes[0].y)) {
170 }
171
172 // Driver can't build an image bigger than the maximal resolution !
173 switch (dev->webcam_type) {
174 case STK11XX_SXGA:
175 if ((width > stk11xx_image_sizes[STK11XX_1280x1024].x)
176 || (height > stk11xx_image_sizes[STK11XX_1280x1024].y)) {
177 width = stk11xx_image_sizes[STK11XX_1280x1024].x;
178 height = stk11xx_image_sizes[STK11XX_1280x1024].y;
179 }
180 break;
181
182 case STK11XX_VGA:
183 if ((width > stk11xx_image_sizes[STK11XX_640x480].x)
184 || (height > stk11xx_image_sizes[STK11XX_640x480].y)) {
185 width = stk11xx_image_sizes[STK11XX_640x480].x;
186 height = stk11xx_image_sizes[STK11XX_640x480].y;
187 }
188 break;
189
190 case STK11XX_PAL:
191 if (! (((width == 720) && (height==576))
192 || ((width == 720) && (height==480))
193 || ((width == 640) && (height==480)))) {
194 width = 640;
195 height = 480;
196 }
197 break;
198
199 default:
200 return -1;
201 }
202
203
204 // Seek the best resolution
205 switch (dev->webcam_type) {
206 case STK11XX_SXGA:
207 for (i=0, find=0; i<=STK11XX_1280x1024; i++) {
209 find = i;
210 }
211 break;
212
213 case STK11XX_VGA:
214 for (i=0, find=0; i<=STK11XX_640x480; i++) {
216 find = i;
217 }
218 break;
219
220 case STK11XX_PAL:
221 for (i=0, find=0; i<=STK11XX_720x576; i++) {
223 find = i;
224 }
225 break;
226
227 default:
228 return -1;
229 }
230
231 // Save the new resolution
232 dev->resolution = find;
233
234 STK_DEBUG("Set mode %d [%dx%d]\n", dev->resolution,
235 stk11xx_image_sizes[dev->resolution].x, stk11xx_image_sizes[dev->resolution].y);
236
237 // Save the new size
238 dev->view.x = width;
239 dev->view.y = height;
240
241
242 // Calculate the frame size
243 if (dev->webcam_type == STK11XX_PAL) {
244 // Here, dev->resolution equals : 640x480 || 720x576
245 dev->image.x = stk11xx_image_sizes[dev->resolution].x;
246 dev->image.y = stk11xx_image_sizes[dev->resolution].y;
247 dev->frame_size = dev->image.x * dev->image.y;
248 }
249 else {
250 switch (dev->resolution) {
251 case STK11XX_80x60:
252 case STK11XX_128x96:
253 case STK11XX_160x120:
254 case STK11XX_213x160:
255 case STK11XX_320x240:
256 case STK11XX_640x480:
257 dev->image.x = stk11xx_image_sizes[STK11XX_640x480].x;
258 dev->image.y = stk11xx_image_sizes[STK11XX_640x480].y;
259 dev->frame_size = dev->image.x * dev->image.y;
260 break;
261
262 case STK11XX_720x576:
263 case STK11XX_800x600:
264 case STK11XX_1024x768:
265 case STK11XX_1280x1024:
266 dev->image.x = stk11xx_image_sizes[STK11XX_1280x1024].x;
267 dev->image.y = stk11xx_image_sizes[STK11XX_1280x1024].y;
268 dev->frame_size = dev->image.x * dev->image.y;
269 break;
270 }
271 }
272
273
274 // Calculate the image size
275 switch (dev->vsettings.palette) {
276 case STK11XX_PALETTE_RGB24:
277 case STK11XX_PALETTE_BGR24:
278 dev->view_size = 3 * dev->view.x * dev->view.y;
279 dev->image_size = 3 * dev->frame_size;
280 break;
281
282 case STK11XX_PALETTE_RGB32:
283 case STK11XX_PALETTE_BGR32:
284 dev->view_size = 3 * dev->view.x * dev->view.y;
285 dev->image_size = 4 * dev->frame_size;
286 break;
287
288 case STK11XX_PALETTE_UYVY:
289 case STK11XX_PALETTE_YUYV:
290 dev->view_size = 2 * dev->view.x * dev->view.y;
291 dev->image_size = 2 * dev->frame_size;
292 break;
293 }
294
295 return 0;
296}
297
298
308static int v4l_stk11xx_open(struct file *fp)
309{
310 int err;
311
312 struct usb_stk11xx *dev;
313 struct video_device *vdev;
314
315 vdev = video_devdata(fp);
317
318 if (dev == NULL) {
319 STK_ERROR("Device not initialized !!!\n");
320 BUG();
321 }
322
323 mutex_lock(&dev->modlock);
324
325 if (dev->vopen) {
326 STK_DEBUG("Device is busy, someone is using the device\n");
327 mutex_unlock(&dev->modlock);
328 return -EBUSY;
329 }
330
331 // Allocate memory
333
334 if (err < 0) {
335 STK_ERROR("Failed to allocate buffer memory !\n");
336 mutex_unlock(&dev->modlock);
337 return err;
338 }
339
340 // Reset buffers and parameters
342
343 // Settings
344 dev->vsync = 0;
345 dev->v1st_cap = 5;
346 dev->error_status = 0;
347 dev->visoc_errors = 0;
348 dev->vframes_error = 0;
349 dev->vframes_dumped = 0;
350 dev->vsettings.hue = 0xffff;
351 dev->vsettings.whiteness = 0xffff;
352 dev->vsettings.depth = 24;
353 dev->vsettings.palette = STK11XX_PALETTE_BGR24;
354
355 // Select the resolution by default
357
358 // Initialize the device
362
363 // Init Isoc and URB
365
366 if (err) {
367 STK_ERROR("Failed to init ISOC stuff !\n");
370 mutex_unlock(&dev->modlock);
371 return err;
372 }
373
374 // Start the video stream
376
377 // Video settings
379
380 // Register interface on power management
381// usb_autopm_get_interface(dev->interface);
382
383 dev->vopen++;
384 fp->private_data = vdev;
385
386 mutex_unlock(&dev->modlock);
387
388 return 0;
389}
390
391
401static int v4l_stk11xx_release(struct file *fp)
402{
403 struct usb_stk11xx *dev;
404
406
407 if (dev->vopen == 0)
408 STK_ERROR("v4l_release called on closed device\n");
409
410 // Stop the video stream
412
413 // ISOC and URB cleanup
415
416 // Free memory
418
419 // Switch off the camera
421
423
424 // Unregister interface on power management
425// usb_autopm_put_interface(dev->interface);
426
427 dev->vopen--;
428
429 return 0;
430}
431
432
446static ssize_t v4l_stk11xx_read(struct file *fp, char __user *buf,
447 size_t count, loff_t *f_pos)
448{
449 int noblock = fp->f_flags & O_NONBLOCK;
450
451 struct usb_stk11xx *dev;
452 struct video_device *vdev;
453
454 int bytes_to_read;
455 void *image_buffer_addr;
456
458
459 vdev = video_devdata(fp);
461
462 STK_STREAM("Read vdev=0x%p, buf=0x%p, count=%zd\n", vdev, buf, count);
463
464 if (dev == NULL)
465 return -EFAULT;
466
467 if (vdev == NULL)
468 return -EFAULT;
469
470 mutex_lock(&dev->modlock);
471
472 if (dev->image_read_pos == 0) {
473 add_wait_queue(&dev->wait_frame, &wait);
474
475 while (dev->full_frames == NULL) {
476 if (dev->error_status) {
477 remove_wait_queue(&dev->wait_frame, &wait);
479 mutex_unlock(&dev->modlock);
480 return -dev->error_status ;
481 }
482
483 if (noblock) {
484 remove_wait_queue(&dev->wait_frame, &wait);
486 mutex_unlock(&dev->modlock);
487 return -EWOULDBLOCK;
488 }
489
490 if (signal_pending(current)) {
491 remove_wait_queue(&dev->wait_frame, &wait);
493 mutex_unlock(&dev->modlock);
494 return -ERESTARTSYS;
495 }
496
497 schedule();
499 }
500
501 remove_wait_queue(&dev->wait_frame, &wait);
503
505 mutex_unlock(&dev->modlock);
506 return -EFAULT;
507 }
508 }
509
510 bytes_to_read = dev->view_size;
511
512 if (count + dev->image_read_pos > bytes_to_read)
513 count = bytes_to_read - dev->image_read_pos;
514
515 image_buffer_addr = dev->image_data;
516 image_buffer_addr += dev->images[dev->fill_image].offset;
517 image_buffer_addr += dev->image_read_pos;
518
520 mutex_unlock(&dev->modlock);
521 return -EFAULT;
522 }
523
524 dev->image_read_pos += count;
525
526 if (dev->image_read_pos >= bytes_to_read) {
527 dev->image_read_pos = 0;
529 }
530
531 mutex_unlock(&dev->modlock);
532
533 return count;
534}
535
536
545static unsigned int v4l_stk11xx_poll(struct file *fp, poll_table *wait)
546{
547 struct usb_stk11xx *dev;
548 struct video_device *vdev;
549
550 vdev = video_devdata(fp);
552
553 STK_STREAM("Poll\n");
554
555 if (vdev == NULL)
556 return -EFAULT;
557
558 if (dev == NULL)
559 return -EFAULT;
560
561 poll_wait(fp, &dev->wait_frame, wait);
562
563 if (dev->error_status)
564 return POLLERR;
565
566 if (dev->full_frames != NULL)
567 return (POLLIN | POLLRDNORM);
568
569 return 0;
570}
571
572
583static int v4l_stk11xx_mmap(struct file *fp, struct vm_area_struct *vma)
584{
585 unsigned int i;
586
587 unsigned long size;
588 unsigned long start;
589 unsigned long pos;
590 unsigned long page;
591
592 struct usb_stk11xx *dev;
593
595
596 STK_STREAM("mmap\n");
597
598 start = vma->vm_start;
599 size = vma->vm_end - vma->vm_start;
600
601 // Find the buffer for this mapping...
602 for (i=0; i<dev->nbuffers; i++) {
603 pos = dev->images[i].offset;
604
605 if ((pos >> PAGE_SHIFT) == vma->vm_pgoff)
606 break;
607 }
608
609 // If no buffer found !
610 if (i == STK11XX_MAX_IMAGES) {
611 STK_ERROR("mmap no buffer found !\n");
612 return -EINVAL;
613 }
614
615 if (i == 0) {
616 unsigned long total_size;
617
618 total_size = dev->nbuffers * dev->len_per_image;
619
620 if (size != dev->len_per_image && size != total_size) {
621 STK_ERROR("Wrong size (%lu) needed to be len_per_image=%d or total_size=%lu\n",
622 size, dev->len_per_image, total_size);
623
624 return -EINVAL;
625 }
626 }
627 else if (size > dev->len_per_image)
628 return -EINVAL;
629
630 vma->vm_flags |= VM_IO;
631
632 pos = (unsigned long) dev->image_data;
633
634 while (size > 0) {
635 page = vmalloc_to_pfn((void *) pos);
636
638 return -EAGAIN;
639
640 start += PAGE_SIZE;
641 pos += PAGE_SIZE;
642
643 if (size > PAGE_SIZE)
644 size -= PAGE_SIZE;
645 else
646 size = 0;
647 }
648
649 return 0;
650}
651
652
664static long v4l_stk11xx_do_ioctl(struct file *fp,
665 unsigned int cmd, void __user *arg)
666{
667 struct usb_stk11xx *dev;
668
670
672
673#if (CONFIG_STK11XX_DEBUG == 1)
675#endif
676
677 switch (cmd) {
678 case VIDIOC_QUERYCAP:
679 {
680 struct v4l2_capability *cap = arg;
681
682 STK_DEBUG("VIDIOC_QUERYCAP\n");
683
684 memset(cap, 0, sizeof(*cap));
685 strlcpy(cap->driver, "stk11xx", sizeof(cap->driver));
686
688 cap->version = (__u32) DRIVER_VERSION_NUM, strlcpy(cap->card, dev->vdev->name, sizeof(cap->card));
689
690 if (usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)) < 0)
691 strlcpy(cap->bus_info, dev->vdev->name, sizeof(cap->bus_info));
692 }
693 break;
694
695 case VIDIOC_ENUMINPUT:
696 {
697 struct v4l2_input *i = arg;
698
699 STK_DEBUG("VIDIOC_ENUMINPUT %d\n", i->index);
700
701 if (dev->webcam_model != SYNTEK_STK_0408) {
702 if (i->index)
703 return -EINVAL;
704 strlcpy(i->name, "USB", sizeof(i->name));
705 }
706 else {
707 if (i->index > 3)
708 return -EINVAL;
709
710 switch (i->index) {
711 case 0:
712 strlcpy(i->name, "Input1", sizeof(i->name));
713 break;
714 case 1:
715 strlcpy(i->name, "Input2", sizeof(i->name));
716 break;
717 case 2:
718 strlcpy(i->name, "Input3", sizeof(i->name));
719 break;
720 case 3:
721 strlcpy(i->name, "Input4", sizeof(i->name));
722 break;
723 }
724 }
725
727 }
728 break;
729
730 case VIDIOC_G_INPUT:
731 {
732 STK_DEBUG("GET INPUT\n");
733
734 return dev->vsettings.input;
735 }
736 break;
737
738 case VIDIOC_S_INPUT:
739 {
740 struct v4l2_input *i = arg;
741
742 STK_DEBUG("SET INPUT %d\n", i->index);
743
744 // TODO add input switching
745
746 if (i->index > 3)
747 return -EINVAL;
748
749 dev->vsettings.input = i->index + 1;
750
752 }
753 break;
754
755 case VIDIOC_QUERYCTRL:
756 {
757 int i;
758 int nbr;
759 struct v4l2_queryctrl *c = arg;
760
761 STK_DEBUG("VIDIOC_QUERYCTRL id = %d\n", c->id);
762
763 nbr = sizeof(stk11xx_controls)/sizeof(struct v4l2_queryctrl);
764
765 for (i=0; i<nbr; i++) {
766 if (stk11xx_controls[i].id == c->id) {
767 STK_DEBUG("VIDIOC_QUERYCTRL found\n");
768 memcpy(c, &stk11xx_controls[i], sizeof(struct v4l2_queryctrl));
769 switch(c->id)
770 {
772 c->default_value = dev->vsettings.default_brightness;
773 break;
775 c->default_value = dev->vsettings.default_whiteness;
776 break;
778 c->default_value = dev->vsettings.default_colour;
779 break;
781 c->default_value = dev->vsettings.default_contrast;
782 break;
783 case V4L2_CID_HFLIP:
784 c->default_value = dev->vsettings.default_hflip;
785 break;
786 case V4L2_CID_VFLIP:
787 c->default_value = dev->vsettings.default_vflip;
788 break;
789 }
790 break;
791 }
792 }
793
794 if (i >= nbr)
795 return -EINVAL;
796 }
797 break;
798
799 case VIDIOC_G_CTRL:
800 {
801 struct v4l2_control *c = arg;
802
803 STK_DEBUG("GET CTRL id=%d\n", c->id);
804
805 switch (c->id) {
807 c->value = dev->vsettings.brightness;
808 break;
809
811 c->value = dev->vsettings.whiteness;
812 break;
813
814 case V4L2_CID_HUE:
815 c->value = dev->vsettings.hue;
816 break;
817
819 c->value = dev->vsettings.colour;
820 break;
821
823 c->value = dev->vsettings.contrast;
824 break;
825
826 case V4L2_CID_HFLIP:
827 c->value = dev->vsettings.hflip;
828 break;
829
830 case V4L2_CID_VFLIP:
831 c->value = dev->vsettings.vflip;
832 break;
833
834
835 default:
836 return -EINVAL;
837 }
838 }
839 break;
840
841 case VIDIOC_S_CTRL:
842 {
843 struct v4l2_control *c = arg;
844
845 STK_DEBUG("SET CTRL id=%d value=%d\n", c->id, c->value);
846
847 switch (c->id) {
849 dev->vsettings.brightness = (0xff00 & c->value);
850 break;
851
852 case V4L2_CID_HUE:
853 dev->vsettings.hue = (0xff00 & c->value);
854 break;
855
857 dev->vsettings.colour = (0xff00 & c->value);
858 break;
859
861 dev->vsettings.contrast = (0xff00 & c->value);
862 break;
863
864 case V4L2_CID_HFLIP:
865 dev->vsettings.hflip = c->value ? 1: 0;
866 break;
867
868 case V4L2_CID_VFLIP:
869 dev->vsettings.vflip = c->value ? 1: 0;
870 break;
871
872 default:
873 return -EINVAL;
874 }
875
877 }
878 break;
879
880 case VIDIOC_ENUM_FMT:
881 {
882 int index;
883 struct v4l2_fmtdesc *fmtd = arg;
884
885 STK_DEBUG("VIDIOC_ENUM_FMT %d\n", fmtd->index);
886
887 index = fmtd->index;
888
889 memset(fmtd, 0, sizeof(*fmtd));
890
892 fmtd->index = index;
893
894 switch (index) {
895 case 0:
896 fmtd->flags = 0;
897 fmtd->pixelformat = V4L2_PIX_FMT_RGB24;
898
899 strcpy(fmtd->description, "rgb24");
900 break;
901
902 case 1:
903 fmtd->flags = 0;
904 fmtd->pixelformat = V4L2_PIX_FMT_RGB32;
905
906 strcpy(fmtd->description, "rgb32");
907 break;
908
909 case 2:
910 fmtd->flags = 0;
911 fmtd->pixelformat = V4L2_PIX_FMT_BGR24;
912
913 strcpy(fmtd->description, "bgr24");
914 break;
915
916 case 3:
917 fmtd->flags = 0;
918 fmtd->pixelformat = V4L2_PIX_FMT_BGR32;
919
920 strcpy(fmtd->description, "bgr32");
921 break;
922
923 case 4:
924 fmtd->flags = 0;
925 fmtd->pixelformat = V4L2_PIX_FMT_UYVY;
926
927 strcpy(fmtd->description, "uyvy");
928 break;
929
930 case 5:
931 fmtd->flags = 0;
932 fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
933
934 strcpy(fmtd->description, "yuyv");
935 break;
936
937 default:
938 return -EINVAL;
939 }
940 }
941 break;
942
943 case VIDIOC_G_FMT:
944 {
945 struct v4l2_format *fmtd = arg;
947
948 STK_DEBUG("GET FMT %d\n", fmtd->type);
949
951 return -EINVAL;
952
953 pix_format.width = dev->view.x;
954 pix_format.height = dev->view.y;
956 pix_format.colorspace = V4L2_COLORSPACE_SRGB;
957 pix_format.priv = 0;
958
959 switch (dev->vsettings.palette) {
960 case STK11XX_PALETTE_RGB24:
961 pix_format.pixelformat = V4L2_PIX_FMT_RGB24;
962 pix_format.sizeimage = pix_format.width * pix_format.height * 3;
963 pix_format.bytesperline = 3 * pix_format.width;
964 break;
965
966 case STK11XX_PALETTE_RGB32:
967 pix_format.pixelformat = V4L2_PIX_FMT_RGB32;
968 pix_format.sizeimage = pix_format.width * pix_format.height * 4;
969 pix_format.bytesperline = 4 * pix_format.width;
970 break;
971
972 case STK11XX_PALETTE_BGR24:
973 pix_format.pixelformat = V4L2_PIX_FMT_BGR24;
974 pix_format.sizeimage = pix_format.width * pix_format.height * 3;
975 pix_format.bytesperline = 3 * pix_format.width;
976 break;
977
978 case STK11XX_PALETTE_BGR32:
979 pix_format.pixelformat = V4L2_PIX_FMT_BGR32;
980 pix_format.sizeimage = pix_format.width * pix_format.height * 4;
981 pix_format.bytesperline = 4 * pix_format.width;
982 break;
983
984 case STK11XX_PALETTE_UYVY:
985 pix_format.pixelformat = V4L2_PIX_FMT_UYVY;
986 pix_format.sizeimage = pix_format.width * pix_format.height * 2;
987 pix_format.bytesperline = 2 * pix_format.width;
988 break;
989
990 case STK11XX_PALETTE_YUYV:
991 pix_format.pixelformat = V4L2_PIX_FMT_YUYV;
992 pix_format.sizeimage = pix_format.width * pix_format.height * 2;
993 pix_format.bytesperline = 2 * pix_format.width;
994 break;
995
996 default:
997 pix_format.pixelformat = 0;
998 pix_format.sizeimage = 0;
999 pix_format.bytesperline = 0;
1000 }
1001
1002 memcpy(&(fmtd->fmt.pix), &pix_format, sizeof(pix_format));
1003 }
1004 break;
1005
1006 case VIDIOC_TRY_FMT:
1007 {
1008 struct v4l2_format *fmtd = arg;
1009
1010 STK_DEBUG("TRY FMT %d\n", fmtd->type);
1011
1012 if (fmtd->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1013 return -EINVAL;
1014
1015 switch (dev->webcam_type) {
1016 case STK11XX_SXGA:
1017 if (fmtd->fmt.pix.width > stk11xx_image_sizes[STK11XX_1280x1024].x)
1018 fmtd->fmt.pix.width = stk11xx_image_sizes[STK11XX_1280x1024].x;
1019 else if (fmtd->fmt.pix.width < stk11xx_image_sizes[0].x)
1020 fmtd->fmt.pix.width = stk11xx_image_sizes[0].x;
1021
1022 if (fmtd->fmt.pix.height > stk11xx_image_sizes[STK11XX_1280x1024].y)
1023 fmtd->fmt.pix.height = stk11xx_image_sizes[STK11XX_1280x1024].y;
1024 else if (fmtd->fmt.pix.height < stk11xx_image_sizes[0].y)
1025 fmtd->fmt.pix.height = stk11xx_image_sizes[0].y;
1026 break;
1027
1028 case STK11XX_PAL:
1029 if (fmtd->fmt.pix.width > stk11xx_image_sizes[STK11XX_720x576].x)
1030 fmtd->fmt.pix.width = stk11xx_image_sizes[STK11XX_720x576].x;
1031 else if (fmtd->fmt.pix.width < stk11xx_image_sizes[0].x)
1032 fmtd->fmt.pix.width = stk11xx_image_sizes[0].x;
1033
1034 if (fmtd->fmt.pix.height > stk11xx_image_sizes[STK11XX_720x576].y)
1035 fmtd->fmt.pix.height = stk11xx_image_sizes[STK11XX_720x576].y;
1036 else if (fmtd->fmt.pix.height < stk11xx_image_sizes[0].y)
1037 fmtd->fmt.pix.height = stk11xx_image_sizes[0].y;
1038 break;
1039
1040 case STK11XX_VGA:
1041 if (fmtd->fmt.pix.width > stk11xx_image_sizes[STK11XX_640x480].x)
1042 fmtd->fmt.pix.width = stk11xx_image_sizes[STK11XX_640x480].x;
1043 else if (fmtd->fmt.pix.width < stk11xx_image_sizes[0].x)
1044 fmtd->fmt.pix.width = stk11xx_image_sizes[0].x;
1045
1046 if (fmtd->fmt.pix.height > stk11xx_image_sizes[STK11XX_640x480].y)
1047 fmtd->fmt.pix.height = stk11xx_image_sizes[STK11XX_640x480].y;
1048 else if (fmtd->fmt.pix.height < stk11xx_image_sizes[0].y)
1049 fmtd->fmt.pix.height = stk11xx_image_sizes[0].y;
1050 break;
1051 }
1052
1053
1054 fmtd->fmt.pix.field = V4L2_FIELD_NONE;
1055 fmtd->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
1056 fmtd->fmt.pix.priv = 0;
1057
1058 switch (fmtd->fmt.pix.pixelformat) {
1059 case V4L2_PIX_FMT_RGB24:
1060 case V4L2_PIX_FMT_BGR24:
1061 dev->vsettings.depth = 24;
1062 fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 3;
1063 fmtd->fmt.pix.bytesperline = 3 * fmtd->fmt.pix.width;
1064 break;
1065
1066 case V4L2_PIX_FMT_RGB32:
1067 case V4L2_PIX_FMT_BGR32:
1068 dev->vsettings.depth = 32;
1069 fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 4;
1070 fmtd->fmt.pix.bytesperline = 4 * fmtd->fmt.pix.width;
1071 break;
1072
1073 case V4L2_PIX_FMT_UYVY:
1074 case V4L2_PIX_FMT_YUYV:
1075 dev->vsettings.depth = 16;
1076 fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 2;
1077 fmtd->fmt.pix.bytesperline = 2 * fmtd->fmt.pix.width;
1078 break;
1079
1080 default:
1081 return -EINVAL;
1082 }
1083 }
1084 break;
1085
1086 case VIDIOC_S_FMT:
1087 {
1088 struct v4l2_format *fmtd = arg;
1089
1090 STK_DEBUG("SET FMT %d : %d\n", fmtd->type, fmtd->fmt.pix.pixelformat);
1091
1092 if (fmtd->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1093 return -EINVAL;
1094
1095 fmtd->fmt.pix.field = V4L2_FIELD_NONE;
1096 fmtd->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
1097 fmtd->fmt.pix.priv = 0;
1098
1099 switch (fmtd->fmt.pix.pixelformat) {
1100 case V4L2_PIX_FMT_RGB24:
1101 dev->vsettings.depth = 24;
1102 dev->vsettings.palette = STK11XX_PALETTE_RGB24;
1103 fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 3;
1104 fmtd->fmt.pix.bytesperline = 3 * fmtd->fmt.pix.width;
1105 break;
1106
1107 case V4L2_PIX_FMT_RGB32:
1108 dev->vsettings.depth = 32;
1109 dev->vsettings.palette = STK11XX_PALETTE_RGB32;
1110 fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 4;
1111 fmtd->fmt.pix.bytesperline = 4 * fmtd->fmt.pix.width;
1112 break;
1113
1114 case V4L2_PIX_FMT_BGR24:
1115 dev->vsettings.depth = 24;
1116 dev->vsettings.palette = STK11XX_PALETTE_BGR24;
1117 fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 3;
1118 fmtd->fmt.pix.bytesperline = 3 * fmtd->fmt.pix.width;
1119 break;
1120
1121 case V4L2_PIX_FMT_BGR32:
1122 dev->vsettings.depth = 32;
1123 dev->vsettings.palette = STK11XX_PALETTE_BGR32;
1124 fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 4;
1125 fmtd->fmt.pix.bytesperline = 4 * fmtd->fmt.pix.width;
1126 break;
1127
1128 case V4L2_PIX_FMT_UYVY:
1129 dev->vsettings.depth = 16;
1130 dev->vsettings.palette = STK11XX_PALETTE_UYVY;
1131 fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 2;
1132 fmtd->fmt.pix.bytesperline = 2 * fmtd->fmt.pix.width;
1133 break;
1134
1135 case V4L2_PIX_FMT_YUYV:
1136 dev->vsettings.depth = 16;
1137 dev->vsettings.palette = STK11XX_PALETTE_YUYV;
1138 fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.width * fmtd->fmt.pix.height * 2;
1139 fmtd->fmt.pix.bytesperline = 2 * fmtd->fmt.pix.width;
1140 break;
1141
1142 default:
1143 return -EINVAL;
1144 }
1145
1146 STK_DEBUG("Set width=%d, height=%d\n", fmtd->fmt.pix.width, fmtd->fmt.pix.height);
1147
1148 // Stop the video stream
1150
1151 // ISOC and URB cleanup
1153
1154 // Switch off the camera
1156
1158
1159 // Select the new video mode
1160 if (v4l_stk11xx_select_video_mode(dev, fmtd->fmt.pix.width, fmtd->fmt.pix.height)) {
1161 STK_ERROR("Select video mode failed !\n");
1162 return -EAGAIN;
1163 }
1164
1165 // Clear the buffers
1167
1168 // Initialize the device
1172
1173 // ISOC and URB init
1175
1176 // Re-start the stream
1178
1179 // Video settings
1181 }
1182 break;
1183
1184 case VIDIOC_QUERYSTD:
1185 {
1186 STK_DEBUG("QUERY STD\n");
1187 return -EINVAL;
1188 }
1189 break;
1190
1191 case VIDIOC_G_STD:
1192 {
1193 v4l2_std_id *std = arg;
1194
1195 STK_DEBUG("GET STD\n");
1196
1198 }
1199 break;
1200
1201 case VIDIOC_S_STD:
1202 {
1203 v4l2_std_id *std = arg;
1204
1205 STK_DEBUG("SET STD\n");
1206
1207 if (*std != V4L2_STD_UNKNOWN)
1208 return -EINVAL;
1209 }
1210 break;
1211
1212 case VIDIOC_ENUMSTD:
1213 {
1214 struct v4l2_standard *std = arg;
1215
1216 STK_DEBUG("VIDIOC_ENUMSTD\n");
1217
1218 if (std->index != 0)
1219 return -EINVAL;
1220
1221 std->id = V4L2_STD_UNKNOWN;
1222 strncpy(std->name, "webcam", sizeof(std->name));
1223
1224 break;
1225 }
1226
1227 case VIDIOC_REQBUFS:
1228 {
1229 int nbuffers;
1230 struct v4l2_requestbuffers *rb = arg;
1231
1232 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1233 return -EINVAL;
1234
1235 if (rb->memory != V4L2_MEMORY_MMAP)
1236 return -EINVAL;
1237
1238 nbuffers = rb->count;
1239
1240 if (nbuffers < 2)
1241 nbuffers = 2;
1242 else if (nbuffers > dev->nbuffers)
1243 nbuffers = dev->nbuffers;
1244
1245 rb->count = dev->nbuffers;
1246 }
1247 break;
1248
1249 case VIDIOC_QUERYBUF:
1250 {
1251 int index;
1252 struct v4l2_buffer *buf = arg;
1253
1254 STK_DEBUG("QUERY BUFFERS %d %d\n", buf->index, dev->nbuffers);
1255
1256 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1257 return -EINVAL;
1258
1259 if (buf->memory != V4L2_MEMORY_MMAP)
1260 return -EINVAL;
1261
1262 index = buf->index;
1263
1264 if (index < 0 || index >= dev->nbuffers)
1265 return -EINVAL;
1266
1267 memset(buf, 0, sizeof(struct v4l2_buffer));
1268
1270 buf->index = index;
1271 buf->m.offset = index * dev->len_per_image;
1272 buf->bytesused = dev->view_size;
1273 buf->field = V4L2_FIELD_NONE;
1274 buf->memory = V4L2_MEMORY_MMAP;
1275 buf->length = dev->len_per_image;
1276 }
1277 break;
1278
1279 case VIDIOC_QBUF:
1280 {
1281 struct v4l2_buffer *buf = arg;
1282
1283 STK_DEBUG("VIDIOC_QBUF\n");
1284
1285 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1286 return -EINVAL;
1287
1288 if (buf->memory != V4L2_MEMORY_MMAP)
1289 return -EINVAL;
1290
1291 if (buf->index < 0 || buf->index >= dev->nbuffers)
1292 return -EINVAL;
1293
1294 buf->flags |= V4L2_BUF_FLAG_QUEUED;
1295 buf->flags &= ~V4L2_BUF_FLAG_DONE;
1296 }
1297 break;
1298
1299 case VIDIOC_DQBUF:
1300 {
1301 int ret;
1302 struct v4l2_buffer *buf = arg;
1303
1304 STK_DEBUG("VIDIOC_DQBUF\n");
1305
1306 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1307 return -EINVAL;
1308
1309 add_wait_queue(&dev->wait_frame, &wait);
1310
1311 while (dev->full_frames == NULL) {
1312 if (dev->error_status) {
1313 remove_wait_queue(&dev->wait_frame, &wait);
1315
1316 return -dev->error_status;
1317 }
1318
1319 if (signal_pending(current)) {
1320 remove_wait_queue(&dev->wait_frame, &wait);
1322
1323 return -ERESTARTSYS;
1324 }
1325
1326 schedule();
1328 }
1329
1330 remove_wait_queue(&dev->wait_frame, &wait);
1332
1333 STK_DEBUG("VIDIOC_DQBUF : frame ready.\n");
1334
1336
1337 if (ret)
1338 return -EFAULT;
1339
1340 buf->index = dev->fill_image;
1341 buf->bytesused = dev->view_size;
1342 buf->flags = V4L2_BUF_FLAG_MAPPED;
1343 buf->field = V4L2_FIELD_NONE;
1344 do_gettimeofday(&buf->timestamp);
1345 buf->sequence = 0;
1346 buf->memory = V4L2_MEMORY_MMAP;
1347 buf->m.offset = dev->fill_image * dev->len_per_image;
1348 buf->length = dev->len_per_image; //buf->bytesused;
1349
1351 }
1352 break;
1353
1354 case VIDIOC_STREAMON:
1355 {
1356 STK_DEBUG("VIDIOC_STREAMON\n");
1357
1359 }
1360 break;
1361
1362 case VIDIOC_STREAMOFF:
1363 {
1364 STK_DEBUG("VIDIOC_STREAMOFF\n");
1365
1367 }
1368 break;
1369
1370 case VIDIOC_G_PARM:
1371 {
1372 struct v4l2_streamparm *sp = arg;
1373
1374 STK_DEBUG("GET PARM %d\n", sp->type);
1375
1376 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1377 return -EINVAL;
1378
1379 sp->parm.capture.capability = 0;
1380 sp->parm.capture.capturemode = 0;
1381 sp->parm.capture.timeperframe.numerator = 1;
1382 sp->parm.capture.timeperframe.denominator = 30;
1383 sp->parm.capture.readbuffers = 2;
1384 sp->parm.capture.extendedmode = 0;
1385 }
1386 break;
1387
1388
1389 case VIDIOC_G_AUDIO:
1390 STK_DEBUG("GET AUDIO\n");
1391 return -EINVAL;
1392 break;
1393
1394 case VIDIOC_S_AUDIO:
1395 STK_DEBUG("SET AUDIO\n");
1396 return -EINVAL;
1397 break;
1398
1399 case VIDIOC_S_TUNER:
1400 STK_DEBUG("SET TUNER\n");
1401 return -EINVAL;
1402 break;
1403
1404 case VIDIOC_G_FBUF:
1405 case VIDIOC_S_FBUF:
1406 case VIDIOC_OVERLAY:
1407 return -EINVAL;
1408 break;
1409
1410 case VIDIOC_G_TUNER:
1411 case VIDIOC_G_FREQUENCY:
1412 case VIDIOC_S_FREQUENCY:
1413 return -EINVAL;
1414 break;
1415
1416 case VIDIOC_QUERYMENU:
1417 return -EINVAL;
1418 break;
1419/*
1420 case VIDIOC_CROPCAP:
1421 {
1422 struct v4l2_cropcap cc;
1423
1424 cc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1425 cc.pixelaspect.numerator = 1;
1426 cc.pixelaspect.denominator = 1;
1427 cc.bounds.top = 0;
1428 cc.bounds.left = 0;
1429 cc.bounds.width = 640;
1430 cc.bounds.height = 480;
1431 cc.defrect.top = 0;
1432 cc.defrect.left = 0;
1433 cc.defrect.width = 640;
1434 cc.defrect.height = 480;
1435
1436 memcpy(arg, &cc, sizeof(cc));
1437 }
1438 break;
1439*/
1440 default:
1441 STK_DEBUG("IOCTL unknown !\n");
1442 return -ENOIOCTLCMD;
1443 }
1444
1445 return 0;
1446}
1447
1448
1460static long v4l_stk11xx_ioctl(struct file *fp,
1461 unsigned int cmd, unsigned long arg)
1462{
1463 long err;
1464 struct usb_stk11xx *dev;
1465 struct video_device *vdev;
1466
1467 vdev = video_devdata(fp);
1469
1470 STK_DEBUG("v4l_stk11xx_ioctl %02X\n", (unsigned char) cmd);
1471
1472 if (dev == NULL)
1473 return -EFAULT;
1474
1475 if (vdev == NULL)
1476 return -EFAULT;
1477
1478 mutex_lock(&dev->modlock);
1479
1481
1482 mutex_unlock(&dev->modlock);
1483
1484 return err;
1485}
1486
1487
1498{
1499 int err;
1500
1501 strcpy(dev->vdev->name, DRIVER_DESC);
1502
1503 dev->vdev->parent = &dev->interface->dev;
1504 dev->vdev->fops = &v4l_stk11xx_fops;
1505 dev->vdev->release = video_device_release;
1506 dev->vdev->minor = -1;
1507
1508 video_set_drvdata(dev->vdev, dev);
1509
1511
1512 if (err)
1513 STK_ERROR("Video register fail !\n");
1514 else
1515 STK_INFO("Syntek USB2.0 Camera is now controlling video device /dev/video%d\n", dev->vdev->minor);
1516
1517 return err;
1518}
1519
1520
1531{
1532 STK_INFO("Syntek USB2.0 Camera release resources video device /dev/video%d\n", dev->vdev->minor);
1533
1534 video_set_drvdata(dev->vdev, NULL);
1536
1537 return 0;
1538}
1539
1540
1546static struct v4l2_file_operations v4l_stk11xx_fops = {
1547 .owner = THIS_MODULE,
1548 .open = v4l_stk11xx_open,
1549 .release = v4l_stk11xx_release,
1550 .read = v4l_stk11xx_read,
1551 .poll = v4l_stk11xx_poll,
1552 .mmap = v4l_stk11xx_mmap,
1553 .ioctl = v4l_stk11xx_ioctl,
1554#if defined(CONFIG_COMPAT) && defined(v4l_compat_ioctl32)
1555 .compat_ioctl = v4l_compat_ioctl32,
1556#endif
1557};
1558
int stk11xx_reset_buffers(struct usb_stk11xx *dev)
Reset all ISOC buffers.
int stk11xx_handle_frame(struct usb_stk11xx *dev)
Handler frame.
int stk11xx_free_buffers(struct usb_stk11xx *dev)
Release all buffers.
void stk11xx_next_image(struct usb_stk11xx *dev)
Prepare the next image.
int stk11xx_allocate_buffers(struct usb_stk11xx *dev)
Allocate all ISOC buffers.
int stk11xx_clear_buffers(struct usb_stk11xx *dev)
Clear current buffers.
int dev_stk11xx_camera_asleep(struct usb_stk11xx *dev)
Wake-up the camera.
int dev_stk11xx_reconf_camera(struct usb_stk11xx *dev)
Reconfigure the camera before the stream.
int dev_stk11xx_camera_off(struct usb_stk11xx *dev)
This function switchs off the camera.
int dev_stk11xx_stop_stream(struct usb_stk11xx *dev)
This function sets the device to stop the stream.
int dev_stk11xx_camera_settings(struct usb_stk11xx *dev)
This function permits to modify the settings of the camera.
int dev_stk11xx_start_stream(struct usb_stk11xx *dev)
This function sets the device to start the stream.
int dev_stk11xx_init_camera(struct usb_stk11xx *dev)
This function initializes the device for the stream.
int dev_stk11xx_camera_on(struct usb_stk11xx *dev)
This function switchs on the camera.
static int fps
void usb_stk11xx_isoc_cleanup(struct usb_stk11xx *dev)
Clean-up all the ISOC buffers.
int usb_stk11xx_isoc_init(struct usb_stk11xx *dev)
Initilize an isochronous pipe.
static struct v4l2_file_operations v4l_stk11xx_fops
Definition stk11xx-v4l.c:52
static unsigned int v4l_stk11xx_poll(struct file *fp, poll_table *wait)
Polling function.
static int v4l_stk11xx_mmap(struct file *fp, struct vm_area_struct *vma)
Memory map.
static struct v4l2_queryctrl stk11xx_controls[]
Definition stk11xx-v4l.c:78
int v4l_stk11xx_register_video_device(struct usb_stk11xx *dev)
Register the video device.
int v4l_stk11xx_select_video_mode(struct usb_stk11xx *dev, int width, int height)
Select a video mode.
int v4l_stk11xx_unregister_video_device(struct usb_stk11xx *dev)
Unregister the video device.
const struct stk11xx_coord stk11xx_image_sizes[STK11XX_NBR_SIZES]
Definition stk11xx-v4l.c:59
static int v4l_stk11xx_open(struct file *fp)
Open the video device.
static long v4l_stk11xx_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
Manage IOCTL.
static long v4l_stk11xx_do_ioctl(struct file *fp, unsigned int cmd, void __user *arg)
Manage IOCTL.
static int v4l_stk11xx_release(struct file *fp)
Release an opened file.
static ssize_t v4l_stk11xx_read(struct file *fp, char __user *buf, size_t count, loff_t *f_pos)
Read the video device.
Driver for Syntek USB video camera.
#define STK_ERROR(str, args...)
Definition stk11xx.h:156
@ STK11XX_SXGA
Definition stk11xx.h:210
@ STK11XX_VGA
Definition stk11xx.h:209
@ STK11XX_PAL
Definition stk11xx.h:211
#define STK_INFO(str, args...)
Definition stk11xx.h:155
#define STK_STREAM(str, args...)
Definition stk11xx.h:181
#define STK_DEBUG(str, args...)
Definition stk11xx.h:158
#define DRIVER_DESC
Definition stk11xx.h:41
#define STK11XX_MAX_IMAGES
Definition stk11xx.h:105
#define DRIVER_VERSION_NUM
Definition stk11xx.h:39