V4L/DVB (5547): Add ENUM_FRAMESIZES and ENUM_FRAMEINTERVALS ioctls

This patch add support for the VIDIOC_ENUM_FRAMESIZES and
VIDIOC_ENUM_FRAMEINTERVALS ioctl.
* check if the maximum native framesize for raw mode is correct
* raw mode framerates for all three chipset types

Signed-off-by: Gregor Jasny <gjasny@web.de>
Signed-off-by: Luc Saillard <luc@saillard.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index d5e6bc8..e20251d 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -1193,6 +1193,64 @@
 			return 0;
 		}
 
+		case VIDIOC_ENUM_FRAMESIZES:
+		{
+			struct v4l2_frmsizeenum *fsize = arg;
+			unsigned int i = 0, index = fsize->index;
+
+			if (fsize->pixel_format == V4L2_PIX_FMT_YUV420) {
+				for (i = 0; i < PSZ_MAX; i++) {
+					if (pdev->image_mask & (1UL << i)) {
+						if (!index--) {
+							fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+							fsize->discrete.width = pwc_image_sizes[i].x;
+							fsize->discrete.height = pwc_image_sizes[i].y;
+							return 0;
+						}
+					}
+				}
+			} else if (fsize->index == 0 &&
+				   ((fsize->pixel_format == V4L2_PIX_FMT_PWC1 && DEVICE_USE_CODEC1(pdev->type)) ||
+				    (fsize->pixel_format == V4L2_PIX_FMT_PWC2 && DEVICE_USE_CODEC23(pdev->type)))) {
+
+				fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+				fsize->discrete.width = pdev->abs_max.x;
+				fsize->discrete.height = pdev->abs_max.y;
+				return 0;
+			}
+			return -EINVAL;
+		}
+
+		case VIDIOC_ENUM_FRAMEINTERVALS:
+		{
+			struct v4l2_frmivalenum *fival = arg;
+			int size = -1;
+			unsigned int i;
+
+			for (i = 0; i < PSZ_MAX; i++) {
+				if (pwc_image_sizes[i].x == fival->width &&
+				    pwc_image_sizes[i].y == fival->height) {
+					size = i;
+					break;
+				}
+			}
+
+			/* TODO: Support raw format */
+			if (size < 0 || fival->pixel_format != V4L2_PIX_FMT_YUV420) {
+				return -EINVAL;
+			}
+
+			i = pwc_get_fps(pdev, fival->index, size);
+			if (!i)
+				return -EINVAL;
+
+			fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+			fival->discrete.numerator = 1;
+			fival->discrete.denominator = i;
+
+			return 0;
+		}
+
 		default:
 			return pwc_ioctl(pdev, cmd, arg);
 	} /* ..switch */