diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-11-20 11:19:20 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-12-10 06:05:01 -0500 |
commit | e75f9cee32827853fc2f9d1ceb6352e3edc33e9d (patch) | |
tree | e1f1db30c237a08773fcf155a771545f3b6aa54f /drivers | |
parent | 207705cd7f82b9f160c6ed552d5788a823701fd1 (diff) |
V4L/DVB (4861): Remove the need of a STD array for drivers using video_ioctl2
video_ioctl2 will auto-generate standard entries at ENUM_FMT.
Also, now, a driver may return a subset of the video array at
the return, to be stored as the current_norm.
For example, a driver may ask for V4L2_STD_PAL. At return,
driver may change it to V4L2_STD_PAL_B. This way, a futher call
to G_STD will return the exact detected video std.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/cafe_ccic.c | 18 | ||||
-rw-r--r-- | drivers/media/video/v4l2-common.c | 73 | ||||
-rw-r--r-- | drivers/media/video/videodev.c | 126 | ||||
-rw-r--r-- | drivers/media/video/vivi.c | 16 |
4 files changed, 159 insertions, 74 deletions
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index dc6e16c2b83b..30864dac26a3 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c | |||
@@ -1679,24 +1679,11 @@ static int cafe_vidioc_s_input(struct file *filp, void *priv, unsigned int i) | |||
1679 | } | 1679 | } |
1680 | 1680 | ||
1681 | /* from vivi.c */ | 1681 | /* from vivi.c */ |
1682 | static int cafe_vidioc_s_std(struct file *filp, void *priv, v4l2_std_id a) | 1682 | static int cafe_vidioc_s_std(struct file *filp, void *priv, v4l2_std_id *a) |
1683 | { | 1683 | { |
1684 | return 0; | 1684 | return 0; |
1685 | } | 1685 | } |
1686 | 1686 | ||
1687 | |||
1688 | /* | ||
1689 | * The TV Norm stuff is weird - we're a camera with little to do with TV, | ||
1690 | * really. The following is what vivi does. | ||
1691 | */ | ||
1692 | static struct v4l2_tvnorm cafe_tvnorm[] = { | ||
1693 | { | ||
1694 | .name = "NTSC-M", | ||
1695 | .id = V4L2_STD_NTSC_M, | ||
1696 | } | ||
1697 | }; | ||
1698 | |||
1699 | |||
1700 | static void cafe_v4l_dev_release(struct video_device *vd) | 1687 | static void cafe_v4l_dev_release(struct video_device *vd) |
1701 | { | 1688 | { |
1702 | struct cafe_camera *cam = container_of(vd, struct cafe_camera, v4ldev); | 1689 | struct cafe_camera *cam = container_of(vd, struct cafe_camera, v4ldev); |
@@ -1726,8 +1713,7 @@ static struct video_device cafe_v4l_template = { | |||
1726 | .type = VFL_TYPE_GRABBER, | 1713 | .type = VFL_TYPE_GRABBER, |
1727 | .type2 = VID_TYPE_CAPTURE, | 1714 | .type2 = VID_TYPE_CAPTURE, |
1728 | .minor = -1, /* Get one dynamically */ | 1715 | .minor = -1, /* Get one dynamically */ |
1729 | .tvnorms = cafe_tvnorm, | 1716 | .tvnorms = V4L2_STD_NTSC_M, |
1730 | .tvnormsize = 1, | ||
1731 | .current_norm = V4L2_STD_NTSC_M, /* make mplayer happy */ | 1717 | .current_norm = V4L2_STD_NTSC_M, /* make mplayer happy */ |
1732 | 1718 | ||
1733 | .fops = &cafe_v4l_fops, | 1719 | .fops = &cafe_v4l_fops, |
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index b0b4abe5c297..752c82c37f55 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c | |||
@@ -87,6 +87,78 @@ MODULE_LICENSE("GPL"); | |||
87 | */ | 87 | */ |
88 | 88 | ||
89 | 89 | ||
90 | char *v4l2_norm_to_name(v4l2_std_id id) | ||
91 | { | ||
92 | char *name; | ||
93 | |||
94 | switch (id) { | ||
95 | case V4L2_STD_PAL: | ||
96 | name="PAL"; break; | ||
97 | case V4L2_STD_PAL_BG: | ||
98 | name="PAL-BG"; break; | ||
99 | case V4L2_STD_PAL_DK: | ||
100 | name="PAL-DK"; break; | ||
101 | case V4L2_STD_PAL_B: | ||
102 | name="PAL-B"; break; | ||
103 | case V4L2_STD_PAL_B1: | ||
104 | name="PAL-B1"; break; | ||
105 | case V4L2_STD_PAL_G: | ||
106 | name="PAL-G"; break; | ||
107 | case V4L2_STD_PAL_H: | ||
108 | name="PAL-H"; break; | ||
109 | case V4L2_STD_PAL_I: | ||
110 | name="PAL-I"; break; | ||
111 | case V4L2_STD_PAL_D: | ||
112 | name="PAL-D"; break; | ||
113 | case V4L2_STD_PAL_D1: | ||
114 | name="PAL-D1"; break; | ||
115 | case V4L2_STD_PAL_K: | ||
116 | name="PAL-K"; break; | ||
117 | case V4L2_STD_PAL_M: | ||
118 | name="PAL-M"; break; | ||
119 | case V4L2_STD_PAL_N: | ||
120 | name="PAL-N"; break; | ||
121 | case V4L2_STD_PAL_Nc: | ||
122 | name="PAL-Nc"; break; | ||
123 | case V4L2_STD_PAL_60: | ||
124 | name="PAL-60"; break; | ||
125 | case V4L2_STD_NTSC: | ||
126 | name="NTSC"; break; | ||
127 | case V4L2_STD_NTSC_M: | ||
128 | name="NTSC-M"; break; | ||
129 | case V4L2_STD_NTSC_M_JP: | ||
130 | name="NTSC-M-JP"; break; | ||
131 | case V4L2_STD_NTSC_443: | ||
132 | name="NTSC-443"; break; | ||
133 | case V4L2_STD_NTSC_M_KR: | ||
134 | name="NTSC-M-KR"; break; | ||
135 | case V4L2_STD_SECAM: | ||
136 | name="SECAM"; break; | ||
137 | case V4L2_STD_SECAM_DK: | ||
138 | name="SECAM-DK"; break; | ||
139 | case V4L2_STD_SECAM_B: | ||
140 | name="SECAM-B"; break; | ||
141 | case V4L2_STD_SECAM_D: | ||
142 | name="SECAM-D"; break; | ||
143 | case V4L2_STD_SECAM_G: | ||
144 | name="SECAM-G"; break; | ||
145 | case V4L2_STD_SECAM_H: | ||
146 | name="SECAM-H"; break; | ||
147 | case V4L2_STD_SECAM_K: | ||
148 | name="SECAM-K"; break; | ||
149 | case V4L2_STD_SECAM_K1: | ||
150 | name="SECAM-K1"; break; | ||
151 | case V4L2_STD_SECAM_L: | ||
152 | name="SECAM-L"; break; | ||
153 | case V4L2_STD_SECAM_LC: | ||
154 | name="SECAM-LC"; break; | ||
155 | default: | ||
156 | name="Unknown"; break; | ||
157 | } | ||
158 | |||
159 | return name; | ||
160 | } | ||
161 | |||
90 | /* Fill in the fields of a v4l2_standard structure according to the | 162 | /* Fill in the fields of a v4l2_standard structure according to the |
91 | 'id' and 'transmission' parameters. Returns negative on error. */ | 163 | 'id' and 'transmission' parameters. Returns negative on error. */ |
92 | int v4l2_video_std_construct(struct v4l2_standard *vs, | 164 | int v4l2_video_std_construct(struct v4l2_standard *vs, |
@@ -1453,6 +1525,7 @@ u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id) | |||
1453 | 1525 | ||
1454 | /* ----------------------------------------------------------------- */ | 1526 | /* ----------------------------------------------------------------- */ |
1455 | 1527 | ||
1528 | EXPORT_SYMBOL(v4l2_norm_to_name); | ||
1456 | EXPORT_SYMBOL(v4l2_video_std_construct); | 1529 | EXPORT_SYMBOL(v4l2_video_std_construct); |
1457 | 1530 | ||
1458 | EXPORT_SYMBOL(v4l2_prio_init); | 1531 | EXPORT_SYMBOL(v4l2_prio_init); |
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index ad42deebdc47..1be712757e4d 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c | |||
@@ -833,20 +833,85 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
833 | case VIDIOC_ENUMSTD: | 833 | case VIDIOC_ENUMSTD: |
834 | { | 834 | { |
835 | struct v4l2_standard *p = arg; | 835 | struct v4l2_standard *p = arg; |
836 | unsigned int index = p->index; | 836 | v4l2_std_id id = vfd->tvnorms,curr_id=0; |
837 | unsigned int index = p->index,i; | ||
837 | 838 | ||
838 | if (!vfd->tvnormsize) { | 839 | if (index<0) { |
839 | printk (KERN_WARNING "%s: no TV norms defined!\n", | 840 | ret=-EINVAL; |
840 | vfd->name); | ||
841 | break; | 841 | break; |
842 | } | 842 | } |
843 | 843 | ||
844 | if (index<0 || index >= vfd->tvnormsize) { | 844 | /* Return norm array on a canonical way */ |
845 | ret=-EINVAL; | 845 | for (i=0;i<= index && id; i++) { |
846 | break; | 846 | if ( (id & V4L2_STD_PAL) == V4L2_STD_PAL) { |
847 | curr_id = V4L2_STD_PAL; | ||
848 | } else if ( (id & V4L2_STD_PAL_BG) == V4L2_STD_PAL_BG) { | ||
849 | curr_id = V4L2_STD_PAL_BG; | ||
850 | } else if ( (id & V4L2_STD_PAL_DK) == V4L2_STD_PAL_DK) { | ||
851 | curr_id = V4L2_STD_PAL_DK; | ||
852 | } else if ( (id & V4L2_STD_PAL_B) == V4L2_STD_PAL_B) { | ||
853 | curr_id = V4L2_STD_PAL_B; | ||
854 | } else if ( (id & V4L2_STD_PAL_B1) == V4L2_STD_PAL_B1) { | ||
855 | curr_id = V4L2_STD_PAL_B1; | ||
856 | } else if ( (id & V4L2_STD_PAL_G) == V4L2_STD_PAL_G) { | ||
857 | curr_id = V4L2_STD_PAL_G; | ||
858 | } else if ( (id & V4L2_STD_PAL_H) == V4L2_STD_PAL_H) { | ||
859 | curr_id = V4L2_STD_PAL_H; | ||
860 | } else if ( (id & V4L2_STD_PAL_I) == V4L2_STD_PAL_I) { | ||
861 | curr_id = V4L2_STD_PAL_I; | ||
862 | } else if ( (id & V4L2_STD_PAL_D) == V4L2_STD_PAL_D) { | ||
863 | curr_id = V4L2_STD_PAL_D; | ||
864 | } else if ( (id & V4L2_STD_PAL_D1) == V4L2_STD_PAL_D1) { | ||
865 | curr_id = V4L2_STD_PAL_D1; | ||
866 | } else if ( (id & V4L2_STD_PAL_K) == V4L2_STD_PAL_K) { | ||
867 | curr_id = V4L2_STD_PAL_K; | ||
868 | } else if ( (id & V4L2_STD_PAL_M) == V4L2_STD_PAL_M) { | ||
869 | curr_id = V4L2_STD_PAL_M; | ||
870 | } else if ( (id & V4L2_STD_PAL_N) == V4L2_STD_PAL_N) { | ||
871 | curr_id = V4L2_STD_PAL_N; | ||
872 | } else if ( (id & V4L2_STD_PAL_Nc) == V4L2_STD_PAL_Nc) { | ||
873 | curr_id = V4L2_STD_PAL_Nc; | ||
874 | } else if ( (id & V4L2_STD_PAL_60) == V4L2_STD_PAL_60) { | ||
875 | curr_id = V4L2_STD_PAL_60; | ||
876 | } else if ( (id & V4L2_STD_NTSC) == V4L2_STD_NTSC) { | ||
877 | curr_id = V4L2_STD_NTSC; | ||
878 | } else if ( (id & V4L2_STD_NTSC_M) == V4L2_STD_NTSC_M) { | ||
879 | curr_id = V4L2_STD_NTSC_M; | ||
880 | } else if ( (id & V4L2_STD_NTSC_M_JP) == V4L2_STD_NTSC_M_JP) { | ||
881 | curr_id = V4L2_STD_NTSC_M_JP; | ||
882 | } else if ( (id & V4L2_STD_NTSC_443) == V4L2_STD_NTSC_443) { | ||
883 | curr_id = V4L2_STD_NTSC_443; | ||
884 | } else if ( (id & V4L2_STD_NTSC_M_KR) == V4L2_STD_NTSC_M_KR) { | ||
885 | curr_id = V4L2_STD_NTSC_M_KR; | ||
886 | } else if ( (id & V4L2_STD_SECAM) == V4L2_STD_SECAM) { | ||
887 | curr_id = V4L2_STD_SECAM; | ||
888 | } else if ( (id & V4L2_STD_SECAM_DK) == V4L2_STD_SECAM_DK) { | ||
889 | curr_id = V4L2_STD_SECAM_DK; | ||
890 | } else if ( (id & V4L2_STD_SECAM_B) == V4L2_STD_SECAM_B) { | ||
891 | curr_id = V4L2_STD_SECAM_B; | ||
892 | } else if ( (id & V4L2_STD_SECAM_D) == V4L2_STD_SECAM_D) { | ||
893 | curr_id = V4L2_STD_SECAM_D; | ||
894 | } else if ( (id & V4L2_STD_SECAM_G) == V4L2_STD_SECAM_G) { | ||
895 | curr_id = V4L2_STD_SECAM_G; | ||
896 | } else if ( (id & V4L2_STD_SECAM_H) == V4L2_STD_SECAM_H) { | ||
897 | curr_id = V4L2_STD_SECAM_H; | ||
898 | } else if ( (id & V4L2_STD_SECAM_K) == V4L2_STD_SECAM_K) { | ||
899 | curr_id = V4L2_STD_SECAM_K; | ||
900 | } else if ( (id & V4L2_STD_SECAM_K1) == V4L2_STD_SECAM_K1) { | ||
901 | curr_id = V4L2_STD_SECAM_K1; | ||
902 | } else if ( (id & V4L2_STD_SECAM_L) == V4L2_STD_SECAM_L) { | ||
903 | curr_id = V4L2_STD_SECAM_L; | ||
904 | } else if ( (id & V4L2_STD_SECAM_LC) == V4L2_STD_SECAM_LC) { | ||
905 | curr_id = V4L2_STD_SECAM_LC; | ||
906 | } else { | ||
907 | break; | ||
908 | } | ||
909 | id &= ~curr_id; | ||
847 | } | 910 | } |
848 | v4l2_video_std_construct(p, vfd->tvnorms[p->index].id, | 911 | if (i<=index) |
849 | vfd->tvnorms[p->index].name); | 912 | return -EINVAL; |
913 | |||
914 | v4l2_video_std_construct(p, curr_id,v4l2_norm_to_name(curr_id)); | ||
850 | p->index = index; | 915 | p->index = index; |
851 | 916 | ||
852 | dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, " | 917 | dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, " |
@@ -872,39 +937,23 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
872 | } | 937 | } |
873 | case VIDIOC_S_STD: | 938 | case VIDIOC_S_STD: |
874 | { | 939 | { |
875 | v4l2_std_id *id = arg; | 940 | v4l2_std_id *id = arg,norm; |
876 | unsigned int i; | ||
877 | |||
878 | if (!vfd->tvnormsize) { | ||
879 | printk (KERN_WARNING "%s: no TV norms defined!\n", | ||
880 | vfd->name); | ||
881 | break; | ||
882 | } | ||
883 | 941 | ||
884 | dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id); | 942 | dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id); |
885 | 943 | ||
886 | /* First search for exact match */ | 944 | norm = (*id) & vfd->tvnorms; |
887 | for (i = 0; i < vfd->tvnormsize; i++) | 945 | if ( vfd->tvnorms && !norm) /* Check if std is supported */ |
888 | if (*id == vfd->tvnorms[i].id) | ||
889 | break; | ||
890 | /* Then for a generic video std that contains desired std */ | ||
891 | if (i == vfd->tvnormsize) | ||
892 | for (i = 0; i < vfd->tvnormsize; i++) | ||
893 | if (*id & vfd->tvnorms[i].id) | ||
894 | break; | ||
895 | if (i == vfd->tvnormsize) { | ||
896 | break; | 946 | break; |
897 | } | ||
898 | 947 | ||
899 | /* Calls the specific handler */ | 948 | /* Calls the specific handler */ |
900 | if (vfd->vidioc_s_std) | 949 | if (vfd->vidioc_s_std) |
901 | ret=vfd->vidioc_s_std(file, fh, i); | 950 | ret=vfd->vidioc_s_std(file, fh, &norm); |
902 | else | 951 | else |
903 | ret=-EINVAL; | 952 | ret=-EINVAL; |
904 | 953 | ||
905 | /* Updates standard information */ | 954 | /* Updates standard information */ |
906 | if (!ret) | 955 | if (ret>=0) |
907 | vfd->current_norm=*id; | 956 | vfd->current_norm=norm; |
908 | 957 | ||
909 | break; | 958 | break; |
910 | } | 959 | } |
@@ -1296,25 +1345,12 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
1296 | ret=vfd->vidioc_g_parm(file, fh, p); | 1345 | ret=vfd->vidioc_g_parm(file, fh, p); |
1297 | } else { | 1346 | } else { |
1298 | struct v4l2_standard s; | 1347 | struct v4l2_standard s; |
1299 | int i; | ||
1300 | |||
1301 | if (!vfd->tvnormsize) { | ||
1302 | printk (KERN_WARNING "%s: no TV norms defined!\n", | ||
1303 | vfd->name); | ||
1304 | break; | ||
1305 | } | ||
1306 | 1348 | ||
1307 | if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1349 | if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1308 | return -EINVAL; | 1350 | return -EINVAL; |
1309 | 1351 | ||
1310 | for (i = 0; i < vfd->tvnormsize; i++) | ||
1311 | if (vfd->tvnorms[i].id == vfd->current_norm) | ||
1312 | break; | ||
1313 | if (i >= vfd->tvnormsize) | ||
1314 | return -EINVAL; | ||
1315 | |||
1316 | v4l2_video_std_construct(&s, vfd->current_norm, | 1352 | v4l2_video_std_construct(&s, vfd->current_norm, |
1317 | vfd->tvnorms[i].name); | 1353 | v4l2_norm_to_name(vfd->current_norm)); |
1318 | 1354 | ||
1319 | memset(p,0,sizeof(*p)); | 1355 | memset(p,0,sizeof(*p)); |
1320 | 1356 | ||
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 9986de5cb3d6..474ddb779643 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c | |||
@@ -1044,16 +1044,8 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) | |||
1044 | return (0); | 1044 | return (0); |
1045 | } | 1045 | } |
1046 | 1046 | ||
1047 | static struct v4l2_tvnorm tvnorms[] = { | 1047 | static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *i) |
1048 | { | ||
1049 | .name = "NTSC-M", | ||
1050 | .id = V4L2_STD_NTSC_M, | ||
1051 | } | ||
1052 | }; | ||
1053 | |||
1054 | static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id a) | ||
1055 | { | 1048 | { |
1056 | |||
1057 | return 0; | 1049 | return 0; |
1058 | } | 1050 | } |
1059 | 1051 | ||
@@ -1333,8 +1325,8 @@ static struct video_device vivi = { | |||
1333 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 1325 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
1334 | .vidiocgmbuf = vidiocgmbuf, | 1326 | .vidiocgmbuf = vidiocgmbuf, |
1335 | #endif | 1327 | #endif |
1336 | .tvnorms = tvnorms, | 1328 | .tvnorms = V4L2_STD_NTSC_M, |
1337 | .tvnormsize = ARRAY_SIZE(tvnorms), | 1329 | .current_norm = V4L2_STD_NTSC_M, |
1338 | }; | 1330 | }; |
1339 | /* ----------------------------------------------------------------- | 1331 | /* ----------------------------------------------------------------- |
1340 | Initialization and module stuff | 1332 | Initialization and module stuff |
@@ -1361,8 +1353,6 @@ static int __init vivi_init(void) | |||
1361 | dev->vidq.timeout.data = (unsigned long)dev; | 1353 | dev->vidq.timeout.data = (unsigned long)dev; |
1362 | init_timer(&dev->vidq.timeout); | 1354 | init_timer(&dev->vidq.timeout); |
1363 | 1355 | ||
1364 | vivi.current_norm = tvnorms[0].id; | ||
1365 | |||
1366 | ret = video_register_device(&vivi, VFL_TYPE_GRABBER, video_nr); | 1356 | ret = video_register_device(&vivi, VFL_TYPE_GRABBER, video_nr); |
1367 | printk(KERN_INFO "Video Technology Magazine Virtual Video Capture Board (Load status: %d)\n", ret); | 1357 | printk(KERN_INFO "Video Technology Magazine Virtual Video Capture Board (Load status: %d)\n", ret); |
1368 | return ret; | 1358 | return ret; |