3 * @author Nicolas VIVIEN
7 * @brief Driver for Microdia USB video camera
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>
42 // USER DEFINED V4L2-CONTROLS:
43 #define V4L2_CID_SHARPNESS (V4L2_CID_PRIVATE_BASE)
46 static struct file_operations v4l_microdia_fops
;
50 * @var microdia_image_sizes
51 * List of all resolutions supported by the driver
53 const struct microdia_coord microdia_image_sizes
[MICRODIA_NBR_SIZES
] = {
69 #define NUM_V4L2_FORMATS 4
71 struct v4l2_pix_format microdia_fmts
[] = {
75 .pixelformat
= V4L2_PIX_FMT_YUV420
,
76 .field
= V4L2_FIELD_NONE
,
79 .colorspace
= V4L2_COLORSPACE_SRGB
,
85 .pixelformat
= V4L2_PIX_FMT_BGR24
,
86 .field
= V4L2_FIELD_NONE
,
89 .colorspace
= V4L2_COLORSPACE_SRGB
,
95 .pixelformat
= V4L2_PIX_FMT_RGB24
,
96 .field
= V4L2_FIELD_NONE
,
99 .colorspace
= V4L2_COLORSPACE_SRGB
,
105 .pixelformat
= V4L2_PIX_FMT_YUYV
,
106 .field
= V4L2_FIELD_NONE
,
107 .bytesperline
= 1280,
109 .colorspace
= V4L2_COLORSPACE_SRGB
,
116 * @param fmt v4l2 fmt id
118 * @returns index of requested format
120 * @brief check if v4l2 forat is supported by device.
122 * This function permits to check if v4l2 format is supported.
124 int v4l2_format_supported(struct usb_microdia
*dev
, __u32 fmt
)
127 for (i
= 0; i
< sizeof(dev
->supported_fmts
) * 8; i
++) {
128 if (i
> (ARRAY_SIZE(microdia_fmts
) - 1))
130 if (dev
->supported_fmts
& (1 << i
) &&
131 microdia_fmts
[i
].pixelformat
== fmt
)
139 * @param index format index
141 * @returns reference to format structure
143 * @brief enumerate supported formats
145 * This function will enumerate all supported formats.
147 struct v4l2_pix_format
*v4l2_enum_supported_formats(struct usb_microdia
*dev
,
151 for (i
= 0; i
< sizeof(dev
->supported_fmts
) * 8; i
++) {
152 if (i
> (ARRAY_SIZE(microdia_fmts
) - 1))
154 if (dev
->supported_fmts
& (1 << i
)) {
156 return µdia_fmts
[i
];
164 * @var microdia_controls
165 * List of all V4Lv2 controls supported by the driver
167 static struct v4l2_queryctrl microdia_controls
[] = {
169 .id
= V4L2_CID_BRIGHTNESS
,
170 .type
= V4L2_CTRL_TYPE_INTEGER
,
171 .name
= "Brightness",
175 .default_value
= 0x7f00,
178 .id
= V4L2_CID_WHITENESS
,
179 .type
= V4L2_CTRL_TYPE_INTEGER
,
184 .default_value
= 0x7f00,
188 .id = V4L2_CID_SATURATION,
189 .type = V4L2_CTRL_TYPE_INTEGER,
190 .name = "Saturation",
194 .default_value = 0x7f00,
198 .id
= V4L2_CID_CONTRAST
,
199 .type
= V4L2_CTRL_TYPE_INTEGER
,
204 .default_value
= 0x0000,
207 .id
= V4L2_CID_EXPOSURE
,
208 .type
= V4L2_CTRL_TYPE_INTEGER
,
213 .default_value
= 0x1000,
216 .id
= V4L2_CID_HFLIP
,
217 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
218 .name
= "Horizontal flip",
225 .id
= V4L2_CID_VFLIP
,
226 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
227 .name
= "Vertical flip",
234 .id
= V4L2_CID_SHARPNESS
,
235 .type
= V4L2_CTRL_TYPE_INTEGER
,
240 .default_value
= 0x1f,
243 .id
= V4L2_CID_RED_BALANCE
,
244 .type
= V4L2_CTRL_TYPE_INTEGER
,
245 .name
= "Red Balance",
249 .default_value
= 0x20,
252 .id
= V4L2_CID_BLUE_BALANCE
,
253 .type
= V4L2_CTRL_TYPE_INTEGER
,
254 .name
= "Blue Balance",
258 .default_value
= 0x20,
261 .id
= V4L2_CID_AUTOGAIN
,
262 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
263 .name
= "Automatic exposure control",
270 .id
= V4L2_CID_AUTO_WHITE_BALANCE
,
271 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
272 .name
= "Automatic whitbalance control",
281 * The following three functions are used to get, test and drop v4l privleges.
283 int v4l_get_privileges(struct file
*file
)
285 struct usb_microdia
*dev
;
288 dev
= video_get_drvdata(video_devdata(file
));
290 if (dev
->owner
== file
)
293 mutex_lock(&open_lock
);
294 if (dev
->owner
!= NULL
) {
300 mutex_unlock(&open_lock
);
304 int v4l_has_privileges(struct file
*file
)
306 struct usb_microdia
*dev
;
309 dev
= video_get_drvdata(video_devdata(file
));
311 if (dev
->owner
== file
)
317 void v4l_drop_privileges(struct file
*file
)
319 struct usb_microdia
*dev
;
321 dev
= video_get_drvdata(video_devdata(file
));
323 if (dev
->owner
== file
)
327 int v4l2_enable_video(struct usb_microdia
*dev
, int mode
)
331 if (mode
== MICRODIA_MODE_IDLE
) {
332 dev_microdia_stop_stream(dev
);
333 usb_microdia_isoc_cleanup(dev
);
334 dev_microdia_camera_off(dev
);
335 microdia_queue_enable(&dev
->queue
, 0);
340 if (dev
->mode
!= MICRODIA_MODE_IDLE
)
343 if (microdia_queue_enable(&dev
->queue
, 1) < 0)
346 dev_microdia_camera_on(dev
);
347 ret
= usb_microdia_isoc_init(dev
);
352 dev_microdia_start_stream(dev
);
353 dev_microdia_camera_settings(dev
);
359 int v4l_microdia_find_resolution(struct usb_microdia
*dev
,
360 int *width
, int *height
)
365 if ((*width
< microdia_image_sizes
[0].x
)
366 || (*height
< microdia_image_sizes
[0].y
)) {
367 *width
= microdia_image_sizes
[0].x
;
368 *height
= microdia_image_sizes
[0].y
;
371 switch (dev
->webcam_type
) {
373 max_res
= MICRODIA_NBR_SIZES
-1;
374 if ((*width
> microdia_image_sizes
[max_res
].x
)
375 || (*height
> microdia_image_sizes
[max_res
].y
)) {
376 *width
= microdia_image_sizes
[max_res
].x
;
377 *height
= microdia_image_sizes
[max_res
].y
;
380 for (i
= 0, find
= 0; i
< MICRODIA_NBR_SIZES
; i
++) {
381 if (microdia_image_sizes
[i
].x
<= *width
&&
382 microdia_image_sizes
[i
].y
<= *height
)
388 max_res
= MICRODIA_NBR_SIZES
-4;
389 if ((*width
> microdia_image_sizes
[max_res
].x
)
390 || (*height
> microdia_image_sizes
[max_res
].y
)) {
391 *width
= microdia_image_sizes
[max_res
].x
;
392 *height
= microdia_image_sizes
[max_res
].y
;
395 for (i
= 0, find
= 0; i
< MICRODIA_NBR_SIZES
-3; i
++) {
396 if (microdia_image_sizes
[i
].x
<= *width
&&
397 microdia_image_sizes
[i
].y
<= *height
)
403 *width
= microdia_image_sizes
[find
].x
;
404 *height
= microdia_image_sizes
[find
].y
;
412 * @param resolution Driver resolution
414 * @returns 0 if all is OK
416 * @brief Select a video mode
418 * This function permits to select a video mode.
420 int v4l_microdia_select_video_mode(struct usb_microdia
*dev
, int resolution
)
422 dev
->resolution
= resolution
;
424 UDIA_DEBUG("Set mode %d [%dx%d]\n", dev
->resolution
,
425 microdia_image_sizes
[dev
->resolution
].x
,
426 microdia_image_sizes
[dev
->resolution
].y
);
428 dev
->view
.x
= microdia_image_sizes
[dev
->resolution
].x
;
429 dev
->view
.y
= microdia_image_sizes
[dev
->resolution
].y
;
433 * Calculate the frame size
435 switch (dev
->resolution
) {
437 case MICRODIA_160x120
:
438 case MICRODIA_320x240
:
439 case MICRODIA_640x480
:
440 dev
->image
.x
= microdia_image_sizes
[MICRODIA_640x480
].x
;
441 dev
->image
.y
= microdia_image_sizes
[MICRODIA_640x480
].y
;
444 case MICRODIA_800x600
:
445 case MICRODIA_1024x768
:
446 case MICRODIA_1280x1024
:
447 dev
->image
.x
= microdia_image_sizes
[MICRODIA_1280x1024
].x
;
448 dev
->image
.y
= microdia_image_sizes
[MICRODIA_1280x1024
].y
;
452 * queue.frame_size is only ever used in isoc_handler
453 * to test if the ISOC data is the correct size
454 * This modificate pre calculates this rather
455 * than doing the calculating in the isoc_handler
457 dev
->queue
.frame_size
= dev
->image
.x
* dev
->image
.y
+
458 (dev
->image
.x
* dev
->image
.y
) / dev
->frame_size_divisor
;
465 * @param inode Pointer on an inode
466 * @param fp File pointer
468 * @returns 0 if all is OK
470 * @brief Open the video device
472 * This function permits to open a video device (/dev/videoX)
474 static int v4l_microdia_open(struct inode
*inode
, struct file
*fp
)
478 struct usb_microdia
*dev
;
479 struct video_device
*vdev
;
481 mutex_lock(&open_lock
);
483 vdev
= video_devdata(fp
);
484 dev
= video_get_drvdata(video_devdata(fp
));
486 fp
->private_data
= vdev
;
488 kref_get(&dev
->vopen
);
490 mutex_unlock(&open_lock
);
496 * @param inode Pointer on inode
497 * @param fp File pointer
499 * @returns 0 if all is OK
501 * @brief Release an opened file.
503 * This function permits to release an opened file with the 'open' method.
505 static int v4l_microdia_release(struct inode
*inode
, struct file
*fp
)
507 struct usb_microdia
*dev
;
508 struct video_device
*vdev
;
510 mutex_lock(&open_lock
);
512 vdev
= video_devdata(fp
);
513 dev
= video_get_drvdata(video_devdata(fp
));
515 if (v4l_has_privileges(fp
)) {
516 v4l2_enable_video(dev
, MICRODIA_MODE_IDLE
);
518 mutex_lock(&dev
->queue
.mutex
);
519 microdia_free_buffers(&dev
->queue
);
520 mutex_unlock(&dev
->queue
.mutex
);
523 v4l_drop_privileges(fp
);
525 kref_put(&dev
->vopen
, usb_microdia_delete
);
527 mutex_unlock(&open_lock
);
533 * @param fp File pointer
535 * @retval buf Buffer in user space
539 * @returns Count value
541 * @brief Read the video device
543 * This function is called by the application is reading the video device.
545 static ssize_t
v4l_microdia_read(struct file
*fp
, char __user
*buf
,
546 size_t count
, loff_t
*f_pos
)
550 struct v4l2_buffer buffer
;
551 struct usb_microdia
*dev
;
553 dev
= video_get_drvdata(video_devdata(fp
));
555 ret
= v4l_get_privileges(fp
);
559 if (dev
->mode
!= MICRODIA_MODE_IDLE
&&
560 dev
->mode
!= MICRODIA_MODE_READ
)
563 buffer
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
564 buffer
.memory
= V4L2_MEMORY_MMAP
;
565 if (dev
->mode
== MICRODIA_MODE_IDLE
) {
566 nbuffers
= microdia_alloc_buffers(&dev
->queue
, 2,
567 MICRODIA_FRAME_SIZE
);
571 for (i
= 0; i
< nbuffers
; i
++) {
572 buffer
= dev
->queue
.buffer
[i
].buf
;
573 microdia_queue_buffer(&dev
->queue
, &buffer
);
576 ret
= v4l2_enable_video(dev
, MICRODIA_MODE_READ
);
581 if (dev
->queue
.read_buffer
== NULL
) {
582 ret
= microdia_dequeue_buffer(&dev
->queue
, &buffer
,
583 fp
->f_flags
& O_NONBLOCK
);
587 microdia_decompress(dev
, &buffer
);
588 dev
->queue
.read_buffer
= &dev
->queue
.buffer
[buffer
.index
];
590 buffer
= dev
->queue
.read_buffer
->buf
;
593 count
= min((size_t)(buffer
.bytesused
- *f_pos
), count
);
594 if (copy_to_user(buf
, dev
->queue
.mem
+ buffer
.m
.offset
+ *f_pos
, count
))
598 if (*f_pos
>= buffer
.bytesused
) {
599 dev
->queue
.read_buffer
= NULL
;
600 microdia_queue_buffer(&dev
->queue
, &buffer
);
608 * @param fp File pointer
611 * @returns 0 if all is OK
613 * @brief Polling function
615 static unsigned int v4l_microdia_poll(struct file
*fp
, poll_table
*wait
)
617 struct usb_microdia
*dev
;
618 struct video_device
*vdev
;
620 vdev
= video_devdata(fp
);
621 dev
= video_get_drvdata(video_devdata(fp
));
623 UDIA_STREAM("Poll\n");
625 if (vdev
== NULL
|| dev
== NULL
)
628 return microdia_queue_poll(&dev
->queue
, fp
, wait
);
631 static void microdia_vm_open(struct vm_area_struct
*vma
)
633 struct microdia_buffer
*buffer
= vma
->vm_private_data
;
634 buffer
->vma_use_count
++;
638 static void microdia_vm_close(struct vm_area_struct
*vma
)
640 struct microdia_buffer
*buffer
= vma
->vm_private_data
;
641 buffer
->vma_use_count
--;
644 struct vm_operations_struct microdia_vm_ops
= {
645 .open
= microdia_vm_open
,
646 .close
= microdia_vm_close
650 * @param fp File pointer
651 * @param vma VMA structure
653 * @returns 0 if all is OK
657 * This function permits to map a memory space.
659 static int v4l_microdia_mmap(struct file
*fp
, struct vm_area_struct
*vma
)
662 unsigned long addr
, start
, size
;
666 struct usb_microdia
*dev
;
667 struct video_device
*vdev
;
668 struct microdia_buffer
*buffer
= NULL
;
670 vdev
= video_devdata(fp
);
671 dev
= video_get_drvdata(video_devdata(fp
));
673 UDIA_STREAM("mmap\n");
675 start
= vma
->vm_start
;
676 size
= vma
->vm_end
- vma
->vm_start
;
678 mutex_lock(&dev
->queue
.mutex
);
680 for (i
= 0; i
< dev
->queue
.count
; ++i
) {
681 buffer
= &dev
->queue
.buffer
[i
];
682 if ((buffer
->buf
.m
.offset
>> PAGE_SHIFT
) == vma
->vm_pgoff
)
686 if (i
== dev
->queue
.count
|| size
!= dev
->queue
.buf_size
) {
691 vma
->vm_flags
|= VM_IO
;
693 addr
= (unsigned long)dev
->queue
.mem
+ buffer
->buf
.m
.offset
;
695 page
= vmalloc_to_page((void *)addr
);
696 ret
= vm_insert_page(vma
, start
, page
);
705 vma
->vm_ops
= µdia_vm_ops
;
706 vma
->vm_private_data
= buffer
;
707 microdia_vm_open(vma
);
709 mutex_unlock(&dev
->queue
.mutex
);
713 int microdia_vidioc_querycap(struct file
*file
, void *priv
,
714 struct v4l2_capability
*cap
)
716 struct usb_microdia
*dev
;
718 dev
= video_get_drvdata(priv
);
720 UDIA_DEBUG("VIDIOC_QUERYCAP\n");
722 strlcpy(cap
->driver
, "microdia", sizeof(cap
->driver
));
723 cap
->capabilities
= V4L2_CAP_VIDEO_CAPTURE
| V4L2_CAP_STREAMING
724 | V4L2_CAP_READWRITE
;
725 cap
->version
= (__u32
) DRIVER_VERSION_NUM
,
726 strlcpy(cap
->card
, dev
->vdev
->name
, sizeof(cap
->card
));
728 if (usb_make_path(dev
->udev
, cap
->bus_info
, sizeof(cap
->bus_info
)) < 0)
729 strlcpy(cap
->bus_info
, dev
->vdev
->name
, sizeof(cap
->bus_info
));
733 int microdia_vidioc_enum_input(struct file
*file
, void *priv
,
734 struct v4l2_input
*input
)
736 UDIA_DEBUG("VIDIOC_ENUMINPUT %d\n", input
->index
);
741 strlcpy(input
->name
, "Webcam", sizeof(input
->name
));
742 input
->type
= V4L2_INPUT_TYPE_CAMERA
;
748 int microdia_vidioc_g_input(struct file
*file
, void *priv
, unsigned int *index
)
750 UDIA_DEBUG("GET INPUT %d\n", *index
);
758 int microdia_vidioc_s_input(struct file
*file
, void *priv
, unsigned int index
)
760 UDIA_DEBUG("SET INPUT %d\n", index
);
762 if (v4l_get_privileges(file
) < 0)
771 int microdia_vidioc_queryctrl(struct file
*file
, void *priv
,
772 struct v4l2_queryctrl
*ctrl
)
777 UDIA_DEBUG("VIDIOC_QUERYCTRL id = %d\n", ctrl
->id
);
779 nbr
= sizeof(microdia_controls
)/sizeof(struct v4l2_queryctrl
);
781 for (i
= 0; i
< nbr
; i
++) {
782 if (microdia_controls
[i
].id
== ctrl
->id
) {
783 UDIA_DEBUG("VIDIOC_QUERYCTRL found\n");
784 memcpy(ctrl
, µdia_controls
[i
],
785 sizeof(struct v4l2_queryctrl
));
796 int microdia_vidioc_g_ctrl(struct file
*file
, void *priv
,
797 struct v4l2_control
*ctrl
)
799 struct usb_microdia
*dev
;
801 dev
= video_get_drvdata(priv
);
803 UDIA_DEBUG("GET CTRL id=%d\n", ctrl
->id
);
806 case V4L2_CID_BRIGHTNESS
:
807 ctrl
->value
= dev
->vsettings
.brightness
;
810 case V4L2_CID_EXPOSURE
:
811 ctrl
->value
= dev
->vsettings
.exposure
;
814 case V4L2_CID_WHITENESS
:
815 ctrl
->value
= dev
->vsettings
.whiteness
;
818 case V4L2_CID_SATURATION:
819 ctrl->value = dev->vsettings.colour;
822 case V4L2_CID_CONTRAST
:
823 ctrl
->value
= dev
->vsettings
.contrast
;
827 ctrl
->value
= dev
->vsettings
.hflip
;
831 ctrl
->value
= dev
->vsettings
.vflip
;
834 case V4L2_CID_SHARPNESS
:
835 ctrl
->value
= dev
->vsettings
.sharpness
;
838 case V4L2_CID_RED_BALANCE
:
839 ctrl
->value
= dev
->vsettings
.rgb_gain
[0];
842 case V4L2_CID_BLUE_BALANCE
:
843 ctrl
->value
= dev
->vsettings
.rgb_gain
[3];
846 case V4L2_CID_AUTOGAIN
:
847 ctrl
->value
= dev
->vsettings
.auto_exposure
;
850 case V4L2_CID_AUTO_WHITE_BALANCE
:
851 ctrl
->value
= dev
->vsettings
.auto_whitebalance
;
860 int microdia_vidioc_s_ctrl(struct file
*file
, void *priv
,
861 struct v4l2_control
*ctrl
)
863 struct usb_microdia
*dev
;
865 dev
= video_get_drvdata(priv
);
867 UDIA_DEBUG("SET CTRL id=%d value=%d\n", ctrl
->id
, ctrl
->value
);
870 case V4L2_CID_BRIGHTNESS
:
871 dev
->vsettings
.brightness
= (0xff00 & ctrl
->value
);
872 dev_microdia_camera_set_brightness(dev
);
875 case V4L2_CID_EXPOSURE
:
876 dev
->vsettings
.exposure
= (0xff00 & ctrl
->value
);
877 dev_microdia_camera_set_exposure(dev
);
880 case V4L2_CID_WHITENESS
:
881 dev
->vsettings
.whiteness
= (0xff00 & ctrl
->value
);
882 dev_microdia_camera_set_gamma(dev
);
885 case V4L2_CID_SATURATION:
886 dev->vsettings.colour = (0xff00 & ctrl->value);
889 case V4L2_CID_CONTRAST
:
890 dev
->vsettings
.contrast
= (0xff00 & ctrl
->value
);
891 dev_microdia_camera_set_contrast(dev
);
895 dev
->vsettings
.hflip
= ctrl
->value
;
896 dev_microdia_camera_set_hvflip(dev
);
900 dev
->vsettings
.vflip
= ctrl
->value
;
901 dev_microdia_camera_set_hvflip(dev
);
904 case V4L2_CID_SHARPNESS
:
905 dev
->vsettings
.sharpness
= ctrl
->value
;
906 dev_microdia_camera_set_sharpness(dev
);
909 case V4L2_CID_RED_BALANCE
:
910 dev
->vsettings
.rgb_gain
[0] = ctrl
->value
;
911 dev_microdia_camera_set_rgb_gain(dev
);
914 case V4L2_CID_BLUE_BALANCE
:
915 dev
->vsettings
.rgb_gain
[3] = ctrl
->value
;
916 dev_microdia_camera_set_rgb_gain(dev
);
919 case V4L2_CID_AUTOGAIN
:
920 dev
->vsettings
.auto_exposure
= ctrl
->value
;
921 dev_microdia_camera_set_auto_exposure(dev
);
924 case V4L2_CID_AUTO_WHITE_BALANCE
:
925 dev
->vsettings
.auto_whitebalance
= ctrl
->value
;
926 dev_microdia_camera_set_auto_whitebalance(dev
);
936 int microdia_vidioc_enum_fmt_cap(struct file
*file
, void *priv
,
937 struct v4l2_fmtdesc
*fmt
)
939 struct usb_microdia
*dev
;
940 struct v4l2_pix_format
*format
;
942 dev
= video_get_drvdata(priv
);
944 UDIA_DEBUG("VIDIOC_ENUM_FMT %d\n", fmt
->index
);
946 format
= v4l2_enum_supported_formats(dev
, fmt
->index
);
951 fmt
->pixelformat
= format
->pixelformat
;
952 fmt
->description
[0] = fmt
->pixelformat
& 0xFF;
953 fmt
->description
[1] = (fmt
->pixelformat
>> 8) & 0xFF;
954 fmt
->description
[2] = (fmt
->pixelformat
>> 16) & 0xFF;
955 fmt
->description
[3] = fmt
->pixelformat
>> 24;
956 fmt
->description
[4] = 0;
961 int microdia_vidioc_try_fmt_cap(struct file
*file
, void *priv
,
962 struct v4l2_format
*fmt
)
964 struct usb_microdia
*dev
;
966 dev
= video_get_drvdata(priv
);
967 UDIA_DEBUG("TRY FMT %d\n", fmt
->type
);
969 /* when this code is used prevents mplayer from setting outfmt
970 if(fmt->fmt.pix.field != V4L2_FIELD_NONE)
974 if (v4l2_format_supported(dev
, fmt
->fmt
.pix
.pixelformat
) < 0)
977 v4l_microdia_find_resolution(dev
, &fmt
->fmt
.pix
.width
,
978 &fmt
->fmt
.pix
.height
);
980 switch (fmt
->fmt
.pix
.pixelformat
) {
981 case V4L2_PIX_FMT_YUV420
:
982 fmt
->fmt
.pix
.bytesperline
= (fmt
->fmt
.pix
.width
* 3)/2;
983 fmt
->fmt
.pix
.sizeimage
= fmt
->fmt
.pix
.height
*
984 fmt
->fmt
.pix
.bytesperline
;
986 case V4L2_PIX_FMT_RGB24
:
987 case V4L2_PIX_FMT_BGR24
:
988 fmt
->fmt
.pix
.bytesperline
= fmt
->fmt
.pix
.width
* 3;
989 fmt
->fmt
.pix
.sizeimage
= fmt
->fmt
.pix
.height
*
990 fmt
->fmt
.pix
.bytesperline
;
992 case V4L2_PIX_FMT_YUYV
:
993 fmt
->fmt
.pix
.bytesperline
= fmt
->fmt
.pix
.width
* 2;
994 fmt
->fmt
.pix
.sizeimage
= fmt
->fmt
.pix
.height
*
995 fmt
->fmt
.pix
.bytesperline
;
1001 fmt
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SRGB
;
1002 fmt
->fmt
.pix
.priv
= 0;
1007 int microdia_vidioc_g_fmt_cap(struct file
*file
, void *priv
,
1008 struct v4l2_format
*fmt
)
1010 struct usb_microdia
*dev
;
1012 dev
= video_get_drvdata(priv
);
1014 UDIA_DEBUG("GET FMT %d\n", fmt
->type
);
1016 memcpy(&(fmt
->fmt
.pix
), &(dev
->vsettings
.format
), sizeof(fmt
->fmt
.pix
));
1022 int microdia_vidioc_s_fmt_cap(struct file
*file
, void *priv
,
1023 struct v4l2_format
*fmt
)
1025 struct usb_microdia
*dev
;
1028 dev
= video_get_drvdata(priv
);
1030 UDIA_DEBUG("SET FMT %d : %d\n", fmt
->type
, fmt
->fmt
.pix
.pixelformat
);
1032 if (v4l_get_privileges(file
) < 0)
1035 if (dev
->queue
.streaming
)
1038 ret
= microdia_vidioc_try_fmt_cap(file
, priv
, fmt
);
1042 UDIA_DEBUG("Set width=%d, height=%d\n",
1044 fmt
->fmt
.pix
.height
);
1046 ret
= v4l_microdia_find_resolution(dev
, &fmt
->fmt
.pix
.width
,
1047 &fmt
->fmt
.pix
.height
);
1049 v4l_microdia_select_video_mode(dev
, ret
);
1051 memcpy(&(dev
->vsettings
.format
), &(fmt
->fmt
.pix
), sizeof(fmt
->fmt
.pix
));
1056 int microdia_vidioc_reqbufs(struct file
*file
, void *priv
,
1057 struct v4l2_requestbuffers
*request
)
1060 struct usb_microdia
*dev
;
1062 dev
= video_get_drvdata(priv
);
1064 if (v4l_get_privileges(file
) < 0) {
1069 if (request
->memory
!= V4L2_MEMORY_MMAP
||
1070 request
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
) {
1075 if (dev
->queue
.streaming
) {
1080 ret
= microdia_alloc_buffers(&dev
->queue
, request
->count
,
1081 MICRODIA_FRAME_SIZE
);
1085 dev
->queue
.drop_incomplete
= 1;
1087 request
->count
= ret
;
1089 UDIA_INFO("Buffers Allocated %d\n", request
->count
);
1094 int microdia_vidioc_querybuf(struct file
*file
, void *priv
,
1095 struct v4l2_buffer
*buffer
)
1097 struct usb_microdia
*dev
;
1099 dev
= video_get_drvdata(priv
);
1101 UDIA_DEBUG("QUERY BUFFERS %d %d\n", buffer
->index
, dev
->queue
.count
);
1103 if (buffer
->memory
!= V4L2_MEMORY_MMAP
||
1104 buffer
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
1107 if (!v4l_has_privileges(file
))
1110 return microdia_query_buffer(&dev
->queue
, buffer
);
1113 int microdia_vidioc_qbuf(struct file
*file
, void *priv
,
1114 struct v4l2_buffer
*buffer
)
1116 struct usb_microdia
*dev
;
1118 dev
= video_get_drvdata(priv
);
1120 UDIA_DEBUG("VIDIOC_QBUF\n");
1122 if (!v4l_has_privileges(file
)) {
1126 return microdia_queue_buffer(&dev
->queue
, buffer
);
1129 int microdia_vidioc_dqbuf(struct file
*file
, void *priv
,
1130 struct v4l2_buffer
*buffer
)
1132 struct usb_microdia
*dev
;
1135 dev
= video_get_drvdata(priv
);
1137 UDIA_DEBUG("VIDIOC_DQBUF\n");
1139 if (!v4l_has_privileges(file
))
1142 ret
= microdia_dequeue_buffer(&dev
->queue
, buffer
,
1143 file
->f_flags
& O_NONBLOCK
);
1147 microdia_decompress(dev
, buffer
);
1152 int microdia_vidioc_streamon(struct file
*file
, void *priv
,
1153 enum v4l2_buf_type type
)
1155 struct usb_microdia
*dev
;
1157 dev
= video_get_drvdata(priv
);
1159 UDIA_DEBUG("VIDIOC_STREAMON\n");
1161 if (!v4l_has_privileges(file
))
1164 if (dev
->mode
!= MICRODIA_MODE_IDLE
)
1167 return v4l2_enable_video(dev
, MICRODIA_MODE_STREAM
);
1170 int microdia_vidioc_streamoff(struct file
*file
, void *priv
,
1171 enum v4l2_buf_type type
)
1173 struct usb_microdia
*dev
;
1175 dev
= video_get_drvdata(priv
);
1177 UDIA_DEBUG("VIDIOC_STREAMOFF\n");
1179 if (!v4l_has_privileges(file
))
1182 return v4l2_enable_video(dev
, MICRODIA_MODE_IDLE
);
1185 int microdia_vidioc_g_param(struct file
*file
, void *priv
,
1186 struct v4l2_streamparm
*param
)
1188 struct usb_microdia
*dev
;
1191 dev
= video_get_drvdata(priv
);
1193 if (param
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
1196 param
->parm
.capture
.capability
= 0;
1197 param
->parm
.capture
.capturemode
= 0;
1198 param
->parm
.capture
.timeperframe
.numerator
= 1;
1199 param
->parm
.capture
.timeperframe
.denominator
= 30;
1200 param
->parm
.capture
.readbuffers
= 2;
1201 param
->parm
.capture
.extendedmode
= 0;
1206 int microdia_vidioc_s_param(struct file
*file
, void *priv
,
1207 struct v4l2_streamparm
*param
)
1209 struct usb_microdia
*dev
;
1211 dev
= video_get_drvdata(priv
);
1213 if (v4l_get_privileges(file
))
1216 if (param
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
1223 * @param inode Inode pointer
1224 * @param fp File pointer
1225 * @param cmd Command
1226 * @param arg Arguements of the command
1228 * @returns 0 if all is OK
1230 * @brief Manage IOCTL
1232 * This function permits to manage all the IOCTL from the application.
1234 static int v4l_microdia_ioctl(struct inode
*inode
, struct file
*fp
,
1235 unsigned int cmd
, unsigned long arg
)
1238 struct usb_microdia
*dev
;
1239 struct video_device
*vdev
;
1241 vdev
= video_devdata(fp
);
1242 dev
= video_get_drvdata(video_devdata(fp
));
1244 UDIA_DEBUG("v4l_microdia_ioctl %02X\n", (unsigned char) cmd
);
1246 if (dev
== NULL
|| vdev
== NULL
)
1249 err
= video_ioctl2(inode
, fp
, cmd
, arg
);
1256 * @param dev Device structure
1258 * @returns 0 if all is OK
1260 * @brief Register the video device
1262 * This function permits to register the USB device to the video device.
1264 int v4l_microdia_register_video_device(struct usb_microdia
*dev
)
1268 strcpy(dev
->vdev
->name
, DRIVER_DESC
);
1270 dev
->vdev
->dev
= &dev
->interface
->dev
;
1271 dev
->vdev
->owner
= THIS_MODULE
;
1272 dev
->vdev
->type
= VID_TYPE_CAPTURE
;
1273 dev
->vdev
->current_norm
= 0;
1274 dev
->vdev
->tvnorms
= 0;
1275 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
1276 dev
->vdev
->hardware
= VID_HARDWARE_MICRODIA
;
1278 dev
->vdev
->fops
= &v4l_microdia_fops
;
1279 dev
->vdev
->release
= video_device_release
;
1280 dev
->vdev
->minor
= -1;
1281 #if CONFIG_MICRODIA_DEBUG
1282 dev
->vdev
->debug
= V4L2_DEBUG_IOCTL_ARG
;
1284 dev
->vdev
->vidioc_querycap
= microdia_vidioc_querycap
;
1285 dev
->vdev
->vidioc_enum_fmt_cap
= microdia_vidioc_enum_fmt_cap
;
1286 dev
->vdev
->vidioc_try_fmt_cap
= microdia_vidioc_try_fmt_cap
;
1287 dev
->vdev
->vidioc_s_fmt_cap
= microdia_vidioc_s_fmt_cap
;
1288 dev
->vdev
->vidioc_g_fmt_cap
= microdia_vidioc_g_fmt_cap
;
1289 dev
->vdev
->vidioc_enum_input
= microdia_vidioc_enum_input
;
1290 dev
->vdev
->vidioc_g_input
= microdia_vidioc_g_input
;
1291 dev
->vdev
->vidioc_s_input
= microdia_vidioc_s_input
;
1292 dev
->vdev
->vidioc_streamon
= microdia_vidioc_streamon
;
1293 dev
->vdev
->vidioc_streamoff
= microdia_vidioc_streamoff
;
1294 dev
->vdev
->vidioc_queryctrl
= microdia_vidioc_queryctrl
;
1295 dev
->vdev
->vidioc_g_ctrl
= microdia_vidioc_g_ctrl
;
1296 dev
->vdev
->vidioc_s_ctrl
= microdia_vidioc_s_ctrl
;
1297 dev
->vdev
->vidioc_g_parm
= microdia_vidioc_g_param
;
1298 dev
->vdev
->vidioc_s_parm
= microdia_vidioc_s_param
;
1299 dev
->vdev
->vidioc_reqbufs
= microdia_vidioc_reqbufs
;
1300 dev
->vdev
->vidioc_qbuf
= microdia_vidioc_qbuf
;
1301 dev
->vdev
->vidioc_dqbuf
= microdia_vidioc_dqbuf
;
1302 dev
->vdev
->vidioc_querybuf
= microdia_vidioc_querybuf
;
1304 video_set_drvdata(dev
->vdev
, dev
);
1306 microdia_queue_init(&dev
->queue
);
1308 err
= video_register_device(dev
->vdev
, VFL_TYPE_GRABBER
, -1);
1311 UDIA_ERROR("Video register fail !\n");
1313 UDIA_INFO("Microdia USB2.0 Camera is now controlling "
1314 "video device /dev/video%d\n",
1322 * @param dev Device structure
1324 * @returns 0 if all is OK
1326 * @brief Unregister the video device
1328 * This function permits to unregister the video device.
1330 int v4l_microdia_unregister_video_device(struct usb_microdia
*dev
)
1332 UDIA_INFO("Microdia USB2.0 Camera release resources video "
1333 "device /dev/video%d\n", dev
->vdev
->minor
);
1335 video_set_drvdata(dev
->vdev
, NULL
);
1336 video_unregister_device(dev
->vdev
);
1343 * @var v4l_microdia_fops
1345 * This variable contains some callback
1347 static struct file_operations v4l_microdia_fops
= {
1348 .owner
= THIS_MODULE
,
1349 .open
= v4l_microdia_open
,
1350 .release
= v4l_microdia_release
,
1351 .read
= v4l_microdia_read
,
1352 .poll
= v4l_microdia_poll
,
1353 .mmap
= v4l_microdia_mmap
,
1354 .ioctl
= v4l_microdia_ioctl
,
1355 #ifdef CONFIG_COMPAT
1356 .compat_ioctl
= v4l_compat_ioctl32
,