diff options
| author | Hans Verkuil <hans.verkuil@cisco.com> | 2012-05-06 12:31:27 -0400 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-14 14:04:11 -0400 |
| commit | a299e407b9ef356bf14fbb49793dc026877440df (patch) | |
| tree | fa83baff4fe3ac75c801d6295cd3c2b0e08d2647 | |
| parent | 7088f4df4c489811f6a5ad9a883b7dd259adfb6a (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.c | 4 | ||||
| -rw-r--r-- | drivers/media/common/saa7146_video.c | 4 | ||||
| -rw-r--r-- | drivers/media/dvb/ttpci/av7110_v4l.c | 48 |
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 | ||
| 506 | static 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 | |||
| 506 | static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a) | 515 | static 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 | ||
| 515 | static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a) | 529 | static 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 | ||
| 521 | static int vidioc_g_sliced_vbi_cap(struct file *file, void *fh, | 540 | static 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) | |||
| 915 | static struct saa7146_ext_vv av7110_vv_data_st = { | 937 | static 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 = { | |||
| 930 | static struct saa7146_ext_vv av7110_vv_data_c = { | 952 | static 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], |
