aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2006-11-20 11:19:20 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-12-10 06:05:01 -0500
commite75f9cee32827853fc2f9d1ceb6352e3edc33e9d (patch)
treee1f1db30c237a08773fcf155a771545f3b6aa54f
parent207705cd7f82b9f160c6ed552d5788a823701fd1 (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>
-rw-r--r--drivers/media/video/cafe_ccic.c18
-rw-r--r--drivers/media/video/v4l2-common.c73
-rw-r--r--drivers/media/video/videodev.c126
-rw-r--r--drivers/media/video/vivi.c16
-rw-r--r--include/media/v4l2-dev.h14
5 files changed, 163 insertions, 84 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 */
1682static int cafe_vidioc_s_std(struct file *filp, void *priv, v4l2_std_id a) 1682static 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 */
1692static struct v4l2_tvnorm cafe_tvnorm[] = {
1693 {
1694 .name = "NTSC-M",
1695 .id = V4L2_STD_NTSC_M,
1696 }
1697};
1698
1699
1700static void cafe_v4l_dev_release(struct video_device *vd) 1687static 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
90char *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. */
92int v4l2_video_std_construct(struct v4l2_standard *vs, 164int 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
1528EXPORT_SYMBOL(v4l2_norm_to_name);
1456EXPORT_SYMBOL(v4l2_video_std_construct); 1529EXPORT_SYMBOL(v4l2_video_std_construct);
1457 1530
1458EXPORT_SYMBOL(v4l2_prio_init); 1531EXPORT_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
1047static struct v4l2_tvnorm tvnorms[] = { 1047static 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
1054static 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;
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 6a11d772700f..fb96472a1bd3 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -43,6 +43,7 @@
43 43
44/* Video standard functions */ 44/* Video standard functions */
45extern unsigned int v4l2_video_std_fps(struct v4l2_standard *vs); 45extern unsigned int v4l2_video_std_fps(struct v4l2_standard *vs);
46extern char *v4l2_norm_to_name(v4l2_std_id id);
46extern int v4l2_video_std_construct(struct v4l2_standard *vs, 47extern int v4l2_video_std_construct(struct v4l2_standard *vs,
47 int id, char *name); 48 int id, char *name);
48 49
@@ -81,12 +82,6 @@ extern long v4l_compat_ioctl32(struct file *file, unsigned int cmd,
81 * This version moves redundant code from video device code to 82 * This version moves redundant code from video device code to
82 * the common handler 83 * the common handler
83 */ 84 */
84struct v4l2_tvnorm {
85 char *name;
86 v4l2_std_id id;
87
88 void *priv_data;
89};
90 85
91struct video_device 86struct video_device
92{ 87{
@@ -104,9 +99,8 @@ struct video_device
104 int debug; /* Activates debug level*/ 99 int debug; /* Activates debug level*/
105 100
106 /* Video standard vars */ 101 /* Video standard vars */
107 int tvnormsize; /* Size of tvnorm array */ 102 v4l2_std_id tvnorms; /* Supported tv norms */
108 v4l2_std_id current_norm; /* Current tvnorm */ 103 v4l2_std_id current_norm; /* Current tvnorm */
109 struct v4l2_tvnorm *tvnorms;
110 104
111 /* callbacks */ 105 /* callbacks */
112 void (*release)(struct video_device *vfd); 106 void (*release)(struct video_device *vfd);
@@ -211,7 +205,7 @@ struct video_device
211 /* Standard handling 205 /* Standard handling
212 G_STD and ENUMSTD are handled by videodev.c 206 G_STD and ENUMSTD are handled by videodev.c
213 */ 207 */
214 int (*vidioc_s_std) (struct file *file, void *fh, v4l2_std_id a); 208 int (*vidioc_s_std) (struct file *file, void *fh, v4l2_std_id *norm);
215 int (*vidioc_querystd) (struct file *file, void *fh, v4l2_std_id *a); 209 int (*vidioc_querystd) (struct file *file, void *fh, v4l2_std_id *a);
216 210
217 /* Input handling */ 211 /* Input handling */