Skip to content

Commit

Permalink
[media] cx231xx: make video scaler work properly
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Devin Heitmueller authored and Mauro Carvalho Chehab committed Oct 21, 2010
1 parent d5a1754 commit 435b4f7
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 56 deletions.
16 changes: 1 addition & 15 deletions drivers/media/video/cx231xx/cx231xx-avcore.c
Original file line number Diff line number Diff line change
Expand Up @@ -992,7 +992,7 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev)
VID_BLK_I2C_ADDRESS,
VERT_TIM_CTRL,
FLD_VACTIVE_CNT,
0x1E6000);
0x1E7000);
status = cx231xx_read_modify_write_i2c_dword(dev,
VID_BLK_I2C_ADDRESS,
VERT_TIM_CTRL,
Expand Down Expand Up @@ -1220,20 +1220,6 @@ int cx231xx_set_audio_decoder_input(struct cx231xx *dev,
return status;
}

/* Set resolution of the video */
int cx231xx_resolution_set(struct cx231xx *dev)
{
/* set horzontal scale */
int status = vid_blk_write_word(dev, HSCALE_CTRL, dev->hscale);
if (status)
return status;

/* set vertical scale */
status = vid_blk_write_word(dev, VSCALE_CTRL, dev->vscale);

return status;
}

/******************************************************************************
* C H I P Specific C O N T R O L functions *
******************************************************************************/
Expand Down
2 changes: 0 additions & 2 deletions drivers/media/video/cx231xx/cx231xx-cards.c
Original file line number Diff line number Diff line change
Expand Up @@ -726,8 +726,6 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
dev->width = maxw;
dev->height = maxh;
dev->interlaced = 0;
dev->hscale = 0;
dev->vscale = 0;
dev->video_input = 0;

errCode = cx231xx_config(dev);
Expand Down
46 changes: 10 additions & 36 deletions drivers/media/video/cx231xx/cx231xx-video.c
Original file line number Diff line number Diff line change
Expand Up @@ -1009,22 +1009,6 @@ static int check_dev(struct cx231xx *dev)
return 0;
}

static void get_scale(struct cx231xx *dev,
unsigned int width, unsigned int height,
unsigned int *hscale, unsigned int *vscale)
{
unsigned int maxw = norm_maxw(dev);
unsigned int maxh = norm_maxh(dev);

*hscale = (((unsigned long)maxw) << 12) / width - 4096L;
if (*hscale >= 0x4000)
*hscale = 0x3fff;

*vscale = (((unsigned long)maxh) << 12) / height - 4096L;
if (*vscale >= 0x4000)
*vscale = 0x3fff;
}

/* ------------------------------------------------------------------
IOCTL vidioc handling
------------------------------------------------------------------*/
Expand Down Expand Up @@ -1071,7 +1055,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
unsigned int height = f->fmt.pix.height;
unsigned int maxw = norm_maxw(dev);
unsigned int maxh = norm_maxh(dev);
unsigned int hscale, vscale;
struct cx231xx_fmt *fmt;

fmt = format_by_fourcc(f->fmt.pix.pixelformat);
Expand All @@ -1085,11 +1068,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
height must be even because of interlacing */
v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, 1, 0);

get_scale(dev, width, height, &hscale, &vscale);

width = (((unsigned long)maxw) << 12) / (hscale + 4096L);
height = (((unsigned long)maxh) << 12) / (vscale + 4096L);

f->fmt.pix.width = width;
f->fmt.pix.height = height;
f->fmt.pix.pixelformat = fmt->fourcc;
Expand Down Expand Up @@ -1140,15 +1118,11 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
dev->width = f->fmt.pix.width;
dev->height = f->fmt.pix.height;
dev->format = fmt;
get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);

v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
call_all(dev, video, s_mbus_fmt, &mbus_fmt);
v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);

/* Set the correct alternate setting for this resolution */
cx231xx_resolution_set(dev);

out:
mutex_unlock(&dev->lock);
return rc;
Expand All @@ -1167,6 +1141,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
{
struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev;
struct v4l2_mbus_framefmt mbus_fmt;
struct v4l2_format f;
int rc;

Expand All @@ -1184,17 +1159,21 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
f.fmt.pix.height = dev->height;
vidioc_try_fmt_vid_cap(file, priv, &f);

call_all(dev, core, s_std, dev->norm);

/* We need to reset basic properties in the decoder related to
resolution (since a standard change effects things like the number
of lines in VACT, etc) */
v4l2_fill_mbus_format(&mbus_fmt, &f.fmt.pix, V4L2_MBUS_FMT_FIXED);
call_all(dev, video, s_mbus_fmt, &mbus_fmt);
v4l2_fill_pix_format(&f.fmt.pix, &mbus_fmt);

/* set new image size */
dev->width = f.fmt.pix.width;
dev->height = f.fmt.pix.height;
get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);

call_all(dev, core, s_std, dev->norm);

mutex_unlock(&dev->lock);

cx231xx_resolution_set(dev);

/* do mode control overrides */
cx231xx_do_mode_ctrl_overrides(dev);

Expand Down Expand Up @@ -2279,8 +2258,6 @@ static int cx231xx_v4l2_open(struct file *filp)
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
dev->width = norm_maxw(dev);
dev->height = norm_maxh(dev);
dev->hscale = 0;
dev->vscale = 0;

/* Power up in Analog TV mode */
if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER)
Expand All @@ -2292,7 +2269,6 @@ static int cx231xx_v4l2_open(struct file *filp)
#if 0
cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);
#endif
cx231xx_resolution_set(dev);

/* set video alternate setting */
cx231xx_set_video_alternate(dev);
Expand Down Expand Up @@ -2688,8 +2664,6 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
dev->width = norm_maxw(dev);
dev->height = norm_maxh(dev);
dev->interlaced = 0;
dev->hscale = 0;
dev->vscale = 0;

/* Analog specific initialization */
dev->format = &format[0];
Expand Down
3 changes: 0 additions & 3 deletions drivers/media/video/cx231xx/cx231xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -645,8 +645,6 @@ struct cx231xx {
/* frame properties */
int width; /* current frame width */
int height; /* current frame height */
unsigned hscale; /* horizontal scale factor (see datasheet) */
unsigned vscale; /* vertical scale factor (see datasheet) */
int interlaced; /* 1=interlace fileds, 0=just top fileds */

struct cx231xx_audio adev;
Expand Down Expand Up @@ -876,7 +874,6 @@ int cx231xx_set_audio_decoder_input(struct cx231xx *dev,
enum AUDIO_INPUT audio_input);

int cx231xx_capture_start(struct cx231xx *dev, int start, u8 media_type);
int cx231xx_resolution_set(struct cx231xx *dev);
int cx231xx_set_video_alternate(struct cx231xx *dev);
int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt);
int is_fw_load(struct cx231xx *dev);
Expand Down

0 comments on commit 435b4f7

Please sign in to comment.