summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2012-05-06 12:31:27 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-05-14 14:04:11 -0400
commita299e407b9ef356bf14fbb49793dc026877440df (patch)
treefa83baff4fe3ac75c801d6295cd3c2b0e08d2647
parent7088f4df4c489811f6a5ad9a883b7dd259adfb6a (diff)
[media] av7110: fix v4l2_compliance test issues
Besides the usual inconsistencies in input enumeration there was also a kernel crash if you tried to poll on a vbi node. The checks for sliced vbi output vs vbi capture were not complete enough. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/common/saa7146_fops.c4
-rw-r--r--drivers/media/common/saa7146_video.c4
-rw-r--r--drivers/media/dvb/ttpci/av7110_v4l.c48
3 files changed, 41 insertions, 15 deletions
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index 428a543ec2ce..7d42c11c8684 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -309,6 +309,8 @@ static int fops_mmap(struct file *file, struct vm_area_struct * vma)
309 case VFL_TYPE_VBI: { 309 case VFL_TYPE_VBI: {
310 DEB_EE("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, vma:%p\n", 310 DEB_EE("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, vma:%p\n",
311 file, vma); 311 file, vma);
312 if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_SLICED_VBI_OUTPUT)
313 return -ENODEV;
312 q = &fh->vbi_q; 314 q = &fh->vbi_q;
313 break; 315 break;
314 } 316 }
@@ -331,6 +333,8 @@ static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait)
331 DEB_EE("file:%p, poll:%p\n", file, wait); 333 DEB_EE("file:%p, poll:%p\n", file, wait);
332 334
333 if (vdev->vfl_type == VFL_TYPE_VBI) { 335 if (vdev->vfl_type == VFL_TYPE_VBI) {
336 if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_SLICED_VBI_OUTPUT)
337 return res | POLLOUT | POLLWRNORM;
334 if( 0 == fh->vbi_q.streaming ) 338 if( 0 == fh->vbi_q.streaming )
335 return res | videobuf_poll_stream(file, &fh->vbi_q, wait); 339 return res | videobuf_poll_stream(file, &fh->vbi_q, wait);
336 q = &fh->vbi_q; 340 q = &fh->vbi_q;
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index 9d193208b892..6d14785d4747 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -458,13 +458,13 @@ static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *
458 V4L2_CAP_READWRITE | 458 V4L2_CAP_READWRITE |
459 V4L2_CAP_STREAMING; 459 V4L2_CAP_STREAMING;
460 cap->device_caps |= dev->ext_vv_data->capabilities; 460 cap->device_caps |= dev->ext_vv_data->capabilities;
461 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
461 if (vdev->vfl_type == VFL_TYPE_GRABBER) 462 if (vdev->vfl_type == VFL_TYPE_GRABBER)
462 cap->device_caps &= 463 cap->device_caps &=
463 ~(V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT); 464 ~(V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT);
464 else 465 else
465 cap->device_caps &= 466 cap->device_caps &=
466 ~(V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY); 467 ~(V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_AUDIO);
467 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
468 return 0; 468 return 0;
469} 469}
470 470
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index 3b7a624b5e9f..1b2d15140a1d 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -107,7 +107,7 @@ static struct v4l2_input inputs[4] = {
107 .index = 1, 107 .index = 1,
108 .name = "Television", 108 .name = "Television",
109 .type = V4L2_INPUT_TYPE_TUNER, 109 .type = V4L2_INPUT_TYPE_TUNER,
110 .audioset = 2, 110 .audioset = 1,
111 .tuner = 0, 111 .tuner = 0,
112 .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 112 .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
113 .status = 0, 113 .status = 0,
@@ -494,7 +494,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
494 dprintk(2, "VIDIOC_S_INPUT: %d\n", input); 494 dprintk(2, "VIDIOC_S_INPUT: %d\n", input);
495 495
496 if (!av7110->analog_tuner_flags) 496 if (!av7110->analog_tuner_flags)
497 return 0; 497 return input ? -EINVAL : 0;
498 498
499 if (input >= 4) 499 if (input >= 4)
500 return -EINVAL; 500 return -EINVAL;
@@ -503,19 +503,38 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
503 return av7110_dvb_c_switch(fh); 503 return av7110_dvb_c_switch(fh);
504} 504}
505 505
506static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
507{
508 dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
509 if (a->index != 0)
510 return -EINVAL;
511 *a = msp3400_v4l2_audio;
512 return 0;
513}
514
506static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a) 515static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
507{ 516{
517 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
518 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
519
508 dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index); 520 dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
509 if (a->index != 0) 521 if (a->index != 0)
510 return -EINVAL; 522 return -EINVAL;
511 memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio)); 523 if (av7110->current_input >= 2)
524 return -EINVAL;
525 *a = msp3400_v4l2_audio;
512 return 0; 526 return 0;
513} 527}
514 528
515static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a) 529static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
516{ 530{
531 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
532 struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
533
517 dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index); 534 dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
518 return 0; 535 if (av7110->current_input >= 2)
536 return -EINVAL;
537 return a->index ? -EINVAL : 0;
519} 538}
520 539
521static int vidioc_g_sliced_vbi_cap(struct file *file, void *fh, 540static int vidioc_g_sliced_vbi_cap(struct file *file, void *fh,
@@ -809,29 +828,32 @@ int av7110_init_v4l(struct av7110 *av7110)
809 vv_data->vid_ops.vidioc_s_tuner = vidioc_s_tuner; 828 vv_data->vid_ops.vidioc_s_tuner = vidioc_s_tuner;
810 vv_data->vid_ops.vidioc_g_frequency = vidioc_g_frequency; 829 vv_data->vid_ops.vidioc_g_frequency = vidioc_g_frequency;
811 vv_data->vid_ops.vidioc_s_frequency = vidioc_s_frequency; 830 vv_data->vid_ops.vidioc_s_frequency = vidioc_s_frequency;
831 vv_data->vid_ops.vidioc_enumaudio = vidioc_enumaudio;
812 vv_data->vid_ops.vidioc_g_audio = vidioc_g_audio; 832 vv_data->vid_ops.vidioc_g_audio = vidioc_g_audio;
813 vv_data->vid_ops.vidioc_s_audio = vidioc_s_audio; 833 vv_data->vid_ops.vidioc_s_audio = vidioc_s_audio;
834 vv_data->vid_ops.vidioc_g_fmt_vbi_cap = NULL;
814 835
815 vv_data->vbi_ops.vidioc_enum_input = vidioc_enum_input;
816 vv_data->vbi_ops.vidioc_g_input = vidioc_g_input;
817 vv_data->vbi_ops.vidioc_s_input = vidioc_s_input;
818 vv_data->vbi_ops.vidioc_g_tuner = vidioc_g_tuner; 836 vv_data->vbi_ops.vidioc_g_tuner = vidioc_g_tuner;
819 vv_data->vbi_ops.vidioc_s_tuner = vidioc_s_tuner; 837 vv_data->vbi_ops.vidioc_s_tuner = vidioc_s_tuner;
820 vv_data->vbi_ops.vidioc_g_frequency = vidioc_g_frequency; 838 vv_data->vbi_ops.vidioc_g_frequency = vidioc_g_frequency;
821 vv_data->vbi_ops.vidioc_s_frequency = vidioc_s_frequency; 839 vv_data->vbi_ops.vidioc_s_frequency = vidioc_s_frequency;
822 vv_data->vbi_ops.vidioc_g_audio = vidioc_g_audio; 840 vv_data->vbi_ops.vidioc_g_fmt_vbi_cap = NULL;
823 vv_data->vbi_ops.vidioc_s_audio = vidioc_s_audio;
824 vv_data->vbi_ops.vidioc_g_sliced_vbi_cap = vidioc_g_sliced_vbi_cap; 841 vv_data->vbi_ops.vidioc_g_sliced_vbi_cap = vidioc_g_sliced_vbi_cap;
825 vv_data->vbi_ops.vidioc_g_fmt_sliced_vbi_out = vidioc_g_fmt_sliced_vbi_out; 842 vv_data->vbi_ops.vidioc_g_fmt_sliced_vbi_out = vidioc_g_fmt_sliced_vbi_out;
826 vv_data->vbi_ops.vidioc_s_fmt_sliced_vbi_out = vidioc_s_fmt_sliced_vbi_out; 843 vv_data->vbi_ops.vidioc_s_fmt_sliced_vbi_out = vidioc_s_fmt_sliced_vbi_out;
827 844
845 if (FW_VERSION(av7110->arm_app) < 0x2623)
846 vv_data->capabilities &= ~V4L2_CAP_SLICED_VBI_OUTPUT;
847
828 if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) { 848 if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) {
829 ERR("cannot register capture device. skipping\n"); 849 ERR("cannot register capture device. skipping\n");
830 saa7146_vv_release(dev); 850 saa7146_vv_release(dev);
831 return -ENODEV; 851 return -ENODEV;
832 } 852 }
833 if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) 853 if (FW_VERSION(av7110->arm_app) >= 0x2623) {
834 ERR("cannot register vbi v4l2 device. skipping\n"); 854 if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI))
855 ERR("cannot register vbi v4l2 device. skipping\n");
856 }
835 return 0; 857 return 0;
836} 858}
837 859
@@ -915,7 +937,7 @@ static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
915static struct saa7146_ext_vv av7110_vv_data_st = { 937static struct saa7146_ext_vv av7110_vv_data_st = {
916 .inputs = 1, 938 .inputs = 1,
917 .audios = 1, 939 .audios = 1,
918 .capabilities = V4L2_CAP_SLICED_VBI_OUTPUT, 940 .capabilities = V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_AUDIO,
919 .flags = 0, 941 .flags = 0,
920 942
921 .stds = &standard[0], 943 .stds = &standard[0],
@@ -930,7 +952,7 @@ static struct saa7146_ext_vv av7110_vv_data_st = {
930static struct saa7146_ext_vv av7110_vv_data_c = { 952static struct saa7146_ext_vv av7110_vv_data_c = {
931 .inputs = 1, 953 .inputs = 1,
932 .audios = 1, 954 .audios = 1,
933 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_SLICED_VBI_OUTPUT, 955 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_AUDIO,
934 .flags = SAA7146_USE_PORT_B_FOR_VBI, 956 .flags = SAA7146_USE_PORT_B_FOR_VBI,
935 957
936 .stds = &standard[0], 958 .stds = &standard[0],