diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2012-05-25 11:04:10 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-07-06 17:13:06 -0400 |
commit | f33e9868a46d943624fd34a4fba28b7f076e6d33 (patch) | |
tree | 493a0d990f7e49a33a357730118bdec06b95c843 /drivers | |
parent | 1a3c60a072dda4e845c40d47384794510a74eaf9 (diff) |
[media] cx88: fix a number of v4l2-compliance violations
- missing COMPRESSED flag for MPEG formats
- set colorspace
- set sizeimage
- add tuner index checks
- setup the frequency ranges correctly
- add missing g_chip_ident ioctl
- fix audmode handling
- don't handle vbi formats on a video node and vice versa.
cx88 now passes the v4l2-compliance tests.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/cx88/cx88-blackbird.c | 24 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-video.c | 71 |
2 files changed, 72 insertions, 23 deletions
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 0f1cc8dba957..38efc1fdb75f 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c | |||
@@ -709,6 +709,7 @@ static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv, | |||
709 | 709 | ||
710 | strlcpy(f->description, "MPEG", sizeof(f->description)); | 710 | strlcpy(f->description, "MPEG", sizeof(f->description)); |
711 | f->pixelformat = V4L2_PIX_FMT_MPEG; | 711 | f->pixelformat = V4L2_PIX_FMT_MPEG; |
712 | f->flags = V4L2_FMT_FLAG_COMPRESSED; | ||
712 | return 0; | 713 | return 0; |
713 | } | 714 | } |
714 | 715 | ||
@@ -720,8 +721,8 @@ static int vidioc_g_fmt_vid_cap (struct file *file, void *priv, | |||
720 | 721 | ||
721 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | 722 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; |
722 | f->fmt.pix.bytesperline = 0; | 723 | f->fmt.pix.bytesperline = 0; |
723 | f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */ | 724 | f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */; |
724 | f->fmt.pix.colorspace = 0; | 725 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; |
725 | f->fmt.pix.width = dev->width; | 726 | f->fmt.pix.width = dev->width; |
726 | f->fmt.pix.height = dev->height; | 727 | f->fmt.pix.height = dev->height; |
727 | f->fmt.pix.field = fh->mpegq.field; | 728 | f->fmt.pix.field = fh->mpegq.field; |
@@ -738,8 +739,8 @@ static int vidioc_try_fmt_vid_cap (struct file *file, void *priv, | |||
738 | 739 | ||
739 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | 740 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; |
740 | f->fmt.pix.bytesperline = 0; | 741 | f->fmt.pix.bytesperline = 0; |
741 | f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */; | 742 | f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */; |
742 | f->fmt.pix.colorspace = 0; | 743 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; |
743 | dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n", | 744 | dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n", |
744 | dev->width, dev->height, fh->mpegq.field ); | 745 | dev->width, dev->height, fh->mpegq.field ); |
745 | return 0; | 746 | return 0; |
@@ -754,8 +755,8 @@ static int vidioc_s_fmt_vid_cap (struct file *file, void *priv, | |||
754 | 755 | ||
755 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | 756 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; |
756 | f->fmt.pix.bytesperline = 0; | 757 | f->fmt.pix.bytesperline = 0; |
757 | f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */; | 758 | f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */; |
758 | f->fmt.pix.colorspace = 0; | 759 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; |
759 | dev->width = f->fmt.pix.width; | 760 | dev->width = f->fmt.pix.width; |
760 | dev->height = f->fmt.pix.height; | 761 | dev->height = f->fmt.pix.height; |
761 | fh->mpegq.field = f->fmt.pix.field; | 762 | fh->mpegq.field = f->fmt.pix.field; |
@@ -819,6 +820,10 @@ static int vidioc_s_frequency (struct file *file, void *priv, | |||
819 | struct cx8802_dev *dev = fh->dev; | 820 | struct cx8802_dev *dev = fh->dev; |
820 | struct cx88_core *core = dev->core; | 821 | struct cx88_core *core = dev->core; |
821 | 822 | ||
823 | if (unlikely(UNSET == core->board.tuner_type)) | ||
824 | return -EINVAL; | ||
825 | if (unlikely(f->tuner != 0)) | ||
826 | return -EINVAL; | ||
822 | if (dev->mpeg_active) | 827 | if (dev->mpeg_active) |
823 | blackbird_stop_codec(dev); | 828 | blackbird_stop_codec(dev); |
824 | 829 | ||
@@ -856,8 +861,9 @@ static int vidioc_g_frequency (struct file *file, void *priv, | |||
856 | 861 | ||
857 | if (unlikely(UNSET == core->board.tuner_type)) | 862 | if (unlikely(UNSET == core->board.tuner_type)) |
858 | return -EINVAL; | 863 | return -EINVAL; |
864 | if (unlikely(f->tuner != 0)) | ||
865 | return -EINVAL; | ||
859 | 866 | ||
860 | f->type = V4L2_TUNER_ANALOG_TV; | ||
861 | f->frequency = core->freq; | 867 | f->frequency = core->freq; |
862 | call_all(core, tuner, g_frequency, f); | 868 | call_all(core, tuner, g_frequency, f); |
863 | 869 | ||
@@ -878,6 +884,8 @@ static int vidioc_s_input (struct file *file, void *priv, unsigned int i) | |||
878 | 884 | ||
879 | if (i >= 4) | 885 | if (i >= 4) |
880 | return -EINVAL; | 886 | return -EINVAL; |
887 | if (0 == INPUT(i).type) | ||
888 | return -EINVAL; | ||
881 | 889 | ||
882 | mutex_lock(&core->lock); | 890 | mutex_lock(&core->lock); |
883 | cx88_newstation(core); | 891 | cx88_newstation(core); |
@@ -898,9 +906,9 @@ static int vidioc_g_tuner (struct file *file, void *priv, | |||
898 | return -EINVAL; | 906 | return -EINVAL; |
899 | 907 | ||
900 | strcpy(t->name, "Television"); | 908 | strcpy(t->name, "Television"); |
901 | t->type = V4L2_TUNER_ANALOG_TV; | ||
902 | t->capability = V4L2_TUNER_CAP_NORM; | 909 | t->capability = V4L2_TUNER_CAP_NORM; |
903 | t->rangehigh = 0xffffffffUL; | 910 | t->rangehigh = 0xffffffffUL; |
911 | call_all(core, tuner, g_tuner, t); | ||
904 | 912 | ||
905 | cx88_get_stereo(core ,t); | 913 | cx88_get_stereo(core ,t); |
906 | reg = cx_read(MO_DEVICE_STATUS); | 914 | reg = cx_read(MO_DEVICE_STATUS); |
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 930d43b0d89e..3dee42141979 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -831,7 +831,6 @@ video_poll(struct file *file, struct poll_table_struct *wait) | |||
831 | return rc | POLLERR; | 831 | return rc | POLLERR; |
832 | return rc | videobuf_poll_stream(file, &fh->vbiq, wait); | 832 | return rc | videobuf_poll_stream(file, &fh->vbiq, wait); |
833 | } | 833 | } |
834 | |||
835 | mutex_lock(&fh->vidq.vb_lock); | 834 | mutex_lock(&fh->vidq.vb_lock); |
836 | if (res_check(fh,RESOURCE_VIDEO)) { | 835 | if (res_check(fh,RESOURCE_VIDEO)) { |
837 | /* streaming capture */ | 836 | /* streaming capture */ |
@@ -1222,8 +1221,8 @@ int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i) | |||
1222 | if ((CX88_VMUX_TELEVISION == INPUT(n).type) || | 1221 | if ((CX88_VMUX_TELEVISION == INPUT(n).type) || |
1223 | (CX88_VMUX_CABLE == INPUT(n).type)) { | 1222 | (CX88_VMUX_CABLE == INPUT(n).type)) { |
1224 | i->type = V4L2_INPUT_TYPE_TUNER; | 1223 | i->type = V4L2_INPUT_TYPE_TUNER; |
1225 | i->std = CX88_NORMS; | ||
1226 | } | 1224 | } |
1225 | i->std = CX88_NORMS; | ||
1227 | return 0; | 1226 | return 0; |
1228 | } | 1227 | } |
1229 | EXPORT_SYMBOL(cx88_enum_input); | 1228 | EXPORT_SYMBOL(cx88_enum_input); |
@@ -1249,6 +1248,8 @@ static int vidioc_s_input (struct file *file, void *priv, unsigned int i) | |||
1249 | 1248 | ||
1250 | if (i >= 4) | 1249 | if (i >= 4) |
1251 | return -EINVAL; | 1250 | return -EINVAL; |
1251 | if (0 == INPUT(i).type) | ||
1252 | return -EINVAL; | ||
1252 | 1253 | ||
1253 | mutex_lock(&core->lock); | 1254 | mutex_lock(&core->lock); |
1254 | cx88_newstation(core); | 1255 | cx88_newstation(core); |
@@ -1269,9 +1270,9 @@ static int vidioc_g_tuner (struct file *file, void *priv, | |||
1269 | return -EINVAL; | 1270 | return -EINVAL; |
1270 | 1271 | ||
1271 | strcpy(t->name, "Television"); | 1272 | strcpy(t->name, "Television"); |
1272 | t->type = V4L2_TUNER_ANALOG_TV; | ||
1273 | t->capability = V4L2_TUNER_CAP_NORM; | 1273 | t->capability = V4L2_TUNER_CAP_NORM; |
1274 | t->rangehigh = 0xffffffffUL; | 1274 | t->rangehigh = 0xffffffffUL; |
1275 | call_all(core, tuner, g_tuner, t); | ||
1275 | 1276 | ||
1276 | cx88_get_stereo(core ,t); | 1277 | cx88_get_stereo(core ,t); |
1277 | reg = cx_read(MO_DEVICE_STATUS); | 1278 | reg = cx_read(MO_DEVICE_STATUS); |
@@ -1301,6 +1302,8 @@ static int vidioc_g_frequency (struct file *file, void *priv, | |||
1301 | 1302 | ||
1302 | if (unlikely(UNSET == core->board.tuner_type)) | 1303 | if (unlikely(UNSET == core->board.tuner_type)) |
1303 | return -EINVAL; | 1304 | return -EINVAL; |
1305 | if (f->tuner) | ||
1306 | return -EINVAL; | ||
1304 | 1307 | ||
1305 | f->frequency = core->freq; | 1308 | f->frequency = core->freq; |
1306 | 1309 | ||
@@ -1318,9 +1321,10 @@ int cx88_set_freq (struct cx88_core *core, | |||
1318 | return -EINVAL; | 1321 | return -EINVAL; |
1319 | 1322 | ||
1320 | mutex_lock(&core->lock); | 1323 | mutex_lock(&core->lock); |
1321 | core->freq = f->frequency; | ||
1322 | cx88_newstation(core); | 1324 | cx88_newstation(core); |
1323 | call_all(core, tuner, s_frequency, f); | 1325 | call_all(core, tuner, s_frequency, f); |
1326 | call_all(core, tuner, g_frequency, f); | ||
1327 | core->freq = f->frequency; | ||
1324 | 1328 | ||
1325 | /* When changing channels it is required to reset TVAUDIO */ | 1329 | /* When changing channels it is required to reset TVAUDIO */ |
1326 | msleep (10); | 1330 | msleep (10); |
@@ -1341,6 +1345,16 @@ static int vidioc_s_frequency (struct file *file, void *priv, | |||
1341 | return cx88_set_freq(core, f); | 1345 | return cx88_set_freq(core, f); |
1342 | } | 1346 | } |
1343 | 1347 | ||
1348 | static int vidioc_g_chip_ident(struct file *file, void *priv, | ||
1349 | struct v4l2_dbg_chip_ident *chip) | ||
1350 | { | ||
1351 | if (!v4l2_chip_match_host(&chip->match)) | ||
1352 | return -EINVAL; | ||
1353 | chip->revision = 0; | ||
1354 | chip->ident = V4L2_IDENT_UNKNOWN; | ||
1355 | return 0; | ||
1356 | } | ||
1357 | |||
1344 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1358 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1345 | static int vidioc_g_register (struct file *file, void *fh, | 1359 | static int vidioc_g_register (struct file *file, void *fh, |
1346 | struct v4l2_dbg_register *reg) | 1360 | struct v4l2_dbg_register *reg) |
@@ -1380,7 +1394,6 @@ static int radio_g_tuner (struct file *file, void *priv, | |||
1380 | return -EINVAL; | 1394 | return -EINVAL; |
1381 | 1395 | ||
1382 | strcpy(t->name, "Radio"); | 1396 | strcpy(t->name, "Radio"); |
1383 | t->type = V4L2_TUNER_RADIO; | ||
1384 | 1397 | ||
1385 | call_all(core, tuner, g_tuner, t); | 1398 | call_all(core, tuner, g_tuner, t); |
1386 | return 0; | 1399 | return 0; |
@@ -1395,6 +1408,8 @@ static int radio_s_tuner (struct file *file, void *priv, | |||
1395 | 1408 | ||
1396 | if (0 != t->index) | 1409 | if (0 != t->index) |
1397 | return -EINVAL; | 1410 | return -EINVAL; |
1411 | if (t->audmode > V4L2_TUNER_MODE_STEREO) | ||
1412 | t->audmode = V4L2_TUNER_MODE_STEREO; | ||
1398 | 1413 | ||
1399 | call_all(core, tuner, s_tuner, t); | 1414 | call_all(core, tuner, s_tuner, t); |
1400 | 1415 | ||
@@ -1543,9 +1558,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
1543 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, | 1558 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, |
1544 | .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, | 1559 | .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, |
1545 | .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, | 1560 | .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, |
1546 | .vidioc_g_fmt_vbi_cap = cx8800_vbi_fmt, | ||
1547 | .vidioc_try_fmt_vbi_cap = cx8800_vbi_fmt, | ||
1548 | .vidioc_s_fmt_vbi_cap = cx8800_vbi_fmt, | ||
1549 | .vidioc_reqbufs = vidioc_reqbufs, | 1561 | .vidioc_reqbufs = vidioc_reqbufs, |
1550 | .vidioc_querybuf = vidioc_querybuf, | 1562 | .vidioc_querybuf = vidioc_querybuf, |
1551 | .vidioc_qbuf = vidioc_qbuf, | 1563 | .vidioc_qbuf = vidioc_qbuf, |
@@ -1562,14 +1574,13 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
1562 | .vidioc_s_frequency = vidioc_s_frequency, | 1574 | .vidioc_s_frequency = vidioc_s_frequency, |
1563 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, | 1575 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, |
1564 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | 1576 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, |
1577 | .vidioc_g_chip_ident = vidioc_g_chip_ident, | ||
1565 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1578 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1566 | .vidioc_g_register = vidioc_g_register, | 1579 | .vidioc_g_register = vidioc_g_register, |
1567 | .vidioc_s_register = vidioc_s_register, | 1580 | .vidioc_s_register = vidioc_s_register, |
1568 | #endif | 1581 | #endif |
1569 | }; | 1582 | }; |
1570 | 1583 | ||
1571 | static struct video_device cx8800_vbi_template; | ||
1572 | |||
1573 | static const struct video_device cx8800_video_template = { | 1584 | static const struct video_device cx8800_video_template = { |
1574 | .name = "cx8800-video", | 1585 | .name = "cx8800-video", |
1575 | .fops = &video_fops, | 1586 | .fops = &video_fops, |
@@ -1578,6 +1589,40 @@ static const struct video_device cx8800_video_template = { | |||
1578 | .current_norm = V4L2_STD_NTSC_M, | 1589 | .current_norm = V4L2_STD_NTSC_M, |
1579 | }; | 1590 | }; |
1580 | 1591 | ||
1592 | static const struct v4l2_ioctl_ops vbi_ioctl_ops = { | ||
1593 | .vidioc_querycap = vidioc_querycap, | ||
1594 | .vidioc_g_fmt_vbi_cap = cx8800_vbi_fmt, | ||
1595 | .vidioc_try_fmt_vbi_cap = cx8800_vbi_fmt, | ||
1596 | .vidioc_s_fmt_vbi_cap = cx8800_vbi_fmt, | ||
1597 | .vidioc_reqbufs = vidioc_reqbufs, | ||
1598 | .vidioc_querybuf = vidioc_querybuf, | ||
1599 | .vidioc_qbuf = vidioc_qbuf, | ||
1600 | .vidioc_dqbuf = vidioc_dqbuf, | ||
1601 | .vidioc_s_std = vidioc_s_std, | ||
1602 | .vidioc_enum_input = vidioc_enum_input, | ||
1603 | .vidioc_g_input = vidioc_g_input, | ||
1604 | .vidioc_s_input = vidioc_s_input, | ||
1605 | .vidioc_streamon = vidioc_streamon, | ||
1606 | .vidioc_streamoff = vidioc_streamoff, | ||
1607 | .vidioc_g_tuner = vidioc_g_tuner, | ||
1608 | .vidioc_s_tuner = vidioc_s_tuner, | ||
1609 | .vidioc_g_frequency = vidioc_g_frequency, | ||
1610 | .vidioc_s_frequency = vidioc_s_frequency, | ||
1611 | .vidioc_g_chip_ident = vidioc_g_chip_ident, | ||
1612 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1613 | .vidioc_g_register = vidioc_g_register, | ||
1614 | .vidioc_s_register = vidioc_s_register, | ||
1615 | #endif | ||
1616 | }; | ||
1617 | |||
1618 | static const struct video_device cx8800_vbi_template = { | ||
1619 | .name = "cx8800-vbi", | ||
1620 | .fops = &video_fops, | ||
1621 | .ioctl_ops = &vbi_ioctl_ops, | ||
1622 | .tvnorms = CX88_NORMS, | ||
1623 | .current_norm = V4L2_STD_NTSC_M, | ||
1624 | }; | ||
1625 | |||
1581 | static const struct v4l2_file_operations radio_fops = | 1626 | static const struct v4l2_file_operations radio_fops = |
1582 | { | 1627 | { |
1583 | .owner = THIS_MODULE, | 1628 | .owner = THIS_MODULE, |
@@ -1595,6 +1640,7 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { | |||
1595 | .vidioc_s_frequency = vidioc_s_frequency, | 1640 | .vidioc_s_frequency = vidioc_s_frequency, |
1596 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, | 1641 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, |
1597 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | 1642 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, |
1643 | .vidioc_g_chip_ident = vidioc_g_chip_ident, | ||
1598 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1644 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1599 | .vidioc_g_register = vidioc_g_register, | 1645 | .vidioc_g_register = vidioc_g_register, |
1600 | .vidioc_s_register = vidioc_s_register, | 1646 | .vidioc_s_register = vidioc_s_register, |
@@ -1682,11 +1728,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, | |||
1682 | goto fail_core; | 1728 | goto fail_core; |
1683 | } | 1729 | } |
1684 | 1730 | ||
1685 | /* Initialize VBI template */ | ||
1686 | memcpy( &cx8800_vbi_template, &cx8800_video_template, | ||
1687 | sizeof(cx8800_vbi_template) ); | ||
1688 | strcpy(cx8800_vbi_template.name,"cx8800-vbi"); | ||
1689 | |||
1690 | /* initialize driver struct */ | 1731 | /* initialize driver struct */ |
1691 | spin_lock_init(&dev->slock); | 1732 | spin_lock_init(&dev->slock); |
1692 | core->tvnorm = cx8800_video_template.current_norm; | 1733 | core->tvnorm = cx8800_video_template.current_norm; |