diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2010-07-29 03:11:42 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-08-02 15:43:41 -0400 |
commit | 765fe17c4f018c019f1976455084f528474fc7f8 (patch) | |
tree | 0e89b01240a58022beeb8ea532e9d3c683deb7a1 | |
parent | b3b5020d8c12037f030242aab8e272148bf1f472 (diff) |
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: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/sh_vou.c | 56 |
1 files changed, 34 insertions, 22 deletions
diff --git a/drivers/media/video/sh_vou.c b/drivers/media/video/sh_vou.c index 3869d515febd..d394187eb701 100644 --- a/drivers/media/video/sh_vou.c +++ b/drivers/media/video/sh_vou.c | |||
@@ -58,7 +58,7 @@ enum sh_vou_status { | |||
58 | }; | 58 | }; |
59 | 59 | ||
60 | #define VOU_MAX_IMAGE_WIDTH 720 | 60 | #define VOU_MAX_IMAGE_WIDTH 720 |
61 | #define VOU_MAX_IMAGE_HEIGHT 480 | 61 | #define VOU_MAX_IMAGE_HEIGHT 576 |
62 | 62 | ||
63 | struct sh_vou_device { | 63 | struct sh_vou_device { |
64 | struct v4l2_device v4l2_dev; | 64 | struct v4l2_device v4l2_dev; |
@@ -528,20 +528,17 @@ struct sh_vou_geometry { | |||
528 | static void vou_adjust_input(struct sh_vou_geometry *geo, v4l2_std_id std) | 528 | static void vou_adjust_input(struct sh_vou_geometry *geo, v4l2_std_id std) |
529 | { | 529 | { |
530 | /* The compiler cannot know, that best and idx will indeed be set */ | 530 | /* The compiler cannot know, that best and idx will indeed be set */ |
531 | unsigned int best_err = UINT_MAX, best = 0, width_max, height_max; | 531 | unsigned int best_err = UINT_MAX, best = 0, img_height_max; |
532 | int i, idx = 0; | 532 | int i, idx = 0; |
533 | 533 | ||
534 | if (std & V4L2_STD_525_60) { | 534 | if (std & V4L2_STD_525_60) |
535 | width_max = 858; | 535 | img_height_max = 480; |
536 | height_max = 262; | 536 | else |
537 | } else { | 537 | img_height_max = 576; |
538 | width_max = 864; | ||
539 | height_max = 312; | ||
540 | } | ||
541 | 538 | ||
542 | /* Image width must be a multiple of 4 */ | 539 | /* Image width must be a multiple of 4 */ |
543 | v4l_bound_align_image(&geo->in_width, 0, VOU_MAX_IMAGE_WIDTH, 2, | 540 | v4l_bound_align_image(&geo->in_width, 0, VOU_MAX_IMAGE_WIDTH, 2, |
544 | &geo->in_height, 0, VOU_MAX_IMAGE_HEIGHT, 1, 0); | 541 | &geo->in_height, 0, img_height_max, 1, 0); |
545 | 542 | ||
546 | /* Select scales to come as close as possible to the output image */ | 543 | /* Select scales to come as close as possible to the output image */ |
547 | for (i = ARRAY_SIZE(vou_scale_h_num) - 1; i >= 0; i--) { | 544 | 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 | unsigned int found = geo->output.height * vou_scale_v_den[i] / | 571 | unsigned int found = geo->output.height * vou_scale_v_den[i] / |
575 | vou_scale_v_num[i]; | 572 | vou_scale_v_num[i]; |
576 | 573 | ||
577 | if (found > VOU_MAX_IMAGE_HEIGHT) | 574 | if (found > img_height_max) |
578 | /* scales increase */ | 575 | /* scales increase */ |
579 | break; | 576 | break; |
580 | 577 | ||
@@ -598,15 +595,18 @@ static void vou_adjust_input(struct sh_vou_geometry *geo, v4l2_std_id std) | |||
598 | */ | 595 | */ |
599 | static void vou_adjust_output(struct sh_vou_geometry *geo, v4l2_std_id std) | 596 | static void vou_adjust_output(struct sh_vou_geometry *geo, v4l2_std_id std) |
600 | { | 597 | { |
601 | unsigned int best_err = UINT_MAX, best, width_max, height_max; | 598 | unsigned int best_err = UINT_MAX, best, width_max, height_max, |
599 | img_height_max; | ||
602 | int i, idx; | 600 | int i, idx; |
603 | 601 | ||
604 | if (std & V4L2_STD_525_60) { | 602 | if (std & V4L2_STD_525_60) { |
605 | width_max = 858; | 603 | width_max = 858; |
606 | height_max = 262 * 2; | 604 | height_max = 262 * 2; |
605 | img_height_max = 480; | ||
607 | } else { | 606 | } else { |
608 | width_max = 864; | 607 | width_max = 864; |
609 | height_max = 312 * 2; | 608 | height_max = 312 * 2; |
609 | img_height_max = 576; | ||
610 | } | 610 | } |
611 | 611 | ||
612 | /* Select scales to come as close as possible to the output image */ | 612 | /* 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 | unsigned int found = geo->in_height * vou_scale_v_num[i] / | 645 | unsigned int found = geo->in_height * vou_scale_v_num[i] / |
646 | vou_scale_v_den[i]; | 646 | vou_scale_v_den[i]; |
647 | 647 | ||
648 | if (found > VOU_MAX_IMAGE_HEIGHT) | 648 | if (found > img_height_max) |
649 | /* scales increase */ | 649 | /* scales increase */ |
650 | break; | 650 | break; |
651 | 651 | ||
@@ -674,6 +674,7 @@ static int sh_vou_s_fmt_vid_out(struct file *file, void *priv, | |||
674 | struct video_device *vdev = video_devdata(file); | 674 | struct video_device *vdev = video_devdata(file); |
675 | struct sh_vou_device *vou_dev = video_get_drvdata(vdev); | 675 | struct sh_vou_device *vou_dev = video_get_drvdata(vdev); |
676 | struct v4l2_pix_format *pix = &fmt->fmt.pix; | 676 | struct v4l2_pix_format *pix = &fmt->fmt.pix; |
677 | unsigned int img_height_max; | ||
677 | int pix_idx; | 678 | int pix_idx; |
678 | struct sh_vou_geometry geo; | 679 | struct sh_vou_geometry geo; |
679 | struct v4l2_mbus_framefmt mbfmt = { | 680 | struct v4l2_mbus_framefmt mbfmt = { |
@@ -702,9 +703,14 @@ static int sh_vou_s_fmt_vid_out(struct file *file, void *priv, | |||
702 | if (pix_idx == ARRAY_SIZE(vou_fmt)) | 703 | if (pix_idx == ARRAY_SIZE(vou_fmt)) |
703 | return -EINVAL; | 704 | return -EINVAL; |
704 | 705 | ||
706 | if (vou_dev->std & V4L2_STD_525_60) | ||
707 | img_height_max = 480; | ||
708 | else | ||
709 | img_height_max = 576; | ||
710 | |||
705 | /* Image width must be a multiple of 4 */ | 711 | /* Image width must be a multiple of 4 */ |
706 | v4l_bound_align_image(&pix->width, 0, VOU_MAX_IMAGE_WIDTH, 2, | 712 | v4l_bound_align_image(&pix->width, 0, VOU_MAX_IMAGE_WIDTH, 2, |
707 | &pix->height, 0, VOU_MAX_IMAGE_HEIGHT, 1, 0); | 713 | &pix->height, 0, img_height_max, 1, 0); |
708 | 714 | ||
709 | geo.in_width = pix->width; | 715 | geo.in_width = pix->width; |
710 | geo.in_height = pix->height; | 716 | geo.in_height = pix->height; |
@@ -725,7 +731,7 @@ static int sh_vou_s_fmt_vid_out(struct file *file, void *priv, | |||
725 | 731 | ||
726 | /* Sanity checks */ | 732 | /* Sanity checks */ |
727 | if ((unsigned)mbfmt.width > VOU_MAX_IMAGE_WIDTH || | 733 | if ((unsigned)mbfmt.width > VOU_MAX_IMAGE_WIDTH || |
728 | (unsigned)mbfmt.height > VOU_MAX_IMAGE_HEIGHT || | 734 | (unsigned)mbfmt.height > img_height_max || |
729 | mbfmt.code != V4L2_MBUS_FMT_YUYV8_2X8) | 735 | mbfmt.code != V4L2_MBUS_FMT_YUYV8_2X8) |
730 | return -EIO; | 736 | return -EIO; |
731 | 737 | ||
@@ -941,6 +947,7 @@ static int sh_vou_s_crop(struct file *file, void *fh, struct v4l2_crop *a) | |||
941 | .field = V4L2_FIELD_INTERLACED, | 947 | .field = V4L2_FIELD_INTERLACED, |
942 | .colorspace = V4L2_COLORSPACE_SMPTE170M, | 948 | .colorspace = V4L2_COLORSPACE_SMPTE170M, |
943 | }; | 949 | }; |
950 | unsigned int img_height_max; | ||
944 | int ret; | 951 | int ret; |
945 | 952 | ||
946 | dev_dbg(vou_dev->v4l2_dev.dev, "%s(): %ux%u@%u:%u\n", __func__, | 953 | 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 | if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) | 956 | if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) |
950 | return -EINVAL; | 957 | return -EINVAL; |
951 | 958 | ||
959 | if (vou_dev->std & V4L2_STD_525_60) | ||
960 | img_height_max = 480; | ||
961 | else | ||
962 | img_height_max = 576; | ||
963 | |||
952 | v4l_bound_align_image(&rect->width, 0, VOU_MAX_IMAGE_WIDTH, 1, | 964 | v4l_bound_align_image(&rect->width, 0, VOU_MAX_IMAGE_WIDTH, 1, |
953 | &rect->height, 0, VOU_MAX_IMAGE_HEIGHT, 1, 0); | 965 | &rect->height, 0, img_height_max, 1, 0); |
954 | 966 | ||
955 | if (rect->width + rect->left > VOU_MAX_IMAGE_WIDTH) | 967 | if (rect->width + rect->left > VOU_MAX_IMAGE_WIDTH) |
956 | rect->left = VOU_MAX_IMAGE_WIDTH - rect->width; | 968 | rect->left = VOU_MAX_IMAGE_WIDTH - rect->width; |
957 | 969 | ||
958 | if (rect->height + rect->top > VOU_MAX_IMAGE_HEIGHT) | 970 | if (rect->height + rect->top > img_height_max) |
959 | rect->top = VOU_MAX_IMAGE_HEIGHT - rect->height; | 971 | rect->top = img_height_max - rect->height; |
960 | 972 | ||
961 | geo.output = *rect; | 973 | geo.output = *rect; |
962 | geo.in_width = pix->width; | 974 | 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 | 993 | ||
982 | /* Sanity checks */ | 994 | /* Sanity checks */ |
983 | if ((unsigned)mbfmt.width > VOU_MAX_IMAGE_WIDTH || | 995 | if ((unsigned)mbfmt.width > VOU_MAX_IMAGE_WIDTH || |
984 | (unsigned)mbfmt.height > VOU_MAX_IMAGE_HEIGHT || | 996 | (unsigned)mbfmt.height > img_height_max || |
985 | mbfmt.code != V4L2_MBUS_FMT_YUYV8_2X8) | 997 | mbfmt.code != V4L2_MBUS_FMT_YUYV8_2X8) |
986 | return -EIO; | 998 | return -EIO; |
987 | 999 | ||
@@ -1330,13 +1342,13 @@ static int __devinit sh_vou_probe(struct platform_device *pdev) | |||
1330 | rect->left = 0; | 1342 | rect->left = 0; |
1331 | rect->top = 0; | 1343 | rect->top = 0; |
1332 | rect->width = VOU_MAX_IMAGE_WIDTH; | 1344 | rect->width = VOU_MAX_IMAGE_WIDTH; |
1333 | rect->height = VOU_MAX_IMAGE_HEIGHT; | 1345 | rect->height = 480; |
1334 | pix->width = VOU_MAX_IMAGE_WIDTH; | 1346 | pix->width = VOU_MAX_IMAGE_WIDTH; |
1335 | pix->height = VOU_MAX_IMAGE_HEIGHT; | 1347 | pix->height = 480; |
1336 | pix->pixelformat = V4L2_PIX_FMT_YVYU; | 1348 | pix->pixelformat = V4L2_PIX_FMT_YVYU; |
1337 | pix->field = V4L2_FIELD_NONE; | 1349 | pix->field = V4L2_FIELD_NONE; |
1338 | pix->bytesperline = VOU_MAX_IMAGE_WIDTH * 2; | 1350 | pix->bytesperline = VOU_MAX_IMAGE_WIDTH * 2; |
1339 | pix->sizeimage = VOU_MAX_IMAGE_WIDTH * 2 * VOU_MAX_IMAGE_HEIGHT; | 1351 | pix->sizeimage = VOU_MAX_IMAGE_WIDTH * 2 * 480; |
1340 | pix->colorspace = V4L2_COLORSPACE_SMPTE170M; | 1352 | pix->colorspace = V4L2_COLORSPACE_SMPTE170M; |
1341 | 1353 | ||
1342 | region = request_mem_region(reg_res->start, resource_size(reg_res), | 1354 | region = request_mem_region(reg_res->start, resource_size(reg_res), |