aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/videodev.c
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 /drivers/media/video/videodev.c
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>
Diffstat (limited to 'drivers/media/video/videodev.c')
-rw-r--r--drivers/media/video/videodev.c126
1 files changed, 81 insertions, 45 deletions
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