aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/em28xx
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2008-12-20 07:06:37 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-30 06:39:20 -0500
commitbddcf63313c6a4a85f94db092f45e31f530da691 (patch)
tree10fa9a1bd5395717cf789dd75dfcad920dd1e0fb /drivers/media/video/em28xx
parent381aaba91de9659ccb8c061d6b7248e606903374 (diff)
V4L/DVB (9927): em28xx: use a more standard way to specify video formats
This patch uses the same code for enumberating video formats that are present on cx88, bttv and saa7134 drivers. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/em28xx')
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c17
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c66
-rw-r--r--drivers/media/video/em28xx/em28xx.h7
3 files changed, 69 insertions, 21 deletions
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index f515f879125..c647dcb20a5 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -621,10 +621,19 @@ int em28xx_capture_start(struct em28xx *dev, int start)
621 return rc; 621 return rc;
622} 622}
623 623
624int em28xx_outfmt_set_yuv422(struct em28xx *dev) 624int em28xx_set_outfmt(struct em28xx *dev)
625{ 625{
626 em28xx_write_reg(dev, EM28XX_R27_OUTFMT, 0x34); 626 int ret;
627 em28xx_write_reg(dev, EM28XX_R10_VINMODE, 0x10); 627
628 ret = em28xx_write_reg_bits(dev, EM28XX_R27_OUTFMT,
629 dev->format->reg | 0x20, 0x3f);
630 if (ret < 0)
631 return ret;
632
633 ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, 0x10);
634 if (ret < 0)
635 return ret;
636
628 return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x11); 637 return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x11);
629} 638}
630 639
@@ -686,7 +695,7 @@ int em28xx_resolution_set(struct em28xx *dev)
686 width = norm_maxw(dev); 695 width = norm_maxw(dev);
687 height = norm_maxh(dev) >> 1; 696 height = norm_maxh(dev) >> 1;
688 697
689 em28xx_outfmt_set_yuv422(dev); 698 em28xx_set_outfmt(dev);
690 em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2); 699 em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2);
691 em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2); 700 em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2);
692 return em28xx_scaler_set(dev, dev->hscale, dev->vscale); 701 return em28xx_scaler_set(dev, dev->hscale, dev->vscale);
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 1b56e78b774..dbae8bcb18d 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -96,6 +96,16 @@ MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
96/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */ 96/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */
97static unsigned long em28xx_devused; 97static unsigned long em28xx_devused;
98 98
99/* supported video standards */
100static struct em28xx_fmt format[] = {
101 {
102 .name = "16bpp YUY2, 4:2:2, packed",
103 .fourcc = V4L2_PIX_FMT_YUYV,
104 .depth = 16,
105 .reg = 0x14,
106 },
107};
108
99/* supported controls */ 109/* supported controls */
100/* Common to all boards */ 110/* Common to all boards */
101static struct v4l2_queryctrl em28xx_qctrl[] = { 111static struct v4l2_queryctrl em28xx_qctrl[] = {
@@ -386,7 +396,8 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
386 struct em28xx *dev = fh->dev; 396 struct em28xx *dev = fh->dev;
387 struct v4l2_frequency f; 397 struct v4l2_frequency f;
388 398
389 *size = 16 * fh->dev->width * fh->dev->height >> 3; 399 *size = (fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 3;
400
390 if (0 == *count) 401 if (0 == *count)
391 *count = EM28XX_DEF_BUF; 402 *count = EM28XX_DEF_BUF;
392 403
@@ -439,9 +450,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
439 struct em28xx *dev = fh->dev; 450 struct em28xx *dev = fh->dev;
440 int rc = 0, urb_init = 0; 451 int rc = 0, urb_init = 0;
441 452
442 /* FIXME: It assumes depth = 16 */ 453 buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 3;
443 /* The only currently supported format is 16 bits/pixel */
444 buf->vb.size = 16 * dev->width * dev->height >> 3;
445 454
446 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) 455 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
447 return -EINVAL; 456 return -EINVAL;
@@ -536,7 +545,7 @@ static int em28xx_config(struct em28xx *dev)
536 dev->mute = 1; /* maybe not the right place... */ 545 dev->mute = 1; /* maybe not the right place... */
537 dev->volume = 0x1f; 546 dev->volume = 0x1f;
538 547
539 em28xx_outfmt_set_yuv422(dev); 548 em28xx_set_outfmt(dev);
540 em28xx_colorlevels_set_default(dev); 549 em28xx_colorlevels_set_default(dev);
541 em28xx_compression_disable(dev); 550 em28xx_compression_disable(dev);
542 551
@@ -704,8 +713,8 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
704 713
705 f->fmt.pix.width = dev->width; 714 f->fmt.pix.width = dev->width;
706 f->fmt.pix.height = dev->height; 715 f->fmt.pix.height = dev->height;
707 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; 716 f->fmt.pix.pixelformat = dev->format->fourcc;
708 f->fmt.pix.bytesperline = dev->width * 2; 717 f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3;
709 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height; 718 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height;
710 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 719 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
711 720
@@ -717,6 +726,17 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
717 return 0; 726 return 0;
718} 727}
719 728
729static struct em28xx_fmt *format_by_fourcc(unsigned int fourcc)
730{
731 unsigned int i;
732
733 for (i = 0; i < ARRAY_SIZE(format); i++)
734 if (format[i].fourcc == fourcc)
735 return &format[i];
736
737 return NULL;
738}
739
720static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, 740static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
721 struct v4l2_format *f) 741 struct v4l2_format *f)
722{ 742{
@@ -727,6 +747,14 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
727 unsigned int maxw = norm_maxw(dev); 747 unsigned int maxw = norm_maxw(dev);
728 unsigned int maxh = norm_maxh(dev); 748 unsigned int maxh = norm_maxh(dev);
729 unsigned int hscale, vscale; 749 unsigned int hscale, vscale;
750 struct em28xx_fmt *fmt;
751
752 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
753 if (!fmt) {
754 em28xx_videodbg("Fourcc format (%08x) invalid.\n",
755 f->fmt.pix.pixelformat);
756 return -EINVAL;
757 }
730 758
731 /* width must even because of the YUYV format 759 /* width must even because of the YUYV format
732 height must be even because of interlacing */ 760 height must be even because of interlacing */
@@ -765,9 +793,9 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
765 793
766 f->fmt.pix.width = width; 794 f->fmt.pix.width = width;
767 f->fmt.pix.height = height; 795 f->fmt.pix.height = height;
768 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; 796 f->fmt.pix.pixelformat = fmt->fourcc;
769 f->fmt.pix.bytesperline = width * 2; 797 f->fmt.pix.bytesperline = (dev->width * fmt->depth + 7) >> 3;
770 f->fmt.pix.sizeimage = width * 2 * height; 798 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height;
771 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 799 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
772 f->fmt.pix.field = V4L2_FIELD_INTERLACED; 800 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
773 801
@@ -780,6 +808,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
780 struct em28xx_fh *fh = priv; 808 struct em28xx_fh *fh = priv;
781 struct em28xx *dev = fh->dev; 809 struct em28xx *dev = fh->dev;
782 int rc; 810 int rc;
811 struct em28xx_fmt *fmt;
783 812
784 rc = check_dev(dev); 813 rc = check_dev(dev);
785 if (rc < 0) 814 if (rc < 0)
@@ -789,6 +818,10 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
789 818
790 vidioc_try_fmt_vid_cap(file, priv, f); 819 vidioc_try_fmt_vid_cap(file, priv, f);
791 820
821 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
822 if (!fmt)
823 return -EINVAL;
824
792 if (videobuf_queue_is_busy(&fh->vb_vidq)) { 825 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
793 em28xx_errdev("%s queue busy\n", __func__); 826 em28xx_errdev("%s queue busy\n", __func__);
794 rc = -EBUSY; 827 rc = -EBUSY;
@@ -804,6 +837,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
804 /* set new image size */ 837 /* set new image size */
805 dev->width = f->fmt.pix.width; 838 dev->width = f->fmt.pix.width;
806 dev->height = f->fmt.pix.height; 839 dev->height = f->fmt.pix.height;
840 dev->format = fmt;
807 get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); 841 get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
808 842
809 em28xx_set_alternate(dev); 843 em28xx_set_alternate(dev);
@@ -1332,15 +1366,13 @@ static int vidioc_querycap(struct file *file, void *priv,
1332} 1366}
1333 1367
1334static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, 1368static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
1335 struct v4l2_fmtdesc *fmtd) 1369 struct v4l2_fmtdesc *f)
1336{ 1370{
1337 if (fmtd->index != 0) 1371 if (unlikely(f->index >= ARRAY_SIZE(format)))
1338 return -EINVAL; 1372 return -EINVAL;
1339 1373
1340 fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1374 strlcpy(f->description, format[f->index].name, sizeof(f->description));
1341 strcpy(fmtd->description, "Packed YUY2"); 1375 f->pixelformat = format[f->index].fourcc;
1342 fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
1343 memset(fmtd->reserved, 0, sizeof(fmtd->reserved));
1344 1376
1345 return 0; 1377 return 0;
1346} 1378}
@@ -2075,6 +2107,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2075 dev->em28xx_write_regs_req = em28xx_write_regs_req; 2107 dev->em28xx_write_regs_req = em28xx_write_regs_req;
2076 dev->em28xx_read_reg_req = em28xx_read_reg_req; 2108 dev->em28xx_read_reg_req = em28xx_read_reg_req;
2077 dev->board.is_em2800 = em28xx_boards[dev->model].is_em2800; 2109 dev->board.is_em2800 = em28xx_boards[dev->model].is_em2800;
2110 dev->format = &format[0];
2078 2111
2079 em28xx_pre_card_setup(dev); 2112 em28xx_pre_card_setup(dev);
2080 2113
@@ -2482,3 +2515,4 @@ static void __exit em28xx_module_exit(void)
2482 2515
2483module_init(em28xx_module_init); 2516module_init(em28xx_module_init);
2484module_exit(em28xx_module_exit); 2517module_exit(em28xx_module_exit);
2518
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 54802d2d1bc..80d1d55d80f 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -209,9 +209,12 @@ struct em28xx_usb_isoc_ctl {
209 209
210}; 210};
211 211
212/* Struct to enumberate video formats */
212struct em28xx_fmt { 213struct em28xx_fmt {
213 char *name; 214 char *name;
214 u32 fourcc; /* v4l2 format id */ 215 u32 fourcc; /* v4l2 format id */
216 int depth;
217 int reg;
215}; 218};
216 219
217/* buffer for one video frame */ 220/* buffer for one video frame */
@@ -430,6 +433,8 @@ struct em28xx {
430 unsigned int has_audio_class:1; 433 unsigned int has_audio_class:1;
431 unsigned int has_alsa_audio:1; 434 unsigned int has_alsa_audio:1;
432 435
436 struct em28xx_fmt *format;
437
433 struct em28xx_IR *ir; 438 struct em28xx_IR *ir;
434 439
435 /* Some older em28xx chips needs a waiting time after writing */ 440 /* Some older em28xx chips needs a waiting time after writing */
@@ -564,7 +569,7 @@ int em28xx_audio_setup(struct em28xx *dev);
564 569
565int em28xx_colorlevels_set_default(struct em28xx *dev); 570int em28xx_colorlevels_set_default(struct em28xx *dev);
566int em28xx_capture_start(struct em28xx *dev, int start); 571int em28xx_capture_start(struct em28xx *dev, int start);
567int em28xx_outfmt_set_yuv422(struct em28xx *dev); 572int em28xx_set_outfmt(struct em28xx *dev);
568int em28xx_resolution_set(struct em28xx *dev); 573int em28xx_resolution_set(struct em28xx *dev);
569int em28xx_set_alternate(struct em28xx *dev); 574int em28xx_set_alternate(struct em28xx *dev);
570int em28xx_init_isoc(struct em28xx *dev, int max_packets, 575int em28xx_init_isoc(struct em28xx *dev, int max_packets,