aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorDevin Heitmueller <dheitmueller@hauppauge.com>2010-07-09 12:29:31 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-10-20 23:17:21 -0400
commit435b4f7897b7e2f233c313e65ac82bd1d3599c43 (patch)
treeceba75faf996b25a98677ca56b44dd04b3cc6431 /drivers/media
parentd5a1754d523f5145a6e4ec8fa3a592cc57400467 (diff)
[media] cx231xx: make video scaler work properly
Move the responsibility for setting up the horizontal and vertical scalers entirely to the cx25840 driver. The cx231xx-avcore was actually programming garbage into the HSCALE_CTRL and VSCALE_CTRL registers (because of differences in how the em28xx driver worked, which the cx231xx driver was derived from). The net effect is that the scaler now works properly (tested with both PAL and NTSC under mplayer and tvtime). This patch also gets rid of cx25840 errors showing up in dmesg which say "720x480 is not a valid size" (since we now properly setup the size of the active video area). Signed-off-by: Devin Heitmueller <dheitmueller@hauppauge.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/cx231xx/cx231xx-avcore.c16
-rw-r--r--drivers/media/video/cx231xx/cx231xx-cards.c2
-rw-r--r--drivers/media/video/cx231xx/cx231xx-video.c46
-rw-r--r--drivers/media/video/cx231xx/cx231xx.h3
4 files changed, 11 insertions, 56 deletions
diff --git a/drivers/media/video/cx231xx/cx231xx-avcore.c b/drivers/media/video/cx231xx/cx231xx-avcore.c
index 64e07d335e77..362a4311cdee 100644
--- a/drivers/media/video/cx231xx/cx231xx-avcore.c
+++ b/drivers/media/video/cx231xx/cx231xx-avcore.c
@@ -992,7 +992,7 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev)
992 VID_BLK_I2C_ADDRESS, 992 VID_BLK_I2C_ADDRESS,
993 VERT_TIM_CTRL, 993 VERT_TIM_CTRL,
994 FLD_VACTIVE_CNT, 994 FLD_VACTIVE_CNT,
995 0x1E6000); 995 0x1E7000);
996 status = cx231xx_read_modify_write_i2c_dword(dev, 996 status = cx231xx_read_modify_write_i2c_dword(dev,
997 VID_BLK_I2C_ADDRESS, 997 VID_BLK_I2C_ADDRESS,
998 VERT_TIM_CTRL, 998 VERT_TIM_CTRL,
@@ -1220,20 +1220,6 @@ int cx231xx_set_audio_decoder_input(struct cx231xx *dev,
1220 return status; 1220 return status;
1221} 1221}
1222 1222
1223/* Set resolution of the video */
1224int cx231xx_resolution_set(struct cx231xx *dev)
1225{
1226 /* set horzontal scale */
1227 int status = vid_blk_write_word(dev, HSCALE_CTRL, dev->hscale);
1228 if (status)
1229 return status;
1230
1231 /* set vertical scale */
1232 status = vid_blk_write_word(dev, VSCALE_CTRL, dev->vscale);
1233
1234 return status;
1235}
1236
1237/****************************************************************************** 1223/******************************************************************************
1238 * C H I P Specific C O N T R O L functions * 1224 * C H I P Specific C O N T R O L functions *
1239 ******************************************************************************/ 1225 ******************************************************************************/
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c
index 4e63c194df01..ed8139acf19a 100644
--- a/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -726,8 +726,6 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
726 dev->width = maxw; 726 dev->width = maxw;
727 dev->height = maxh; 727 dev->height = maxh;
728 dev->interlaced = 0; 728 dev->interlaced = 0;
729 dev->hscale = 0;
730 dev->vscale = 0;
731 dev->video_input = 0; 729 dev->video_input = 0;
732 730
733 errCode = cx231xx_config(dev); 731 errCode = cx231xx_config(dev);
diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c
index 585c0316a48c..03a94e6a30ef 100644
--- a/drivers/media/video/cx231xx/cx231xx-video.c
+++ b/drivers/media/video/cx231xx/cx231xx-video.c
@@ -1009,22 +1009,6 @@ static int check_dev(struct cx231xx *dev)
1009 return 0; 1009 return 0;
1010} 1010}
1011 1011
1012static void get_scale(struct cx231xx *dev,
1013 unsigned int width, unsigned int height,
1014 unsigned int *hscale, unsigned int *vscale)
1015{
1016 unsigned int maxw = norm_maxw(dev);
1017 unsigned int maxh = norm_maxh(dev);
1018
1019 *hscale = (((unsigned long)maxw) << 12) / width - 4096L;
1020 if (*hscale >= 0x4000)
1021 *hscale = 0x3fff;
1022
1023 *vscale = (((unsigned long)maxh) << 12) / height - 4096L;
1024 if (*vscale >= 0x4000)
1025 *vscale = 0x3fff;
1026}
1027
1028/* ------------------------------------------------------------------ 1012/* ------------------------------------------------------------------
1029 IOCTL vidioc handling 1013 IOCTL vidioc handling
1030 ------------------------------------------------------------------*/ 1014 ------------------------------------------------------------------*/
@@ -1071,7 +1055,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
1071 unsigned int height = f->fmt.pix.height; 1055 unsigned int height = f->fmt.pix.height;
1072 unsigned int maxw = norm_maxw(dev); 1056 unsigned int maxw = norm_maxw(dev);
1073 unsigned int maxh = norm_maxh(dev); 1057 unsigned int maxh = norm_maxh(dev);
1074 unsigned int hscale, vscale;
1075 struct cx231xx_fmt *fmt; 1058 struct cx231xx_fmt *fmt;
1076 1059
1077 fmt = format_by_fourcc(f->fmt.pix.pixelformat); 1060 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
@@ -1085,11 +1068,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
1085 height must be even because of interlacing */ 1068 height must be even because of interlacing */
1086 v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, 1, 0); 1069 v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, 1, 0);
1087 1070
1088 get_scale(dev, width, height, &hscale, &vscale);
1089
1090 width = (((unsigned long)maxw) << 12) / (hscale + 4096L);
1091 height = (((unsigned long)maxh) << 12) / (vscale + 4096L);
1092
1093 f->fmt.pix.width = width; 1071 f->fmt.pix.width = width;
1094 f->fmt.pix.height = height; 1072 f->fmt.pix.height = height;
1095 f->fmt.pix.pixelformat = fmt->fourcc; 1073 f->fmt.pix.pixelformat = fmt->fourcc;
@@ -1140,15 +1118,11 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1140 dev->width = f->fmt.pix.width; 1118 dev->width = f->fmt.pix.width;
1141 dev->height = f->fmt.pix.height; 1119 dev->height = f->fmt.pix.height;
1142 dev->format = fmt; 1120 dev->format = fmt;
1143 get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
1144 1121
1145 v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); 1122 v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
1146 call_all(dev, video, s_mbus_fmt, &mbus_fmt); 1123 call_all(dev, video, s_mbus_fmt, &mbus_fmt);
1147 v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); 1124 v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
1148 1125
1149 /* Set the correct alternate setting for this resolution */
1150 cx231xx_resolution_set(dev);
1151
1152out: 1126out:
1153 mutex_unlock(&dev->lock); 1127 mutex_unlock(&dev->lock);
1154 return rc; 1128 return rc;
@@ -1167,6 +1141,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
1167{ 1141{
1168 struct cx231xx_fh *fh = priv; 1142 struct cx231xx_fh *fh = priv;
1169 struct cx231xx *dev = fh->dev; 1143 struct cx231xx *dev = fh->dev;
1144 struct v4l2_mbus_framefmt mbus_fmt;
1170 struct v4l2_format f; 1145 struct v4l2_format f;
1171 int rc; 1146 int rc;
1172 1147
@@ -1184,17 +1159,21 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
1184 f.fmt.pix.height = dev->height; 1159 f.fmt.pix.height = dev->height;
1185 vidioc_try_fmt_vid_cap(file, priv, &f); 1160 vidioc_try_fmt_vid_cap(file, priv, &f);
1186 1161
1162 call_all(dev, core, s_std, dev->norm);
1163
1164 /* We need to reset basic properties in the decoder related to
1165 resolution (since a standard change effects things like the number
1166 of lines in VACT, etc) */
1167 v4l2_fill_mbus_format(&mbus_fmt, &f.fmt.pix, V4L2_MBUS_FMT_FIXED);
1168 call_all(dev, video, s_mbus_fmt, &mbus_fmt);
1169 v4l2_fill_pix_format(&f.fmt.pix, &mbus_fmt);
1170
1187 /* set new image size */ 1171 /* set new image size */
1188 dev->width = f.fmt.pix.width; 1172 dev->width = f.fmt.pix.width;
1189 dev->height = f.fmt.pix.height; 1173 dev->height = f.fmt.pix.height;
1190 get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
1191
1192 call_all(dev, core, s_std, dev->norm);
1193 1174
1194 mutex_unlock(&dev->lock); 1175 mutex_unlock(&dev->lock);
1195 1176
1196 cx231xx_resolution_set(dev);
1197
1198 /* do mode control overrides */ 1177 /* do mode control overrides */
1199 cx231xx_do_mode_ctrl_overrides(dev); 1178 cx231xx_do_mode_ctrl_overrides(dev);
1200 1179
@@ -2279,8 +2258,6 @@ static int cx231xx_v4l2_open(struct file *filp)
2279 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { 2258 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
2280 dev->width = norm_maxw(dev); 2259 dev->width = norm_maxw(dev);
2281 dev->height = norm_maxh(dev); 2260 dev->height = norm_maxh(dev);
2282 dev->hscale = 0;
2283 dev->vscale = 0;
2284 2261
2285 /* Power up in Analog TV mode */ 2262 /* Power up in Analog TV mode */
2286 if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER) 2263 if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER)
@@ -2292,7 +2269,6 @@ static int cx231xx_v4l2_open(struct file *filp)
2292#if 0 2269#if 0
2293 cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); 2270 cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);
2294#endif 2271#endif
2295 cx231xx_resolution_set(dev);
2296 2272
2297 /* set video alternate setting */ 2273 /* set video alternate setting */
2298 cx231xx_set_video_alternate(dev); 2274 cx231xx_set_video_alternate(dev);
@@ -2688,8 +2664,6 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
2688 dev->width = norm_maxw(dev); 2664 dev->width = norm_maxw(dev);
2689 dev->height = norm_maxh(dev); 2665 dev->height = norm_maxh(dev);
2690 dev->interlaced = 0; 2666 dev->interlaced = 0;
2691 dev->hscale = 0;
2692 dev->vscale = 0;
2693 2667
2694 /* Analog specific initialization */ 2668 /* Analog specific initialization */
2695 dev->format = &format[0]; 2669 dev->format = &format[0];
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h
index 634d595818d8..aa273428d021 100644
--- a/drivers/media/video/cx231xx/cx231xx.h
+++ b/drivers/media/video/cx231xx/cx231xx.h
@@ -645,8 +645,6 @@ struct cx231xx {
645 /* frame properties */ 645 /* frame properties */
646 int width; /* current frame width */ 646 int width; /* current frame width */
647 int height; /* current frame height */ 647 int height; /* current frame height */
648 unsigned hscale; /* horizontal scale factor (see datasheet) */
649 unsigned vscale; /* vertical scale factor (see datasheet) */
650 int interlaced; /* 1=interlace fileds, 0=just top fileds */ 648 int interlaced; /* 1=interlace fileds, 0=just top fileds */
651 649
652 struct cx231xx_audio adev; 650 struct cx231xx_audio adev;
@@ -876,7 +874,6 @@ int cx231xx_set_audio_decoder_input(struct cx231xx *dev,
876 enum AUDIO_INPUT audio_input); 874 enum AUDIO_INPUT audio_input);
877 875
878int cx231xx_capture_start(struct cx231xx *dev, int start, u8 media_type); 876int cx231xx_capture_start(struct cx231xx *dev, int start, u8 media_type);
879int cx231xx_resolution_set(struct cx231xx *dev);
880int cx231xx_set_video_alternate(struct cx231xx *dev); 877int cx231xx_set_video_alternate(struct cx231xx *dev);
881int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt); 878int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt);
882int is_fw_load(struct cx231xx *dev); 879int is_fw_load(struct cx231xx *dev);