aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/pci/ivtv/ivtv-ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/pci/ivtv/ivtv-ioctl.c')
-rw-r--r--drivers/media/pci/ivtv/ivtv-ioctl.c159
1 files changed, 99 insertions, 60 deletions
diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c
index 4d8ee18c3feb..6fe6c4a0e858 100644
--- a/drivers/media/pci/ivtv/ivtv-ioctl.c
+++ b/drivers/media/pci/ivtv/ivtv-ioctl.c
@@ -448,9 +448,12 @@ static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f
448static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) 448static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
449{ 449{
450 struct ivtv *itv = fh2id(fh)->itv; 450 struct ivtv *itv = fh2id(fh)->itv;
451 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
451 struct v4l2_window *winfmt = &fmt->fmt.win; 452 struct v4l2_window *winfmt = &fmt->fmt.win;
452 453
453 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) 454 if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
455 return -EINVAL;
456 if (!itv->osd_video_pbase)
454 return -EINVAL; 457 return -EINVAL;
455 winfmt->chromakey = itv->osd_chroma_key; 458 winfmt->chromakey = itv->osd_chroma_key;
456 winfmt->global_alpha = itv->osd_global_alpha; 459 winfmt->global_alpha = itv->osd_global_alpha;
@@ -555,10 +558,13 @@ static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format
555static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) 558static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
556{ 559{
557 struct ivtv *itv = fh2id(fh)->itv; 560 struct ivtv *itv = fh2id(fh)->itv;
561 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
558 u32 chromakey = fmt->fmt.win.chromakey; 562 u32 chromakey = fmt->fmt.win.chromakey;
559 u8 global_alpha = fmt->fmt.win.global_alpha; 563 u8 global_alpha = fmt->fmt.win.global_alpha;
560 564
561 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) 565 if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
566 return -EINVAL;
567 if (!itv->osd_video_pbase)
562 return -EINVAL; 568 return -EINVAL;
563 ivtv_g_fmt_vid_out_overlay(file, fh, fmt); 569 ivtv_g_fmt_vid_out_overlay(file, fh, fmt);
564 fmt->fmt.win.chromakey = chromakey; 570 fmt->fmt.win.chromakey = chromakey;
@@ -741,6 +747,11 @@ static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vc
741 snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev)); 747 snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
742 vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS; 748 vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS;
743 vcap->device_caps = s->caps; 749 vcap->device_caps = s->caps;
750 if ((s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY) &&
751 !itv->osd_video_pbase) {
752 vcap->capabilities &= ~V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
753 vcap->device_caps &= ~V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
754 }
744 return 0; 755 return 0;
745} 756}
746 757
@@ -816,80 +827,103 @@ static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropca
816{ 827{
817 struct ivtv_open_id *id = fh2id(fh); 828 struct ivtv_open_id *id = fh2id(fh);
818 struct ivtv *itv = id->itv; 829 struct ivtv *itv = id->itv;
819 struct yuv_playback_info *yi = &itv->yuv_info;
820 int streamtype;
821
822 streamtype = id->type;
823 830
824 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
825 return -EINVAL;
826 cropcap->bounds.top = cropcap->bounds.left = 0;
827 cropcap->bounds.width = 720;
828 if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { 831 if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
829 cropcap->bounds.height = itv->is_50hz ? 576 : 480;
830 cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10; 832 cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
831 cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11; 833 cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
832 } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { 834 } else if (cropcap->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
833 if (yi->track_osd) {
834 cropcap->bounds.width = yi->osd_full_w;
835 cropcap->bounds.height = yi->osd_full_h;
836 } else {
837 cropcap->bounds.width = 720;
838 cropcap->bounds.height =
839 itv->is_out_50hz ? 576 : 480;
840 }
841 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; 835 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
842 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; 836 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
843 } else { 837 } else {
844 cropcap->bounds.height = itv->is_out_50hz ? 576 : 480; 838 return -EINVAL;
845 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
846 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
847 } 839 }
848 cropcap->defrect = cropcap->bounds;
849 return 0; 840 return 0;
850} 841}
851 842
852static int ivtv_s_crop(struct file *file, void *fh, const struct v4l2_crop *crop) 843static int ivtv_s_selection(struct file *file, void *fh,
844 struct v4l2_selection *sel)
853{ 845{
854 struct ivtv_open_id *id = fh2id(fh); 846 struct ivtv_open_id *id = fh2id(fh);
855 struct ivtv *itv = id->itv; 847 struct ivtv *itv = id->itv;
856 struct yuv_playback_info *yi = &itv->yuv_info; 848 struct yuv_playback_info *yi = &itv->yuv_info;
857 int streamtype; 849 struct v4l2_rect r = { 0, 0, 720, 0 };
850 int streamtype = id->type;
858 851
859 streamtype = id->type; 852 if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
853 !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
854 return -EINVAL;
860 855
861 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && 856 if (sel->target != V4L2_SEL_TGT_COMPOSE)
862 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
863 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
864 yi->main_rect = crop->c;
865 return 0;
866 } else {
867 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
868 crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
869 itv->main_rect = crop->c;
870 return 0;
871 }
872 }
873 return -EINVAL; 857 return -EINVAL;
858
859
860 if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
861 !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
862 return -EINVAL;
863
864 r.height = itv->is_out_50hz ? 576 : 480;
865 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV && yi->track_osd) {
866 r.width = yi->osd_full_w;
867 r.height = yi->osd_full_h;
868 }
869 sel->r.width = clamp(sel->r.width, 16U, r.width);
870 sel->r.height = clamp(sel->r.height, 16U, r.height);
871 sel->r.left = clamp_t(unsigned, sel->r.left, 0, r.width - sel->r.width);
872 sel->r.top = clamp_t(unsigned, sel->r.top, 0, r.height - sel->r.height);
873
874 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
875 yi->main_rect = sel->r;
876 return 0;
877 }
878 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
879 sel->r.width, sel->r.height, sel->r.left, sel->r.top)) {
880 itv->main_rect = sel->r;
881 return 0;
874 } 882 }
875 return -EINVAL; 883 return -EINVAL;
876} 884}
877 885
878static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop) 886static int ivtv_g_selection(struct file *file, void *fh,
887 struct v4l2_selection *sel)
879{ 888{
880 struct ivtv_open_id *id = fh2id(fh); 889 struct ivtv_open_id *id = fh2id(fh);
881 struct ivtv *itv = id->itv; 890 struct ivtv *itv = id->itv;
882 struct yuv_playback_info *yi = &itv->yuv_info; 891 struct yuv_playback_info *yi = &itv->yuv_info;
883 int streamtype; 892 struct v4l2_rect r = { 0, 0, 720, 0 };
893 int streamtype = id->type;
894
895 if (sel->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
896 switch (sel->target) {
897 case V4L2_SEL_TGT_CROP_DEFAULT:
898 case V4L2_SEL_TGT_CROP_BOUNDS:
899 sel->r.top = sel->r.left = 0;
900 sel->r.width = 720;
901 sel->r.height = itv->is_50hz ? 576 : 480;
902 return 0;
903 default:
904 return -EINVAL;
905 }
906 }
884 907
885 streamtype = id->type; 908 if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
909 !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
910 return -EINVAL;
886 911
887 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && 912 switch (sel->target) {
888 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { 913 case V4L2_SEL_TGT_COMPOSE:
889 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) 914 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV)
890 crop->c = yi->main_rect; 915 sel->r = yi->main_rect;
891 else 916 else
892 crop->c = itv->main_rect; 917 sel->r = itv->main_rect;
918 return 0;
919 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
920 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
921 r.height = itv->is_out_50hz ? 576 : 480;
922 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV && yi->track_osd) {
923 r.width = yi->osd_full_w;
924 r.height = yi->osd_full_h;
925 }
926 sel->r = r;
893 return 0; 927 return 0;
894 } 928 }
895 return -EINVAL; 929 return -EINVAL;
@@ -987,7 +1021,7 @@ int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
987 else 1021 else
988 std = V4L2_STD_ALL; 1022 std = V4L2_STD_ALL;
989 for (i = 0; i <= IVTV_ENC_STREAM_TYPE_VBI; i++) 1023 for (i = 0; i <= IVTV_ENC_STREAM_TYPE_VBI; i++)
990 itv->streams[i].vdev->tvnorms = std; 1024 itv->streams[i].vdev.tvnorms = std;
991 1025
992 /* prevent others from messing with the streams until 1026 /* prevent others from messing with the streams until
993 we're finished changing inputs. */ 1027 we're finished changing inputs. */
@@ -1038,7 +1072,7 @@ static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *
1038 struct ivtv *itv = fh2id(fh)->itv; 1072 struct ivtv *itv = fh2id(fh)->itv;
1039 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; 1073 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
1040 1074
1041 if (s->vdev->vfl_dir) 1075 if (s->vdev.vfl_dir)
1042 return -ENOTTY; 1076 return -ENOTTY;
1043 if (vf->tuner != 0) 1077 if (vf->tuner != 0)
1044 return -EINVAL; 1078 return -EINVAL;
@@ -1052,7 +1086,7 @@ int ivtv_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *v
1052 struct ivtv *itv = fh2id(fh)->itv; 1086 struct ivtv *itv = fh2id(fh)->itv;
1053 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; 1087 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
1054 1088
1055 if (s->vdev->vfl_dir) 1089 if (s->vdev.vfl_dir)
1056 return -ENOTTY; 1090 return -ENOTTY;
1057 if (vf->tuner != 0) 1091 if (vf->tuner != 0)
1058 return -EINVAL; 1092 return -EINVAL;
@@ -1340,6 +1374,7 @@ static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder
1340static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) 1374static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1341{ 1375{
1342 struct ivtv *itv = fh2id(fh)->itv; 1376 struct ivtv *itv = fh2id(fh)->itv;
1377 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
1343 u32 data[CX2341X_MBOX_MAX_DATA]; 1378 u32 data[CX2341X_MBOX_MAX_DATA];
1344 struct yuv_playback_info *yi = &itv->yuv_info; 1379 struct yuv_playback_info *yi = &itv->yuv_info;
1345 1380
@@ -1363,10 +1398,10 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1363 0, 1398 0,
1364 }; 1399 };
1365 1400
1366 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) 1401 if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1367 return -EINVAL; 1402 return -ENOTTY;
1368 if (!itv->osd_video_pbase) 1403 if (!itv->osd_video_pbase)
1369 return -EINVAL; 1404 return -ENOTTY;
1370 1405
1371 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY | 1406 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
1372 V4L2_FBUF_CAP_GLOBAL_ALPHA; 1407 V4L2_FBUF_CAP_GLOBAL_ALPHA;
@@ -1427,12 +1462,13 @@ static int ivtv_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffe
1427{ 1462{
1428 struct ivtv_open_id *id = fh2id(fh); 1463 struct ivtv_open_id *id = fh2id(fh);
1429 struct ivtv *itv = id->itv; 1464 struct ivtv *itv = id->itv;
1465 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
1430 struct yuv_playback_info *yi = &itv->yuv_info; 1466 struct yuv_playback_info *yi = &itv->yuv_info;
1431 1467
1432 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) 1468 if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1433 return -EINVAL; 1469 return -ENOTTY;
1434 if (!itv->osd_video_pbase) 1470 if (!itv->osd_video_pbase)
1435 return -EINVAL; 1471 return -ENOTTY;
1436 1472
1437 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; 1473 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
1438 itv->osd_local_alpha_state = 1474 itv->osd_local_alpha_state =
@@ -1447,9 +1483,12 @@ static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
1447{ 1483{
1448 struct ivtv_open_id *id = fh2id(fh); 1484 struct ivtv_open_id *id = fh2id(fh);
1449 struct ivtv *itv = id->itv; 1485 struct ivtv *itv = id->itv;
1486 struct ivtv_stream *s = &itv->streams[fh2id(fh)->type];
1450 1487
1451 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) 1488 if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1452 return -EINVAL; 1489 return -ENOTTY;
1490 if (!itv->osd_video_pbase)
1491 return -ENOTTY;
1453 1492
1454 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0); 1493 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0);
1455 1494
@@ -1547,7 +1586,7 @@ static int ivtv_log_status(struct file *file, void *fh)
1547 for (i = 0; i < IVTV_MAX_STREAMS; i++) { 1586 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1548 struct ivtv_stream *s = &itv->streams[i]; 1587 struct ivtv_stream *s = &itv->streams[i];
1549 1588
1550 if (s->vdev == NULL || s->buffers == 0) 1589 if (s->vdev.v4l2_dev == NULL || s->buffers == 0)
1551 continue; 1590 continue;
1552 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags, 1591 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
1553 (s->buffers - s->q_free.buffers) * 100 / s->buffers, 1592 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
@@ -1837,8 +1876,8 @@ static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
1837 .vidioc_enum_output = ivtv_enum_output, 1876 .vidioc_enum_output = ivtv_enum_output,
1838 .vidioc_enumaudout = ivtv_enumaudout, 1877 .vidioc_enumaudout = ivtv_enumaudout,
1839 .vidioc_cropcap = ivtv_cropcap, 1878 .vidioc_cropcap = ivtv_cropcap,
1840 .vidioc_s_crop = ivtv_s_crop, 1879 .vidioc_s_selection = ivtv_s_selection,
1841 .vidioc_g_crop = ivtv_g_crop, 1880 .vidioc_g_selection = ivtv_g_selection,
1842 .vidioc_g_input = ivtv_g_input, 1881 .vidioc_g_input = ivtv_g_input,
1843 .vidioc_s_input = ivtv_s_input, 1882 .vidioc_s_input = ivtv_s_input,
1844 .vidioc_g_output = ivtv_g_output, 1883 .vidioc_g_output = ivtv_g_output,