diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-12-20 07:06:37 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-12-30 06:39:20 -0500 |
commit | bddcf63313c6a4a85f94db092f45e31f530da691 (patch) | |
tree | 10fa9a1bd5395717cf789dd75dfcad920dd1e0fb /drivers | |
parent | 381aaba91de9659ccb8c061d6b7248e606903374 (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')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-core.c | 17 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-video.c | 66 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx.h | 7 |
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 f515f8791251..c647dcb20a57 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 | ||
624 | int em28xx_outfmt_set_yuv422(struct em28xx *dev) | 624 | int 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 1b56e78b7744..dbae8bcb18d7 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 */ |
97 | static unsigned long em28xx_devused; | 97 | static unsigned long em28xx_devused; |
98 | 98 | ||
99 | /* supported video standards */ | ||
100 | static 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 */ |
101 | static struct v4l2_queryctrl em28xx_qctrl[] = { | 111 | static 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 | ||
729 | static 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 | |||
720 | static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | 740 | static 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 | ||
1334 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | 1368 | static 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 | ||
2483 | module_init(em28xx_module_init); | 2516 | module_init(em28xx_module_init); |
2484 | module_exit(em28xx_module_exit); | 2517 | module_exit(em28xx_module_exit); |
2518 | |||
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 54802d2d1bc5..80d1d55d80f9 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 */ | ||
212 | struct em28xx_fmt { | 213 | struct 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 | ||
565 | int em28xx_colorlevels_set_default(struct em28xx *dev); | 570 | int em28xx_colorlevels_set_default(struct em28xx *dev); |
566 | int em28xx_capture_start(struct em28xx *dev, int start); | 571 | int em28xx_capture_start(struct em28xx *dev, int start); |
567 | int em28xx_outfmt_set_yuv422(struct em28xx *dev); | 572 | int em28xx_set_outfmt(struct em28xx *dev); |
568 | int em28xx_resolution_set(struct em28xx *dev); | 573 | int em28xx_resolution_set(struct em28xx *dev); |
569 | int em28xx_set_alternate(struct em28xx *dev); | 574 | int em28xx_set_alternate(struct em28xx *dev); |
570 | int em28xx_init_isoc(struct em28xx *dev, int max_packets, | 575 | int em28xx_init_isoc(struct em28xx *dev, int max_packets, |