diff options
Diffstat (limited to 'drivers/media/video/videodev.c')
-rw-r--r-- | drivers/media/video/videodev.c | 735 |
1 files changed, 466 insertions, 269 deletions
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 7649860a388d..6616e6570557 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c | |||
@@ -17,15 +17,19 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #define dbgarg(cmd, fmt, arg...) \ | 19 | #define dbgarg(cmd, fmt, arg...) \ |
20 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \ | 20 | do { \ |
21 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \ | ||
21 | printk(KERN_DEBUG "%s: ", vfd->name); \ | 22 | printk(KERN_DEBUG "%s: ", vfd->name); \ |
22 | v4l_printk_ioctl(cmd); \ | 23 | v4l_printk_ioctl(cmd); \ |
23 | printk(" " fmt, ## arg); \ | 24 | printk(" " fmt, ## arg); \ |
24 | } | 25 | } \ |
26 | } while (0) | ||
25 | 27 | ||
26 | #define dbgarg2(fmt, arg...) \ | 28 | #define dbgarg2(fmt, arg...) \ |
27 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ | 29 | do { \ |
28 | printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg); | 30 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ |
31 | printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);\ | ||
32 | } while (0) | ||
29 | 33 | ||
30 | #include <linux/module.h> | 34 | #include <linux/module.h> |
31 | #include <linux/types.h> | 35 | #include <linux/types.h> |
@@ -138,7 +142,7 @@ EXPORT_SYMBOL(v4l2_video_std_construct); | |||
138 | /* ----------------------------------------------------------------- */ | 142 | /* ----------------------------------------------------------------- */ |
139 | /* some arrays for pretty-printing debug messages of enum types */ | 143 | /* some arrays for pretty-printing debug messages of enum types */ |
140 | 144 | ||
141 | char *v4l2_field_names[] = { | 145 | const char *v4l2_field_names[] = { |
142 | [V4L2_FIELD_ANY] = "any", | 146 | [V4L2_FIELD_ANY] = "any", |
143 | [V4L2_FIELD_NONE] = "none", | 147 | [V4L2_FIELD_NONE] = "none", |
144 | [V4L2_FIELD_TOP] = "top", | 148 | [V4L2_FIELD_TOP] = "top", |
@@ -152,19 +156,19 @@ char *v4l2_field_names[] = { | |||
152 | }; | 156 | }; |
153 | EXPORT_SYMBOL(v4l2_field_names); | 157 | EXPORT_SYMBOL(v4l2_field_names); |
154 | 158 | ||
155 | char *v4l2_type_names[] = { | 159 | const char *v4l2_type_names[] = { |
156 | [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap", | 160 | [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "vid-cap", |
157 | [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over", | 161 | [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "vid-overlay", |
158 | [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out", | 162 | [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "vid-out", |
159 | [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap", | 163 | [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap", |
160 | [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", | 164 | [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", |
161 | [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap", | 165 | [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap", |
162 | [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out", | 166 | [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out", |
163 | [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over", | 167 | [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay", |
164 | }; | 168 | }; |
165 | EXPORT_SYMBOL(v4l2_type_names); | 169 | EXPORT_SYMBOL(v4l2_type_names); |
166 | 170 | ||
167 | static char *v4l2_memory_names[] = { | 171 | static const char *v4l2_memory_names[] = { |
168 | [V4L2_MEMORY_MMAP] = "mmap", | 172 | [V4L2_MEMORY_MMAP] = "mmap", |
169 | [V4L2_MEMORY_USERPTR] = "userptr", | 173 | [V4L2_MEMORY_USERPTR] = "userptr", |
170 | [V4L2_MEMORY_OVERLAY] = "overlay", | 174 | [V4L2_MEMORY_OVERLAY] = "overlay", |
@@ -278,6 +282,7 @@ static const char *v4l2_ioctls[] = { | |||
278 | [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER", | 282 | [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER", |
279 | 283 | ||
280 | [_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT", | 284 | [_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT", |
285 | [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK", | ||
281 | #endif | 286 | #endif |
282 | }; | 287 | }; |
283 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) | 288 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) |
@@ -371,6 +376,14 @@ EXPORT_SYMBOL(v4l_printk_ioctl); | |||
371 | * sysfs stuff | 376 | * sysfs stuff |
372 | */ | 377 | */ |
373 | 378 | ||
379 | static ssize_t show_index(struct device *cd, | ||
380 | struct device_attribute *attr, char *buf) | ||
381 | { | ||
382 | struct video_device *vfd = container_of(cd, struct video_device, | ||
383 | class_dev); | ||
384 | return sprintf(buf, "%i\n", vfd->index); | ||
385 | } | ||
386 | |||
374 | static ssize_t show_name(struct device *cd, | 387 | static ssize_t show_name(struct device *cd, |
375 | struct device_attribute *attr, char *buf) | 388 | struct device_attribute *attr, char *buf) |
376 | { | 389 | { |
@@ -379,6 +392,12 @@ static ssize_t show_name(struct device *cd, | |||
379 | return sprintf(buf, "%.*s\n", (int)sizeof(vfd->name), vfd->name); | 392 | return sprintf(buf, "%.*s\n", (int)sizeof(vfd->name), vfd->name); |
380 | } | 393 | } |
381 | 394 | ||
395 | static struct device_attribute video_device_attrs[] = { | ||
396 | __ATTR(name, S_IRUGO, show_name, NULL), | ||
397 | __ATTR(index, S_IRUGO, show_index, NULL), | ||
398 | __ATTR_NULL | ||
399 | }; | ||
400 | |||
382 | struct video_device *video_device_alloc(void) | 401 | struct video_device *video_device_alloc(void) |
383 | { | 402 | { |
384 | struct video_device *vfd; | 403 | struct video_device *vfd; |
@@ -407,11 +426,6 @@ static void video_release(struct device *cd) | |||
407 | vfd->release(vfd); | 426 | vfd->release(vfd); |
408 | } | 427 | } |
409 | 428 | ||
410 | static struct device_attribute video_device_attrs[] = { | ||
411 | __ATTR(name, S_IRUGO, show_name, NULL), | ||
412 | __ATTR_NULL | ||
413 | }; | ||
414 | |||
415 | static struct class video_class = { | 429 | static struct class video_class = { |
416 | .name = VIDEO_NAME, | 430 | .name = VIDEO_NAME, |
417 | .dev_attrs = video_device_attrs, | 431 | .dev_attrs = video_device_attrs, |
@@ -650,7 +664,7 @@ static void dbgbuf(unsigned int cmd, struct video_device *vfd, | |||
650 | p->field, p->sequence, | 664 | p->field, p->sequence, |
651 | prt_names(p->memory, v4l2_memory_names), | 665 | prt_names(p->memory, v4l2_memory_names), |
652 | p->m.userptr, p->length); | 666 | p->m.userptr, p->length); |
653 | dbgarg2 ("timecode= %02d:%02d:%02d type=%d, " | 667 | dbgarg2("timecode=%02d:%02d:%02d type=%d, " |
654 | "flags=0x%08d, frames=%d, userbits=0x%08x\n", | 668 | "flags=0x%08d, frames=%d, userbits=0x%08x\n", |
655 | tc->hours,tc->minutes,tc->seconds, | 669 | tc->hours,tc->minutes,tc->seconds, |
656 | tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits); | 670 | tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits); |
@@ -659,7 +673,7 @@ static void dbgbuf(unsigned int cmd, struct video_device *vfd, | |||
659 | static inline void dbgrect(struct video_device *vfd, char *s, | 673 | static inline void dbgrect(struct video_device *vfd, char *s, |
660 | struct v4l2_rect *r) | 674 | struct v4l2_rect *r) |
661 | { | 675 | { |
662 | dbgarg2 ("%sRect start at %dx%d, size= %dx%d\n", s, r->left, r->top, | 676 | dbgarg2("%sRect start at %dx%d, size=%dx%d\n", s, r->left, r->top, |
663 | r->width, r->height); | 677 | r->width, r->height); |
664 | }; | 678 | }; |
665 | 679 | ||
@@ -677,40 +691,85 @@ static inline void v4l_print_pix_fmt (struct video_device *vfd, | |||
677 | fmt->bytesperline, fmt->sizeimage, fmt->colorspace); | 691 | fmt->bytesperline, fmt->sizeimage, fmt->colorspace); |
678 | }; | 692 | }; |
679 | 693 | ||
694 | static inline void v4l_print_ext_ctrls(unsigned int cmd, | ||
695 | struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals) | ||
696 | { | ||
697 | __u32 i; | ||
698 | |||
699 | if (!(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) | ||
700 | return; | ||
701 | dbgarg(cmd, ""); | ||
702 | printk(KERN_CONT "class=0x%x", c->ctrl_class); | ||
703 | for (i = 0; i < c->count; i++) { | ||
704 | if (show_vals) | ||
705 | printk(KERN_CONT " id/val=0x%x/0x%x", | ||
706 | c->controls[i].id, c->controls[i].value); | ||
707 | else | ||
708 | printk(KERN_CONT " id=0x%x", c->controls[i].id); | ||
709 | } | ||
710 | printk(KERN_CONT "\n"); | ||
711 | }; | ||
712 | |||
713 | static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv) | ||
714 | { | ||
715 | __u32 i; | ||
716 | |||
717 | /* zero the reserved fields */ | ||
718 | c->reserved[0] = c->reserved[1] = 0; | ||
719 | for (i = 0; i < c->count; i++) { | ||
720 | c->controls[i].reserved2[0] = 0; | ||
721 | c->controls[i].reserved2[1] = 0; | ||
722 | } | ||
723 | /* V4L2_CID_PRIVATE_BASE cannot be used as control class | ||
724 | when using extended controls. | ||
725 | Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL | ||
726 | is it allowed for backwards compatibility. | ||
727 | */ | ||
728 | if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE) | ||
729 | return 0; | ||
730 | /* Check that all controls are from the same control class. */ | ||
731 | for (i = 0; i < c->count; i++) { | ||
732 | if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) { | ||
733 | c->error_idx = i; | ||
734 | return 0; | ||
735 | } | ||
736 | } | ||
737 | return 1; | ||
738 | } | ||
680 | 739 | ||
681 | static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type) | 740 | static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type) |
682 | { | 741 | { |
683 | switch (type) { | 742 | switch (type) { |
684 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 743 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
685 | if (vfd->vidioc_try_fmt_cap) | 744 | if (vfd->vidioc_try_fmt_vid_cap) |
686 | return (0); | 745 | return (0); |
687 | break; | 746 | break; |
688 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 747 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
689 | if (vfd->vidioc_try_fmt_overlay) | 748 | if (vfd->vidioc_try_fmt_vid_overlay) |
690 | return (0); | 749 | return (0); |
691 | break; | 750 | break; |
692 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 751 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: |
693 | if (vfd->vidioc_try_fmt_vbi) | 752 | if (vfd->vidioc_try_fmt_vid_out) |
694 | return (0); | 753 | return (0); |
695 | break; | 754 | break; |
696 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: | 755 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: |
697 | if (vfd->vidioc_try_fmt_vbi_output) | 756 | if (vfd->vidioc_try_fmt_vid_out_overlay) |
698 | return (0); | 757 | return (0); |
699 | break; | 758 | break; |
700 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | 759 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
701 | if (vfd->vidioc_try_fmt_vbi_capture) | 760 | if (vfd->vidioc_try_fmt_vbi_cap) |
702 | return (0); | 761 | return (0); |
703 | break; | 762 | break; |
704 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | 763 | case V4L2_BUF_TYPE_VBI_OUTPUT: |
705 | if (vfd->vidioc_try_fmt_video_output) | 764 | if (vfd->vidioc_try_fmt_vbi_out) |
706 | return (0); | 765 | return (0); |
707 | break; | 766 | break; |
708 | case V4L2_BUF_TYPE_VBI_OUTPUT: | 767 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: |
709 | if (vfd->vidioc_try_fmt_vbi_output) | 768 | if (vfd->vidioc_try_fmt_sliced_vbi_cap) |
710 | return (0); | 769 | return (0); |
711 | break; | 770 | break; |
712 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: | 771 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: |
713 | if (vfd->vidioc_try_fmt_output_overlay) | 772 | if (vfd->vidioc_try_fmt_sliced_vbi_out) |
714 | return (0); | 773 | return (0); |
715 | break; | 774 | break; |
716 | case V4L2_BUF_TYPE_PRIVATE: | 775 | case V4L2_BUF_TYPE_PRIVATE: |
@@ -827,46 +886,37 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
827 | 886 | ||
828 | switch (type) { | 887 | switch (type) { |
829 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 888 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
830 | if (vfd->vidioc_enum_fmt_cap) | 889 | if (vfd->vidioc_enum_fmt_vid_cap) |
831 | ret=vfd->vidioc_enum_fmt_cap(file, fh, f); | 890 | ret = vfd->vidioc_enum_fmt_vid_cap(file, fh, f); |
832 | break; | 891 | break; |
833 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 892 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
834 | if (vfd->vidioc_enum_fmt_overlay) | 893 | if (vfd->vidioc_enum_fmt_vid_overlay) |
835 | ret=vfd->vidioc_enum_fmt_overlay(file, fh, f); | 894 | ret = vfd->vidioc_enum_fmt_vid_overlay(file, |
895 | fh, f); | ||
836 | break; | 896 | break; |
897 | #if 1 | ||
898 | /* V4L2_BUF_TYPE_VBI_CAPTURE should not support VIDIOC_ENUM_FMT | ||
899 | * according to the spec. The bttv and saa7134 drivers support | ||
900 | * it though, so just warn that this is deprecated and will be | ||
901 | * removed in the near future. */ | ||
837 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 902 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
838 | if (vfd->vidioc_enum_fmt_vbi) | 903 | if (vfd->vidioc_enum_fmt_vbi_cap) { |
839 | ret=vfd->vidioc_enum_fmt_vbi(file, fh, f); | 904 | printk(KERN_WARNING "vidioc_enum_fmt_vbi_cap will be removed in 2.6.28!\n"); |
840 | break; | 905 | ret = vfd->vidioc_enum_fmt_vbi_cap(file, fh, f); |
841 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: | 906 | } |
842 | if (vfd->vidioc_enum_fmt_vbi_output) | ||
843 | ret=vfd->vidioc_enum_fmt_vbi_output(file, | ||
844 | fh, f); | ||
845 | break; | ||
846 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | ||
847 | if (vfd->vidioc_enum_fmt_vbi_capture) | ||
848 | ret=vfd->vidioc_enum_fmt_vbi_capture(file, | ||
849 | fh, f); | ||
850 | break; | 907 | break; |
908 | #endif | ||
851 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | 909 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: |
852 | if (vfd->vidioc_enum_fmt_video_output) | 910 | if (vfd->vidioc_enum_fmt_vid_out) |
853 | ret=vfd->vidioc_enum_fmt_video_output(file, | 911 | ret = vfd->vidioc_enum_fmt_vid_out(file, fh, f); |
854 | fh, f); | ||
855 | break; | ||
856 | case V4L2_BUF_TYPE_VBI_OUTPUT: | ||
857 | if (vfd->vidioc_enum_fmt_vbi_output) | ||
858 | ret=vfd->vidioc_enum_fmt_vbi_output(file, | ||
859 | fh, f); | ||
860 | break; | ||
861 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: | ||
862 | if (vfd->vidioc_enum_fmt_output_overlay) | ||
863 | ret=vfd->vidioc_enum_fmt_output_overlay(file, fh, f); | ||
864 | break; | 912 | break; |
865 | case V4L2_BUF_TYPE_PRIVATE: | 913 | case V4L2_BUF_TYPE_PRIVATE: |
866 | if (vfd->vidioc_enum_fmt_type_private) | 914 | if (vfd->vidioc_enum_fmt_type_private) |
867 | ret=vfd->vidioc_enum_fmt_type_private(file, | 915 | ret = vfd->vidioc_enum_fmt_type_private(file, |
868 | fh, f); | 916 | fh, f); |
869 | break; | 917 | break; |
918 | default: | ||
919 | break; | ||
870 | } | 920 | } |
871 | if (!ret) | 921 | if (!ret) |
872 | dbgarg (cmd, "index=%d, type=%d, flags=%d, " | 922 | dbgarg (cmd, "index=%d, type=%d, flags=%d, " |
@@ -882,54 +932,56 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
882 | case VIDIOC_G_FMT: | 932 | case VIDIOC_G_FMT: |
883 | { | 933 | { |
884 | struct v4l2_format *f = (struct v4l2_format *)arg; | 934 | struct v4l2_format *f = (struct v4l2_format *)arg; |
885 | enum v4l2_buf_type type=f->type; | ||
886 | 935 | ||
887 | memset(&f->fmt.pix,0,sizeof(f->fmt.pix)); | 936 | memset(f->fmt.raw_data, 0, sizeof(f->fmt.raw_data)); |
888 | f->type=type; | ||
889 | 937 | ||
890 | /* FIXME: Should be one dump per type */ | 938 | /* FIXME: Should be one dump per type */ |
891 | dbgarg (cmd, "type=%s\n", prt_names(type, | 939 | dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names)); |
892 | v4l2_type_names)); | ||
893 | 940 | ||
894 | switch (type) { | 941 | switch (f->type) { |
895 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 942 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
896 | if (vfd->vidioc_g_fmt_cap) | 943 | if (vfd->vidioc_g_fmt_vid_cap) |
897 | ret=vfd->vidioc_g_fmt_cap(file, fh, f); | 944 | ret = vfd->vidioc_g_fmt_vid_cap(file, fh, f); |
898 | if (!ret) | 945 | if (!ret) |
899 | v4l_print_pix_fmt(vfd,&f->fmt.pix); | 946 | v4l_print_pix_fmt(vfd, &f->fmt.pix); |
900 | break; | 947 | break; |
901 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 948 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
902 | if (vfd->vidioc_g_fmt_overlay) | 949 | if (vfd->vidioc_g_fmt_vid_overlay) |
903 | ret=vfd->vidioc_g_fmt_overlay(file, fh, f); | 950 | ret = vfd->vidioc_g_fmt_vid_overlay(file, |
904 | break; | 951 | fh, f); |
905 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
906 | if (vfd->vidioc_g_fmt_vbi) | ||
907 | ret=vfd->vidioc_g_fmt_vbi(file, fh, f); | ||
908 | break; | ||
909 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: | ||
910 | if (vfd->vidioc_g_fmt_vbi_output) | ||
911 | ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f); | ||
912 | break; | ||
913 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | ||
914 | if (vfd->vidioc_g_fmt_vbi_capture) | ||
915 | ret=vfd->vidioc_g_fmt_vbi_capture(file, fh, f); | ||
916 | break; | 952 | break; |
917 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | 953 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: |
918 | if (vfd->vidioc_g_fmt_video_output) | 954 | if (vfd->vidioc_g_fmt_vid_out) |
919 | ret=vfd->vidioc_g_fmt_video_output(file, | 955 | ret = vfd->vidioc_g_fmt_vid_out(file, fh, f); |
920 | fh, f); | 956 | if (!ret) |
957 | v4l_print_pix_fmt(vfd, &f->fmt.pix); | ||
921 | break; | 958 | break; |
922 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: | 959 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: |
923 | if (vfd->vidioc_g_fmt_output_overlay) | 960 | if (vfd->vidioc_g_fmt_vid_out_overlay) |
924 | ret=vfd->vidioc_g_fmt_output_overlay(file, fh, f); | 961 | ret = vfd->vidioc_g_fmt_vid_out_overlay(file, |
962 | fh, f); | ||
963 | break; | ||
964 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
965 | if (vfd->vidioc_g_fmt_vbi_cap) | ||
966 | ret = vfd->vidioc_g_fmt_vbi_cap(file, fh, f); | ||
925 | break; | 967 | break; |
926 | case V4L2_BUF_TYPE_VBI_OUTPUT: | 968 | case V4L2_BUF_TYPE_VBI_OUTPUT: |
927 | if (vfd->vidioc_g_fmt_vbi_output) | 969 | if (vfd->vidioc_g_fmt_vbi_out) |
928 | ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f); | 970 | ret = vfd->vidioc_g_fmt_vbi_out(file, fh, f); |
971 | break; | ||
972 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | ||
973 | if (vfd->vidioc_g_fmt_sliced_vbi_cap) | ||
974 | ret = vfd->vidioc_g_fmt_sliced_vbi_cap(file, | ||
975 | fh, f); | ||
976 | break; | ||
977 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: | ||
978 | if (vfd->vidioc_g_fmt_sliced_vbi_out) | ||
979 | ret = vfd->vidioc_g_fmt_sliced_vbi_out(file, | ||
980 | fh, f); | ||
929 | break; | 981 | break; |
930 | case V4L2_BUF_TYPE_PRIVATE: | 982 | case V4L2_BUF_TYPE_PRIVATE: |
931 | if (vfd->vidioc_g_fmt_type_private) | 983 | if (vfd->vidioc_g_fmt_type_private) |
932 | ret=vfd->vidioc_g_fmt_type_private(file, | 984 | ret = vfd->vidioc_g_fmt_type_private(file, |
933 | fh, f); | 985 | fh, f); |
934 | break; | 986 | break; |
935 | } | 987 | } |
@@ -941,48 +993,50 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
941 | struct v4l2_format *f = (struct v4l2_format *)arg; | 993 | struct v4l2_format *f = (struct v4l2_format *)arg; |
942 | 994 | ||
943 | /* FIXME: Should be one dump per type */ | 995 | /* FIXME: Should be one dump per type */ |
944 | dbgarg (cmd, "type=%s\n", prt_names(f->type, | 996 | dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names)); |
945 | v4l2_type_names)); | ||
946 | 997 | ||
947 | switch (f->type) { | 998 | switch (f->type) { |
948 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 999 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
949 | v4l_print_pix_fmt(vfd,&f->fmt.pix); | 1000 | v4l_print_pix_fmt(vfd, &f->fmt.pix); |
950 | if (vfd->vidioc_s_fmt_cap) | 1001 | if (vfd->vidioc_s_fmt_vid_cap) |
951 | ret=vfd->vidioc_s_fmt_cap(file, fh, f); | 1002 | ret = vfd->vidioc_s_fmt_vid_cap(file, fh, f); |
952 | break; | 1003 | break; |
953 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 1004 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
954 | if (vfd->vidioc_s_fmt_overlay) | 1005 | if (vfd->vidioc_s_fmt_vid_overlay) |
955 | ret=vfd->vidioc_s_fmt_overlay(file, fh, f); | 1006 | ret = vfd->vidioc_s_fmt_vid_overlay(file, |
956 | break; | 1007 | fh, f); |
957 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
958 | if (vfd->vidioc_s_fmt_vbi) | ||
959 | ret=vfd->vidioc_s_fmt_vbi(file, fh, f); | ||
960 | break; | ||
961 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: | ||
962 | if (vfd->vidioc_s_fmt_vbi_output) | ||
963 | ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f); | ||
964 | break; | ||
965 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | ||
966 | if (vfd->vidioc_s_fmt_vbi_capture) | ||
967 | ret=vfd->vidioc_s_fmt_vbi_capture(file, fh, f); | ||
968 | break; | 1008 | break; |
969 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | 1009 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: |
970 | if (vfd->vidioc_s_fmt_video_output) | 1010 | v4l_print_pix_fmt(vfd, &f->fmt.pix); |
971 | ret=vfd->vidioc_s_fmt_video_output(file, | 1011 | if (vfd->vidioc_s_fmt_vid_out) |
972 | fh, f); | 1012 | ret = vfd->vidioc_s_fmt_vid_out(file, fh, f); |
973 | break; | 1013 | break; |
974 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: | 1014 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: |
975 | if (vfd->vidioc_s_fmt_output_overlay) | 1015 | if (vfd->vidioc_s_fmt_vid_out_overlay) |
976 | ret=vfd->vidioc_s_fmt_output_overlay(file, fh, f); | 1016 | ret = vfd->vidioc_s_fmt_vid_out_overlay(file, |
1017 | fh, f); | ||
1018 | break; | ||
1019 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
1020 | if (vfd->vidioc_s_fmt_vbi_cap) | ||
1021 | ret = vfd->vidioc_s_fmt_vbi_cap(file, fh, f); | ||
977 | break; | 1022 | break; |
978 | case V4L2_BUF_TYPE_VBI_OUTPUT: | 1023 | case V4L2_BUF_TYPE_VBI_OUTPUT: |
979 | if (vfd->vidioc_s_fmt_vbi_output) | 1024 | if (vfd->vidioc_s_fmt_vbi_out) |
980 | ret=vfd->vidioc_s_fmt_vbi_output(file, | 1025 | ret = vfd->vidioc_s_fmt_vbi_out(file, fh, f); |
981 | fh, f); | 1026 | break; |
1027 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | ||
1028 | if (vfd->vidioc_s_fmt_sliced_vbi_cap) | ||
1029 | ret = vfd->vidioc_s_fmt_sliced_vbi_cap(file, | ||
1030 | fh, f); | ||
1031 | break; | ||
1032 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: | ||
1033 | if (vfd->vidioc_s_fmt_sliced_vbi_out) | ||
1034 | ret = vfd->vidioc_s_fmt_sliced_vbi_out(file, | ||
1035 | fh, f); | ||
982 | break; | 1036 | break; |
983 | case V4L2_BUF_TYPE_PRIVATE: | 1037 | case V4L2_BUF_TYPE_PRIVATE: |
984 | if (vfd->vidioc_s_fmt_type_private) | 1038 | if (vfd->vidioc_s_fmt_type_private) |
985 | ret=vfd->vidioc_s_fmt_type_private(file, | 1039 | ret = vfd->vidioc_s_fmt_type_private(file, |
986 | fh, f); | 1040 | fh, f); |
987 | break; | 1041 | break; |
988 | } | 1042 | } |
@@ -997,46 +1051,48 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
997 | v4l2_type_names)); | 1051 | v4l2_type_names)); |
998 | switch (f->type) { | 1052 | switch (f->type) { |
999 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 1053 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
1000 | if (vfd->vidioc_try_fmt_cap) | 1054 | if (vfd->vidioc_try_fmt_vid_cap) |
1001 | ret=vfd->vidioc_try_fmt_cap(file, fh, f); | 1055 | ret = vfd->vidioc_try_fmt_vid_cap(file, fh, f); |
1002 | if (!ret) | 1056 | if (!ret) |
1003 | v4l_print_pix_fmt(vfd,&f->fmt.pix); | 1057 | v4l_print_pix_fmt(vfd, &f->fmt.pix); |
1004 | break; | 1058 | break; |
1005 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 1059 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
1006 | if (vfd->vidioc_try_fmt_overlay) | 1060 | if (vfd->vidioc_try_fmt_vid_overlay) |
1007 | ret=vfd->vidioc_try_fmt_overlay(file, fh, f); | 1061 | ret = vfd->vidioc_try_fmt_vid_overlay(file, |
1062 | fh, f); | ||
1063 | break; | ||
1064 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | ||
1065 | if (vfd->vidioc_try_fmt_vid_out) | ||
1066 | ret = vfd->vidioc_try_fmt_vid_out(file, fh, f); | ||
1067 | if (!ret) | ||
1068 | v4l_print_pix_fmt(vfd, &f->fmt.pix); | ||
1069 | break; | ||
1070 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: | ||
1071 | if (vfd->vidioc_try_fmt_vid_out_overlay) | ||
1072 | ret = vfd->vidioc_try_fmt_vid_out_overlay(file, | ||
1073 | fh, f); | ||
1008 | break; | 1074 | break; |
1009 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 1075 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
1010 | if (vfd->vidioc_try_fmt_vbi) | 1076 | if (vfd->vidioc_try_fmt_vbi_cap) |
1011 | ret=vfd->vidioc_try_fmt_vbi(file, fh, f); | 1077 | ret = vfd->vidioc_try_fmt_vbi_cap(file, fh, f); |
1012 | break; | 1078 | break; |
1013 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: | 1079 | case V4L2_BUF_TYPE_VBI_OUTPUT: |
1014 | if (vfd->vidioc_try_fmt_vbi_output) | 1080 | if (vfd->vidioc_try_fmt_vbi_out) |
1015 | ret=vfd->vidioc_try_fmt_vbi_output(file, | 1081 | ret = vfd->vidioc_try_fmt_vbi_out(file, fh, f); |
1016 | fh, f); | ||
1017 | break; | 1082 | break; |
1018 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | 1083 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: |
1019 | if (vfd->vidioc_try_fmt_vbi_capture) | 1084 | if (vfd->vidioc_try_fmt_sliced_vbi_cap) |
1020 | ret=vfd->vidioc_try_fmt_vbi_capture(file, | 1085 | ret = vfd->vidioc_try_fmt_sliced_vbi_cap(file, |
1021 | fh, f); | ||
1022 | break; | ||
1023 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | ||
1024 | if (vfd->vidioc_try_fmt_video_output) | ||
1025 | ret=vfd->vidioc_try_fmt_video_output(file, | ||
1026 | fh, f); | 1086 | fh, f); |
1027 | break; | 1087 | break; |
1028 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: | 1088 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: |
1029 | if (vfd->vidioc_try_fmt_output_overlay) | 1089 | if (vfd->vidioc_try_fmt_sliced_vbi_out) |
1030 | ret=vfd->vidioc_try_fmt_output_overlay(file, fh, f); | 1090 | ret = vfd->vidioc_try_fmt_sliced_vbi_out(file, |
1031 | break; | ||
1032 | case V4L2_BUF_TYPE_VBI_OUTPUT: | ||
1033 | if (vfd->vidioc_try_fmt_vbi_output) | ||
1034 | ret=vfd->vidioc_try_fmt_vbi_output(file, | ||
1035 | fh, f); | 1091 | fh, f); |
1036 | break; | 1092 | break; |
1037 | case V4L2_BUF_TYPE_PRIVATE: | 1093 | case V4L2_BUF_TYPE_PRIVATE: |
1038 | if (vfd->vidioc_try_fmt_type_private) | 1094 | if (vfd->vidioc_try_fmt_type_private) |
1039 | ret=vfd->vidioc_try_fmt_type_private(file, | 1095 | ret = vfd->vidioc_try_fmt_type_private(file, |
1040 | fh, f); | 1096 | fh, f); |
1041 | break; | 1097 | break; |
1042 | } | 1098 | } |
@@ -1120,29 +1176,29 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
1120 | } | 1176 | } |
1121 | case VIDIOC_G_FBUF: | 1177 | case VIDIOC_G_FBUF: |
1122 | { | 1178 | { |
1123 | struct v4l2_framebuffer *p=arg; | 1179 | struct v4l2_framebuffer *p = arg; |
1180 | |||
1124 | if (!vfd->vidioc_g_fbuf) | 1181 | if (!vfd->vidioc_g_fbuf) |
1125 | break; | 1182 | break; |
1126 | ret=vfd->vidioc_g_fbuf(file, fh, arg); | 1183 | ret = vfd->vidioc_g_fbuf(file, fh, arg); |
1127 | if (!ret) { | 1184 | if (!ret) { |
1128 | dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n", | 1185 | dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n", |
1129 | p->capability,p->flags, | 1186 | p->capability, p->flags, |
1130 | (unsigned long)p->base); | 1187 | (unsigned long)p->base); |
1131 | v4l_print_pix_fmt (vfd, &p->fmt); | 1188 | v4l_print_pix_fmt(vfd, &p->fmt); |
1132 | } | 1189 | } |
1133 | break; | 1190 | break; |
1134 | } | 1191 | } |
1135 | case VIDIOC_S_FBUF: | 1192 | case VIDIOC_S_FBUF: |
1136 | { | 1193 | { |
1137 | struct v4l2_framebuffer *p=arg; | 1194 | struct v4l2_framebuffer *p = arg; |
1195 | |||
1138 | if (!vfd->vidioc_s_fbuf) | 1196 | if (!vfd->vidioc_s_fbuf) |
1139 | break; | 1197 | break; |
1140 | 1198 | dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n", | |
1141 | dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n", | 1199 | p->capability, p->flags, (unsigned long)p->base); |
1142 | p->capability,p->flags,(unsigned long)p->base); | 1200 | v4l_print_pix_fmt(vfd, &p->fmt); |
1143 | v4l_print_pix_fmt (vfd, &p->fmt); | 1201 | ret = vfd->vidioc_s_fbuf(file, fh, arg); |
1144 | ret=vfd->vidioc_s_fbuf(file, fh, arg); | ||
1145 | |||
1146 | break; | 1202 | break; |
1147 | } | 1203 | } |
1148 | case VIDIOC_STREAMON: | 1204 | case VIDIOC_STREAMON: |
@@ -1194,7 +1250,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
1194 | v4l2_video_std_construct(p, curr_id, descr); | 1250 | v4l2_video_std_construct(p, curr_id, descr); |
1195 | p->index = index; | 1251 | p->index = index; |
1196 | 1252 | ||
1197 | dbgarg(cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, " | 1253 | dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, " |
1198 | "framelines=%d\n", p->index, | 1254 | "framelines=%d\n", p->index, |
1199 | (unsigned long long)p->id, p->name, | 1255 | (unsigned long long)p->id, p->name, |
1200 | p->frameperiod.numerator, | 1256 | p->frameperiod.numerator, |
@@ -1208,18 +1264,22 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
1208 | { | 1264 | { |
1209 | v4l2_std_id *id = arg; | 1265 | v4l2_std_id *id = arg; |
1210 | 1266 | ||
1211 | *id = vfd->current_norm; | 1267 | ret = 0; |
1212 | 1268 | /* Calls the specific handler */ | |
1213 | dbgarg (cmd, "value=%08Lx\n", (long long unsigned) *id); | 1269 | if (vfd->vidioc_g_std) |
1270 | ret = vfd->vidioc_g_std(file, fh, id); | ||
1271 | else | ||
1272 | *id = vfd->current_norm; | ||
1214 | 1273 | ||
1215 | ret=0; | 1274 | if (!ret) |
1275 | dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id); | ||
1216 | break; | 1276 | break; |
1217 | } | 1277 | } |
1218 | case VIDIOC_S_STD: | 1278 | case VIDIOC_S_STD: |
1219 | { | 1279 | { |
1220 | v4l2_std_id *id = arg,norm; | 1280 | v4l2_std_id *id = arg,norm; |
1221 | 1281 | ||
1222 | dbgarg (cmd, "value=%08Lx\n", (long long unsigned) *id); | 1282 | dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id); |
1223 | 1283 | ||
1224 | norm = (*id) & vfd->tvnorms; | 1284 | norm = (*id) & vfd->tvnorms; |
1225 | if ( vfd->tvnorms && !norm) /* Check if std is supported */ | 1285 | if ( vfd->tvnorms && !norm) /* Check if std is supported */ |
@@ -1295,6 +1355,25 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
1295 | } | 1355 | } |
1296 | 1356 | ||
1297 | /* ------ output switching ---------- */ | 1357 | /* ------ output switching ---------- */ |
1358 | case VIDIOC_ENUMOUTPUT: | ||
1359 | { | ||
1360 | struct v4l2_output *p = arg; | ||
1361 | int i = p->index; | ||
1362 | |||
1363 | if (!vfd->vidioc_enum_output) | ||
1364 | break; | ||
1365 | memset(p, 0, sizeof(*p)); | ||
1366 | p->index = i; | ||
1367 | |||
1368 | ret = vfd->vidioc_enum_output(file, fh, p); | ||
1369 | if (!ret) | ||
1370 | dbgarg(cmd, "index=%d, name=%s, type=%d, " | ||
1371 | "audioset=0x%x, " | ||
1372 | "modulator=%d, std=0x%08Lx\n", | ||
1373 | p->index, p->name, p->type, p->audioset, | ||
1374 | p->modulator, (unsigned long long)p->std); | ||
1375 | break; | ||
1376 | } | ||
1298 | case VIDIOC_G_OUTPUT: | 1377 | case VIDIOC_G_OUTPUT: |
1299 | { | 1378 | { |
1300 | unsigned int *i = arg; | 1379 | unsigned int *i = arg; |
@@ -1320,132 +1399,172 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
1320 | /* --- controls ---------------------------------------------- */ | 1399 | /* --- controls ---------------------------------------------- */ |
1321 | case VIDIOC_QUERYCTRL: | 1400 | case VIDIOC_QUERYCTRL: |
1322 | { | 1401 | { |
1323 | struct v4l2_queryctrl *p=arg; | 1402 | struct v4l2_queryctrl *p = arg; |
1324 | 1403 | ||
1325 | if (!vfd->vidioc_queryctrl) | 1404 | if (!vfd->vidioc_queryctrl) |
1326 | break; | 1405 | break; |
1327 | ret=vfd->vidioc_queryctrl(file, fh, p); | 1406 | ret = vfd->vidioc_queryctrl(file, fh, p); |
1328 | |||
1329 | if (!ret) | 1407 | if (!ret) |
1330 | dbgarg (cmd, "id=%d, type=%d, name=%s, " | 1408 | dbgarg(cmd, "id=0x%x, type=%d, name=%s, min/max=%d/%d, " |
1331 | "min/max=%d/%d," | 1409 | "step=%d, default=%d, flags=0x%08x\n", |
1332 | " step=%d, default=%d, flags=0x%08x\n", | 1410 | p->id, p->type, p->name, |
1333 | p->id,p->type,p->name,p->minimum, | 1411 | p->minimum, p->maximum, |
1334 | p->maximum,p->step,p->default_value, | 1412 | p->step, p->default_value, p->flags); |
1335 | p->flags); | 1413 | else |
1414 | dbgarg(cmd, "id=0x%x\n", p->id); | ||
1336 | break; | 1415 | break; |
1337 | } | 1416 | } |
1338 | case VIDIOC_G_CTRL: | 1417 | case VIDIOC_G_CTRL: |
1339 | { | 1418 | { |
1340 | struct v4l2_control *p = arg; | 1419 | struct v4l2_control *p = arg; |
1341 | 1420 | ||
1342 | if (!vfd->vidioc_g_ctrl) | 1421 | if (vfd->vidioc_g_ctrl) |
1422 | ret = vfd->vidioc_g_ctrl(file, fh, p); | ||
1423 | else if (vfd->vidioc_g_ext_ctrls) { | ||
1424 | struct v4l2_ext_controls ctrls; | ||
1425 | struct v4l2_ext_control ctrl; | ||
1426 | |||
1427 | ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id); | ||
1428 | ctrls.count = 1; | ||
1429 | ctrls.controls = &ctrl; | ||
1430 | ctrl.id = p->id; | ||
1431 | ctrl.value = p->value; | ||
1432 | if (check_ext_ctrls(&ctrls, 1)) { | ||
1433 | ret = vfd->vidioc_g_ext_ctrls(file, fh, &ctrls); | ||
1434 | if (ret == 0) | ||
1435 | p->value = ctrl.value; | ||
1436 | } | ||
1437 | } else | ||
1343 | break; | 1438 | break; |
1344 | dbgarg(cmd, "Enum for index=%d\n", p->id); | ||
1345 | |||
1346 | ret=vfd->vidioc_g_ctrl(file, fh, p); | ||
1347 | if (!ret) | 1439 | if (!ret) |
1348 | dbgarg2 ( "id=%d, value=%d\n", p->id, p->value); | 1440 | dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value); |
1441 | else | ||
1442 | dbgarg(cmd, "id=0x%x\n", p->id); | ||
1349 | break; | 1443 | break; |
1350 | } | 1444 | } |
1351 | case VIDIOC_S_CTRL: | 1445 | case VIDIOC_S_CTRL: |
1352 | { | 1446 | { |
1353 | struct v4l2_control *p = arg; | 1447 | struct v4l2_control *p = arg; |
1448 | struct v4l2_ext_controls ctrls; | ||
1449 | struct v4l2_ext_control ctrl; | ||
1450 | |||
1451 | if (!vfd->vidioc_s_ctrl && !vfd->vidioc_s_ext_ctrls) | ||
1452 | break; | ||
1354 | 1453 | ||
1355 | if (!vfd->vidioc_s_ctrl) | 1454 | dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value); |
1455 | |||
1456 | if (vfd->vidioc_s_ctrl) { | ||
1457 | ret = vfd->vidioc_s_ctrl(file, fh, p); | ||
1458 | break; | ||
1459 | } | ||
1460 | if (!vfd->vidioc_s_ext_ctrls) | ||
1356 | break; | 1461 | break; |
1357 | dbgarg (cmd, "id=%d, value=%d\n", p->id, p->value); | ||
1358 | 1462 | ||
1359 | ret=vfd->vidioc_s_ctrl(file, fh, p); | 1463 | ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id); |
1464 | ctrls.count = 1; | ||
1465 | ctrls.controls = &ctrl; | ||
1466 | ctrl.id = p->id; | ||
1467 | ctrl.value = p->value; | ||
1468 | if (check_ext_ctrls(&ctrls, 1)) | ||
1469 | ret = vfd->vidioc_s_ext_ctrls(file, fh, &ctrls); | ||
1360 | break; | 1470 | break; |
1361 | } | 1471 | } |
1362 | case VIDIOC_G_EXT_CTRLS: | 1472 | case VIDIOC_G_EXT_CTRLS: |
1363 | { | 1473 | { |
1364 | struct v4l2_ext_controls *p = arg; | 1474 | struct v4l2_ext_controls *p = arg; |
1365 | 1475 | ||
1366 | if (vfd->vidioc_g_ext_ctrls) { | 1476 | p->error_idx = p->count; |
1367 | dbgarg(cmd, "count=%d\n", p->count); | 1477 | if (!vfd->vidioc_g_ext_ctrls) |
1368 | 1478 | break; | |
1369 | ret=vfd->vidioc_g_ext_ctrls(file, fh, p); | 1479 | if (check_ext_ctrls(p, 0)) |
1370 | } | 1480 | ret = vfd->vidioc_g_ext_ctrls(file, fh, p); |
1481 | v4l_print_ext_ctrls(cmd, vfd, p, !ret); | ||
1371 | break; | 1482 | break; |
1372 | } | 1483 | } |
1373 | case VIDIOC_S_EXT_CTRLS: | 1484 | case VIDIOC_S_EXT_CTRLS: |
1374 | { | 1485 | { |
1375 | struct v4l2_ext_controls *p = arg; | 1486 | struct v4l2_ext_controls *p = arg; |
1376 | 1487 | ||
1377 | if (vfd->vidioc_s_ext_ctrls) { | 1488 | p->error_idx = p->count; |
1378 | dbgarg(cmd, "count=%d\n", p->count); | 1489 | if (!vfd->vidioc_s_ext_ctrls) |
1379 | 1490 | break; | |
1380 | ret=vfd->vidioc_s_ext_ctrls(file, fh, p); | 1491 | v4l_print_ext_ctrls(cmd, vfd, p, 1); |
1381 | } | 1492 | if (check_ext_ctrls(p, 0)) |
1493 | ret = vfd->vidioc_s_ext_ctrls(file, fh, p); | ||
1382 | break; | 1494 | break; |
1383 | } | 1495 | } |
1384 | case VIDIOC_TRY_EXT_CTRLS: | 1496 | case VIDIOC_TRY_EXT_CTRLS: |
1385 | { | 1497 | { |
1386 | struct v4l2_ext_controls *p = arg; | 1498 | struct v4l2_ext_controls *p = arg; |
1387 | 1499 | ||
1388 | if (vfd->vidioc_try_ext_ctrls) { | 1500 | p->error_idx = p->count; |
1389 | dbgarg(cmd, "count=%d\n", p->count); | 1501 | if (!vfd->vidioc_try_ext_ctrls) |
1390 | 1502 | break; | |
1391 | ret=vfd->vidioc_try_ext_ctrls(file, fh, p); | 1503 | v4l_print_ext_ctrls(cmd, vfd, p, 1); |
1392 | } | 1504 | if (check_ext_ctrls(p, 0)) |
1505 | ret = vfd->vidioc_try_ext_ctrls(file, fh, p); | ||
1393 | break; | 1506 | break; |
1394 | } | 1507 | } |
1395 | case VIDIOC_QUERYMENU: | 1508 | case VIDIOC_QUERYMENU: |
1396 | { | 1509 | { |
1397 | struct v4l2_querymenu *p=arg; | 1510 | struct v4l2_querymenu *p = arg; |
1511 | |||
1398 | if (!vfd->vidioc_querymenu) | 1512 | if (!vfd->vidioc_querymenu) |
1399 | break; | 1513 | break; |
1400 | ret=vfd->vidioc_querymenu(file, fh, p); | 1514 | ret = vfd->vidioc_querymenu(file, fh, p); |
1401 | if (!ret) | 1515 | if (!ret) |
1402 | dbgarg (cmd, "id=%d, index=%d, name=%s\n", | 1516 | dbgarg(cmd, "id=0x%x, index=%d, name=%s\n", |
1403 | p->id,p->index,p->name); | 1517 | p->id, p->index, p->name); |
1518 | else | ||
1519 | dbgarg(cmd, "id=0x%x, index=%d\n", | ||
1520 | p->id, p->index); | ||
1404 | break; | 1521 | break; |
1405 | } | 1522 | } |
1406 | /* --- audio ---------------------------------------------- */ | 1523 | /* --- audio ---------------------------------------------- */ |
1407 | case VIDIOC_ENUMAUDIO: | 1524 | case VIDIOC_ENUMAUDIO: |
1408 | { | 1525 | { |
1409 | struct v4l2_audio *p=arg; | 1526 | struct v4l2_audio *p = arg; |
1410 | 1527 | ||
1411 | if (!vfd->vidioc_enumaudio) | 1528 | if (!vfd->vidioc_enumaudio) |
1412 | break; | 1529 | break; |
1413 | dbgarg(cmd, "Enum for index=%d\n", p->index); | 1530 | ret = vfd->vidioc_enumaudio(file, fh, p); |
1414 | ret=vfd->vidioc_enumaudio(file, fh, p); | ||
1415 | if (!ret) | 1531 | if (!ret) |
1416 | dbgarg2("index=%d, name=%s, capability=%d, " | 1532 | dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " |
1417 | "mode=%d\n",p->index,p->name, | 1533 | "mode=0x%x\n", p->index, p->name, |
1418 | p->capability, p->mode); | 1534 | p->capability, p->mode); |
1535 | else | ||
1536 | dbgarg(cmd, "index=%d\n", p->index); | ||
1419 | break; | 1537 | break; |
1420 | } | 1538 | } |
1421 | case VIDIOC_G_AUDIO: | 1539 | case VIDIOC_G_AUDIO: |
1422 | { | 1540 | { |
1423 | struct v4l2_audio *p=arg; | 1541 | struct v4l2_audio *p = arg; |
1424 | __u32 index=p->index; | 1542 | __u32 index = p->index; |
1425 | 1543 | ||
1426 | if (!vfd->vidioc_g_audio) | 1544 | if (!vfd->vidioc_g_audio) |
1427 | break; | 1545 | break; |
1428 | 1546 | ||
1429 | memset(p,0,sizeof(*p)); | 1547 | memset(p, 0, sizeof(*p)); |
1430 | p->index=index; | 1548 | p->index = index; |
1431 | dbgarg(cmd, "Get for index=%d\n", p->index); | 1549 | ret = vfd->vidioc_g_audio(file, fh, p); |
1432 | ret=vfd->vidioc_g_audio(file, fh, p); | ||
1433 | if (!ret) | 1550 | if (!ret) |
1434 | dbgarg2("index=%d, name=%s, capability=%d, " | 1551 | dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " |
1435 | "mode=%d\n",p->index, | 1552 | "mode=0x%x\n", p->index, |
1436 | p->name,p->capability, p->mode); | 1553 | p->name, p->capability, p->mode); |
1554 | else | ||
1555 | dbgarg(cmd, "index=%d\n", p->index); | ||
1437 | break; | 1556 | break; |
1438 | } | 1557 | } |
1439 | case VIDIOC_S_AUDIO: | 1558 | case VIDIOC_S_AUDIO: |
1440 | { | 1559 | { |
1441 | struct v4l2_audio *p=arg; | 1560 | struct v4l2_audio *p = arg; |
1442 | 1561 | ||
1443 | if (!vfd->vidioc_s_audio) | 1562 | if (!vfd->vidioc_s_audio) |
1444 | break; | 1563 | break; |
1445 | dbgarg(cmd, "index=%d, name=%s, capability=%d, " | 1564 | dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " |
1446 | "mode=%d\n", p->index, p->name, | 1565 | "mode=0x%x\n", p->index, p->name, |
1447 | p->capability, p->mode); | 1566 | p->capability, p->mode); |
1448 | ret=vfd->vidioc_s_audio(file, fh, p); | 1567 | ret = vfd->vidioc_s_audio(file, fh, p); |
1449 | break; | 1568 | break; |
1450 | } | 1569 | } |
1451 | case VIDIOC_ENUMAUDOUT: | 1570 | case VIDIOC_ENUMAUDOUT: |
@@ -1521,9 +1640,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
1521 | struct v4l2_crop *p=arg; | 1640 | struct v4l2_crop *p=arg; |
1522 | if (!vfd->vidioc_g_crop) | 1641 | if (!vfd->vidioc_g_crop) |
1523 | break; | 1642 | break; |
1643 | dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); | ||
1524 | ret=vfd->vidioc_g_crop(file, fh, p); | 1644 | ret=vfd->vidioc_g_crop(file, fh, p); |
1525 | if (!ret) { | 1645 | if (!ret) { |
1526 | dbgarg(cmd, "type=%d\n", p->type); | ||
1527 | dbgrect(vfd, "", &p->c); | 1646 | dbgrect(vfd, "", &p->c); |
1528 | } | 1647 | } |
1529 | break; | 1648 | break; |
@@ -1533,21 +1652,24 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
1533 | struct v4l2_crop *p=arg; | 1652 | struct v4l2_crop *p=arg; |
1534 | if (!vfd->vidioc_s_crop) | 1653 | if (!vfd->vidioc_s_crop) |
1535 | break; | 1654 | break; |
1536 | dbgarg(cmd, "type=%d\n", p->type); | 1655 | dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); |
1537 | dbgrect(vfd, "", &p->c); | 1656 | dbgrect(vfd, "", &p->c); |
1538 | ret=vfd->vidioc_s_crop(file, fh, p); | 1657 | ret=vfd->vidioc_s_crop(file, fh, p); |
1539 | break; | 1658 | break; |
1540 | } | 1659 | } |
1541 | case VIDIOC_CROPCAP: | 1660 | case VIDIOC_CROPCAP: |
1542 | { | 1661 | { |
1543 | struct v4l2_cropcap *p=arg; | 1662 | struct v4l2_cropcap *p = arg; |
1663 | |||
1544 | /*FIXME: Should also show v4l2_fract pixelaspect */ | 1664 | /*FIXME: Should also show v4l2_fract pixelaspect */ |
1545 | if (!vfd->vidioc_cropcap) | 1665 | if (!vfd->vidioc_cropcap) |
1546 | break; | 1666 | break; |
1547 | dbgarg(cmd, "type=%d\n", p->type); | 1667 | dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); |
1548 | dbgrect(vfd, "bounds ", &p->bounds); | 1668 | ret = vfd->vidioc_cropcap(file, fh, p); |
1549 | dbgrect(vfd, "defrect ", &p->defrect); | 1669 | if (!ret) { |
1550 | ret=vfd->vidioc_cropcap(file, fh, p); | 1670 | dbgrect(vfd, "bounds ", &p->bounds); |
1671 | dbgrect(vfd, "defrect ", &p->defrect); | ||
1672 | } | ||
1551 | break; | 1673 | break; |
1552 | } | 1674 | } |
1553 | case VIDIOC_G_JPEGCOMP: | 1675 | case VIDIOC_G_JPEGCOMP: |
@@ -1590,26 +1712,26 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
1590 | } | 1712 | } |
1591 | case VIDIOC_ENCODER_CMD: | 1713 | case VIDIOC_ENCODER_CMD: |
1592 | { | 1714 | { |
1593 | struct v4l2_encoder_cmd *p=arg; | 1715 | struct v4l2_encoder_cmd *p = arg; |
1594 | 1716 | ||
1595 | if (!vfd->vidioc_encoder_cmd) | 1717 | if (!vfd->vidioc_encoder_cmd) |
1596 | break; | 1718 | break; |
1597 | ret=vfd->vidioc_encoder_cmd(file, fh, p); | 1719 | memset(&p->raw, 0, sizeof(p->raw)); |
1720 | ret = vfd->vidioc_encoder_cmd(file, fh, p); | ||
1598 | if (!ret) | 1721 | if (!ret) |
1599 | dbgarg (cmd, "cmd=%d, flags=%d\n", | 1722 | dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); |
1600 | p->cmd,p->flags); | ||
1601 | break; | 1723 | break; |
1602 | } | 1724 | } |
1603 | case VIDIOC_TRY_ENCODER_CMD: | 1725 | case VIDIOC_TRY_ENCODER_CMD: |
1604 | { | 1726 | { |
1605 | struct v4l2_encoder_cmd *p=arg; | 1727 | struct v4l2_encoder_cmd *p = arg; |
1606 | 1728 | ||
1607 | if (!vfd->vidioc_try_encoder_cmd) | 1729 | if (!vfd->vidioc_try_encoder_cmd) |
1608 | break; | 1730 | break; |
1609 | ret=vfd->vidioc_try_encoder_cmd(file, fh, p); | 1731 | memset(&p->raw, 0, sizeof(p->raw)); |
1732 | ret = vfd->vidioc_try_encoder_cmd(file, fh, p); | ||
1610 | if (!ret) | 1733 | if (!ret) |
1611 | dbgarg (cmd, "cmd=%d, flags=%d\n", | 1734 | dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); |
1612 | p->cmd,p->flags); | ||
1613 | break; | 1735 | break; |
1614 | } | 1736 | } |
1615 | case VIDIOC_G_PARM: | 1737 | case VIDIOC_G_PARM: |
@@ -1649,54 +1771,57 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
1649 | } | 1771 | } |
1650 | case VIDIOC_G_TUNER: | 1772 | case VIDIOC_G_TUNER: |
1651 | { | 1773 | { |
1652 | struct v4l2_tuner *p=arg; | 1774 | struct v4l2_tuner *p = arg; |
1653 | __u32 index=p->index; | 1775 | __u32 index = p->index; |
1654 | 1776 | ||
1655 | if (!vfd->vidioc_g_tuner) | 1777 | if (!vfd->vidioc_g_tuner) |
1656 | break; | 1778 | break; |
1657 | 1779 | ||
1658 | memset(p,0,sizeof(*p)); | 1780 | memset(p, 0, sizeof(*p)); |
1659 | p->index=index; | 1781 | p->index = index; |
1660 | 1782 | ||
1661 | ret=vfd->vidioc_g_tuner(file, fh, p); | 1783 | ret = vfd->vidioc_g_tuner(file, fh, p); |
1662 | if (!ret) | 1784 | if (!ret) |
1663 | dbgarg (cmd, "index=%d, name=%s, type=%d, " | 1785 | dbgarg(cmd, "index=%d, name=%s, type=%d, " |
1664 | "capability=%d, rangelow=%d, " | 1786 | "capability=0x%x, rangelow=%d, " |
1665 | "rangehigh=%d, signal=%d, afc=%d, " | 1787 | "rangehigh=%d, signal=%d, afc=%d, " |
1666 | "rxsubchans=%d, audmode=%d\n", | 1788 | "rxsubchans=0x%x, audmode=%d\n", |
1667 | p->index, p->name, p->type, | 1789 | p->index, p->name, p->type, |
1668 | p->capability, p->rangelow, | 1790 | p->capability, p->rangelow, |
1669 | p->rangehigh, p->rxsubchans, | 1791 | p->rangehigh, p->signal, p->afc, |
1670 | p->audmode, p->signal, p->afc); | 1792 | p->rxsubchans, p->audmode); |
1671 | break; | 1793 | break; |
1672 | } | 1794 | } |
1673 | case VIDIOC_S_TUNER: | 1795 | case VIDIOC_S_TUNER: |
1674 | { | 1796 | { |
1675 | struct v4l2_tuner *p=arg; | 1797 | struct v4l2_tuner *p = arg; |
1798 | |||
1676 | if (!vfd->vidioc_s_tuner) | 1799 | if (!vfd->vidioc_s_tuner) |
1677 | break; | 1800 | break; |
1678 | dbgarg (cmd, "index=%d, name=%s, type=%d, " | 1801 | dbgarg(cmd, "index=%d, name=%s, type=%d, " |
1679 | "capability=%d, rangelow=%d, rangehigh=%d, " | 1802 | "capability=0x%x, rangelow=%d, " |
1680 | "signal=%d, afc=%d, rxsubchans=%d, " | 1803 | "rangehigh=%d, signal=%d, afc=%d, " |
1681 | "audmode=%d\n",p->index, p->name, p->type, | 1804 | "rxsubchans=0x%x, audmode=%d\n", |
1682 | p->capability, p->rangelow,p->rangehigh, | 1805 | p->index, p->name, p->type, |
1683 | p->rxsubchans, p->audmode, p->signal, | 1806 | p->capability, p->rangelow, |
1684 | p->afc); | 1807 | p->rangehigh, p->signal, p->afc, |
1685 | ret=vfd->vidioc_s_tuner(file, fh, p); | 1808 | p->rxsubchans, p->audmode); |
1809 | ret = vfd->vidioc_s_tuner(file, fh, p); | ||
1686 | break; | 1810 | break; |
1687 | } | 1811 | } |
1688 | case VIDIOC_G_FREQUENCY: | 1812 | case VIDIOC_G_FREQUENCY: |
1689 | { | 1813 | { |
1690 | struct v4l2_frequency *p=arg; | 1814 | struct v4l2_frequency *p = arg; |
1815 | |||
1691 | if (!vfd->vidioc_g_frequency) | 1816 | if (!vfd->vidioc_g_frequency) |
1692 | break; | 1817 | break; |
1693 | 1818 | ||
1694 | memset(p,0,sizeof(*p)); | 1819 | memset(p->reserved, 0, sizeof(p->reserved)); |
1695 | 1820 | ||
1696 | ret=vfd->vidioc_g_frequency(file, fh, p); | 1821 | ret = vfd->vidioc_g_frequency(file, fh, p); |
1697 | if (!ret) | 1822 | if (!ret) |
1698 | dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n", | 1823 | dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", |
1699 | p->tuner,p->type,p->frequency); | 1824 | p->tuner, p->type, p->frequency); |
1700 | break; | 1825 | break; |
1701 | } | 1826 | } |
1702 | case VIDIOC_S_FREQUENCY: | 1827 | case VIDIOC_S_FREQUENCY: |
@@ -1711,12 +1836,17 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
1711 | } | 1836 | } |
1712 | case VIDIOC_G_SLICED_VBI_CAP: | 1837 | case VIDIOC_G_SLICED_VBI_CAP: |
1713 | { | 1838 | { |
1714 | struct v4l2_sliced_vbi_cap *p=arg; | 1839 | struct v4l2_sliced_vbi_cap *p = arg; |
1840 | __u32 type = p->type; | ||
1841 | |||
1715 | if (!vfd->vidioc_g_sliced_vbi_cap) | 1842 | if (!vfd->vidioc_g_sliced_vbi_cap) |
1716 | break; | 1843 | break; |
1717 | ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p); | 1844 | memset(p, 0, sizeof(*p)); |
1845 | p->type = type; | ||
1846 | dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); | ||
1847 | ret = vfd->vidioc_g_sliced_vbi_cap(file, fh, p); | ||
1718 | if (!ret) | 1848 | if (!ret) |
1719 | dbgarg (cmd, "service_set=%d\n", p->service_set); | 1849 | dbgarg2("service_set=%d\n", p->service_set); |
1720 | break; | 1850 | break; |
1721 | } | 1851 | } |
1722 | case VIDIOC_LOG_STATUS: | 1852 | case VIDIOC_LOG_STATUS: |
@@ -1763,13 +1893,23 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
1763 | ret = vfd->vidioc_default(file, fh, cmd, arg); | 1893 | ret = vfd->vidioc_default(file, fh, cmd, arg); |
1764 | break; | 1894 | break; |
1765 | } | 1895 | } |
1896 | case VIDIOC_S_HW_FREQ_SEEK: | ||
1897 | { | ||
1898 | struct v4l2_hw_freq_seek *p = arg; | ||
1899 | if (!vfd->vidioc_s_hw_freq_seek) | ||
1900 | break; | ||
1901 | dbgarg(cmd, | ||
1902 | "tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n", | ||
1903 | p->tuner, p->type, p->seek_upward, p->wrap_around); | ||
1904 | ret = vfd->vidioc_s_hw_freq_seek(file, fh, p); | ||
1905 | break; | ||
1906 | } | ||
1766 | } /* switch */ | 1907 | } /* switch */ |
1767 | 1908 | ||
1768 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { | 1909 | if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { |
1769 | if (ret<0) { | 1910 | if (ret < 0) { |
1770 | printk("%s: err: on ", vfd->name); | ||
1771 | v4l_print_ioctl(vfd->name, cmd); | 1911 | v4l_print_ioctl(vfd->name, cmd); |
1772 | printk("\n"); | 1912 | printk(KERN_CONT " error %d\n", ret); |
1773 | } | 1913 | } |
1774 | } | 1914 | } |
1775 | 1915 | ||
@@ -1871,8 +2011,55 @@ out: | |||
1871 | } | 2011 | } |
1872 | EXPORT_SYMBOL(video_ioctl2); | 2012 | EXPORT_SYMBOL(video_ioctl2); |
1873 | 2013 | ||
2014 | /** | ||
2015 | * get_index - assign stream number based on parent device | ||
2016 | * @vdev: video_device to assign index number to, vdev->dev should be assigned | ||
2017 | * @num: -1 if auto assign, requested number otherwise | ||
2018 | * | ||
2019 | * | ||
2020 | * returns -ENFILE if num is already in use, a free index number if | ||
2021 | * successful. | ||
2022 | */ | ||
2023 | static int get_index(struct video_device *vdev, int num) | ||
2024 | { | ||
2025 | u32 used = 0; | ||
2026 | const int max_index = sizeof(used) * 8 - 1; | ||
2027 | int i; | ||
2028 | |||
2029 | /* Currently a single v4l driver instance cannot create more than | ||
2030 | 32 devices. | ||
2031 | Increase to u64 or an array of u32 if more are needed. */ | ||
2032 | if (num > max_index) { | ||
2033 | printk(KERN_ERR "videodev: %s num is too large\n", __func__); | ||
2034 | return -EINVAL; | ||
2035 | } | ||
2036 | |||
2037 | for (i = 0; i < VIDEO_NUM_DEVICES; i++) { | ||
2038 | if (video_device[i] != NULL && | ||
2039 | video_device[i] != vdev && | ||
2040 | video_device[i]->dev == vdev->dev) { | ||
2041 | used |= 1 << video_device[i]->index; | ||
2042 | } | ||
2043 | } | ||
2044 | |||
2045 | if (num >= 0) { | ||
2046 | if (used & (1 << num)) | ||
2047 | return -ENFILE; | ||
2048 | return num; | ||
2049 | } | ||
2050 | |||
2051 | i = ffz(used); | ||
2052 | return i > max_index ? -ENFILE : i; | ||
2053 | } | ||
2054 | |||
1874 | static const struct file_operations video_fops; | 2055 | static const struct file_operations video_fops; |
1875 | 2056 | ||
2057 | int video_register_device(struct video_device *vfd, int type, int nr) | ||
2058 | { | ||
2059 | return video_register_device_index(vfd, type, nr, -1); | ||
2060 | } | ||
2061 | EXPORT_SYMBOL(video_register_device); | ||
2062 | |||
1876 | /** | 2063 | /** |
1877 | * video_register_device - register video4linux devices | 2064 | * video_register_device - register video4linux devices |
1878 | * @vfd: video device structure we want to register | 2065 | * @vfd: video device structure we want to register |
@@ -1898,7 +2085,8 @@ static const struct file_operations video_fops; | |||
1898 | * %VFL_TYPE_RADIO - A radio card | 2085 | * %VFL_TYPE_RADIO - A radio card |
1899 | */ | 2086 | */ |
1900 | 2087 | ||
1901 | int video_register_device(struct video_device *vfd, int type, int nr) | 2088 | int video_register_device_index(struct video_device *vfd, int type, int nr, |
2089 | int index) | ||
1902 | { | 2090 | { |
1903 | int i=0; | 2091 | int i=0; |
1904 | int base; | 2092 | int base; |
@@ -1955,20 +2143,29 @@ int video_register_device(struct video_device *vfd, int type, int nr) | |||
1955 | } | 2143 | } |
1956 | video_device[i]=vfd; | 2144 | video_device[i]=vfd; |
1957 | vfd->minor=i; | 2145 | vfd->minor=i; |
2146 | |||
2147 | ret = get_index(vfd, index); | ||
2148 | vfd->index = ret; | ||
2149 | |||
1958 | mutex_unlock(&videodev_lock); | 2150 | mutex_unlock(&videodev_lock); |
2151 | |||
2152 | if (ret < 0) { | ||
2153 | printk(KERN_ERR "%s: get_index failed\n", __func__); | ||
2154 | goto fail_minor; | ||
2155 | } | ||
2156 | |||
1959 | mutex_init(&vfd->lock); | 2157 | mutex_init(&vfd->lock); |
1960 | 2158 | ||
1961 | /* sysfs class */ | 2159 | /* sysfs class */ |
1962 | memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev)); | 2160 | memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev)); |
1963 | if (vfd->dev) | ||
1964 | vfd->class_dev.parent = vfd->dev; | ||
1965 | vfd->class_dev.class = &video_class; | 2161 | vfd->class_dev.class = &video_class; |
1966 | vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); | 2162 | vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); |
2163 | if (vfd->dev) | ||
2164 | vfd->class_dev.parent = vfd->dev; | ||
1967 | sprintf(vfd->class_dev.bus_id, "%s%d", name_base, i - base); | 2165 | sprintf(vfd->class_dev.bus_id, "%s%d", name_base, i - base); |
1968 | ret = device_register(&vfd->class_dev); | 2166 | ret = device_register(&vfd->class_dev); |
1969 | if (ret < 0) { | 2167 | if (ret < 0) { |
1970 | printk(KERN_ERR "%s: device_register failed\n", | 2168 | printk(KERN_ERR "%s: device_register failed\n", __func__); |
1971 | __func__); | ||
1972 | goto fail_minor; | 2169 | goto fail_minor; |
1973 | } | 2170 | } |
1974 | 2171 | ||
@@ -1988,7 +2185,7 @@ fail_minor: | |||
1988 | mutex_unlock(&videodev_lock); | 2185 | mutex_unlock(&videodev_lock); |
1989 | return ret; | 2186 | return ret; |
1990 | } | 2187 | } |
1991 | EXPORT_SYMBOL(video_register_device); | 2188 | EXPORT_SYMBOL(video_register_device_index); |
1992 | 2189 | ||
1993 | /** | 2190 | /** |
1994 | * video_unregister_device - unregister a video4linux device | 2191 | * video_unregister_device - unregister a video4linux device |