aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/mt9m001.c30
-rw-r--r--drivers/media/video/mt9m111.c20
-rw-r--r--drivers/media/video/mt9t031.c49
-rw-r--r--drivers/media/video/mt9v022.c24
-rw-r--r--drivers/media/video/mx1_camera.c10
-rw-r--r--drivers/media/video/mx3_camera.c25
-rw-r--r--drivers/media/video/ov772x.c6
-rw-r--r--drivers/media/video/pxa_camera.c14
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c28
-rw-r--r--drivers/media/video/soc_camera.c62
-rw-r--r--drivers/media/video/soc_camera_platform.c12
-rw-r--r--drivers/media/video/tw9910.c38
-rw-r--r--include/media/soc_camera.h10
13 files changed, 174 insertions, 154 deletions
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index 2a73dac11d37..8b36a74b1be0 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -240,8 +240,8 @@ static int mt9m001_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
240 struct i2c_client *client = sd->priv; 240 struct i2c_client *client = sd->priv;
241 struct soc_camera_device *icd = client->dev.platform_data; 241 struct soc_camera_device *icd = client->dev.platform_data;
242 struct v4l2_rect rect = { 242 struct v4l2_rect rect = {
243 .left = icd->x_current, 243 .left = icd->rect_current.left,
244 .top = icd->y_current, 244 .top = icd->rect_current.top,
245 .width = f->fmt.pix.width, 245 .width = f->fmt.pix.width,
246 .height = f->fmt.pix.height, 246 .height = f->fmt.pix.height,
247 }; 247 };
@@ -467,11 +467,13 @@ static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
467 case V4L2_CID_EXPOSURE_AUTO: 467 case V4L2_CID_EXPOSURE_AUTO:
468 if (ctrl->value) { 468 if (ctrl->value) {
469 const u16 vblank = 25; 469 const u16 vblank = 25;
470 if (reg_write(client, MT9M001_SHUTTER_WIDTH, icd->height + 470 if (reg_write(client, MT9M001_SHUTTER_WIDTH,
471 icd->rect_current.height +
471 icd->y_skip_top + vblank) < 0) 472 icd->y_skip_top + vblank) < 0)
472 return -EIO; 473 return -EIO;
473 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); 474 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
474 icd->exposure = (524 + (icd->height + icd->y_skip_top + vblank - 1) * 475 icd->exposure = (524 + (icd->rect_current.height +
476 icd->y_skip_top + vblank - 1) *
475 (qctrl->maximum - qctrl->minimum)) / 477 (qctrl->maximum - qctrl->minimum)) /
476 1048 + qctrl->minimum; 478 1048 + qctrl->minimum;
477 mt9m001->autoexposure = 1; 479 mt9m001->autoexposure = 1;
@@ -613,16 +615,16 @@ static int mt9m001_probe(struct i2c_client *client,
613 v4l2_i2c_subdev_init(&mt9m001->subdev, client, &mt9m001_subdev_ops); 615 v4l2_i2c_subdev_init(&mt9m001->subdev, client, &mt9m001_subdev_ops);
614 616
615 /* Second stage probe - when a capture adapter is there */ 617 /* Second stage probe - when a capture adapter is there */
616 icd->ops = &mt9m001_ops; 618 icd->ops = &mt9m001_ops;
617 icd->x_min = 20; 619 icd->rect_max.left = 20;
618 icd->y_min = 12; 620 icd->rect_max.top = 12;
619 icd->x_current = 20; 621 icd->rect_max.width = 1280;
620 icd->y_current = 12; 622 icd->rect_max.height = 1024;
621 icd->width_min = 48; 623 icd->rect_current.left = 20;
622 icd->width_max = 1280; 624 icd->rect_current.top = 12;
623 icd->height_min = 32; 625 icd->width_min = 48;
624 icd->height_max = 1024; 626 icd->height_min = 32;
625 icd->y_skip_top = 1; 627 icd->y_skip_top = 1;
626 /* Simulated autoexposure. If enabled, we calculate shutter width 628 /* Simulated autoexposure. If enabled, we calculate shutter width
627 * ourselves in the driver based on vertical blanking and frame width */ 629 * ourselves in the driver based on vertical blanking and frame width */
628 mt9m001->autoexposure = 1; 630 mt9m001->autoexposure = 1;
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index 29f976afd465..45101fd90ce0 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -948,16 +948,16 @@ static int mt9m111_probe(struct i2c_client *client,
948 v4l2_i2c_subdev_init(&mt9m111->subdev, client, &mt9m111_subdev_ops); 948 v4l2_i2c_subdev_init(&mt9m111->subdev, client, &mt9m111_subdev_ops);
949 949
950 /* Second stage probe - when a capture adapter is there */ 950 /* Second stage probe - when a capture adapter is there */
951 icd->ops = &mt9m111_ops; 951 icd->ops = &mt9m111_ops;
952 icd->x_min = MT9M111_MIN_DARK_COLS; 952 icd->rect_max.left = MT9M111_MIN_DARK_COLS;
953 icd->y_min = MT9M111_MIN_DARK_ROWS; 953 icd->rect_max.top = MT9M111_MIN_DARK_ROWS;
954 icd->x_current = icd->x_min; 954 icd->rect_max.width = MT9M111_MAX_WIDTH;
955 icd->y_current = icd->y_min; 955 icd->rect_max.height = MT9M111_MAX_HEIGHT;
956 icd->width_min = MT9M111_MIN_DARK_ROWS; 956 icd->rect_current.left = icd->rect_max.left;
957 icd->width_max = MT9M111_MAX_WIDTH; 957 icd->rect_current.top = icd->rect_max.top;
958 icd->height_min = MT9M111_MIN_DARK_COLS; 958 icd->width_min = MT9M111_MIN_DARK_ROWS;
959 icd->height_max = MT9M111_MAX_HEIGHT; 959 icd->height_min = MT9M111_MIN_DARK_COLS;
960 icd->y_skip_top = 0; 960 icd->y_skip_top = 0;
961 961
962 ret = mt9m111_video_probe(icd, client); 962 ret = mt9m111_video_probe(icd, client);
963 if (ret) { 963 if (ret) {
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index 27a5edda902c..dc3eb652a7cf 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -222,12 +222,12 @@ static unsigned long mt9t031_query_bus_param(struct soc_camera_device *icd)
222static void recalculate_limits(struct soc_camera_device *icd, 222static void recalculate_limits(struct soc_camera_device *icd,
223 u16 xskip, u16 yskip) 223 u16 xskip, u16 yskip)
224{ 224{
225 icd->x_min = (MT9T031_COLUMN_SKIP + xskip - 1) / xskip; 225 icd->rect_max.left = (MT9T031_COLUMN_SKIP + xskip - 1) / xskip;
226 icd->y_min = (MT9T031_ROW_SKIP + yskip - 1) / yskip; 226 icd->rect_max.top = (MT9T031_ROW_SKIP + yskip - 1) / yskip;
227 icd->width_min = (MT9T031_MIN_WIDTH + xskip - 1) / xskip; 227 icd->width_min = (MT9T031_MIN_WIDTH + xskip - 1) / xskip;
228 icd->height_min = (MT9T031_MIN_HEIGHT + yskip - 1) / yskip; 228 icd->height_min = (MT9T031_MIN_HEIGHT + yskip - 1) / yskip;
229 icd->width_max = MT9T031_MAX_WIDTH / xskip; 229 icd->rect_max.width = MT9T031_MAX_WIDTH / xskip;
230 icd->height_max = MT9T031_MAX_HEIGHT / yskip; 230 icd->rect_max.height = MT9T031_MAX_HEIGHT / yskip;
231} 231}
232 232
233static int mt9t031_set_params(struct soc_camera_device *icd, 233static int mt9t031_set_params(struct soc_camera_device *icd,
@@ -241,11 +241,13 @@ static int mt9t031_set_params(struct soc_camera_device *icd,
241 vblank = MT9T031_VERTICAL_BLANK; 241 vblank = MT9T031_VERTICAL_BLANK;
242 242
243 /* Make sure we don't exceed sensor limits */ 243 /* Make sure we don't exceed sensor limits */
244 if (rect->left + rect->width > icd->width_max) 244 if (rect->left + rect->width > icd->rect_max.width)
245 rect->left = (icd->width_max - rect->width) / 2 + icd->x_min; 245 rect->left = (icd->rect_max.width - rect->width) / 2 +
246 icd->rect_max.left;
246 247
247 if (rect->top + rect->height > icd->height_max) 248 if (rect->top + rect->height > icd->rect_max.height)
248 rect->top = (icd->height_max - rect->height) / 2 + icd->y_min; 249 rect->top = (icd->rect_max.height - rect->height) / 2 +
250 icd->rect_max.top;
249 251
250 width = rect->width * xskip; 252 width = rect->width * xskip;
251 height = rect->height * yskip; 253 height = rect->height * yskip;
@@ -346,8 +348,8 @@ static int mt9t031_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
346 int ret; 348 int ret;
347 u16 xskip, yskip; 349 u16 xskip, yskip;
348 struct v4l2_rect rect = { 350 struct v4l2_rect rect = {
349 .left = icd->x_current, 351 .left = icd->rect_current.left,
350 .top = icd->y_current, 352 .top = icd->rect_current.top,
351 .width = f->fmt.pix.width, 353 .width = f->fmt.pix.width,
352 .height = f->fmt.pix.height, 354 .height = f->fmt.pix.height,
353 }; 355 };
@@ -618,12 +620,13 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
618 if (ctrl->value) { 620 if (ctrl->value) {
619 const u16 vblank = MT9T031_VERTICAL_BLANK; 621 const u16 vblank = MT9T031_VERTICAL_BLANK;
620 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; 622 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
621 if (set_shutter(client, icd->height + 623 if (set_shutter(client, icd->rect_current.height +
622 icd->y_skip_top + vblank) < 0) 624 icd->y_skip_top + vblank) < 0)
623 return -EIO; 625 return -EIO;
624 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); 626 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
625 icd->exposure = (shutter_max / 2 + (icd->height + 627 icd->exposure = (shutter_max / 2 +
626 icd->y_skip_top + vblank - 1) * 628 (icd->rect_current.height +
629 icd->y_skip_top + vblank - 1) *
627 (qctrl->maximum - qctrl->minimum)) / 630 (qctrl->maximum - qctrl->minimum)) /
628 shutter_max + qctrl->minimum; 631 shutter_max + qctrl->minimum;
629 mt9t031->autoexposure = 1; 632 mt9t031->autoexposure = 1;
@@ -726,16 +729,16 @@ static int mt9t031_probe(struct i2c_client *client,
726 v4l2_i2c_subdev_init(&mt9t031->subdev, client, &mt9t031_subdev_ops); 729 v4l2_i2c_subdev_init(&mt9t031->subdev, client, &mt9t031_subdev_ops);
727 730
728 /* Second stage probe - when a capture adapter is there */ 731 /* Second stage probe - when a capture adapter is there */
729 icd->ops = &mt9t031_ops; 732 icd->ops = &mt9t031_ops;
730 icd->x_min = MT9T031_COLUMN_SKIP; 733 icd->rect_max.left = MT9T031_COLUMN_SKIP;
731 icd->y_min = MT9T031_ROW_SKIP; 734 icd->rect_max.top = MT9T031_ROW_SKIP;
732 icd->x_current = icd->x_min; 735 icd->rect_current.left = icd->rect_max.left;
733 icd->y_current = icd->y_min; 736 icd->rect_current.top = icd->rect_max.top;
734 icd->width_min = MT9T031_MIN_WIDTH; 737 icd->width_min = MT9T031_MIN_WIDTH;
735 icd->width_max = MT9T031_MAX_WIDTH; 738 icd->rect_max.width = MT9T031_MAX_WIDTH;
736 icd->height_min = MT9T031_MIN_HEIGHT; 739 icd->height_min = MT9T031_MIN_HEIGHT;
737 icd->height_max = MT9T031_MAX_HEIGHT; 740 icd->rect_max.height = MT9T031_MAX_HEIGHT;
738 icd->y_skip_top = 0; 741 icd->y_skip_top = 0;
739 /* Simulated autoexposure. If enabled, we calculate shutter width 742 /* Simulated autoexposure. If enabled, we calculate shutter width
740 * ourselves in the driver based on vertical blanking and frame width */ 743 * ourselves in the driver based on vertical blanking and frame width */
741 mt9t031->autoexposure = 1; 744 mt9t031->autoexposure = 1;
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index 3cb9f0f1e256..d2b0981ec1c1 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -298,8 +298,8 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
298 struct soc_camera_device *icd = client->dev.platform_data; 298 struct soc_camera_device *icd = client->dev.platform_data;
299 struct v4l2_pix_format *pix = &f->fmt.pix; 299 struct v4l2_pix_format *pix = &f->fmt.pix;
300 struct v4l2_rect rect = { 300 struct v4l2_rect rect = {
301 .left = icd->x_current, 301 .left = icd->rect_current.left,
302 .top = icd->y_current, 302 .top = icd->rect_current.top,
303 .width = pix->width, 303 .width = pix->width,
304 .height = pix->height, 304 .height = pix->height,
305 }; 305 };
@@ -741,16 +741,16 @@ static int mt9v022_probe(struct i2c_client *client,
741 741
742 mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT; 742 mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT;
743 743
744 icd->ops = &mt9v022_ops; 744 icd->ops = &mt9v022_ops;
745 icd->x_min = 1; 745 icd->rect_max.left = 1;
746 icd->y_min = 4; 746 icd->rect_max.top = 4;
747 icd->x_current = 1; 747 icd->rect_max.width = 752;
748 icd->y_current = 4; 748 icd->rect_max.height = 480;
749 icd->width_min = 48; 749 icd->rect_current.left = 1;
750 icd->width_max = 752; 750 icd->rect_current.top = 4;
751 icd->height_min = 32; 751 icd->width_min = 48;
752 icd->height_max = 480; 752 icd->height_min = 32;
753 icd->y_skip_top = 1; 753 icd->y_skip_top = 1;
754 754
755 ret = mt9v022_video_probe(icd, client); 755 ret = mt9v022_video_probe(icd, client);
756 if (ret) { 756 if (ret) {
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c
index ea4ceaec85fe..948a4714be9a 100644
--- a/drivers/media/video/mx1_camera.c
+++ b/drivers/media/video/mx1_camera.c
@@ -126,7 +126,7 @@ static int mx1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
126{ 126{
127 struct soc_camera_device *icd = vq->priv_data; 127 struct soc_camera_device *icd = vq->priv_data;
128 128
129 *size = icd->width * icd->height * 129 *size = icd->rect_current.width * icd->rect_current.height *
130 ((icd->current_fmt->depth + 7) >> 3); 130 ((icd->current_fmt->depth + 7) >> 3);
131 131
132 if (!*count) 132 if (!*count)
@@ -178,12 +178,12 @@ static int mx1_videobuf_prepare(struct videobuf_queue *vq,
178 buf->inwork = 1; 178 buf->inwork = 1;
179 179
180 if (buf->fmt != icd->current_fmt || 180 if (buf->fmt != icd->current_fmt ||
181 vb->width != icd->width || 181 vb->width != icd->rect_current.width ||
182 vb->height != icd->height || 182 vb->height != icd->rect_current.height ||
183 vb->field != field) { 183 vb->field != field) {
184 buf->fmt = icd->current_fmt; 184 buf->fmt = icd->current_fmt;
185 vb->width = icd->width; 185 vb->width = icd->rect_current.width;
186 vb->height = icd->height; 186 vb->height = icd->rect_current.height;
187 vb->field = field; 187 vb->field = field;
188 vb->state = VIDEOBUF_NEEDS_INIT; 188 vb->state = VIDEOBUF_NEEDS_INIT;
189 } 189 }
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index 677d355be8fc..6c3b7f9b906f 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -220,7 +220,7 @@ static int mx3_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
220 if (!mx3_cam->idmac_channel[0]) 220 if (!mx3_cam->idmac_channel[0])
221 return -EINVAL; 221 return -EINVAL;
222 222
223 *size = icd->width * icd->height * bpp; 223 *size = icd->rect_current.width * icd->rect_current.height * bpp;
224 224
225 if (!*count) 225 if (!*count)
226 *count = 32; 226 *count = 32;
@@ -241,7 +241,7 @@ static int mx3_videobuf_prepare(struct videobuf_queue *vq,
241 struct mx3_camera_buffer *buf = 241 struct mx3_camera_buffer *buf =
242 container_of(vb, struct mx3_camera_buffer, vb); 242 container_of(vb, struct mx3_camera_buffer, vb);
243 /* current_fmt _must_ always be set */ 243 /* current_fmt _must_ always be set */
244 size_t new_size = icd->width * icd->height * 244 size_t new_size = icd->rect_current.width * icd->rect_current.height *
245 ((icd->current_fmt->depth + 7) >> 3); 245 ((icd->current_fmt->depth + 7) >> 3);
246 int ret; 246 int ret;
247 247
@@ -251,12 +251,12 @@ static int mx3_videobuf_prepare(struct videobuf_queue *vq,
251 */ 251 */
252 252
253 if (buf->fmt != icd->current_fmt || 253 if (buf->fmt != icd->current_fmt ||
254 vb->width != icd->width || 254 vb->width != icd->rect_current.width ||
255 vb->height != icd->height || 255 vb->height != icd->rect_current.height ||
256 vb->field != field) { 256 vb->field != field) {
257 buf->fmt = icd->current_fmt; 257 buf->fmt = icd->current_fmt;
258 vb->width = icd->width; 258 vb->width = icd->rect_current.width;
259 vb->height = icd->height; 259 vb->height = icd->rect_current.height;
260 vb->field = field; 260 vb->field = field;
261 if (vb->state != VIDEOBUF_NEEDS_INIT) 261 if (vb->state != VIDEOBUF_NEEDS_INIT)
262 free_buffer(vq, buf); 262 free_buffer(vq, buf);
@@ -354,9 +354,9 @@ static void mx3_videobuf_queue(struct videobuf_queue *vq,
354 354
355 /* This is the configuration of one sg-element */ 355 /* This is the configuration of one sg-element */
356 video->out_pixel_fmt = fourcc_to_ipu_pix(data_fmt->fourcc); 356 video->out_pixel_fmt = fourcc_to_ipu_pix(data_fmt->fourcc);
357 video->out_width = icd->width; 357 video->out_width = icd->rect_current.width;
358 video->out_height = icd->height; 358 video->out_height = icd->rect_current.height;
359 video->out_stride = icd->width; 359 video->out_stride = icd->rect_current.width;
360 360
361#ifdef DEBUG 361#ifdef DEBUG
362 /* helps to see what DMA actually has written */ 362 /* helps to see what DMA actually has written */
@@ -538,7 +538,8 @@ static bool channel_change_requested(struct soc_camera_device *icd,
538 struct idmac_channel *ichan = mx3_cam->idmac_channel[0]; 538 struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
539 539
540 /* Do buffers have to be re-allocated or channel re-configured? */ 540 /* Do buffers have to be re-allocated or channel re-configured? */
541 return ichan && rect->width * rect->height > icd->width * icd->height; 541 return ichan && rect->width * rect->height >
542 icd->rect_current.width * icd->rect_current.height;
542} 543}
543 544
544static int test_platform_param(struct mx3_camera_dev *mx3_cam, 545static int test_platform_param(struct mx3_camera_dev *mx3_cam,
@@ -808,8 +809,8 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd,
808 const struct soc_camera_format_xlate *xlate; 809 const struct soc_camera_format_xlate *xlate;
809 struct v4l2_pix_format *pix = &f->fmt.pix; 810 struct v4l2_pix_format *pix = &f->fmt.pix;
810 struct v4l2_rect rect = { 811 struct v4l2_rect rect = {
811 .left = icd->x_current, 812 .left = icd->rect_current.left,
812 .top = icd->y_current, 813 .top = icd->rect_current.top,
813 .width = pix->width, 814 .width = pix->width,
814 .height = pix->height, 815 .height = pix->height,
815 }; 816 };
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index 4c550f91ca24..3417398e1b50 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -1120,9 +1120,9 @@ static int ov772x_probe(struct i2c_client *client,
1120 1120
1121 v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops); 1121 v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops);
1122 1122
1123 icd->ops = &ov772x_ops; 1123 icd->ops = &ov772x_ops;
1124 icd->width_max = MAX_WIDTH; 1124 icd->rect_max.width = MAX_WIDTH;
1125 icd->height_max = MAX_HEIGHT; 1125 icd->rect_max.height = MAX_HEIGHT;
1126 1126
1127 ret = ov772x_video_probe(icd, client); 1127 ret = ov772x_video_probe(icd, client);
1128 if (ret) { 1128 if (ret) {
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index bdc0d85c461b..0e4daaad2f4d 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -239,7 +239,7 @@ static int pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
239 239
240 dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size); 240 dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
241 241
242 *size = roundup(icd->width * icd->height * 242 *size = roundup(icd->rect_current.width * icd->rect_current.height *
243 ((icd->current_fmt->depth + 7) >> 3), 8); 243 ((icd->current_fmt->depth + 7) >> 3), 8);
244 244
245 if (0 == *count) 245 if (0 == *count)
@@ -443,12 +443,12 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
443 buf->inwork = 1; 443 buf->inwork = 1;
444 444
445 if (buf->fmt != icd->current_fmt || 445 if (buf->fmt != icd->current_fmt ||
446 vb->width != icd->width || 446 vb->width != icd->rect_current.width ||
447 vb->height != icd->height || 447 vb->height != icd->rect_current.height ||
448 vb->field != field) { 448 vb->field != field) {
449 buf->fmt = icd->current_fmt; 449 buf->fmt = icd->current_fmt;
450 vb->width = icd->width; 450 vb->width = icd->rect_current.width;
451 vb->height = icd->height; 451 vb->height = icd->rect_current.height;
452 vb->field = field; 452 vb->field = field;
453 vb->state = VIDEOBUF_NEEDS_INIT; 453 vb->state = VIDEOBUF_NEEDS_INIT;
454 } 454 }
@@ -1118,7 +1118,7 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1118 if (cicr0 & CICR0_ENB) 1118 if (cicr0 & CICR0_ENB)
1119 __raw_writel(cicr0 & ~CICR0_ENB, pcdev->base + CICR0); 1119 __raw_writel(cicr0 & ~CICR0_ENB, pcdev->base + CICR0);
1120 1120
1121 cicr1 = CICR1_PPL_VAL(icd->width - 1) | bpp | dw; 1121 cicr1 = CICR1_PPL_VAL(icd->rect_current.width - 1) | bpp | dw;
1122 1122
1123 switch (pixfmt) { 1123 switch (pixfmt) {
1124 case V4L2_PIX_FMT_YUV422P: 1124 case V4L2_PIX_FMT_YUV422P:
@@ -1147,7 +1147,7 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1147 } 1147 }
1148 1148
1149 cicr2 = 0; 1149 cicr2 = 0;
1150 cicr3 = CICR3_LPF_VAL(icd->height - 1) | 1150 cicr3 = CICR3_LPF_VAL(icd->rect_current.height - 1) |
1151 CICR3_BFW_VAL(min((unsigned short)255, icd->y_skip_top)); 1151 CICR3_BFW_VAL(min((unsigned short)255, icd->y_skip_top));
1152 cicr4 |= pcdev->mclk_divisor; 1152 cicr4 |= pcdev->mclk_divisor;
1153 1153
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 16fa56efaf99..4c4b60c32263 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -146,7 +146,8 @@ static int sh_mobile_ceu_videobuf_setup(struct videobuf_queue *vq,
146 struct sh_mobile_ceu_dev *pcdev = ici->priv; 146 struct sh_mobile_ceu_dev *pcdev = ici->priv;
147 int bytes_per_pixel = (icd->current_fmt->depth + 7) >> 3; 147 int bytes_per_pixel = (icd->current_fmt->depth + 7) >> 3;
148 148
149 *size = PAGE_ALIGN(icd->width * icd->height * bytes_per_pixel); 149 *size = PAGE_ALIGN(icd->rect_current.width * icd->rect_current.height *
150 bytes_per_pixel);
150 151
151 if (0 == *count) 152 if (0 == *count)
152 *count = 2; 153 *count = 2;
@@ -205,7 +206,7 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
205 phys_addr_top = videobuf_to_dma_contig(pcdev->active); 206 phys_addr_top = videobuf_to_dma_contig(pcdev->active);
206 ceu_write(pcdev, CDAYR, phys_addr_top); 207 ceu_write(pcdev, CDAYR, phys_addr_top);
207 if (pcdev->is_interlaced) { 208 if (pcdev->is_interlaced) {
208 phys_addr_bottom = phys_addr_top + icd->width; 209 phys_addr_bottom = phys_addr_top + icd->rect_current.width;
209 ceu_write(pcdev, CDBYR, phys_addr_bottom); 210 ceu_write(pcdev, CDBYR, phys_addr_bottom);
210 } 211 }
211 212
@@ -214,10 +215,12 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
214 case V4L2_PIX_FMT_NV21: 215 case V4L2_PIX_FMT_NV21:
215 case V4L2_PIX_FMT_NV16: 216 case V4L2_PIX_FMT_NV16:
216 case V4L2_PIX_FMT_NV61: 217 case V4L2_PIX_FMT_NV61:
217 phys_addr_top += icd->width * icd->height; 218 phys_addr_top += icd->rect_current.width *
219 icd->rect_current.height;
218 ceu_write(pcdev, CDACR, phys_addr_top); 220 ceu_write(pcdev, CDACR, phys_addr_top);
219 if (pcdev->is_interlaced) { 221 if (pcdev->is_interlaced) {
220 phys_addr_bottom = phys_addr_top + icd->width; 222 phys_addr_bottom = phys_addr_top +
223 icd->rect_current.width;
221 ceu_write(pcdev, CDBCR, phys_addr_bottom); 224 ceu_write(pcdev, CDBCR, phys_addr_bottom);
222 } 225 }
223 } 226 }
@@ -251,12 +254,12 @@ static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq,
251 BUG_ON(NULL == icd->current_fmt); 254 BUG_ON(NULL == icd->current_fmt);
252 255
253 if (buf->fmt != icd->current_fmt || 256 if (buf->fmt != icd->current_fmt ||
254 vb->width != icd->width || 257 vb->width != icd->rect_current.width ||
255 vb->height != icd->height || 258 vb->height != icd->rect_current.height ||
256 vb->field != field) { 259 vb->field != field) {
257 buf->fmt = icd->current_fmt; 260 buf->fmt = icd->current_fmt;
258 vb->width = icd->width; 261 vb->width = icd->rect_current.width;
259 vb->height = icd->height; 262 vb->height = icd->rect_current.height;
260 vb->field = field; 263 vb->field = field;
261 vb->state = VIDEOBUF_NEEDS_INIT; 264 vb->state = VIDEOBUF_NEEDS_INIT;
262 } 265 }
@@ -475,17 +478,18 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
475 mdelay(1); 478 mdelay(1);
476 479
477 if (yuv_mode) { 480 if (yuv_mode) {
478 width = icd->width * 2; 481 width = icd->rect_current.width * 2;
479 width = buswidth == 16 ? width / 2 : width; 482 width = buswidth == 16 ? width / 2 : width;
480 cfszr_width = cdwdr_width = icd->width; 483 cfszr_width = cdwdr_width = icd->rect_current.width;
481 } else { 484 } else {
482 width = icd->width * ((icd->current_fmt->depth + 7) >> 3); 485 width = icd->rect_current.width *
486 ((icd->current_fmt->depth + 7) >> 3);
483 width = buswidth == 16 ? width / 2 : width; 487 width = buswidth == 16 ? width / 2 : width;
484 cfszr_width = buswidth == 8 ? width / 2 : width; 488 cfszr_width = buswidth == 8 ? width / 2 : width;
485 cdwdr_width = buswidth == 16 ? width * 2 : width; 489 cdwdr_width = buswidth == 16 ? width * 2 : width;
486 } 490 }
487 491
488 height = icd->height; 492 height = icd->rect_current.height;
489 if (pcdev->is_interlaced) { 493 if (pcdev->is_interlaced) {
490 height /= 2; 494 height /= 2;
491 cdwdr_width *= 2; 495 cdwdr_width *= 2;
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index b3fb8f290ad5..5028023b72aa 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -288,17 +288,17 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
288 return -EINVAL; 288 return -EINVAL;
289 } 289 }
290 290
291 icd->width = pix->width; 291 icd->rect_current.width = pix->width;
292 icd->height = pix->height; 292 icd->rect_current.height = pix->height;
293 icf->vb_vidq.field = 293 icf->vb_vidq.field =
294 icd->field = pix->field; 294 icd->field = pix->field;
295 295
296 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 296 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
297 dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n", 297 dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n",
298 f->type); 298 f->type);
299 299
300 dev_dbg(&icd->dev, "set width: %d height: %d\n", 300 dev_dbg(&icd->dev, "set width: %d height: %d\n",
301 icd->width, icd->height); 301 icd->rect_current.width, icd->rect_current.height);
302 302
303 /* set physical bus parameters */ 303 /* set physical bus parameters */
304 return ici->ops->set_bus_param(icd, pix->pixelformat); 304 return ici->ops->set_bus_param(icd, pix->pixelformat);
@@ -341,8 +341,8 @@ static int soc_camera_open(struct file *file)
341 struct v4l2_format f = { 341 struct v4l2_format f = {
342 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, 342 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
343 .fmt.pix = { 343 .fmt.pix = {
344 .width = icd->width, 344 .width = icd->rect_current.width,
345 .height = icd->height, 345 .height = icd->rect_current.height,
346 .field = icd->field, 346 .field = icd->field,
347 }, 347 },
348 }; 348 };
@@ -553,8 +553,8 @@ static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv,
553 553
554 WARN_ON(priv != file->private_data); 554 WARN_ON(priv != file->private_data);
555 555
556 pix->width = icd->width; 556 pix->width = icd->rect_current.width;
557 pix->height = icd->height; 557 pix->height = icd->rect_current.height;
558 pix->field = icf->vb_vidq.field; 558 pix->field = icf->vb_vidq.field;
559 pix->pixelformat = icd->current_fmt->fourcc; 559 pix->pixelformat = icd->current_fmt->fourcc;
560 pix->bytesperline = pix->width * 560 pix->bytesperline = pix->width *
@@ -718,12 +718,9 @@ static int soc_camera_cropcap(struct file *file, void *fh,
718 struct soc_camera_device *icd = icf->icd; 718 struct soc_camera_device *icd = icf->icd;
719 719
720 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 720 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
721 a->bounds.left = icd->x_min; 721 a->bounds = icd->rect_max;
722 a->bounds.top = icd->y_min; 722 a->defrect.left = icd->rect_max.left;
723 a->bounds.width = icd->width_max; 723 a->defrect.top = icd->rect_max.top;
724 a->bounds.height = icd->height_max;
725 a->defrect.left = icd->x_min;
726 a->defrect.top = icd->y_min;
727 a->defrect.width = DEFAULT_WIDTH; 724 a->defrect.width = DEFAULT_WIDTH;
728 a->defrect.height = DEFAULT_HEIGHT; 725 a->defrect.height = DEFAULT_HEIGHT;
729 a->pixelaspect.numerator = 1; 726 a->pixelaspect.numerator = 1;
@@ -738,11 +735,8 @@ static int soc_camera_g_crop(struct file *file, void *fh,
738 struct soc_camera_file *icf = file->private_data; 735 struct soc_camera_file *icf = file->private_data;
739 struct soc_camera_device *icd = icf->icd; 736 struct soc_camera_device *icd = icf->icd;
740 737
741 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 738 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
742 a->c.left = icd->x_current; 739 a->c = icd->rect_current;
743 a->c.top = icd->y_current;
744 a->c.width = icd->width;
745 a->c.height = icd->height;
746 740
747 return 0; 741 return 0;
748} 742}
@@ -761,13 +755,29 @@ static int soc_camera_s_crop(struct file *file, void *fh,
761 /* Cropping is allowed during a running capture, guard consistency */ 755 /* Cropping is allowed during a running capture, guard consistency */
762 mutex_lock(&icf->vb_vidq.vb_lock); 756 mutex_lock(&icf->vb_vidq.vb_lock);
763 757
758 if (a->c.width > icd->rect_max.width)
759 a->c.width = icd->rect_max.width;
760
761 if (a->c.width < icd->width_min)
762 a->c.width = icd->width_min;
763
764 if (a->c.height > icd->rect_max.height)
765 a->c.height = icd->rect_max.height;
766
767 if (a->c.height < icd->height_min)
768 a->c.height = icd->height_min;
769
770 if (a->c.width + a->c.left > icd->rect_max.width + icd->rect_max.left)
771 a->c.left = icd->rect_max.width + icd->rect_max.left -
772 a->c.width;
773
774 if (a->c.height + a->c.top > icd->rect_max.height + icd->rect_max.top)
775 a->c.top = icd->rect_max.height + icd->rect_max.top -
776 a->c.height;
777
764 ret = ici->ops->set_crop(icd, &a->c); 778 ret = ici->ops->set_crop(icd, &a->c);
765 if (!ret) { 779 if (!ret)
766 icd->width = a->c.width; 780 icd->rect_current = a->c;
767 icd->height = a->c.height;
768 icd->x_current = a->c.left;
769 icd->y_current = a->c.top;
770 }
771 781
772 mutex_unlock(&icf->vb_vidq.vb_lock); 782 mutex_unlock(&icf->vb_vidq.vb_lock);
773 783
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c
index 8168cf470eb3..9e406c113aa4 100644
--- a/drivers/media/video/soc_camera_platform.c
+++ b/drivers/media/video/soc_camera_platform.c
@@ -127,12 +127,12 @@ static int soc_camera_platform_probe(struct platform_device *pdev)
127 platform_set_drvdata(pdev, priv); 127 platform_set_drvdata(pdev, priv);
128 dev_set_drvdata(&icd->dev, &pdev->dev); 128 dev_set_drvdata(&icd->dev, &pdev->dev);
129 129
130 icd->width_min = 0; 130 icd->width_min = 0;
131 icd->width_max = p->format.width; 131 icd->rect_max.width = p->format.width;
132 icd->height_min = 0; 132 icd->height_min = 0;
133 icd->height_max = p->format.height; 133 icd->rect_max.height = p->format.height;
134 icd->y_skip_top = 0; 134 icd->y_skip_top = 0;
135 icd->ops = &soc_camera_platform_ops; 135 icd->ops = &soc_camera_platform_ops;
136 136
137 ici = to_soc_camera_host(icd->dev.parent); 137 ici = to_soc_camera_host(icd->dev.parent);
138 138
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c
index a006df1d28ec..7199e0f71b2a 100644
--- a/drivers/media/video/tw9910.c
+++ b/drivers/media/video/tw9910.c
@@ -715,8 +715,8 @@ static int tw9910_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
715 struct soc_camera_device *icd = client->dev.platform_data; 715 struct soc_camera_device *icd = client->dev.platform_data;
716 struct v4l2_pix_format *pix = &f->fmt.pix; 716 struct v4l2_pix_format *pix = &f->fmt.pix;
717 struct v4l2_rect rect = { 717 struct v4l2_rect rect = {
718 .left = icd->x_current, 718 .left = icd->rect_current.left,
719 .top = icd->y_current, 719 .top = icd->rect_current.top,
720 .width = pix->width, 720 .width = pix->width,
721 .height = pix->height, 721 .height = pix->height,
722 }; 722 };
@@ -840,6 +840,19 @@ static struct v4l2_subdev_ops tw9910_subdev_ops = {
840 * i2c_driver function 840 * i2c_driver function
841 */ 841 */
842 842
843static void limit_to_scale(struct soc_camera_device *icd,
844 const struct tw9910_scale_ctrl *scale)
845{
846 if (scale->width > icd->rect_max.width)
847 icd->rect_max.width = scale->width;
848 if (scale->width < icd->width_min)
849 icd->width_min = scale->width;
850 if (scale->height > icd->rect_max.height)
851 icd->rect_max.height = scale->height;
852 if (scale->height < icd->height_min)
853 icd->height_min = scale->height;
854}
855
843static int tw9910_probe(struct i2c_client *client, 856static int tw9910_probe(struct i2c_client *client,
844 const struct i2c_device_id *did) 857 const struct i2c_device_id *did)
845 858
@@ -885,25 +898,18 @@ static int tw9910_probe(struct i2c_client *client,
885 /* 898 /*
886 * set width and height 899 * set width and height
887 */ 900 */
888 icd->width_max = tw9910_ntsc_scales[0].width; /* set default */ 901 icd->rect_max.width = tw9910_ntsc_scales[0].width; /* set default */
889 icd->width_min = tw9910_ntsc_scales[0].width; 902 icd->width_min = tw9910_ntsc_scales[0].width;
890 icd->height_max = tw9910_ntsc_scales[0].height; 903 icd->rect_max.height = tw9910_ntsc_scales[0].height;
891 icd->height_min = tw9910_ntsc_scales[0].height; 904 icd->height_min = tw9910_ntsc_scales[0].height;
892 905
893 scale = tw9910_ntsc_scales; 906 scale = tw9910_ntsc_scales;
894 for (i = 0; i < ARRAY_SIZE(tw9910_ntsc_scales); i++) { 907 for (i = 0; i < ARRAY_SIZE(tw9910_ntsc_scales); i++)
895 icd->width_max = max(scale[i].width, icd->width_max); 908 limit_to_scale(icd, scale + i);
896 icd->width_min = min(scale[i].width, icd->width_min); 909
897 icd->height_max = max(scale[i].height, icd->height_max);
898 icd->height_min = min(scale[i].height, icd->height_min);
899 }
900 scale = tw9910_pal_scales; 910 scale = tw9910_pal_scales;
901 for (i = 0; i < ARRAY_SIZE(tw9910_pal_scales); i++) { 911 for (i = 0; i < ARRAY_SIZE(tw9910_pal_scales); i++)
902 icd->width_max = max(scale[i].width, icd->width_max); 912 limit_to_scale(icd, scale + i);
903 icd->width_min = min(scale[i].width, icd->width_min);
904 icd->height_max = max(scale[i].height, icd->height_max);
905 icd->height_min = min(scale[i].height, icd->height_min);
906 }
907 913
908 ret = tw9910_video_probe(icd, client); 914 ret = tw9910_video_probe(icd, client);
909 if (ret) { 915 if (ret) {
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index 2d116bbbcce1..f623c010a539 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -22,16 +22,10 @@ struct soc_camera_device {
22 struct list_head list; 22 struct list_head list;
23 struct device dev; 23 struct device dev;
24 struct device *pdev; /* Platform device */ 24 struct device *pdev; /* Platform device */
25 unsigned short width; /* Current window */ 25 struct v4l2_rect rect_current; /* Current window */
26 unsigned short height; /* sizes */ 26 struct v4l2_rect rect_max; /* Maximum window */
27 unsigned short x_min; /* Camera capabilities */
28 unsigned short y_min;
29 unsigned short x_current; /* Current window location */
30 unsigned short y_current;
31 unsigned short width_min; 27 unsigned short width_min;
32 unsigned short width_max;
33 unsigned short height_min; 28 unsigned short height_min;
34 unsigned short height_max;
35 unsigned short y_skip_top; /* Lines to skip at the top */ 29 unsigned short y_skip_top; /* Lines to skip at the top */
36 unsigned short gain; 30 unsigned short gain;
37 unsigned short exposure; 31 unsigned short exposure;