aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/em28xx/em28xx-video.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-video.c')
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c84
1 files changed, 55 insertions, 29 deletions
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 8fe1beecfff..ff37b4c15f4 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -90,10 +90,35 @@ MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
90/* supported video standards */ 90/* supported video standards */
91static struct em28xx_fmt format[] = { 91static struct em28xx_fmt format[] = {
92 { 92 {
93 .name = "16bpp YUY2, 4:2:2, packed", 93 .name = "16 bpp YUY2, 4:2:2, packed",
94 .fourcc = V4L2_PIX_FMT_YUYV, 94 .fourcc = V4L2_PIX_FMT_YUYV,
95 .depth = 16, 95 .depth = 16,
96 .reg = EM28XX_OUTFMT_YUV422_Y0UY1V, 96 .reg = EM28XX_OUTFMT_YUV422_Y0UY1V,
97 }, {
98 .name = "16 bpp RGB 565, LE",
99 .fourcc = V4L2_PIX_FMT_RGB565,
100 .depth = 16,
101 .reg = EM28XX_OUTFMT_RGB_16_656,
102 }, {
103 .name = "8 bpp Bayer BGBG..GRGR",
104 .fourcc = V4L2_PIX_FMT_SBGGR8,
105 .depth = 8,
106 .reg = EM28XX_OUTFMT_RGB_8_BGBG,
107 }, {
108 .name = "8 bpp Bayer GRGR..BGBG",
109 .fourcc = V4L2_PIX_FMT_SGRBG8,
110 .depth = 8,
111 .reg = EM28XX_OUTFMT_RGB_8_GRGR,
112 }, {
113 .name = "8 bpp Bayer GBGB..RGRG",
114 .fourcc = V4L2_PIX_FMT_SGBRG8,
115 .depth = 8,
116 .reg = EM28XX_OUTFMT_RGB_8_GBGB,
117 }, {
118 .name = "12 bpp YUV411",
119 .fourcc = V4L2_PIX_FMT_YUV411P,
120 .depth = 12,
121 .reg = EM28XX_OUTFMT_YUV411,
97 }, 122 },
98}; 123};
99 124
@@ -632,8 +657,8 @@ static void get_scale(struct em28xx *dev,
632 unsigned int width, unsigned int height, 657 unsigned int width, unsigned int height,
633 unsigned int *hscale, unsigned int *vscale) 658 unsigned int *hscale, unsigned int *vscale)
634{ 659{
635 unsigned int maxw = norm_maxw(dev); 660 unsigned int maxw = norm_maxw(dev);
636 unsigned int maxh = norm_maxh(dev); 661 unsigned int maxh = norm_maxh(dev);
637 662
638 *hscale = (((unsigned long)maxw) << 12) / width - 4096L; 663 *hscale = (((unsigned long)maxw) << 12) / width - 4096L;
639 if (*hscale >= 0x4000) 664 if (*hscale >= 0x4000)
@@ -733,13 +758,34 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
733 return 0; 758 return 0;
734} 759}
735 760
761static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc,
762 unsigned width, unsigned height)
763{
764 struct em28xx_fmt *fmt;
765
766 fmt = format_by_fourcc(fourcc);
767 if (!fmt)
768 return -EINVAL;
769
770 dev->format = fmt;
771 dev->width = width;
772 dev->height = height;
773
774 /* set new image size */
775 get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
776
777 em28xx_set_alternate(dev);
778 em28xx_resolution_set(dev);
779
780 return 0;
781}
782
736static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, 783static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
737 struct v4l2_format *f) 784 struct v4l2_format *f)
738{ 785{
739 struct em28xx_fh *fh = priv; 786 struct em28xx_fh *fh = priv;
740 struct em28xx *dev = fh->dev; 787 struct em28xx *dev = fh->dev;
741 int rc; 788 int rc;
742 struct em28xx_fmt *fmt;
743 789
744 rc = check_dev(dev); 790 rc = check_dev(dev);
745 if (rc < 0) 791 if (rc < 0)
@@ -749,12 +795,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
749 795
750 vidioc_try_fmt_vid_cap(file, priv, f); 796 vidioc_try_fmt_vid_cap(file, priv, f);
751 797
752 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
753 if (!fmt) {
754 rc = -EINVAL;
755 goto out;
756 }
757
758 if (videobuf_queue_is_busy(&fh->vb_vidq)) { 798 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
759 em28xx_errdev("%s queue busy\n", __func__); 799 em28xx_errdev("%s queue busy\n", __func__);
760 rc = -EBUSY; 800 rc = -EBUSY;
@@ -767,16 +807,8 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
767 goto out; 807 goto out;
768 } 808 }
769 809
770 /* set new image size */ 810 rc = em28xx_set_video_format(dev, f->fmt.pix.pixelformat,
771 dev->width = f->fmt.pix.width; 811 f->fmt.pix.width, f->fmt.pix.height);
772 dev->height = f->fmt.pix.height;
773 dev->format = fmt;
774 get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
775
776 em28xx_set_alternate(dev);
777 em28xx_resolution_set(dev);
778
779 rc = 0;
780 812
781out: 813out:
782 mutex_unlock(&dev->lock); 814 mutex_unlock(&dev->lock);
@@ -1616,11 +1648,6 @@ static int em28xx_v4l2_open(struct file *filp)
1616 filp->private_data = fh; 1648 filp->private_data = fh;
1617 1649
1618 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { 1650 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
1619 dev->width = norm_maxw(dev);
1620 dev->height = norm_maxh(dev);
1621 dev->hscale = 0;
1622 dev->vscale = 0;
1623
1624 em28xx_set_mode(dev, EM28XX_ANALOG_MODE); 1651 em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
1625 em28xx_set_alternate(dev); 1652 em28xx_set_alternate(dev);
1626 em28xx_resolution_set(dev); 1653 em28xx_resolution_set(dev);
@@ -1962,15 +1989,14 @@ int em28xx_register_analog_devices(struct em28xx *dev)
1962 1989
1963 /* set default norm */ 1990 /* set default norm */
1964 dev->norm = em28xx_video_template.current_norm; 1991 dev->norm = em28xx_video_template.current_norm;
1965 dev->width = norm_maxw(dev);
1966 dev->height = norm_maxh(dev);
1967 dev->interlaced = EM28XX_INTERLACED_DEFAULT; 1992 dev->interlaced = EM28XX_INTERLACED_DEFAULT;
1968 dev->hscale = 0;
1969 dev->vscale = 0;
1970 dev->ctl_input = 0; 1993 dev->ctl_input = 0;
1971 1994
1972 /* Analog specific initialization */ 1995 /* Analog specific initialization */
1973 dev->format = &format[0]; 1996 dev->format = &format[0];
1997 em28xx_set_video_format(dev, format[0].fourcc,
1998 norm_maxw(dev), norm_maxh(dev));
1999
1974 video_mux(dev, dev->ctl_input); 2000 video_mux(dev, dev->ctl_input);
1975 2001
1976 /* Audio defaults */ 2002 /* Audio defaults */