3 * @author Nicolas VIVIEN
6 * @brief V4L2 interface and functions
8 * @note Copyright (C) Nicolas VIVIEN
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include <linux/module.h>
28 #include <linux/init.h>
29 #include <linux/kernel.h>
30 #include <linux/version.h>
31 #include <linux/errno.h>
32 #include <linux/slab.h>
33 #include <linux/kref.h>
34 #include <linux/vmalloc.h>
35 #include <linux/usb.h>
37 #include <media/v4l2-common.h>
44 /* USER DEFINED V4L2-CONTROLS: */
45 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
46 #define V4L2_CID_AUTOEXPOSURE (V4L2_CID_PRIVATE_BASE + 0)
48 #define V4L2_CID_SHARPNESS (V4L2_CID_PRIVATE_BASE + 0)
49 #define V4L2_CID_AUTOEXPOSURE (V4L2_CID_PRIVATE_BASE + 1)
52 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
53 #include <media/v4l2-ioctl.h>
56 static struct file_operations v4l_microdia_fops
;
62 #define NUM_V4L2_FORMATS 4
64 struct v4l2_pix_format microdia_fmts
[] = {
68 .pixelformat
= V4L2_PIX_FMT_YUV420
,
69 .field
= V4L2_FIELD_NONE
,
72 .colorspace
= V4L2_COLORSPACE_SRGB
,
78 .pixelformat
= V4L2_PIX_FMT_BGR24
,
79 .field
= V4L2_FIELD_NONE
,
82 .colorspace
= V4L2_COLORSPACE_SRGB
,
88 .pixelformat
= V4L2_PIX_FMT_RGB24
,
89 .field
= V4L2_FIELD_NONE
,
92 .colorspace
= V4L2_COLORSPACE_SRGB
,
98 .pixelformat
= V4L2_PIX_FMT_YUYV
,
99 .field
= V4L2_FIELD_NONE
,
100 .bytesperline
= 1280,
102 .colorspace
= V4L2_COLORSPACE_SRGB
,
109 * @param fmt v4l2 fmt id
111 * @returns index of requested format
113 * @brief check if v4l2 forat is supported by device.
115 * This function permits to check if v4l2 format is supported.
117 int v4l2_format_supported(struct usb_microdia
*dev
, __u32 fmt
)
120 for (i
= 0; i
< sizeof(dev
->supported_fmts
) * 8; i
++) {
121 if (i
> (ARRAY_SIZE(microdia_fmts
) - 1))
123 if (dev
->supported_fmts
& (1 << i
) &&
124 microdia_fmts
[i
].pixelformat
== fmt
)
132 * @param index format index
134 * @returns reference to format structure
136 * @brief enumerate supported formats
138 * This function will enumerate all supported formats.
140 struct v4l2_pix_format
*v4l2_enum_supported_formats(struct usb_microdia
*dev
,
144 for (i
= 0; i
< sizeof(dev
->supported_fmts
) * 8; i
++) {
145 if (i
> (ARRAY_SIZE(microdia_fmts
) - 1))
147 if (dev
->supported_fmts
& (1 << i
)) {
149 return µdia_fmts
[i
];
157 * @var microdia_controls
158 * List of all V4Lv2 controls supported by the driver
160 static struct v4l2_queryctrl microdia_controls
[] = {
162 .id
= V4L2_CID_BRIGHTNESS
,
163 .type
= V4L2_CTRL_TYPE_INTEGER
,
164 .name
= "Brightness",
168 .default_value
= 0x7f00,
171 .id
= V4L2_CID_WHITENESS
,
172 .type
= V4L2_CTRL_TYPE_INTEGER
,
177 .default_value
= 0x7f00,
181 .id = V4L2_CID_SATURATION,
182 .type = V4L2_CTRL_TYPE_INTEGER,
183 .name = "Saturation",
187 .default_value = 0x7f00,
191 .id
= V4L2_CID_CONTRAST
,
192 .type
= V4L2_CTRL_TYPE_INTEGER
,
197 .default_value
= 0x0000,
200 .id
= V4L2_CID_EXPOSURE
,
201 .type
= V4L2_CTRL_TYPE_INTEGER
,
206 .default_value
= 0x1000,
209 .id
= V4L2_CID_HFLIP
,
210 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
211 .name
= "Horizontal flip",
218 .id
= V4L2_CID_VFLIP
,
219 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
220 .name
= "Vertical flip",
227 .id
= V4L2_CID_SHARPNESS
,
228 .type
= V4L2_CTRL_TYPE_INTEGER
,
233 .default_value
= 0x1f,
236 .id
= V4L2_CID_RED_BALANCE
,
237 .type
= V4L2_CTRL_TYPE_INTEGER
,
238 .name
= "Red Balance",
242 .default_value
= 0x20,
245 .id
= V4L2_CID_BLUE_BALANCE
,
246 .type
= V4L2_CTRL_TYPE_INTEGER
,
247 .name
= "Blue Balance",
251 .default_value
= 0x20,
254 .id
= V4L2_CID_AUTOEXPOSURE
,
255 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
256 .name
= "Automatic exposure control",
263 .id
= V4L2_CID_AUTO_WHITE_BALANCE
,
264 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
265 .name
= "Automatic whitbalance control",
274 * @brief Get V4L privileges
278 * @return 0 or negative error code
281 int v4l_get_privileges(struct file
*file
)
283 struct usb_microdia
*dev
;
286 dev
= video_get_drvdata(video_devdata(file
));
288 if (dev
->owner
== file
)
291 mutex_lock(&open_lock
);
292 if (dev
->owner
!= NULL
) {
298 mutex_unlock(&open_lock
);
303 * @brief Check whether there are V4L privileges
310 int v4l_has_privileges(struct file
*file
)
312 struct usb_microdia
*dev
;
315 dev
= video_get_drvdata(video_devdata(file
));
317 if (dev
->owner
== file
)
324 * @brief Drop V4L privileges
329 void v4l_drop_privileges(struct file
*file
)
331 struct usb_microdia
*dev
;
333 dev
= video_get_drvdata(video_devdata(file
));
335 if (dev
->owner
== file
)
340 * @brief Enable video stream
342 * @param dev Pointer to device structure
343 * @param mode Mode for video stream
345 * @returns 0 or negative error value
348 int v4l2_enable_video(struct usb_microdia
*dev
, int mode
)
352 if (mode
== MICRODIA_MODE_IDLE
) {
353 dev_microdia_stop_stream(dev
);
354 usb_microdia_isoc_cleanup(dev
);
355 dev_microdia_camera_off(dev
);
356 microdia_queue_enable(&dev
->queue
, 0);
361 if (dev
->mode
!= MICRODIA_MODE_IDLE
)
364 if (microdia_queue_enable(&dev
->queue
, 1) < 0)
367 dev_microdia_camera_on(dev
);
368 ret
= usb_microdia_isoc_init(dev
);
373 dev_microdia_start_stream(dev
);
374 dev_microdia_camera_settings(dev
);
381 * @param inode Pointer on an inode
382 * @param fp File pointer
384 * @returns 0 if all is OK
386 * @brief Open the video device
388 * This function permits to open a video device (/dev/videoX)
390 static int v4l_microdia_open(struct inode
*inode
, struct file
*fp
)
394 struct usb_microdia
*dev
;
395 struct video_device
*vdev
;
397 mutex_lock(&open_lock
);
399 vdev
= video_devdata(fp
);
400 dev
= video_get_drvdata(video_devdata(fp
));
402 fp
->private_data
= vdev
;
404 kref_get(&dev
->vopen
);
406 mutex_unlock(&open_lock
);
412 * @param inode Pointer on inode
413 * @param fp File pointer
415 * @returns 0 if all is OK
417 * @brief Release an opened file.
419 * This function permits to release an opened file with the 'open' method.
421 static int v4l_microdia_release(struct inode
*inode
, struct file
*fp
)
423 struct usb_microdia
*dev
;
424 struct video_device
*vdev
;
426 mutex_lock(&open_lock
);
428 vdev
= video_devdata(fp
);
429 dev
= video_get_drvdata(video_devdata(fp
));
431 if (v4l_has_privileges(fp
)) {
432 v4l2_enable_video(dev
, MICRODIA_MODE_IDLE
);
434 mutex_lock(&dev
->queue
.mutex
);
435 microdia_free_buffers(&dev
->queue
);
436 mutex_unlock(&dev
->queue
.mutex
);
439 v4l_drop_privileges(fp
);
441 kref_put(&dev
->vopen
, usb_microdia_delete
);
443 mutex_unlock(&open_lock
);
449 * @param fp File pointer
451 * @retval buf Buffer in user space
455 * @returns Count value
457 * @brief Read the video device
459 * This function is called by the application is reading the video device.
461 static ssize_t
v4l_microdia_read(struct file
*fp
, char __user
*buf
,
462 size_t count
, loff_t
*f_pos
)
466 struct v4l2_buffer buffer
;
467 struct usb_microdia
*dev
;
469 dev
= video_get_drvdata(video_devdata(fp
));
471 ret
= v4l_get_privileges(fp
);
475 if (dev
->mode
!= MICRODIA_MODE_IDLE
&&
476 dev
->mode
!= MICRODIA_MODE_READ
)
479 buffer
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
480 buffer
.memory
= V4L2_MEMORY_MMAP
;
481 if (dev
->mode
== MICRODIA_MODE_IDLE
) {
482 nbuffers
= microdia_alloc_buffers(&dev
->queue
, 2,
483 MICRODIA_FRAME_SIZE
);
487 for (i
= 0; i
< nbuffers
; i
++) {
488 buffer
= dev
->queue
.buffer
[i
].buf
;
489 microdia_queue_buffer(&dev
->queue
, &buffer
);
492 ret
= v4l2_enable_video(dev
, MICRODIA_MODE_READ
);
497 if (dev
->queue
.read_buffer
== NULL
) {
498 ret
= microdia_dequeue_buffer(&dev
->queue
, &buffer
,
499 fp
->f_flags
& O_NONBLOCK
);
503 microdia_decompress(dev
, &buffer
);
504 dev
->queue
.read_buffer
= &dev
->queue
.buffer
[buffer
.index
];
506 buffer
= dev
->queue
.read_buffer
->buf
;
509 count
= min((size_t)(buffer
.bytesused
- *f_pos
), count
);
510 if (copy_to_user(buf
, dev
->queue
.mem
+ buffer
.m
.offset
+ *f_pos
, count
))
514 if (*f_pos
>= buffer
.bytesused
) {
515 dev
->queue
.read_buffer
= NULL
;
516 microdia_queue_buffer(&dev
->queue
, &buffer
);
524 * @param fp File pointer
527 * @returns 0 if all is OK
529 * @brief Polling function
531 static unsigned int v4l_microdia_poll(struct file
*fp
, poll_table
*wait
)
533 struct usb_microdia
*dev
;
534 struct video_device
*vdev
;
536 vdev
= video_devdata(fp
);
537 dev
= video_get_drvdata(video_devdata(fp
));
539 UDIA_STREAM("Poll\n");
541 if (vdev
== NULL
|| dev
== NULL
)
544 return microdia_queue_poll(&dev
->queue
, fp
, wait
);
551 static void microdia_vm_open(struct vm_area_struct
*vma
)
553 struct microdia_buffer
*buffer
= vma
->vm_private_data
;
554 buffer
->vma_use_count
++;
562 static void microdia_vm_close(struct vm_area_struct
*vma
)
564 struct microdia_buffer
*buffer
= vma
->vm_private_data
;
565 buffer
->vma_use_count
--;
568 struct vm_operations_struct microdia_vm_ops
= {
569 .open
= microdia_vm_open
,
570 .close
= microdia_vm_close
574 * @param fp File pointer
575 * @param vma VMA structure
577 * @returns 0 if all is OK
581 * This function permits to map a memory space.
583 static int v4l_microdia_mmap(struct file
*fp
, struct vm_area_struct
*vma
)
586 unsigned long addr
, start
, size
;
590 struct usb_microdia
*dev
;
591 struct video_device
*vdev
;
592 struct microdia_buffer
*buffer
= NULL
;
594 vdev
= video_devdata(fp
);
595 dev
= video_get_drvdata(video_devdata(fp
));
597 UDIA_STREAM("mmap\n");
599 start
= vma
->vm_start
;
600 size
= vma
->vm_end
- vma
->vm_start
;
602 mutex_lock(&dev
->queue
.mutex
);
604 for (i
= 0; i
< dev
->queue
.count
; ++i
) {
605 buffer
= &dev
->queue
.buffer
[i
];
606 if ((buffer
->buf
.m
.offset
>> PAGE_SHIFT
) == vma
->vm_pgoff
)
610 if (i
== dev
->queue
.count
|| size
!= dev
->queue
.buf_size
) {
615 vma
->vm_flags
|= VM_IO
;
617 addr
= (unsigned long)dev
->queue
.mem
+ buffer
->buf
.m
.offset
;
619 page
= vmalloc_to_page((void *)addr
);
620 ret
= vm_insert_page(vma
, start
, page
);
629 vma
->vm_ops
= µdia_vm_ops
;
630 vma
->vm_private_data
= buffer
;
631 microdia_vm_open(vma
);
633 mutex_unlock(&dev
->queue
.mutex
);
645 int microdia_vidioc_querycap(struct file
*file
, void *priv
,
646 struct v4l2_capability
*cap
)
648 struct usb_microdia
*dev
;
650 dev
= video_get_drvdata(priv
);
652 UDIA_DEBUG("VIDIOC_QUERYCAP\n");
654 strlcpy(cap
->driver
, "microdia", sizeof(cap
->driver
));
655 cap
->capabilities
= V4L2_CAP_VIDEO_CAPTURE
| V4L2_CAP_STREAMING
656 | V4L2_CAP_READWRITE
;
657 cap
->version
= (__u32
) DRIVER_VERSION_NUM
,
658 strlcpy(cap
->card
, dev
->vdev
->name
, sizeof(cap
->card
));
660 if (usb_make_path(dev
->udev
, cap
->bus_info
, sizeof(cap
->bus_info
)) < 0)
661 strlcpy(cap
->bus_info
, dev
->vdev
->name
, sizeof(cap
->bus_info
));
670 * @return 0 or negative error code
673 int microdia_vidioc_enum_input(struct file
*file
, void *priv
,
674 struct v4l2_input
*input
)
676 UDIA_DEBUG("VIDIOC_ENUMINPUT %d\n", input
->index
);
681 strlcpy(input
->name
, "Webcam", sizeof(input
->name
));
682 input
->type
= V4L2_INPUT_TYPE_CAMERA
;
693 * @return 0 or negative error code
696 int microdia_vidioc_g_input(struct file
*file
, void *priv
, unsigned int *index
)
698 UDIA_DEBUG("GET INPUT %d\n", *index
);
711 * @return 0 or negative error code
714 int microdia_vidioc_s_input(struct file
*file
, void *priv
, unsigned int index
)
716 UDIA_DEBUG("SET INPUT %d\n", index
);
718 if (v4l_get_privileges(file
) < 0)
732 * @return 0 or negative error code
735 int microdia_vidioc_queryctrl(struct file
*file
, void *priv
,
736 struct v4l2_queryctrl
*ctrl
)
741 UDIA_DEBUG("VIDIOC_QUERYCTRL id = %d\n", ctrl
->id
);
743 nbr
= sizeof(microdia_controls
)/sizeof(struct v4l2_queryctrl
);
745 for (i
= 0; i
< nbr
; i
++) {
746 if (microdia_controls
[i
].id
== ctrl
->id
) {
747 UDIA_DEBUG("VIDIOC_QUERYCTRL found\n");
748 memcpy(ctrl
, µdia_controls
[i
],
749 sizeof(struct v4l2_queryctrl
));
765 * @return 0 or negative error code
768 int microdia_vidioc_g_ctrl(struct file
*file
, void *priv
,
769 struct v4l2_control
*ctrl
)
771 struct usb_microdia
*dev
;
773 dev
= video_get_drvdata(priv
);
775 UDIA_DEBUG("GET CTRL id=%d\n", ctrl
->id
);
778 case V4L2_CID_BRIGHTNESS
:
779 ctrl
->value
= dev
->vsettings
.brightness
;
782 case V4L2_CID_EXPOSURE
:
783 ctrl
->value
= dev
->vsettings
.exposure
;
786 case V4L2_CID_WHITENESS
:
787 ctrl
->value
= dev
->vsettings
.whiteness
;
790 case V4L2_CID_SATURATION:
791 ctrl->value = dev->vsettings.colour;
794 case V4L2_CID_CONTRAST
:
795 ctrl
->value
= dev
->vsettings
.contrast
;
799 ctrl
->value
= dev
->vsettings
.hflip
;
803 ctrl
->value
= dev
->vsettings
.vflip
;
806 case V4L2_CID_SHARPNESS
:
807 ctrl
->value
= dev
->vsettings
.sharpness
;
810 case V4L2_CID_RED_BALANCE
:
811 ctrl
->value
= dev
->vsettings
.rgb_gain
[0];
814 case V4L2_CID_BLUE_BALANCE
:
815 ctrl
->value
= dev
->vsettings
.rgb_gain
[3];
818 case V4L2_CID_AUTOEXPOSURE
:
819 ctrl
->value
= dev
->vsettings
.auto_exposure
;
822 case V4L2_CID_AUTO_WHITE_BALANCE
:
823 ctrl
->value
= dev
->vsettings
.auto_whitebalance
;
833 * @brief Apply v4l2 settings on camera
837 * @param ctrl V4L2 control structure
839 * @returns 0 or negative error value
842 int microdia_vidioc_s_ctrl(struct file
*file
, void *priv
,
843 struct v4l2_control
*ctrl
)
845 struct usb_microdia
*dev
;
847 dev
= video_get_drvdata(priv
);
849 UDIA_DEBUG("SET CTRL id=%d value=%d\n", ctrl
->id
, ctrl
->value
);
852 case V4L2_CID_BRIGHTNESS
:
853 dev
->vsettings
.brightness
= (0xff00 & ctrl
->value
);
854 dev_microdia_camera_set_brightness(dev
);
857 case V4L2_CID_EXPOSURE
:
858 dev
->vsettings
.exposure
= (0xff00 & ctrl
->value
);
859 dev_microdia_camera_set_exposure(dev
);
862 case V4L2_CID_WHITENESS
:
863 dev
->vsettings
.whiteness
= (0xff00 & ctrl
->value
);
864 dev_microdia_camera_set_gamma(dev
);
867 case V4L2_CID_SATURATION:
868 dev->vsettings.colour = (0xff00 & ctrl->value);
871 case V4L2_CID_CONTRAST
:
872 dev
->vsettings
.contrast
= (0xff00 & ctrl
->value
);
873 dev_microdia_camera_set_contrast(dev
);
877 dev
->vsettings
.hflip
= ctrl
->value
;
878 dev_microdia_camera_set_hvflip(dev
);
882 dev
->vsettings
.vflip
= ctrl
->value
;
883 dev_microdia_camera_set_hvflip(dev
);
886 case V4L2_CID_SHARPNESS
:
887 dev
->vsettings
.sharpness
= ctrl
->value
;
888 dev_microdia_camera_set_sharpness(dev
);
891 case V4L2_CID_RED_BALANCE
:
892 dev
->vsettings
.rgb_gain
[0] = ctrl
->value
;
893 dev_microdia_camera_set_rgb_gain(dev
);
896 case V4L2_CID_BLUE_BALANCE
:
897 dev
->vsettings
.rgb_gain
[3] = ctrl
->value
;
898 dev_microdia_camera_set_rgb_gain(dev
);
901 case V4L2_CID_AUTOEXPOSURE
:
902 dev
->vsettings
.auto_exposure
= ctrl
->value
;
903 dev_microdia_camera_set_auto_exposure(dev
);
906 case V4L2_CID_AUTO_WHITE_BALANCE
:
907 dev
->vsettings
.auto_whitebalance
= ctrl
->value
;
908 dev_microdia_camera_set_auto_whitebalance(dev
);
923 * @return 0 or negative error code
926 int microdia_vidioc_enum_fmt_cap(struct file
*file
, void *priv
,
927 struct v4l2_fmtdesc
*fmt
)
929 struct usb_microdia
*dev
;
930 struct v4l2_pix_format
*format
;
932 dev
= video_get_drvdata(priv
);
934 UDIA_DEBUG("VIDIOC_ENUM_FMT %d\n", fmt
->index
);
936 format
= v4l2_enum_supported_formats(dev
, fmt
->index
);
941 fmt
->pixelformat
= format
->pixelformat
;
942 fmt
->description
[0] = fmt
->pixelformat
& 0xFF;
943 fmt
->description
[1] = (fmt
->pixelformat
>> 8) & 0xFF;
944 fmt
->description
[2] = (fmt
->pixelformat
>> 16) & 0xFF;
945 fmt
->description
[3] = fmt
->pixelformat
>> 24;
946 fmt
->description
[4] = 0;
956 * @return 0 or negative error code
959 int microdia_vidioc_try_fmt_cap(struct file
*file
, void *priv
,
960 struct v4l2_format
*fmt
)
962 struct usb_microdia
*dev
;
964 dev
= video_get_drvdata(priv
);
965 UDIA_DEBUG("TRY FMT %d\n", fmt
->type
);
967 /* when this code is used prevents mplayer from setting outfmt
968 if(fmt->fmt.pix.field != V4L2_FIELD_NONE)
972 if (v4l2_format_supported(dev
, fmt
->fmt
.pix
.pixelformat
) < 0)
975 sn9c20x_get_closest_resolution(&fmt
->fmt
.pix
.width
,
976 &fmt
->fmt
.pix
.height
);
978 switch (fmt
->fmt
.pix
.pixelformat
) {
979 case V4L2_PIX_FMT_YUV420
:
980 fmt
->fmt
.pix
.bytesperline
= (fmt
->fmt
.pix
.width
* 3)/2;
981 fmt
->fmt
.pix
.sizeimage
= fmt
->fmt
.pix
.height
*
982 fmt
->fmt
.pix
.bytesperline
;
984 case V4L2_PIX_FMT_RGB24
:
985 case V4L2_PIX_FMT_BGR24
:
986 fmt
->fmt
.pix
.bytesperline
= fmt
->fmt
.pix
.width
* 3;
987 fmt
->fmt
.pix
.sizeimage
= fmt
->fmt
.pix
.height
*
988 fmt
->fmt
.pix
.bytesperline
;
990 case V4L2_PIX_FMT_YUYV
:
991 fmt
->fmt
.pix
.bytesperline
= fmt
->fmt
.pix
.width
* 2;
992 fmt
->fmt
.pix
.sizeimage
= fmt
->fmt
.pix
.height
*
993 fmt
->fmt
.pix
.bytesperline
;
999 fmt
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SRGB
;
1000 fmt
->fmt
.pix
.priv
= 0;
1013 int microdia_vidioc_g_fmt_cap(struct file
*file
, void *priv
,
1014 struct v4l2_format
*fmt
)
1016 struct usb_microdia
*dev
;
1018 dev
= video_get_drvdata(priv
);
1020 UDIA_DEBUG("GET FMT %d\n", fmt
->type
);
1022 memcpy(&(fmt
->fmt
.pix
), &(dev
->vsettings
.format
), sizeof(fmt
->fmt
.pix
));
1033 * @return 0 or negative error code
1036 int microdia_vidioc_s_fmt_cap(struct file
*file
, void *priv
,
1037 struct v4l2_format
*fmt
)
1039 struct usb_microdia
*dev
;
1042 dev
= video_get_drvdata(priv
);
1044 UDIA_DEBUG("SET FMT %d : %d\n", fmt
->type
, fmt
->fmt
.pix
.pixelformat
);
1046 if (v4l_get_privileges(file
) < 0)
1049 if (dev
->queue
.streaming
)
1052 ret
= microdia_vidioc_try_fmt_cap(file
, priv
, fmt
);
1056 sn9c20x_set_resolution(dev
, fmt
->fmt
.pix
.width
, fmt
->fmt
.pix
.height
);
1058 memcpy(&(dev
->vsettings
.format
), &(fmt
->fmt
.pix
), sizeof(fmt
->fmt
.pix
));
1068 * @return 0 or negative error code
1071 int microdia_vidioc_reqbufs(struct file
*file
, void *priv
,
1072 struct v4l2_requestbuffers
*request
)
1075 struct usb_microdia
*dev
;
1077 dev
= video_get_drvdata(priv
);
1079 if (v4l_get_privileges(file
) < 0) {
1084 if (request
->memory
!= V4L2_MEMORY_MMAP
||
1085 request
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
) {
1090 if (dev
->queue
.streaming
) {
1095 ret
= microdia_alloc_buffers(&dev
->queue
, request
->count
,
1096 MICRODIA_FRAME_SIZE
);
1100 dev
->queue
.drop_incomplete
= 1;
1102 request
->count
= ret
;
1104 UDIA_INFO("Buffers Allocated %d\n", request
->count
);
1114 * @return 0 or negative error code
1117 int microdia_vidioc_querybuf(struct file
*file
, void *priv
,
1118 struct v4l2_buffer
*buffer
)
1120 struct usb_microdia
*dev
;
1122 dev
= video_get_drvdata(priv
);
1124 UDIA_DEBUG("QUERY BUFFERS %d %d\n", buffer
->index
, dev
->queue
.count
);
1126 if (buffer
->memory
!= V4L2_MEMORY_MMAP
||
1127 buffer
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
1130 if (!v4l_has_privileges(file
))
1133 return microdia_query_buffer(&dev
->queue
, buffer
);
1141 * @return 0 or negative error code
1144 int microdia_vidioc_qbuf(struct file
*file
, void *priv
,
1145 struct v4l2_buffer
*buffer
)
1147 struct usb_microdia
*dev
;
1149 dev
= video_get_drvdata(priv
);
1151 UDIA_DEBUG("VIDIOC_QBUF\n");
1153 if (!v4l_has_privileges(file
))
1156 return microdia_queue_buffer(&dev
->queue
, buffer
);
1164 * @return 0 or negative error code
1167 int microdia_vidioc_dqbuf(struct file
*file
, void *priv
,
1168 struct v4l2_buffer
*buffer
)
1170 struct usb_microdia
*dev
;
1173 dev
= video_get_drvdata(priv
);
1175 UDIA_DEBUG("VIDIOC_DQBUF\n");
1177 if (!v4l_has_privileges(file
))
1180 ret
= microdia_dequeue_buffer(&dev
->queue
, buffer
,
1181 file
->f_flags
& O_NONBLOCK
);
1185 microdia_decompress(dev
, buffer
);
1195 * @return 0 or negative error code
1198 int microdia_vidioc_streamon(struct file
*file
, void *priv
,
1199 enum v4l2_buf_type type
)
1201 struct usb_microdia
*dev
;
1203 dev
= video_get_drvdata(priv
);
1205 UDIA_DEBUG("VIDIOC_STREAMON\n");
1207 if (!v4l_has_privileges(file
))
1210 if (dev
->mode
!= MICRODIA_MODE_IDLE
)
1213 return v4l2_enable_video(dev
, MICRODIA_MODE_STREAM
);
1221 * @return 0 or negative error code
1224 int microdia_vidioc_streamoff(struct file
*file
, void *priv
,
1225 enum v4l2_buf_type type
)
1227 struct usb_microdia
*dev
;
1229 dev
= video_get_drvdata(priv
);
1231 UDIA_DEBUG("VIDIOC_STREAMOFF\n");
1233 if (!v4l_has_privileges(file
))
1236 return v4l2_enable_video(dev
, MICRODIA_MODE_IDLE
);
1244 * @return 0 or negative error code
1247 int microdia_vidioc_g_param(struct file
*file
, void *priv
,
1248 struct v4l2_streamparm
*param
)
1250 struct usb_microdia
*dev
;
1253 dev
= video_get_drvdata(priv
);
1255 if (param
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
1258 param
->parm
.capture
.capability
= 0;
1259 param
->parm
.capture
.capturemode
= 0;
1260 param
->parm
.capture
.timeperframe
.numerator
= 1;
1261 param
->parm
.capture
.timeperframe
.denominator
= 30;
1262 param
->parm
.capture
.readbuffers
= 2;
1263 param
->parm
.capture
.extendedmode
= 0;
1273 * @return 0 or negative error code
1276 int microdia_vidioc_s_param(struct file
*file
, void *priv
,
1277 struct v4l2_streamparm
*param
)
1279 struct usb_microdia
*dev
;
1281 dev
= video_get_drvdata(priv
);
1283 if (v4l_get_privileges(file
))
1286 if (param
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
1293 * @param inode Inode pointer
1294 * @param fp File pointer
1295 * @param cmd Command
1296 * @param arg Arguements of the command
1298 * @returns 0 if all is OK
1300 * @brief Manage IOCTL
1302 * This function permits to manage all the IOCTL from the application.
1304 static int v4l_microdia_ioctl(struct inode
*inode
, struct file
*fp
,
1305 unsigned int cmd
, unsigned long arg
)
1308 struct usb_microdia
*dev
;
1309 struct video_device
*vdev
;
1311 vdev
= video_devdata(fp
);
1312 dev
= video_get_drvdata(video_devdata(fp
));
1314 UDIA_DEBUG("v4l_microdia_ioctl %02X\n", (unsigned char) cmd
);
1316 if (dev
== NULL
|| vdev
== NULL
)
1319 err
= video_ioctl2(inode
, fp
, cmd
, arg
);
1325 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
1326 static const struct v4l2_ioctl_ops microdia_v4l2_ioctl_ops
= {
1327 .vidioc_querycap
= microdia_vidioc_querycap
,
1328 .vidioc_enum_fmt_vid_cap
= microdia_vidioc_enum_fmt_cap
,
1329 .vidioc_try_fmt_vid_cap
= microdia_vidioc_try_fmt_cap
,
1330 .vidioc_s_fmt_vid_cap
= microdia_vidioc_s_fmt_cap
,
1331 .vidioc_g_fmt_vid_cap
= microdia_vidioc_g_fmt_cap
,
1332 .vidioc_enum_input
= microdia_vidioc_enum_input
,
1333 .vidioc_g_input
= microdia_vidioc_g_input
,
1334 .vidioc_s_input
= microdia_vidioc_s_input
,
1335 .vidioc_streamon
= microdia_vidioc_streamon
,
1336 .vidioc_streamoff
= microdia_vidioc_streamoff
,
1337 .vidioc_queryctrl
= microdia_vidioc_queryctrl
,
1338 .vidioc_g_ctrl
= microdia_vidioc_g_ctrl
,
1339 .vidioc_s_ctrl
= microdia_vidioc_s_ctrl
,
1340 .vidioc_g_parm
= microdia_vidioc_g_param
,
1341 .vidioc_s_parm
= microdia_vidioc_s_param
,
1342 .vidioc_reqbufs
= microdia_vidioc_reqbufs
,
1343 .vidioc_qbuf
= microdia_vidioc_qbuf
,
1344 .vidioc_dqbuf
= microdia_vidioc_dqbuf
,
1345 .vidioc_querybuf
= microdia_vidioc_querybuf
,
1350 * @param dev Device structure
1352 * @returns 0 if all is OK
1354 * @brief Register the video device
1356 * This function permits to register the USB device to the video device.
1358 int v4l_microdia_register_video_device(struct usb_microdia
*dev
)
1362 strcpy(dev
->vdev
->name
, DRIVER_DESC
);
1364 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
1365 dev
->vdev
->dev
= &dev
->interface
->dev
;
1366 dev
->vdev
->owner
= THIS_MODULE
;
1367 dev
->vdev
->type
= VID_TYPE_CAPTURE
;
1369 dev
->vdev
->dev
= dev
->interface
->dev
;
1371 dev
->vdev
->current_norm
= 0;
1372 dev
->vdev
->tvnorms
= 0;
1373 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
1374 dev
->vdev
->hardware
= VID_HARDWARE_MICRODIA
;
1376 dev
->vdev
->fops
= &v4l_microdia_fops
;
1377 dev
->vdev
->release
= video_device_release
;
1378 dev
->vdev
->minor
= -1;
1380 if (log_level
& MICRODIA_DEBUG
)
1381 dev
->vdev
->debug
= V4L2_DEBUG_IOCTL_ARG
;
1383 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
1384 dev
->vdev
->vidioc_querycap
= microdia_vidioc_querycap
;
1385 dev
->vdev
->vidioc_enum_fmt_cap
= microdia_vidioc_enum_fmt_cap
;
1386 dev
->vdev
->vidioc_try_fmt_cap
= microdia_vidioc_try_fmt_cap
;
1387 dev
->vdev
->vidioc_s_fmt_cap
= microdia_vidioc_s_fmt_cap
;
1388 dev
->vdev
->vidioc_g_fmt_cap
= microdia_vidioc_g_fmt_cap
;
1389 dev
->vdev
->vidioc_enum_input
= microdia_vidioc_enum_input
;
1390 dev
->vdev
->vidioc_g_input
= microdia_vidioc_g_input
;
1391 dev
->vdev
->vidioc_s_input
= microdia_vidioc_s_input
;
1392 dev
->vdev
->vidioc_streamon
= microdia_vidioc_streamon
;
1393 dev
->vdev
->vidioc_streamoff
= microdia_vidioc_streamoff
;
1394 dev
->vdev
->vidioc_queryctrl
= microdia_vidioc_queryctrl
;
1395 dev
->vdev
->vidioc_g_ctrl
= microdia_vidioc_g_ctrl
;
1396 dev
->vdev
->vidioc_s_ctrl
= microdia_vidioc_s_ctrl
;
1397 dev
->vdev
->vidioc_g_parm
= microdia_vidioc_g_param
;
1398 dev
->vdev
->vidioc_s_parm
= microdia_vidioc_s_param
;
1399 dev
->vdev
->vidioc_reqbufs
= microdia_vidioc_reqbufs
;
1400 dev
->vdev
->vidioc_qbuf
= microdia_vidioc_qbuf
;
1401 dev
->vdev
->vidioc_dqbuf
= microdia_vidioc_dqbuf
;
1402 dev
->vdev
->vidioc_querybuf
= microdia_vidioc_querybuf
;
1404 dev
->vdev
->ioctl_ops
= µdia_v4l2_ioctl_ops
;
1407 video_set_drvdata(dev
->vdev
, dev
);
1409 microdia_queue_init(&dev
->queue
);
1411 err
= video_register_device(dev
->vdev
, VFL_TYPE_GRABBER
, -1);
1414 UDIA_ERROR("Video register fail !\n");
1416 UDIA_INFO("Microdia USB 2.0 Webcam is now controlling "
1417 "video device /dev/video%d\n",
1425 * @param dev Device structure
1427 * @returns 0 if all is OK
1429 * @brief Unregister the video device
1431 * This function permits to unregister the video device.
1433 int v4l_microdia_unregister_video_device(struct usb_microdia
*dev
)
1435 UDIA_INFO("Microdia USB 2.0 Webcam releases control of video "
1436 "device /dev/video%d\n", dev
->vdev
->minor
);
1438 video_set_drvdata(dev
->vdev
, NULL
);
1439 video_unregister_device(dev
->vdev
);
1446 * @var v4l_microdia_fops
1448 * This variable contains some callback
1450 static struct file_operations v4l_microdia_fops
= {
1451 .owner
= THIS_MODULE
,
1452 .open
= v4l_microdia_open
,
1453 .release
= v4l_microdia_release
,
1454 .read
= v4l_microdia_read
,
1455 .poll
= v4l_microdia_poll
,
1456 .mmap
= v4l_microdia_mmap
,
1457 .ioctl
= v4l_microdia_ioctl
,
1458 #ifdef CONFIG_COMPAT
1459 .compat_ioctl
= v4l_compat_ioctl32
,