3 * @author Nicolas VIVIEN
7 * @brief V4L2 interface and functions
9 * @note Copyright (C) Nicolas VIVIEN
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include <linux/module.h>
29 #include <linux/init.h>
30 #include <linux/kernel.h>
31 #include <linux/version.h>
32 #include <linux/errno.h>
33 #include <linux/slab.h>
34 #include <linux/kref.h>
35 #include <linux/vmalloc.h>
36 #include <linux/usb.h>
37 #include <media/v4l2-common.h>
43 /* USER DEFINED V4L2-CONTROLS: */
44 #define V4L2_CID_SHARPNESS (V4L2_CID_PRIVATE_BASE + 0)
45 #define V4L2_CID_AUTOEXPOSURE (V4L2_CID_PRIVATE_BASE + 1)
48 static struct file_operations v4l_microdia_fops
;
54 #define NUM_V4L2_FORMATS 4
56 struct v4l2_pix_format microdia_fmts
[] = {
60 .pixelformat
= V4L2_PIX_FMT_YUV420
,
61 .field
= V4L2_FIELD_NONE
,
64 .colorspace
= V4L2_COLORSPACE_SRGB
,
70 .pixelformat
= V4L2_PIX_FMT_BGR24
,
71 .field
= V4L2_FIELD_NONE
,
74 .colorspace
= V4L2_COLORSPACE_SRGB
,
80 .pixelformat
= V4L2_PIX_FMT_RGB24
,
81 .field
= V4L2_FIELD_NONE
,
84 .colorspace
= V4L2_COLORSPACE_SRGB
,
90 .pixelformat
= V4L2_PIX_FMT_YUYV
,
91 .field
= V4L2_FIELD_NONE
,
94 .colorspace
= V4L2_COLORSPACE_SRGB
,
101 * @param fmt v4l2 fmt id
103 * @returns index of requested format
105 * @brief check if v4l2 forat is supported by device.
107 * This function permits to check if v4l2 format is supported.
109 int v4l2_format_supported(struct usb_microdia
*dev
, __u32 fmt
)
112 for (i
= 0; i
< sizeof(dev
->supported_fmts
) * 8; i
++) {
113 if (i
> (ARRAY_SIZE(microdia_fmts
) - 1))
115 if (dev
->supported_fmts
& (1 << i
) &&
116 microdia_fmts
[i
].pixelformat
== fmt
)
124 * @param index format index
126 * @returns reference to format structure
128 * @brief enumerate supported formats
130 * This function will enumerate all supported formats.
132 struct v4l2_pix_format
*v4l2_enum_supported_formats(struct usb_microdia
*dev
,
136 for (i
= 0; i
< sizeof(dev
->supported_fmts
) * 8; i
++) {
137 if (i
> (ARRAY_SIZE(microdia_fmts
) - 1))
139 if (dev
->supported_fmts
& (1 << i
)) {
141 return µdia_fmts
[i
];
149 * @var microdia_controls
150 * List of all V4Lv2 controls supported by the driver
152 static struct v4l2_queryctrl microdia_controls
[] = {
154 .id
= V4L2_CID_BRIGHTNESS
,
155 .type
= V4L2_CTRL_TYPE_INTEGER
,
156 .name
= "Brightness",
160 .default_value
= 0x7f00,
163 .id
= V4L2_CID_WHITENESS
,
164 .type
= V4L2_CTRL_TYPE_INTEGER
,
169 .default_value
= 0x7f00,
173 .id = V4L2_CID_SATURATION,
174 .type = V4L2_CTRL_TYPE_INTEGER,
175 .name = "Saturation",
179 .default_value = 0x7f00,
183 .id
= V4L2_CID_CONTRAST
,
184 .type
= V4L2_CTRL_TYPE_INTEGER
,
189 .default_value
= 0x0000,
192 .id
= V4L2_CID_EXPOSURE
,
193 .type
= V4L2_CTRL_TYPE_INTEGER
,
198 .default_value
= 0x1000,
201 .id
= V4L2_CID_HFLIP
,
202 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
203 .name
= "Horizontal flip",
210 .id
= V4L2_CID_VFLIP
,
211 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
212 .name
= "Vertical flip",
219 .id
= V4L2_CID_SHARPNESS
,
220 .type
= V4L2_CTRL_TYPE_INTEGER
,
225 .default_value
= 0x1f,
228 .id
= V4L2_CID_RED_BALANCE
,
229 .type
= V4L2_CTRL_TYPE_INTEGER
,
230 .name
= "Red Balance",
234 .default_value
= 0x20,
237 .id
= V4L2_CID_BLUE_BALANCE
,
238 .type
= V4L2_CTRL_TYPE_INTEGER
,
239 .name
= "Blue Balance",
243 .default_value
= 0x20,
246 .id
= V4L2_CID_AUTOEXPOSURE
,
247 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
248 .name
= "Automatic exposure control",
255 .id
= V4L2_CID_AUTO_WHITE_BALANCE
,
256 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
257 .name
= "Automatic whitbalance control",
266 * The following three functions are used to get, test and drop v4l privleges.
268 int v4l_get_privileges(struct file
*file
)
270 struct usb_microdia
*dev
;
273 dev
= video_get_drvdata(video_devdata(file
));
275 if (dev
->owner
== file
)
278 mutex_lock(&open_lock
);
279 if (dev
->owner
!= NULL
) {
285 mutex_unlock(&open_lock
);
289 int v4l_has_privileges(struct file
*file
)
291 struct usb_microdia
*dev
;
294 dev
= video_get_drvdata(video_devdata(file
));
296 if (dev
->owner
== file
)
302 void v4l_drop_privileges(struct file
*file
)
304 struct usb_microdia
*dev
;
306 dev
= video_get_drvdata(video_devdata(file
));
308 if (dev
->owner
== file
)
313 * @brief Enable video stream
315 * @param dev Pointer to device structure
316 * @param mode Mode for video stream
318 * @returns 0 or negative error value
321 int v4l2_enable_video(struct usb_microdia
*dev
, int mode
)
325 if (mode
== MICRODIA_MODE_IDLE
) {
326 dev_microdia_stop_stream(dev
);
327 usb_microdia_isoc_cleanup(dev
);
328 dev_microdia_camera_off(dev
);
329 microdia_queue_enable(&dev
->queue
, 0);
334 if (dev
->mode
!= MICRODIA_MODE_IDLE
)
337 if (microdia_queue_enable(&dev
->queue
, 1) < 0)
340 dev_microdia_camera_on(dev
);
341 ret
= usb_microdia_isoc_init(dev
);
346 dev_microdia_start_stream(dev
);
347 dev_microdia_camera_settings(dev
);
354 * @param inode Pointer on an inode
355 * @param fp File pointer
357 * @returns 0 if all is OK
359 * @brief Open the video device
361 * This function permits to open a video device (/dev/videoX)
363 static int v4l_microdia_open(struct inode
*inode
, struct file
*fp
)
367 struct usb_microdia
*dev
;
368 struct video_device
*vdev
;
370 mutex_lock(&open_lock
);
372 vdev
= video_devdata(fp
);
373 dev
= video_get_drvdata(video_devdata(fp
));
375 fp
->private_data
= vdev
;
377 kref_get(&dev
->vopen
);
379 mutex_unlock(&open_lock
);
385 * @param inode Pointer on inode
386 * @param fp File pointer
388 * @returns 0 if all is OK
390 * @brief Release an opened file.
392 * This function permits to release an opened file with the 'open' method.
394 static int v4l_microdia_release(struct inode
*inode
, struct file
*fp
)
396 struct usb_microdia
*dev
;
397 struct video_device
*vdev
;
399 mutex_lock(&open_lock
);
401 vdev
= video_devdata(fp
);
402 dev
= video_get_drvdata(video_devdata(fp
));
404 if (v4l_has_privileges(fp
)) {
405 v4l2_enable_video(dev
, MICRODIA_MODE_IDLE
);
407 mutex_lock(&dev
->queue
.mutex
);
408 microdia_free_buffers(&dev
->queue
);
409 mutex_unlock(&dev
->queue
.mutex
);
412 v4l_drop_privileges(fp
);
414 kref_put(&dev
->vopen
, usb_microdia_delete
);
416 mutex_unlock(&open_lock
);
422 * @param fp File pointer
424 * @retval buf Buffer in user space
428 * @returns Count value
430 * @brief Read the video device
432 * This function is called by the application is reading the video device.
434 static ssize_t
v4l_microdia_read(struct file
*fp
, char __user
*buf
,
435 size_t count
, loff_t
*f_pos
)
439 struct v4l2_buffer buffer
;
440 struct usb_microdia
*dev
;
442 dev
= video_get_drvdata(video_devdata(fp
));
444 ret
= v4l_get_privileges(fp
);
448 if (dev
->mode
!= MICRODIA_MODE_IDLE
&&
449 dev
->mode
!= MICRODIA_MODE_READ
)
452 buffer
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
453 buffer
.memory
= V4L2_MEMORY_MMAP
;
454 if (dev
->mode
== MICRODIA_MODE_IDLE
) {
455 nbuffers
= microdia_alloc_buffers(&dev
->queue
, 2,
456 MICRODIA_FRAME_SIZE
);
460 for (i
= 0; i
< nbuffers
; i
++) {
461 buffer
= dev
->queue
.buffer
[i
].buf
;
462 microdia_queue_buffer(&dev
->queue
, &buffer
);
465 ret
= v4l2_enable_video(dev
, MICRODIA_MODE_READ
);
470 if (dev
->queue
.read_buffer
== NULL
) {
471 ret
= microdia_dequeue_buffer(&dev
->queue
, &buffer
,
472 fp
->f_flags
& O_NONBLOCK
);
476 microdia_decompress(dev
, &buffer
);
477 dev
->queue
.read_buffer
= &dev
->queue
.buffer
[buffer
.index
];
479 buffer
= dev
->queue
.read_buffer
->buf
;
482 count
= min((size_t)(buffer
.bytesused
- *f_pos
), count
);
483 if (copy_to_user(buf
, dev
->queue
.mem
+ buffer
.m
.offset
+ *f_pos
, count
))
487 if (*f_pos
>= buffer
.bytesused
) {
488 dev
->queue
.read_buffer
= NULL
;
489 microdia_queue_buffer(&dev
->queue
, &buffer
);
497 * @param fp File pointer
500 * @returns 0 if all is OK
502 * @brief Polling function
504 static unsigned int v4l_microdia_poll(struct file
*fp
, poll_table
*wait
)
506 struct usb_microdia
*dev
;
507 struct video_device
*vdev
;
509 vdev
= video_devdata(fp
);
510 dev
= video_get_drvdata(video_devdata(fp
));
512 UDIA_STREAM("Poll\n");
514 if (vdev
== NULL
|| dev
== NULL
)
517 return microdia_queue_poll(&dev
->queue
, fp
, wait
);
520 static void microdia_vm_open(struct vm_area_struct
*vma
)
522 struct microdia_buffer
*buffer
= vma
->vm_private_data
;
523 buffer
->vma_use_count
++;
527 static void microdia_vm_close(struct vm_area_struct
*vma
)
529 struct microdia_buffer
*buffer
= vma
->vm_private_data
;
530 buffer
->vma_use_count
--;
533 struct vm_operations_struct microdia_vm_ops
= {
534 .open
= microdia_vm_open
,
535 .close
= microdia_vm_close
539 * @param fp File pointer
540 * @param vma VMA structure
542 * @returns 0 if all is OK
546 * This function permits to map a memory space.
548 static int v4l_microdia_mmap(struct file
*fp
, struct vm_area_struct
*vma
)
551 unsigned long addr
, start
, size
;
555 struct usb_microdia
*dev
;
556 struct video_device
*vdev
;
557 struct microdia_buffer
*buffer
= NULL
;
559 vdev
= video_devdata(fp
);
560 dev
= video_get_drvdata(video_devdata(fp
));
562 UDIA_STREAM("mmap\n");
564 start
= vma
->vm_start
;
565 size
= vma
->vm_end
- vma
->vm_start
;
567 mutex_lock(&dev
->queue
.mutex
);
569 for (i
= 0; i
< dev
->queue
.count
; ++i
) {
570 buffer
= &dev
->queue
.buffer
[i
];
571 if ((buffer
->buf
.m
.offset
>> PAGE_SHIFT
) == vma
->vm_pgoff
)
575 if (i
== dev
->queue
.count
|| size
!= dev
->queue
.buf_size
) {
580 vma
->vm_flags
|= VM_IO
;
582 addr
= (unsigned long)dev
->queue
.mem
+ buffer
->buf
.m
.offset
;
584 page
= vmalloc_to_page((void *)addr
);
585 ret
= vm_insert_page(vma
, start
, page
);
594 vma
->vm_ops
= µdia_vm_ops
;
595 vma
->vm_private_data
= buffer
;
596 microdia_vm_open(vma
);
598 mutex_unlock(&dev
->queue
.mutex
);
602 int microdia_vidioc_querycap(struct file
*file
, void *priv
,
603 struct v4l2_capability
*cap
)
605 struct usb_microdia
*dev
;
607 dev
= video_get_drvdata(priv
);
609 UDIA_DEBUG("VIDIOC_QUERYCAP\n");
611 strlcpy(cap
->driver
, "microdia", sizeof(cap
->driver
));
612 cap
->capabilities
= V4L2_CAP_VIDEO_CAPTURE
| V4L2_CAP_STREAMING
613 | V4L2_CAP_READWRITE
;
614 cap
->version
= (__u32
) DRIVER_VERSION_NUM
,
615 strlcpy(cap
->card
, dev
->vdev
->name
, sizeof(cap
->card
));
617 if (usb_make_path(dev
->udev
, cap
->bus_info
, sizeof(cap
->bus_info
)) < 0)
618 strlcpy(cap
->bus_info
, dev
->vdev
->name
, sizeof(cap
->bus_info
));
622 int microdia_vidioc_enum_input(struct file
*file
, void *priv
,
623 struct v4l2_input
*input
)
625 UDIA_DEBUG("VIDIOC_ENUMINPUT %d\n", input
->index
);
630 strlcpy(input
->name
, "Webcam", sizeof(input
->name
));
631 input
->type
= V4L2_INPUT_TYPE_CAMERA
;
637 int microdia_vidioc_g_input(struct file
*file
, void *priv
, unsigned int *index
)
639 UDIA_DEBUG("GET INPUT %d\n", *index
);
647 int microdia_vidioc_s_input(struct file
*file
, void *priv
, unsigned int index
)
649 UDIA_DEBUG("SET INPUT %d\n", index
);
651 if (v4l_get_privileges(file
) < 0)
660 int microdia_vidioc_queryctrl(struct file
*file
, void *priv
,
661 struct v4l2_queryctrl
*ctrl
)
666 UDIA_DEBUG("VIDIOC_QUERYCTRL id = %d\n", ctrl
->id
);
668 nbr
= sizeof(microdia_controls
)/sizeof(struct v4l2_queryctrl
);
670 for (i
= 0; i
< nbr
; i
++) {
671 if (microdia_controls
[i
].id
== ctrl
->id
) {
672 UDIA_DEBUG("VIDIOC_QUERYCTRL found\n");
673 memcpy(ctrl
, µdia_controls
[i
],
674 sizeof(struct v4l2_queryctrl
));
685 int microdia_vidioc_g_ctrl(struct file
*file
, void *priv
,
686 struct v4l2_control
*ctrl
)
688 struct usb_microdia
*dev
;
690 dev
= video_get_drvdata(priv
);
692 UDIA_DEBUG("GET CTRL id=%d\n", ctrl
->id
);
695 case V4L2_CID_BRIGHTNESS
:
696 ctrl
->value
= dev
->vsettings
.brightness
;
699 case V4L2_CID_EXPOSURE
:
700 ctrl
->value
= dev
->vsettings
.exposure
;
703 case V4L2_CID_WHITENESS
:
704 ctrl
->value
= dev
->vsettings
.whiteness
;
707 case V4L2_CID_SATURATION:
708 ctrl->value = dev->vsettings.colour;
711 case V4L2_CID_CONTRAST
:
712 ctrl
->value
= dev
->vsettings
.contrast
;
716 ctrl
->value
= dev
->vsettings
.hflip
;
720 ctrl
->value
= dev
->vsettings
.vflip
;
723 case V4L2_CID_SHARPNESS
:
724 ctrl
->value
= dev
->vsettings
.sharpness
;
727 case V4L2_CID_RED_BALANCE
:
728 ctrl
->value
= dev
->vsettings
.rgb_gain
[0];
731 case V4L2_CID_BLUE_BALANCE
:
732 ctrl
->value
= dev
->vsettings
.rgb_gain
[3];
735 case V4L2_CID_AUTOEXPOSURE
:
736 ctrl
->value
= dev
->vsettings
.auto_exposure
;
739 case V4L2_CID_AUTO_WHITE_BALANCE
:
740 ctrl
->value
= dev
->vsettings
.auto_whitebalance
;
750 * @brief Apply v4l2 settings on camera
754 * @param ctrl V4L2 control structure
756 * @returns 0 or negative error value
759 int microdia_vidioc_s_ctrl(struct file
*file
, void *priv
,
760 struct v4l2_control
*ctrl
)
762 struct usb_microdia
*dev
;
764 dev
= video_get_drvdata(priv
);
766 UDIA_DEBUG("SET CTRL id=%d value=%d\n", ctrl
->id
, ctrl
->value
);
769 case V4L2_CID_BRIGHTNESS
:
770 dev
->vsettings
.brightness
= (0xff00 & ctrl
->value
);
771 dev_microdia_camera_set_brightness(dev
);
774 case V4L2_CID_EXPOSURE
:
775 dev
->vsettings
.exposure
= (0xff00 & ctrl
->value
);
776 dev_microdia_camera_set_exposure(dev
);
779 case V4L2_CID_WHITENESS
:
780 dev
->vsettings
.whiteness
= (0xff00 & ctrl
->value
);
781 dev_microdia_camera_set_gamma(dev
);
784 case V4L2_CID_SATURATION:
785 dev->vsettings.colour = (0xff00 & ctrl->value);
788 case V4L2_CID_CONTRAST
:
789 dev
->vsettings
.contrast
= (0xff00 & ctrl
->value
);
790 dev_microdia_camera_set_contrast(dev
);
794 dev
->vsettings
.hflip
= ctrl
->value
;
795 dev_microdia_camera_set_hvflip(dev
);
799 dev
->vsettings
.vflip
= ctrl
->value
;
800 dev_microdia_camera_set_hvflip(dev
);
803 case V4L2_CID_SHARPNESS
:
804 dev
->vsettings
.sharpness
= ctrl
->value
;
805 dev_microdia_camera_set_sharpness(dev
);
808 case V4L2_CID_RED_BALANCE
:
809 dev
->vsettings
.rgb_gain
[0] = ctrl
->value
;
810 dev_microdia_camera_set_rgb_gain(dev
);
813 case V4L2_CID_BLUE_BALANCE
:
814 dev
->vsettings
.rgb_gain
[3] = ctrl
->value
;
815 dev_microdia_camera_set_rgb_gain(dev
);
818 case V4L2_CID_AUTOEXPOSURE
:
819 dev
->vsettings
.auto_exposure
= ctrl
->value
;
820 dev_microdia_camera_set_auto_exposure(dev
);
823 case V4L2_CID_AUTO_WHITE_BALANCE
:
824 dev
->vsettings
.auto_whitebalance
= ctrl
->value
;
825 dev_microdia_camera_set_auto_whitebalance(dev
);
835 int microdia_vidioc_enum_fmt_cap(struct file
*file
, void *priv
,
836 struct v4l2_fmtdesc
*fmt
)
838 struct usb_microdia
*dev
;
839 struct v4l2_pix_format
*format
;
841 dev
= video_get_drvdata(priv
);
843 UDIA_DEBUG("VIDIOC_ENUM_FMT %d\n", fmt
->index
);
845 format
= v4l2_enum_supported_formats(dev
, fmt
->index
);
850 fmt
->pixelformat
= format
->pixelformat
;
851 fmt
->description
[0] = fmt
->pixelformat
& 0xFF;
852 fmt
->description
[1] = (fmt
->pixelformat
>> 8) & 0xFF;
853 fmt
->description
[2] = (fmt
->pixelformat
>> 16) & 0xFF;
854 fmt
->description
[3] = fmt
->pixelformat
>> 24;
855 fmt
->description
[4] = 0;
860 int microdia_vidioc_try_fmt_cap(struct file
*file
, void *priv
,
861 struct v4l2_format
*fmt
)
863 struct usb_microdia
*dev
;
865 dev
= video_get_drvdata(priv
);
866 UDIA_DEBUG("TRY FMT %d\n", fmt
->type
);
868 /* when this code is used prevents mplayer from setting outfmt
869 if(fmt->fmt.pix.field != V4L2_FIELD_NONE)
873 if (v4l2_format_supported(dev
, fmt
->fmt
.pix
.pixelformat
) < 0)
876 sn9c20x_get_closest_resolution(&fmt
->fmt
.pix
.width
,
877 &fmt
->fmt
.pix
.height
);
879 switch (fmt
->fmt
.pix
.pixelformat
) {
880 case V4L2_PIX_FMT_YUV420
:
881 fmt
->fmt
.pix
.bytesperline
= (fmt
->fmt
.pix
.width
* 3)/2;
882 fmt
->fmt
.pix
.sizeimage
= fmt
->fmt
.pix
.height
*
883 fmt
->fmt
.pix
.bytesperline
;
885 case V4L2_PIX_FMT_RGB24
:
886 case V4L2_PIX_FMT_BGR24
:
887 fmt
->fmt
.pix
.bytesperline
= fmt
->fmt
.pix
.width
* 3;
888 fmt
->fmt
.pix
.sizeimage
= fmt
->fmt
.pix
.height
*
889 fmt
->fmt
.pix
.bytesperline
;
891 case V4L2_PIX_FMT_YUYV
:
892 fmt
->fmt
.pix
.bytesperline
= fmt
->fmt
.pix
.width
* 2;
893 fmt
->fmt
.pix
.sizeimage
= fmt
->fmt
.pix
.height
*
894 fmt
->fmt
.pix
.bytesperline
;
900 fmt
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SRGB
;
901 fmt
->fmt
.pix
.priv
= 0;
906 int microdia_vidioc_g_fmt_cap(struct file
*file
, void *priv
,
907 struct v4l2_format
*fmt
)
909 struct usb_microdia
*dev
;
911 dev
= video_get_drvdata(priv
);
913 UDIA_DEBUG("GET FMT %d\n", fmt
->type
);
915 memcpy(&(fmt
->fmt
.pix
), &(dev
->vsettings
.format
), sizeof(fmt
->fmt
.pix
));
921 int microdia_vidioc_s_fmt_cap(struct file
*file
, void *priv
,
922 struct v4l2_format
*fmt
)
924 struct usb_microdia
*dev
;
927 dev
= video_get_drvdata(priv
);
929 UDIA_DEBUG("SET FMT %d : %d\n", fmt
->type
, fmt
->fmt
.pix
.pixelformat
);
931 if (v4l_get_privileges(file
) < 0)
934 if (dev
->queue
.streaming
)
937 ret
= microdia_vidioc_try_fmt_cap(file
, priv
, fmt
);
941 sn9c20x_set_resolution(dev
, fmt
->fmt
.pix
.width
, fmt
->fmt
.pix
.height
);
943 memcpy(&(dev
->vsettings
.format
), &(fmt
->fmt
.pix
), sizeof(fmt
->fmt
.pix
));
948 int microdia_vidioc_reqbufs(struct file
*file
, void *priv
,
949 struct v4l2_requestbuffers
*request
)
952 struct usb_microdia
*dev
;
954 dev
= video_get_drvdata(priv
);
956 if (v4l_get_privileges(file
) < 0) {
961 if (request
->memory
!= V4L2_MEMORY_MMAP
||
962 request
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
) {
967 if (dev
->queue
.streaming
) {
972 ret
= microdia_alloc_buffers(&dev
->queue
, request
->count
,
973 MICRODIA_FRAME_SIZE
);
977 dev
->queue
.drop_incomplete
= 1;
979 request
->count
= ret
;
981 UDIA_INFO("Buffers Allocated %d\n", request
->count
);
986 int microdia_vidioc_querybuf(struct file
*file
, void *priv
,
987 struct v4l2_buffer
*buffer
)
989 struct usb_microdia
*dev
;
991 dev
= video_get_drvdata(priv
);
993 UDIA_DEBUG("QUERY BUFFERS %d %d\n", buffer
->index
, dev
->queue
.count
);
995 if (buffer
->memory
!= V4L2_MEMORY_MMAP
||
996 buffer
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
999 if (!v4l_has_privileges(file
))
1002 return microdia_query_buffer(&dev
->queue
, buffer
);
1005 int microdia_vidioc_qbuf(struct file
*file
, void *priv
,
1006 struct v4l2_buffer
*buffer
)
1008 struct usb_microdia
*dev
;
1010 dev
= video_get_drvdata(priv
);
1012 UDIA_DEBUG("VIDIOC_QBUF\n");
1014 if (!v4l_has_privileges(file
))
1017 return microdia_queue_buffer(&dev
->queue
, buffer
);
1020 int microdia_vidioc_dqbuf(struct file
*file
, void *priv
,
1021 struct v4l2_buffer
*buffer
)
1023 struct usb_microdia
*dev
;
1026 dev
= video_get_drvdata(priv
);
1028 UDIA_DEBUG("VIDIOC_DQBUF\n");
1030 if (!v4l_has_privileges(file
))
1033 ret
= microdia_dequeue_buffer(&dev
->queue
, buffer
,
1034 file
->f_flags
& O_NONBLOCK
);
1038 microdia_decompress(dev
, buffer
);
1043 int microdia_vidioc_streamon(struct file
*file
, void *priv
,
1044 enum v4l2_buf_type type
)
1046 struct usb_microdia
*dev
;
1048 dev
= video_get_drvdata(priv
);
1050 UDIA_DEBUG("VIDIOC_STREAMON\n");
1052 if (!v4l_has_privileges(file
))
1055 if (dev
->mode
!= MICRODIA_MODE_IDLE
)
1058 return v4l2_enable_video(dev
, MICRODIA_MODE_STREAM
);
1061 int microdia_vidioc_streamoff(struct file
*file
, void *priv
,
1062 enum v4l2_buf_type type
)
1064 struct usb_microdia
*dev
;
1066 dev
= video_get_drvdata(priv
);
1068 UDIA_DEBUG("VIDIOC_STREAMOFF\n");
1070 if (!v4l_has_privileges(file
))
1073 return v4l2_enable_video(dev
, MICRODIA_MODE_IDLE
);
1076 int microdia_vidioc_g_param(struct file
*file
, void *priv
,
1077 struct v4l2_streamparm
*param
)
1079 struct usb_microdia
*dev
;
1082 dev
= video_get_drvdata(priv
);
1084 if (param
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
1087 param
->parm
.capture
.capability
= 0;
1088 param
->parm
.capture
.capturemode
= 0;
1089 param
->parm
.capture
.timeperframe
.numerator
= 1;
1090 param
->parm
.capture
.timeperframe
.denominator
= 30;
1091 param
->parm
.capture
.readbuffers
= 2;
1092 param
->parm
.capture
.extendedmode
= 0;
1097 int microdia_vidioc_s_param(struct file
*file
, void *priv
,
1098 struct v4l2_streamparm
*param
)
1100 struct usb_microdia
*dev
;
1102 dev
= video_get_drvdata(priv
);
1104 if (v4l_get_privileges(file
))
1107 if (param
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
1114 * @param inode Inode pointer
1115 * @param fp File pointer
1116 * @param cmd Command
1117 * @param arg Arguements of the command
1119 * @returns 0 if all is OK
1121 * @brief Manage IOCTL
1123 * This function permits to manage all the IOCTL from the application.
1125 static int v4l_microdia_ioctl(struct inode
*inode
, struct file
*fp
,
1126 unsigned int cmd
, unsigned long arg
)
1129 struct usb_microdia
*dev
;
1130 struct video_device
*vdev
;
1132 vdev
= video_devdata(fp
);
1133 dev
= video_get_drvdata(video_devdata(fp
));
1135 UDIA_DEBUG("v4l_microdia_ioctl %02X\n", (unsigned char) cmd
);
1137 if (dev
== NULL
|| vdev
== NULL
)
1140 err
= video_ioctl2(inode
, fp
, cmd
, arg
);
1147 * @param dev Device structure
1149 * @returns 0 if all is OK
1151 * @brief Register the video device
1153 * This function permits to register the USB device to the video device.
1155 int v4l_microdia_register_video_device(struct usb_microdia
*dev
)
1159 strcpy(dev
->vdev
->name
, DRIVER_DESC
);
1161 dev
->vdev
->dev
= &dev
->interface
->dev
;
1162 dev
->vdev
->owner
= THIS_MODULE
;
1163 dev
->vdev
->type
= VID_TYPE_CAPTURE
;
1164 dev
->vdev
->current_norm
= 0;
1165 dev
->vdev
->tvnorms
= 0;
1166 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
1167 dev
->vdev
->hardware
= VID_HARDWARE_MICRODIA
;
1169 dev
->vdev
->fops
= &v4l_microdia_fops
;
1170 dev
->vdev
->release
= video_device_release
;
1171 dev
->vdev
->minor
= -1;
1173 if (log_level
& MICRODIA_DEBUG
)
1174 dev
->vdev
->debug
= V4L2_DEBUG_IOCTL_ARG
;
1176 dev
->vdev
->vidioc_querycap
= microdia_vidioc_querycap
;
1177 dev
->vdev
->vidioc_enum_fmt_cap
= microdia_vidioc_enum_fmt_cap
;
1178 dev
->vdev
->vidioc_try_fmt_cap
= microdia_vidioc_try_fmt_cap
;
1179 dev
->vdev
->vidioc_s_fmt_cap
= microdia_vidioc_s_fmt_cap
;
1180 dev
->vdev
->vidioc_g_fmt_cap
= microdia_vidioc_g_fmt_cap
;
1181 dev
->vdev
->vidioc_enum_input
= microdia_vidioc_enum_input
;
1182 dev
->vdev
->vidioc_g_input
= microdia_vidioc_g_input
;
1183 dev
->vdev
->vidioc_s_input
= microdia_vidioc_s_input
;
1184 dev
->vdev
->vidioc_streamon
= microdia_vidioc_streamon
;
1185 dev
->vdev
->vidioc_streamoff
= microdia_vidioc_streamoff
;
1186 dev
->vdev
->vidioc_queryctrl
= microdia_vidioc_queryctrl
;
1187 dev
->vdev
->vidioc_g_ctrl
= microdia_vidioc_g_ctrl
;
1188 dev
->vdev
->vidioc_s_ctrl
= microdia_vidioc_s_ctrl
;
1189 dev
->vdev
->vidioc_g_parm
= microdia_vidioc_g_param
;
1190 dev
->vdev
->vidioc_s_parm
= microdia_vidioc_s_param
;
1191 dev
->vdev
->vidioc_reqbufs
= microdia_vidioc_reqbufs
;
1192 dev
->vdev
->vidioc_qbuf
= microdia_vidioc_qbuf
;
1193 dev
->vdev
->vidioc_dqbuf
= microdia_vidioc_dqbuf
;
1194 dev
->vdev
->vidioc_querybuf
= microdia_vidioc_querybuf
;
1196 video_set_drvdata(dev
->vdev
, dev
);
1198 microdia_queue_init(&dev
->queue
);
1200 err
= video_register_device(dev
->vdev
, VFL_TYPE_GRABBER
, -1);
1203 UDIA_ERROR("Video register fail !\n");
1205 UDIA_INFO("Microdia USB2.0 Camera is now controlling "
1206 "video device /dev/video%d\n",
1214 * @param dev Device structure
1216 * @returns 0 if all is OK
1218 * @brief Unregister the video device
1220 * This function permits to unregister the video device.
1222 int v4l_microdia_unregister_video_device(struct usb_microdia
*dev
)
1224 UDIA_INFO("Microdia USB2.0 Camera release resources video "
1225 "device /dev/video%d\n", dev
->vdev
->minor
);
1227 video_set_drvdata(dev
->vdev
, NULL
);
1228 video_unregister_device(dev
->vdev
);
1235 * @var v4l_microdia_fops
1237 * This variable contains some callback
1239 static struct file_operations v4l_microdia_fops
= {
1240 .owner
= THIS_MODULE
,
1241 .open
= v4l_microdia_open
,
1242 .release
= v4l_microdia_release
,
1243 .read
= v4l_microdia_read
,
1244 .poll
= v4l_microdia_poll
,
1245 .mmap
= v4l_microdia_mmap
,
1246 .ioctl
= v4l_microdia_ioctl
,
1247 #ifdef CONFIG_COMPAT
1248 .compat_ioctl
= v4l_compat_ioctl32
,