[media] pwc: Remove software emulation of arbritary resolutions

The pwc driver claims to support any resolution between 160x120
and 640x480, but emulates this by simply drawing a black border
around the image. Userspace can draw its own black border if it
really wants one.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 821e3c2..c4362ef 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -460,16 +460,6 @@
 
 ----------------------------
 
-What:	Software emulation of arbritary resolutions in the pwc driver
-When:	3.3
-Why:	The pwc driver claims to support any resolution between 160x120
-	and 640x480, but emulates this by simply drawing a black border
-	around the image. Userspace can draw its own black border if it
-	really wants one.
-Who:	Hans de Goede <hdegoede@redhat.com>
-
-----------------------------
-
 What:	For VIDIOC_S_FREQUENCY the type field must match the device node's type.
 	If not, return -EINVAL.
 When:	3.2
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c
index 684b7c5..6b9c97f 100644
--- a/drivers/media/video/pwc/pwc-ctrl.c
+++ b/drivers/media/video/pwc/pwc-ctrl.c
@@ -102,8 +102,6 @@
 #include "pwc-nala.h"
 };
 
-static void pwc_set_image_buffer_size(struct pwc_device *pdev);
-
 /****************************************************************************/
 
 static int _send_control_msg(struct pwc_device *pdev,
@@ -221,8 +219,9 @@
 	/* Set various parameters */
 	pdev->vframes = frames;
 	pdev->valternate = pEntry->alternate;
-	pdev->image = pwc_image_sizes[size];
-	pdev->frame_size = (pdev->image.x * pdev->image.y * 3) / 2;
+	pdev->width  = pwc_image_sizes[size][0];
+	pdev->height = pwc_image_sizes[size][1];
+	pdev->frame_size = (pdev->width * pdev->height * 3) / 2;
 	if (pEntry->compressed) {
 		if (pdev->release < 5) { /* 4 fold compression */
 			pdev->vbandlength = 528;
@@ -282,12 +281,13 @@
 	/* Set various parameters */
 	pdev->vframes = frames;
 	pdev->valternate = pChoose->alternate;
-	pdev->image = pwc_image_sizes[size];
+	pdev->width  = pwc_image_sizes[size][0];
+	pdev->height = pwc_image_sizes[size][1];
 	pdev->vbandlength = pChoose->bandlength;
 	if (pChoose->bandlength > 0)
-		pdev->frame_size = (pChoose->bandlength * pdev->image.y) / 4;
+		pdev->frame_size = (pChoose->bandlength * pdev->height) / 4;
 	else
-		pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8;
+		pdev->frame_size = (pdev->width * pdev->height * 12) / 8;
 	return 0;
 }
 
@@ -339,37 +339,25 @@
 	/* All set and go */
 	pdev->vframes = frames;
 	pdev->valternate = pChoose->alternate;
-	pdev->image = pwc_image_sizes[size];
+	pdev->width  = pwc_image_sizes[size][0];
+	pdev->height = pwc_image_sizes[size][1];
 	pdev->vbandlength = pChoose->bandlength;
 	if (pdev->vbandlength > 0)
-		pdev->frame_size = (pdev->vbandlength * pdev->image.y) / 4;
+		pdev->frame_size = (pdev->vbandlength * pdev->height) / 4;
 	else
-		pdev->frame_size = (pdev->image.x * pdev->image.y * 12) / 8;
+		pdev->frame_size = (pdev->width * pdev->height * 12) / 8;
 	PWC_TRACE("frame_size=%d, vframes=%d, vsize=%d, vbandlength=%d\n",
 	    pdev->frame_size, pdev->vframes, size, pdev->vbandlength);
 	return 0;
 }
 
-
-
-/**
-   @pdev: device structure
-   @width: viewport width
-   @height: viewport height
-   @frame: framerate, in fps
-   @compression: preferred compression ratio
- */
 int pwc_set_video_mode(struct pwc_device *pdev, int width, int height,
 	int frames, int compression)
 {
 	int ret, size;
 
 	PWC_DEBUG_FLOW("set_video_mode(%dx%d @ %d, pixfmt %08x).\n", width, height, frames, pdev->pixfmt);
-	size = pwc_decode_size(pdev, width, height);
-	if (size < 0) {
-		PWC_DEBUG_MODULE("Could not find suitable size.\n");
-		return -ERANGE;
-	}
+	size = pwc_get_size(pdev, width, height);
 	PWC_TRACE("decode_size = %d.\n", size);
 
 	if (DEVICE_USE_CODEC1(pdev->type)) {
@@ -385,12 +373,9 @@
 		PWC_ERROR("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret);
 		return ret;
 	}
-	pdev->view.x = width;
-	pdev->view.y = height;
 	pdev->vcompression = compression;
 	pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size;
-	pwc_set_image_buffer_size(pdev);
-	PWC_DEBUG_SIZE("Set viewport to %dx%d, image size is %dx%d.\n", width, height, pwc_image_sizes[size].x, pwc_image_sizes[size].y);
+	PWC_DEBUG_SIZE("Set resolution to %dx%d\n", pdev->width, pdev->height);
 	return 0;
 }
 
@@ -447,34 +432,6 @@
 	return ret;
 }
 
-static void pwc_set_image_buffer_size(struct pwc_device *pdev)
-{
-	int factor = 0;
-
-	/* for V4L2_PIX_FMT_YUV420 */
-	switch (pdev->pixfmt) {
-	case V4L2_PIX_FMT_YUV420:
-		factor = 6;
-		break;
-	case V4L2_PIX_FMT_PWC1:
-	case V4L2_PIX_FMT_PWC2:
-		factor = 6; /* can be uncompressed YUV420P */
-		break;
-	}
-
-	/* Set sizes in bytes */
-	pdev->image.size = pdev->image.x * pdev->image.y * factor / 4;
-	pdev->view.size  = pdev->view.x  * pdev->view.y  * factor / 4;
-
-	/* Align offset, or you'll get some very weird results in
-	   YUV420 mode... x must be multiple of 4 (to get the Y's in
-	   place), and y even (or you'll mixup U & V). This is less of a
-	   problem for YUV420P.
-	 */
-	pdev->offset.x = ((pdev->view.x - pdev->image.x) / 2) & 0xFFFC;
-	pdev->offset.y = ((pdev->view.y - pdev->image.y) / 2) & 0xFFFE;
-}
-
 int pwc_get_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, int *data)
 {
 	int ret;
diff --git a/drivers/media/video/pwc/pwc-dec23.c b/drivers/media/video/pwc/pwc-dec23.c
index e531f85..2c67091 100644
--- a/drivers/media/video/pwc/pwc-dec23.c
+++ b/drivers/media/video/pwc/pwc-dec23.c
@@ -656,10 +656,6 @@
  *
  * Uncompress a pwc23 buffer.
  *
- * pwc.view: size of the image wanted
- * pwc.image: size of the image returned by the camera
- * pwc.offset: (x,y) to displayer image in the view
- *
  * src: raw data
  * dst: image output
  */
@@ -667,7 +663,7 @@
 			  const void *src,
 			  void *dst)
 {
-	int bandlines_left, stride, bytes_per_block;
+	int bandlines_left, bytes_per_block;
 	struct pwc_dec23_private *pdec = pwc->decompress_data;
 
 	/* YUV420P image format */
@@ -678,28 +674,23 @@
 
 	mutex_lock(&pdec->lock);
 
-	bandlines_left = pwc->image.y / 4;
-	bytes_per_block = pwc->view.x * 4;
-	plane_size = pwc->view.x * pwc->view.y;
+	bandlines_left = pwc->height / 4;
+	bytes_per_block = pwc->width * 4;
+	plane_size = pwc->height * pwc->width;
 
-	/* offset in Y plane */
-	stride = pwc->view.x * pwc->offset.y;
-	pout_planar_y = dst + stride + pwc->offset.x;
-
-	/* offsets in U/V planes */
-	stride = (pwc->view.x * pwc->offset.y) / 4 + pwc->offset.x / 2;
-	pout_planar_u = dst + plane_size + stride;
-	pout_planar_v = dst + plane_size + plane_size / 4 + stride;
+	pout_planar_y = dst;
+	pout_planar_u = dst + plane_size;
+	pout_planar_v = dst + plane_size + plane_size / 4;
 
 	while (bandlines_left--) {
 		DecompressBand23(pwc->decompress_data,
 				 src,
 				 pout_planar_y, pout_planar_u, pout_planar_v,
-				 pwc->image.x, pwc->view.x);
+				 pwc->width, pwc->width);
 		src += pwc->vbandlength;
 		pout_planar_y += bytes_per_block;
-		pout_planar_u += pwc->view.x;
-		pout_planar_v += pwc->view.x;
+		pout_planar_u += pwc->width;
+		pout_planar_v += pwc->width;
 	}
 	mutex_unlock(&pdec->lock);
 }
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 963b4a5..be4406a 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -656,6 +656,7 @@
 				unsigned int sizes[], void *alloc_ctxs[])
 {
 	struct pwc_device *pdev = vb2_get_drv_priv(vq);
+	int size;
 
 	if (*nbuffers < MIN_FRAMES)
 		*nbuffers = MIN_FRAMES;
@@ -664,7 +665,9 @@
 
 	*nplanes = 1;
 
-	sizes[0] = PAGE_ALIGN((pdev->abs_max.x * pdev->abs_max.y * 3) / 2);
+	size = pwc_get_size(pdev, MAX_WIDTH, MAX_HEIGHT);
+	sizes[0] = PAGE_ALIGN(pwc_image_sizes[size][0] *
+			      pwc_image_sizes[size][1] * 3 / 2);
 
 	return 0;
 }
@@ -742,7 +745,7 @@
 	pwc_camera_power(pdev, 1);
 	if (pdev->power_save) {
 		/* Restore video mode */
-		pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y,
+		pwc_set_video_mode(pdev, pdev->width, pdev->height,
 				   pdev->vframes, pdev->vcompression);
 	}
 	pwc_set_leds(pdev, led_on, led_off);
@@ -1056,7 +1059,6 @@
 	}
 	pdev->type = type_id;
 	pdev->vframes = default_fps;
-	strcpy(pdev->serial, serial_number);
 	pdev->features = features;
 	pwc_construct(pdev); /* set min/max sizes correct */
 
@@ -1119,7 +1121,7 @@
 	pwc_set_leds(pdev, 0, 0);
 
 	/* Setup intial videomode */
-	rc = pwc_set_video_mode(pdev, pdev->view_max.x, pdev->view_max.y,
+	rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT,
 				pdev->vframes, pdev->vcompression);
 	if (rc)
 		goto err_free_mem;
diff --git a/drivers/media/video/pwc/pwc-misc.c b/drivers/media/video/pwc/pwc-misc.c
index 0b03133..23a55b5 100644
--- a/drivers/media/video/pwc/pwc-misc.c
+++ b/drivers/media/video/pwc/pwc-misc.c
@@ -27,67 +27,47 @@
 
 #include "pwc.h"
 
-const struct pwc_coord pwc_image_sizes[PSZ_MAX] =
+const int pwc_image_sizes[PSZ_MAX][2] =
 {
-	{ 128,  96, 0 }, /* sqcif */
-	{ 160, 120, 0 }, /* qsif */
-	{ 176, 144, 0 }, /* qcif */
-	{ 320, 240, 0 }, /* sif */
-	{ 352, 288, 0 }, /* cif */
-	{ 640, 480, 0 }, /* vga */
+	{ 128,  96 }, /* sqcif */
+	{ 160, 120 }, /* qsif */
+	{ 176, 144 }, /* qcif */
+	{ 320, 240 }, /* sif */
+	{ 352, 288 }, /* cif */
+	{ 640, 480 }, /* vga */
 };
 
 /* x,y -> PSZ_ */
-int pwc_decode_size(struct pwc_device *pdev, int width, int height)
+int pwc_get_size(struct pwc_device *pdev, int width, int height)
 {
-	int i, find;
-
-	/* Make sure we don't go beyond our max size.
-	   NB: we have different limits for RAW and normal modes. In case
-	   you don't have the decompressor loaded or use RAW mode,
-	   the maximum viewable size is smaller.
-	*/
-	if (pdev->pixfmt != V4L2_PIX_FMT_YUV420)
-	{
-		if (width > pdev->abs_max.x || height > pdev->abs_max.y)
-		{
-			PWC_DEBUG_SIZE("VIDEO_PALETTE_RAW: going beyond abs_max.\n");
-			return -1;
-		}
-	}
-	else
-	{
-		if (width > pdev->view_max.x || height > pdev->view_max.y)
-		{
-			PWC_DEBUG_SIZE("VIDEO_PALETTE_not RAW: going beyond view_max.\n");
-			return -1;
-		}
-	}
+	int i;
 
 	/* Find the largest size supported by the camera that fits into the
-	   requested size.
-	 */
-	find = -1;
-	for (i = 0; i < PSZ_MAX; i++) {
-		if (pdev->image_mask & (1 << i)) {
-			if (pwc_image_sizes[i].x <= width && pwc_image_sizes[i].y <= height)
-				find = i;
-		}
+	   requested size. */
+	for (i = PSZ_MAX - 1; i >= 0; i--) {
+		if (!(pdev->image_mask & (1 << i)))
+			continue;
+
+		if (pwc_image_sizes[i][0] <= width &&
+		    pwc_image_sizes[i][1] <= height)
+			return i;
 	}
-	return find;
+
+	/* No mode found, return the smallest mode we have */
+	for (i = 0; i < PSZ_MAX; i++) {
+		if (pdev->image_mask & (1 << i))
+			return i;
+	}
+
+	/* Never reached there always is atleast one supported mode */
+	return 0;
 }
 
-/* initialize variables depending on type and decompressor*/
+/* initialize variables depending on type and decompressor */
 void pwc_construct(struct pwc_device *pdev)
 {
 	if (DEVICE_USE_CODEC1(pdev->type)) {
 
-		pdev->view_min.x = 128;
-		pdev->view_min.y =  96;
-		pdev->view_max.x = 352;
-		pdev->view_max.y = 288;
-		pdev->abs_max.x  = 352;
-		pdev->abs_max.y  = 288;
 		pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QCIF | 1 << PSZ_CIF;
 		pdev->vcinterface = 2;
 		pdev->vendpoint = 4;
@@ -96,13 +76,7 @@
 
 	} else if (DEVICE_USE_CODEC3(pdev->type)) {
 
-		pdev->view_min.x = 160;
-		pdev->view_min.y = 120;
-		pdev->view_max.x = 640;
-		pdev->view_max.y = 480;
 		pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA;
-		pdev->abs_max.x = 640;
-		pdev->abs_max.y = 480;
 		pdev->vcinterface = 3;
 		pdev->vendpoint = 5;
 		pdev->frame_header_size = TOUCAM_HEADER_SIZE;
@@ -110,20 +84,11 @@
 
 	} else /* if (DEVICE_USE_CODEC2(pdev->type)) */ {
 
-		pdev->view_min.x = 128;
-		pdev->view_min.y =  96;
-		/* Anthill bug #38: PWC always reports max size, even without PWCX */
-		pdev->view_max.x = 640;
-		pdev->view_max.y = 480;
 		pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF | 1 << PSZ_VGA;
-		pdev->abs_max.x = 640;
-		pdev->abs_max.y = 480;
 		pdev->vcinterface = 3;
 		pdev->vendpoint = 4;
 		pdev->frame_header_size = 0;
 		pdev->frame_trailer_size = 0;
 	}
 	pdev->pixfmt = V4L2_PIX_FMT_YUV420; /* default */
-	pdev->view_min.size = pdev->view_min.x * pdev->view_min.y;
-	pdev->view_max.size = pdev->view_max.x * pdev->view_max.y;
 }
diff --git a/drivers/media/video/pwc/pwc-uncompress.c b/drivers/media/video/pwc/pwc-uncompress.c
index e55b568..b65903f 100644
--- a/drivers/media/video/pwc/pwc-uncompress.c
+++ b/drivers/media/video/pwc/pwc-uncompress.c
@@ -35,7 +35,7 @@
 
 int pwc_decompress(struct pwc_device *pdev, struct pwc_frame_buf *fbuf)
 {
-	int n, line, col, stride;
+	int n, line, col;
 	void *yuv, *image;
 	u16 *src;
 	u16 *dsty, *dstu, *dstv;
@@ -60,35 +60,23 @@
 		return 0;
 	}
 
-	vb2_set_plane_payload(&fbuf->vb, 0, pdev->view.size);
+	vb2_set_plane_payload(&fbuf->vb, 0,
+			      pdev->width * pdev->height * 3 / 2);
 
 	if (pdev->vbandlength == 0) {
 		/* Uncompressed mode.
-		 * We copy the data into the output buffer, using the viewport
-		 * size (which may be larger than the image size).
-		 * Unfortunately we have to do a bit of byte stuffing to get
-		 * the desired output format/size.
 		 *
 		 * We do some byte shuffling here to go from the
 		 * native format to YUV420P.
 		 */
 		src = (u16 *)yuv;
-		n = pdev->view.x * pdev->view.y;
+		n = pdev->width * pdev->height;
+		dsty = (u16 *)(image);
+		dstu = (u16 *)(image + n);
+		dstv = (u16 *)(image + n + n / 4);
 
-		/* offset in Y plane */
-		stride = pdev->view.x * pdev->offset.y + pdev->offset.x;
-		dsty = (u16 *)(image + stride);
-
-		/* offsets in U/V planes */
-		stride = pdev->view.x * pdev->offset.y / 4 + pdev->offset.x / 2;
-		dstu = (u16 *)(image + n +         stride);
-		dstv = (u16 *)(image + n + n / 4 + stride);
-
-		/* increment after each line */
-		stride = (pdev->view.x - pdev->image.x) / 2; /* u16 is 2 bytes */
-
-		for (line = 0; line < pdev->image.y; line++) {
-			for (col = 0; col < pdev->image.x; col += 4) {
+		for (line = 0; line < pdev->height; line++) {
+			for (col = 0; col < pdev->width; col += 4) {
 				*dsty++ = *src++;
 				*dsty++ = *src++;
 				if (line & 1)
@@ -96,11 +84,6 @@
 				else
 					*dstu++ = *src++;
 			}
-			dsty += stride;
-			if (line & 1)
-				dstv += (stride >> 1);
-			else
-				dstu += (stride >> 1);
 		}
 
 		return 0;
@@ -122,6 +105,3 @@
 	}
 	return 0;
 }
-
-
-/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index 87457b5..097ec58 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -398,8 +398,8 @@
 static void pwc_vidioc_fill_fmt(const struct pwc_device *pdev, struct v4l2_format *f)
 {
 	memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));
-	f->fmt.pix.width        = pdev->view.x;
-	f->fmt.pix.height       = pdev->view.y;
+	f->fmt.pix.width        = pdev->width;
+	f->fmt.pix.height       = pdev->height;
 	f->fmt.pix.field        = V4L2_FIELD_NONE;
 	if (pdev->pixfmt == V4L2_PIX_FMT_YUV420) {
 		f->fmt.pix.pixelformat  = V4L2_PIX_FMT_YUV420;
@@ -429,6 +429,8 @@
 /* ioctl(VIDIOC_TRY_FMT) */
 static int pwc_vidioc_try_fmt(struct pwc_device *pdev, struct v4l2_format *f)
 {
+	int size;
+
 	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
 		PWC_DEBUG_IOCTL("Bad video type must be V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
 		return -EINVAL;
@@ -455,15 +457,9 @@
 
 	}
 
-	if (f->fmt.pix.width > pdev->view_max.x)
-		f->fmt.pix.width = pdev->view_max.x;
-	else if (f->fmt.pix.width < pdev->view_min.x)
-		f->fmt.pix.width = pdev->view_min.x;
-
-	if (f->fmt.pix.height > pdev->view_max.y)
-		f->fmt.pix.height = pdev->view_max.y;
-	else if (f->fmt.pix.height < pdev->view_min.y)
-		f->fmt.pix.height = pdev->view_min.y;
+	size = pwc_get_size(pdev, f->fmt.pix.width, f->fmt.pix.height);
+	f->fmt.pix.width  = pwc_image_sizes[size][0];
+	f->fmt.pix.height = pwc_image_sizes[size][1];
 
 	return 0;
 }
@@ -972,7 +968,7 @@
 
 	mutex_lock(&pdev->udevlock); /* To avoid race with s_fmt */
 	PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n",
-			pdev->image.x, pdev->image.y);
+			pdev->width, pdev->height);
 	pwc_vidioc_fill_fmt(pdev, f);
 	mutex_unlock(&pdev->udevlock);
 	return 0;
@@ -1061,25 +1057,21 @@
 	struct pwc_device *pdev = video_drvdata(file);
 	unsigned int i = 0, index = fsize->index;
 
-	if (fsize->pixel_format == V4L2_PIX_FMT_YUV420) {
+	if (fsize->pixel_format == V4L2_PIX_FMT_YUV420 ||
+	    (fsize->pixel_format == V4L2_PIX_FMT_PWC1 &&
+			DEVICE_USE_CODEC1(pdev->type)) ||
+	    (fsize->pixel_format == V4L2_PIX_FMT_PWC2 &&
+			DEVICE_USE_CODEC23(pdev->type))) {
 		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;
-				}
+			if (!(pdev->image_mask & (1UL << i)))
+				continue;
+			if (!index--) {
+				fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+				fsize->discrete.width = pwc_image_sizes[i][0];
+				fsize->discrete.height = pwc_image_sizes[i][1];
+				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;
 }
@@ -1092,8 +1084,8 @@
 	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) {
+		if (pwc_image_sizes[i][0] == fival->width &&
+				pwc_image_sizes[i][1] == fival->height) {
 			size = i;
 			break;
 		}
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 19c692c..5d01385 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -107,6 +107,9 @@
 #define FEATURE_CODEC1			0x0002
 #define FEATURE_CODEC2			0x0004
 
+#define MAX_WIDTH		640
+#define MAX_HEIGHT		480
+
 /* Ignore errors in the first N frames, to allow for startup delays */
 #define FRAME_LOWMARK 5
 
@@ -205,12 +208,6 @@
 	__u8   rawframe[0];	/* frame_size = H / 4 * vbandlength */
 } __packed;
 
-/* structure for transferring x & y coordinates */
-struct pwc_coord {
-	int x, y;		/* guess what */
-	int size;		/* size, or offset */
-};
-
 /* intermediate buffers with raw data from the USB cam */
 struct pwc_frame_buf
 {
@@ -233,7 +230,6 @@
 	int type;
 	int release;		/* release number */
 	int features;		/* feature bits */
-	char serial[30];	/* serial number (string) */
 
 	/*** Video data ***/
 	struct file *capt_file;	/* file doing video capture */
@@ -286,10 +282,7 @@
 	 * a gray or black border. view_min <= image <= view <= view_max;
 	 */
 	int image_mask;				/* supported sizes */
-	struct pwc_coord view_min, view_max;	/* minimum and maximum view */
-	struct pwc_coord abs_max;		/* maximum supported size */
-	struct pwc_coord image, view;		/* image and viewport size */
-	struct pwc_coord offset;		/* offset of the viewport */
+	int width, height;			/* current resolution */
 
 #ifdef CONFIG_USB_PWC_INPUT_EVDEV
 	struct input_dev *button_dev;	/* webcam snapshot button input */
@@ -364,9 +357,9 @@
 
 /** Functions in pwc-misc.c */
 /* sizes in pixels */
-extern const struct pwc_coord pwc_image_sizes[PSZ_MAX];
+extern const int pwc_image_sizes[PSZ_MAX][2];
 
-int pwc_decode_size(struct pwc_device *pdev, int width, int height);
+int pwc_get_size(struct pwc_device *pdev, int width, int height);
 void pwc_construct(struct pwc_device *pdev);
 
 /** Functions in pwc-ctrl.c */