aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2013-04-13 12:06:00 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-04-16 17:08:13 -0400
commit988f7b80ab6e541aef5972d347d6cc7d905abd21 (patch)
treeae095e6e113218b3db3cf93a529ffc0065046333 /drivers/media
parent8d125c507dee259d12299c9eb6e8d32ac1f8ae6d (diff)
[media] cx25821: g/s/try/enum_fmt related fixes and cleanups
- fill in colorspace - zero priv - delete unsupported formats - fix field handling - s_std should update width/height - proper mapping of width/height to valid resolutions Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/pci/cx25821/cx25821-video.c134
1 files changed, 32 insertions, 102 deletions
diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c
index f82da1e69e60..aec6fdfe944d 100644
--- a/drivers/media/pci/cx25821/cx25821-video.c
+++ b/drivers/media/pci/cx25821/cx25821-video.c
@@ -54,11 +54,6 @@ MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
54 54
55static const struct cx25821_fmt formats[] = { 55static const struct cx25821_fmt formats[] = {
56 { 56 {
57 .name = "8 bpp, gray",
58 .fourcc = V4L2_PIX_FMT_GREY,
59 .depth = 8,
60 .flags = FORMAT_FLAGS_PACKED,
61 }, {
62 .name = "4:1:1, packed, Y41P", 57 .name = "4:1:1, packed, Y41P",
63 .fourcc = V4L2_PIX_FMT_Y41P, 58 .fourcc = V4L2_PIX_FMT_Y41P,
64 .depth = 12, 59 .depth = 12,
@@ -68,16 +63,6 @@ static const struct cx25821_fmt formats[] = {
68 .fourcc = V4L2_PIX_FMT_YUYV, 63 .fourcc = V4L2_PIX_FMT_YUYV,
69 .depth = 16, 64 .depth = 16,
70 .flags = FORMAT_FLAGS_PACKED, 65 .flags = FORMAT_FLAGS_PACKED,
71 }, {
72 .name = "4:2:2, packed, UYVY",
73 .fourcc = V4L2_PIX_FMT_UYVY,
74 .depth = 16,
75 .flags = FORMAT_FLAGS_PACKED,
76 }, {
77 .name = "4:2:0, YUV",
78 .fourcc = V4L2_PIX_FMT_YUV420,
79 .depth = 12,
80 .flags = FORMAT_FLAGS_PACKED,
81 }, 66 },
82}; 67};
83 68
@@ -85,14 +70,9 @@ static const struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc)
85{ 70{
86 unsigned int i; 71 unsigned int i;
87 72
88 if (fourcc == V4L2_PIX_FMT_Y41P || fourcc == V4L2_PIX_FMT_YUV411P)
89 return formats + 1;
90
91 for (i = 0; i < ARRAY_SIZE(formats); i++) 73 for (i = 0; i < ARRAY_SIZE(formats); i++)
92 if (formats[i].fourcc == fourcc) 74 if (formats[i].fourcc == fourcc)
93 return formats + i; 75 return formats + i;
94
95 pr_err("%s(0x%08x) NOT FOUND\n", __func__, fourcc);
96 return NULL; 76 return NULL;
97} 77}
98 78
@@ -381,8 +361,7 @@ static int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buff
381 bpl_local = buf->bpl; /* Default */ 361 bpl_local = buf->bpl; /* Default */
382 362
383 if (chan->use_cif_resolution) { 363 if (chan->use_cif_resolution) {
384 if (dev->tvnorm & V4L2_STD_PAL_BG || 364 if (dev->tvnorm & V4L2_STD_625_50)
385 dev->tvnorm & V4L2_STD_PAL_DK)
386 bpl_local = 352 << 1; 365 bpl_local = 352 << 1;
387 else 366 else
388 bpl_local = chan->cif_width << 1; 367 bpl_local = chan->cif_width << 1;
@@ -612,8 +591,10 @@ static int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
612 f->fmt.pix.height = chan->height; 591 f->fmt.pix.height = chan->height;
613 f->fmt.pix.field = chan->vidq.field; 592 f->fmt.pix.field = chan->vidq.field;
614 f->fmt.pix.pixelformat = chan->fmt->fourcc; 593 f->fmt.pix.pixelformat = chan->fmt->fourcc;
615 f->fmt.pix.bytesperline = (f->fmt.pix.width * chan->fmt->depth) >> 3; 594 f->fmt.pix.bytesperline = (chan->width * chan->fmt->depth) >> 3;
616 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; 595 f->fmt.pix.sizeimage = chan->height * f->fmt.pix.bytesperline;
596 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
597 f->fmt.pix.priv = 0;
617 598
618 return 0; 599 return 0;
619} 600}
@@ -621,48 +602,39 @@ static int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
621static int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv, 602static int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
622 struct v4l2_format *f) 603 struct v4l2_format *f)
623{ 604{
605 struct cx25821_channel *chan = video_drvdata(file);
606 struct cx25821_dev *dev = chan->dev;
624 const struct cx25821_fmt *fmt; 607 const struct cx25821_fmt *fmt;
625 enum v4l2_field field; 608 enum v4l2_field field = f->fmt.pix.field;
626 unsigned int maxw, maxh; 609 unsigned int maxw, maxh;
610 unsigned w;
627 611
628 fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); 612 fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
629 if (NULL == fmt) 613 if (NULL == fmt)
630 return -EINVAL; 614 return -EINVAL;
631
632 field = f->fmt.pix.field;
633 maxw = 720; 615 maxw = 720;
634 maxh = 576; 616 maxh = (dev->tvnorm & V4L2_STD_625_50) ? 576 : 480;
635 617
636 if (V4L2_FIELD_ANY == field) { 618 w = f->fmt.pix.width;
637 if (f->fmt.pix.height > maxh / 2) 619 if (field != V4L2_FIELD_BOTTOM)
638 field = V4L2_FIELD_INTERLACED; 620 field = V4L2_FIELD_TOP;
639 else 621 if (w < 352) {
640 field = V4L2_FIELD_TOP; 622 w = 176;
641 } 623 f->fmt.pix.height = maxh / 4;
642 624 } else if (w < 720) {
643 switch (field) { 625 w = 352;
644 case V4L2_FIELD_TOP: 626 f->fmt.pix.height = maxh / 2;
645 case V4L2_FIELD_BOTTOM: 627 } else {
646 maxh = maxh / 2; 628 w = 720;
647 break; 629 f->fmt.pix.height = maxh;
648 case V4L2_FIELD_INTERLACED: 630 field = V4L2_FIELD_INTERLACED;
649 break;
650 default:
651 return -EINVAL;
652 } 631 }
653
654 f->fmt.pix.field = field; 632 f->fmt.pix.field = field;
655 if (f->fmt.pix.height < 32) 633 f->fmt.pix.width = w;
656 f->fmt.pix.height = 32;
657 if (f->fmt.pix.height > maxh)
658 f->fmt.pix.height = maxh;
659 if (f->fmt.pix.width < 48)
660 f->fmt.pix.width = 48;
661 if (f->fmt.pix.width > maxw)
662 f->fmt.pix.width = maxw;
663 f->fmt.pix.width &= ~0x03;
664 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; 634 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
665 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; 635 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
636 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
637 f->fmt.pix.priv = 0;
666 638
667 return 0; 639 return 0;
668} 640}
@@ -696,43 +668,6 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
696 return videobuf_streamoff(&chan->vidq); 668 return videobuf_streamoff(&chan->vidq);
697} 669}
698 670
699static int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm)
700{
701 if (tvnorm == V4L2_STD_PAL_BG) {
702 if (width == 352 || width == 720)
703 return 1;
704 else
705 return 0;
706 }
707
708 if (tvnorm == V4L2_STD_NTSC_M) {
709 if (width == 320 || width == 352 || width == 720)
710 return 1;
711 else
712 return 0;
713 }
714 return 0;
715}
716
717static int cx25821_is_valid_height(u32 height, v4l2_std_id tvnorm)
718{
719 if (tvnorm == V4L2_STD_PAL_BG) {
720 if (height == 576 || height == 288)
721 return 1;
722 else
723 return 0;
724 }
725
726 if (tvnorm == V4L2_STD_NTSC_M) {
727 if (height == 480 || height == 240)
728 return 1;
729 else
730 return 0;
731 }
732
733 return 0;
734}
735
736static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, 671static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
737 struct v4l2_format *f) 672 struct v4l2_format *f)
738{ 673{
@@ -749,20 +684,13 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
749 684
750 chan->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); 685 chan->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
751 chan->vidq.field = f->fmt.pix.field; 686 chan->vidq.field = f->fmt.pix.field;
752 687 chan->width = f->fmt.pix.width;
753 /* check if width and height is valid based on set standard */ 688 chan->height = f->fmt.pix.height;
754 if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm))
755 chan->width = f->fmt.pix.width;
756
757 if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm))
758 chan->height = f->fmt.pix.height;
759 689
760 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P) 690 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
761 pix_format = PIXEL_FRMT_411; 691 pix_format = PIXEL_FRMT_411;
762 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
763 pix_format = PIXEL_FRMT_422;
764 else 692 else
765 return -EINVAL; 693 pix_format = PIXEL_FRMT_422;
766 694
767 cx25821_set_pixel_format(dev, SRAM_CH00, pix_format); 695 cx25821_set_pixel_format(dev, SRAM_CH00, pix_format);
768 696
@@ -879,6 +807,8 @@ int cx25821_vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms)
879 return 0; 807 return 0;
880 808
881 cx25821_set_tvnorm(dev, tvnorms); 809 cx25821_set_tvnorm(dev, tvnorms);
810 chan->width = 720;
811 chan->height = (dev->tvnorm & V4L2_STD_625_50) ? 576 : 480;
882 812
883 medusa_set_videostandard(dev); 813 medusa_set_videostandard(dev);
884 814