Commit 765fe17c authored by Guennadi Liakhovetski's avatar Guennadi Liakhovetski Committed by Mauro Carvalho Chehab

V4L/DVB: V4L2: sh_vou: VOU does support the full PAL resolution too

SH7724 datasheet specifies 480 pixels as the VOU maximum vertical resolution.
This is a bug in the datasheet, VOU also supports the full PAL resolution: 576
lines. Adjust the driver accordingly.
Signed-off-by: default avatarGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent b3b5020d
...@@ -58,7 +58,7 @@ enum sh_vou_status { ...@@ -58,7 +58,7 @@ enum sh_vou_status {
}; };
#define VOU_MAX_IMAGE_WIDTH 720 #define VOU_MAX_IMAGE_WIDTH 720
#define VOU_MAX_IMAGE_HEIGHT 480 #define VOU_MAX_IMAGE_HEIGHT 576
struct sh_vou_device { struct sh_vou_device {
struct v4l2_device v4l2_dev; struct v4l2_device v4l2_dev;
...@@ -528,20 +528,17 @@ struct sh_vou_geometry { ...@@ -528,20 +528,17 @@ struct sh_vou_geometry {
static void vou_adjust_input(struct sh_vou_geometry *geo, v4l2_std_id std) static void vou_adjust_input(struct sh_vou_geometry *geo, v4l2_std_id std)
{ {
/* The compiler cannot know, that best and idx will indeed be set */ /* The compiler cannot know, that best and idx will indeed be set */
unsigned int best_err = UINT_MAX, best = 0, width_max, height_max; unsigned int best_err = UINT_MAX, best = 0, img_height_max;
int i, idx = 0; int i, idx = 0;
if (std & V4L2_STD_525_60) { if (std & V4L2_STD_525_60)
width_max = 858; img_height_max = 480;
height_max = 262; else
} else { img_height_max = 576;
width_max = 864;
height_max = 312;
}
/* Image width must be a multiple of 4 */ /* Image width must be a multiple of 4 */
v4l_bound_align_image(&geo->in_width, 0, VOU_MAX_IMAGE_WIDTH, 2, v4l_bound_align_image(&geo->in_width, 0, VOU_MAX_IMAGE_WIDTH, 2,
&geo->in_height, 0, VOU_MAX_IMAGE_HEIGHT, 1, 0); &geo->in_height, 0, img_height_max, 1, 0);
/* Select scales to come as close as possible to the output image */ /* Select scales to come as close as possible to the output image */
for (i = ARRAY_SIZE(vou_scale_h_num) - 1; i >= 0; i--) { for (i = ARRAY_SIZE(vou_scale_h_num) - 1; i >= 0; i--) {
...@@ -574,7 +571,7 @@ static void vou_adjust_input(struct sh_vou_geometry *geo, v4l2_std_id std) ...@@ -574,7 +571,7 @@ static void vou_adjust_input(struct sh_vou_geometry *geo, v4l2_std_id std)
unsigned int found = geo->output.height * vou_scale_v_den[i] / unsigned int found = geo->output.height * vou_scale_v_den[i] /
vou_scale_v_num[i]; vou_scale_v_num[i];
if (found > VOU_MAX_IMAGE_HEIGHT) if (found > img_height_max)
/* scales increase */ /* scales increase */
break; break;
...@@ -598,15 +595,18 @@ static void vou_adjust_input(struct sh_vou_geometry *geo, v4l2_std_id std) ...@@ -598,15 +595,18 @@ static void vou_adjust_input(struct sh_vou_geometry *geo, v4l2_std_id std)
*/ */
static void vou_adjust_output(struct sh_vou_geometry *geo, v4l2_std_id std) static void vou_adjust_output(struct sh_vou_geometry *geo, v4l2_std_id std)
{ {
unsigned int best_err = UINT_MAX, best, width_max, height_max; unsigned int best_err = UINT_MAX, best, width_max, height_max,
img_height_max;
int i, idx; int i, idx;
if (std & V4L2_STD_525_60) { if (std & V4L2_STD_525_60) {
width_max = 858; width_max = 858;
height_max = 262 * 2; height_max = 262 * 2;
img_height_max = 480;
} else { } else {
width_max = 864; width_max = 864;
height_max = 312 * 2; height_max = 312 * 2;
img_height_max = 576;
} }
/* Select scales to come as close as possible to the output image */ /* Select scales to come as close as possible to the output image */
...@@ -645,7 +645,7 @@ static void vou_adjust_output(struct sh_vou_geometry *geo, v4l2_std_id std) ...@@ -645,7 +645,7 @@ static void vou_adjust_output(struct sh_vou_geometry *geo, v4l2_std_id std)
unsigned int found = geo->in_height * vou_scale_v_num[i] / unsigned int found = geo->in_height * vou_scale_v_num[i] /
vou_scale_v_den[i]; vou_scale_v_den[i];
if (found > VOU_MAX_IMAGE_HEIGHT) if (found > img_height_max)
/* scales increase */ /* scales increase */
break; break;
...@@ -674,6 +674,7 @@ static int sh_vou_s_fmt_vid_out(struct file *file, void *priv, ...@@ -674,6 +674,7 @@ static int sh_vou_s_fmt_vid_out(struct file *file, void *priv,
struct video_device *vdev = video_devdata(file); struct video_device *vdev = video_devdata(file);
struct sh_vou_device *vou_dev = video_get_drvdata(vdev); struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
struct v4l2_pix_format *pix = &fmt->fmt.pix; struct v4l2_pix_format *pix = &fmt->fmt.pix;
unsigned int img_height_max;
int pix_idx; int pix_idx;
struct sh_vou_geometry geo; struct sh_vou_geometry geo;
struct v4l2_mbus_framefmt mbfmt = { struct v4l2_mbus_framefmt mbfmt = {
...@@ -702,9 +703,14 @@ static int sh_vou_s_fmt_vid_out(struct file *file, void *priv, ...@@ -702,9 +703,14 @@ static int sh_vou_s_fmt_vid_out(struct file *file, void *priv,
if (pix_idx == ARRAY_SIZE(vou_fmt)) if (pix_idx == ARRAY_SIZE(vou_fmt))
return -EINVAL; return -EINVAL;
if (vou_dev->std & V4L2_STD_525_60)
img_height_max = 480;
else
img_height_max = 576;
/* Image width must be a multiple of 4 */ /* Image width must be a multiple of 4 */
v4l_bound_align_image(&pix->width, 0, VOU_MAX_IMAGE_WIDTH, 2, v4l_bound_align_image(&pix->width, 0, VOU_MAX_IMAGE_WIDTH, 2,
&pix->height, 0, VOU_MAX_IMAGE_HEIGHT, 1, 0); &pix->height, 0, img_height_max, 1, 0);
geo.in_width = pix->width; geo.in_width = pix->width;
geo.in_height = pix->height; geo.in_height = pix->height;
...@@ -725,7 +731,7 @@ static int sh_vou_s_fmt_vid_out(struct file *file, void *priv, ...@@ -725,7 +731,7 @@ static int sh_vou_s_fmt_vid_out(struct file *file, void *priv,
/* Sanity checks */ /* Sanity checks */
if ((unsigned)mbfmt.width > VOU_MAX_IMAGE_WIDTH || if ((unsigned)mbfmt.width > VOU_MAX_IMAGE_WIDTH ||
(unsigned)mbfmt.height > VOU_MAX_IMAGE_HEIGHT || (unsigned)mbfmt.height > img_height_max ||
mbfmt.code != V4L2_MBUS_FMT_YUYV8_2X8) mbfmt.code != V4L2_MBUS_FMT_YUYV8_2X8)
return -EIO; return -EIO;
...@@ -941,6 +947,7 @@ static int sh_vou_s_crop(struct file *file, void *fh, struct v4l2_crop *a) ...@@ -941,6 +947,7 @@ static int sh_vou_s_crop(struct file *file, void *fh, struct v4l2_crop *a)
.field = V4L2_FIELD_INTERLACED, .field = V4L2_FIELD_INTERLACED,
.colorspace = V4L2_COLORSPACE_SMPTE170M, .colorspace = V4L2_COLORSPACE_SMPTE170M,
}; };
unsigned int img_height_max;
int ret; int ret;
dev_dbg(vou_dev->v4l2_dev.dev, "%s(): %ux%u@%u:%u\n", __func__, dev_dbg(vou_dev->v4l2_dev.dev, "%s(): %ux%u@%u:%u\n", __func__,
...@@ -949,14 +956,19 @@ static int sh_vou_s_crop(struct file *file, void *fh, struct v4l2_crop *a) ...@@ -949,14 +956,19 @@ static int sh_vou_s_crop(struct file *file, void *fh, struct v4l2_crop *a)
if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
return -EINVAL; return -EINVAL;
if (vou_dev->std & V4L2_STD_525_60)
img_height_max = 480;
else
img_height_max = 576;
v4l_bound_align_image(&rect->width, 0, VOU_MAX_IMAGE_WIDTH, 1, v4l_bound_align_image(&rect->width, 0, VOU_MAX_IMAGE_WIDTH, 1,
&rect->height, 0, VOU_MAX_IMAGE_HEIGHT, 1, 0); &rect->height, 0, img_height_max, 1, 0);
if (rect->width + rect->left > VOU_MAX_IMAGE_WIDTH) if (rect->width + rect->left > VOU_MAX_IMAGE_WIDTH)
rect->left = VOU_MAX_IMAGE_WIDTH - rect->width; rect->left = VOU_MAX_IMAGE_WIDTH - rect->width;
if (rect->height + rect->top > VOU_MAX_IMAGE_HEIGHT) if (rect->height + rect->top > img_height_max)
rect->top = VOU_MAX_IMAGE_HEIGHT - rect->height; rect->top = img_height_max - rect->height;
geo.output = *rect; geo.output = *rect;
geo.in_width = pix->width; geo.in_width = pix->width;
...@@ -981,7 +993,7 @@ static int sh_vou_s_crop(struct file *file, void *fh, struct v4l2_crop *a) ...@@ -981,7 +993,7 @@ static int sh_vou_s_crop(struct file *file, void *fh, struct v4l2_crop *a)
/* Sanity checks */ /* Sanity checks */
if ((unsigned)mbfmt.width > VOU_MAX_IMAGE_WIDTH || if ((unsigned)mbfmt.width > VOU_MAX_IMAGE_WIDTH ||
(unsigned)mbfmt.height > VOU_MAX_IMAGE_HEIGHT || (unsigned)mbfmt.height > img_height_max ||
mbfmt.code != V4L2_MBUS_FMT_YUYV8_2X8) mbfmt.code != V4L2_MBUS_FMT_YUYV8_2X8)
return -EIO; return -EIO;
...@@ -1330,13 +1342,13 @@ static int __devinit sh_vou_probe(struct platform_device *pdev) ...@@ -1330,13 +1342,13 @@ static int __devinit sh_vou_probe(struct platform_device *pdev)
rect->left = 0; rect->left = 0;
rect->top = 0; rect->top = 0;
rect->width = VOU_MAX_IMAGE_WIDTH; rect->width = VOU_MAX_IMAGE_WIDTH;
rect->height = VOU_MAX_IMAGE_HEIGHT; rect->height = 480;
pix->width = VOU_MAX_IMAGE_WIDTH; pix->width = VOU_MAX_IMAGE_WIDTH;
pix->height = VOU_MAX_IMAGE_HEIGHT; pix->height = 480;
pix->pixelformat = V4L2_PIX_FMT_YVYU; pix->pixelformat = V4L2_PIX_FMT_YVYU;
pix->field = V4L2_FIELD_NONE; pix->field = V4L2_FIELD_NONE;
pix->bytesperline = VOU_MAX_IMAGE_WIDTH * 2; pix->bytesperline = VOU_MAX_IMAGE_WIDTH * 2;
pix->sizeimage = VOU_MAX_IMAGE_WIDTH * 2 * VOU_MAX_IMAGE_HEIGHT; pix->sizeimage = VOU_MAX_IMAGE_WIDTH * 2 * 480;
pix->colorspace = V4L2_COLORSPACE_SMPTE170M; pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
region = request_mem_region(reg_res->start, resource_size(reg_res), region = request_mem_region(reg_res->start, resource_size(reg_res),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment