diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-07-13 19:15:02 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-07-24 13:03:24 -0400 |
commit | 5569996421fa1cfc1fc0d9e683ac1def46ea985d (patch) | |
tree | 552bf2fc87952018f5af8ae3653c535e599ffe90 /drivers/media | |
parent | b04fb6615285d18df34ffd6cdd51db7a8a78dda0 (diff) |
V4L/DVB (12239): em28xx: fix webcam scaling
While trying to fix an mt9v001 webcam, I noticed that HSCALE/VSCALE do
work with em28xx + webcam. The issue is that the scaling setup depends
on the number of visible rows/cols of the input image.
With mt9v011 (Silvercrest), the resolution is 640x480. So, the scaling
is different from a normal TV image (720x480 on NTSC). This were causing
a wrong scaling and a previous patch disabled scaling.
As each sensor have their different resolution setting, the xres/yres
should be adjusted accordingly with the input sensor.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-cards.c | 6 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-core.c | 5 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-video.c | 16 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx.h | 15 |
4 files changed, 18 insertions, 24 deletions
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 1318766b35bb..d4a7e6075cc9 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -58,8 +58,6 @@ static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | |||
58 | module_param_array(card, int, NULL, 0444); | 58 | module_param_array(card, int, NULL, 0444); |
59 | MODULE_PARM_DESC(card, "card type"); | 59 | MODULE_PARM_DESC(card, "card type"); |
60 | 60 | ||
61 | #define MT9V011_VERSION 0x8243 | ||
62 | |||
63 | /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */ | 61 | /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */ |
64 | static unsigned long em28xx_devused; | 62 | static unsigned long em28xx_devused; |
65 | 63 | ||
@@ -1730,10 +1728,12 @@ static int em28xx_hint_sensor(struct em28xx *dev) | |||
1730 | version = be16_to_cpu(version_be); | 1728 | version = be16_to_cpu(version_be); |
1731 | 1729 | ||
1732 | switch (version) { | 1730 | switch (version) { |
1733 | case MT9V011_VERSION: | 1731 | case 0x8243: /* mt9v011 640x480 1.3 Mpix sensor */ |
1734 | dev->model = EM2820_BOARD_SILVERCREST_WEBCAM; | 1732 | dev->model = EM2820_BOARD_SILVERCREST_WEBCAM; |
1735 | sensor_name = "mt9v011"; | 1733 | sensor_name = "mt9v011"; |
1736 | dev->em28xx_sensor = EM28XX_MT9V011; | 1734 | dev->em28xx_sensor = EM28XX_MT9V011; |
1735 | dev->sensor_xres = 640; | ||
1736 | dev->sensor_yres = 480; | ||
1737 | break; | 1737 | break; |
1738 | default: | 1738 | default: |
1739 | printk("Unknown Micron Sensor 0x%04x\n", be16_to_cpu(version)); | 1739 | printk("Unknown Micron Sensor 0x%04x\n", be16_to_cpu(version)); |
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 8649bdb7eb91..c7fcce713945 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
@@ -707,10 +707,7 @@ static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) | |||
707 | u8 mode; | 707 | u8 mode; |
708 | /* the em2800 scaler only supports scaling down to 50% */ | 708 | /* the em2800 scaler only supports scaling down to 50% */ |
709 | 709 | ||
710 | if (dev->board.is_webcam) { | 710 | if (dev->board.is_em2800) { |
711 | /* FIXME: Don't use the scaler yet */ | ||
712 | mode = 0; | ||
713 | } else if (dev->board.is_em2800) { | ||
714 | mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00); | 711 | mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00); |
715 | } else { | 712 | } else { |
716 | u8 buf[2]; | 713 | u8 buf[2]; |
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 89ab2e3b9a2c..ff37b4c15f44 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -657,8 +657,8 @@ static void get_scale(struct em28xx *dev, | |||
657 | unsigned int width, unsigned int height, | 657 | unsigned int width, unsigned int height, |
658 | unsigned int *hscale, unsigned int *vscale) | 658 | unsigned int *hscale, unsigned int *vscale) |
659 | { | 659 | { |
660 | unsigned int maxw = norm_maxw(dev); | 660 | unsigned int maxw = norm_maxw(dev); |
661 | unsigned int maxh = norm_maxh(dev); | 661 | unsigned int maxh = norm_maxh(dev); |
662 | 662 | ||
663 | *hscale = (((unsigned long)maxw) << 12) / width - 4096L; | 663 | *hscale = (((unsigned long)maxw) << 12) / width - 4096L; |
664 | if (*hscale >= 0x4000) | 664 | if (*hscale >= 0x4000) |
@@ -726,11 +726,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
726 | return -EINVAL; | 726 | return -EINVAL; |
727 | } | 727 | } |
728 | 728 | ||
729 | if (dev->board.is_webcam) { | 729 | if (dev->board.is_em2800) { |
730 | /* FIXME: This is the only supported fmt */ | ||
731 | width = 640; | ||
732 | height = 480; | ||
733 | } else if (dev->board.is_em2800) { | ||
734 | /* the em2800 can only scale down to 50% */ | 730 | /* the em2800 can only scale down to 50% */ |
735 | height = height > (3 * maxh / 4) ? maxh : maxh / 2; | 731 | height = height > (3 * maxh / 4) ? maxh : maxh / 2; |
736 | width = width > (3 * maxw / 4) ? maxw : maxw / 2; | 732 | width = width > (3 * maxw / 4) ? maxw : maxw / 2; |
@@ -767,12 +763,6 @@ static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc, | |||
767 | { | 763 | { |
768 | struct em28xx_fmt *fmt; | 764 | struct em28xx_fmt *fmt; |
769 | 765 | ||
770 | /* FIXME: This is the only supported fmt */ | ||
771 | if (dev->board.is_webcam) { | ||
772 | width = 640; | ||
773 | height = 480; | ||
774 | } | ||
775 | |||
776 | fmt = format_by_fourcc(fourcc); | 766 | fmt = format_by_fourcc(fourcc); |
777 | if (!fmt) | 767 | if (!fmt) |
778 | return -EINVAL; | 768 | return -EINVAL; |
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 655dd78cc07b..71444ddbe40c 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -479,6 +479,7 @@ struct em28xx { | |||
479 | struct em28xx_board board; | 479 | struct em28xx_board board; |
480 | 480 | ||
481 | enum em28xx_sensor em28xx_sensor; | 481 | enum em28xx_sensor em28xx_sensor; |
482 | int sensor_xres, sensor_yres; | ||
482 | 483 | ||
483 | unsigned int stream_on:1; /* Locks streams */ | 484 | unsigned int stream_on:1; /* Locks streams */ |
484 | unsigned int has_audio_class:1; | 485 | unsigned int has_audio_class:1; |
@@ -760,17 +761,23 @@ static inline int em28xx_gamma_set(struct em28xx *dev, s32 val) | |||
760 | /*FIXME: maxw should be dependent of alt mode */ | 761 | /*FIXME: maxw should be dependent of alt mode */ |
761 | static inline unsigned int norm_maxw(struct em28xx *dev) | 762 | static inline unsigned int norm_maxw(struct em28xx *dev) |
762 | { | 763 | { |
764 | if (dev->board.is_webcam) | ||
765 | return dev->sensor_xres; | ||
766 | |||
763 | if (dev->board.max_range_640_480) | 767 | if (dev->board.max_range_640_480) |
764 | return 640; | 768 | return 640; |
765 | else | 769 | |
766 | return 720; | 770 | return 720; |
767 | } | 771 | } |
768 | 772 | ||
769 | static inline unsigned int norm_maxh(struct em28xx *dev) | 773 | static inline unsigned int norm_maxh(struct em28xx *dev) |
770 | { | 774 | { |
775 | if (dev->board.is_webcam) | ||
776 | return dev->sensor_yres; | ||
777 | |||
771 | if (dev->board.max_range_640_480) | 778 | if (dev->board.max_range_640_480) |
772 | return 480; | 779 | return 480; |
773 | else | 780 | |
774 | return (dev->norm & V4L2_STD_625_50) ? 576 : 480; | 781 | return (dev->norm & V4L2_STD_625_50) ? 576 : 480; |
775 | } | 782 | } |
776 | #endif | 783 | #endif |