diff options
Diffstat (limited to 'drivers/media/video/mt9t031.c')
-rw-r--r-- | drivers/media/video/mt9t031.c | 220 |
1 files changed, 130 insertions, 90 deletions
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c index cd3eb7731ac2..f234ba602049 100644 --- a/drivers/media/video/mt9t031.c +++ b/drivers/media/video/mt9t031.c | |||
@@ -47,7 +47,7 @@ | |||
47 | #define MT9T031_MAX_HEIGHT 1536 | 47 | #define MT9T031_MAX_HEIGHT 1536 |
48 | #define MT9T031_MAX_WIDTH 2048 | 48 | #define MT9T031_MAX_WIDTH 2048 |
49 | #define MT9T031_MIN_HEIGHT 2 | 49 | #define MT9T031_MIN_HEIGHT 2 |
50 | #define MT9T031_MIN_WIDTH 2 | 50 | #define MT9T031_MIN_WIDTH 18 |
51 | #define MT9T031_HORIZONTAL_BLANK 142 | 51 | #define MT9T031_HORIZONTAL_BLANK 142 |
52 | #define MT9T031_VERTICAL_BLANK 25 | 52 | #define MT9T031_VERTICAL_BLANK 25 |
53 | #define MT9T031_COLUMN_SKIP 32 | 53 | #define MT9T031_COLUMN_SKIP 32 |
@@ -69,10 +69,11 @@ static const struct soc_camera_data_format mt9t031_colour_formats[] = { | |||
69 | 69 | ||
70 | struct mt9t031 { | 70 | struct mt9t031 { |
71 | struct v4l2_subdev subdev; | 71 | struct v4l2_subdev subdev; |
72 | struct v4l2_rect rect; /* Sensor window */ | ||
72 | int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */ | 73 | int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */ |
73 | unsigned char autoexposure; | ||
74 | u16 xskip; | 74 | u16 xskip; |
75 | u16 yskip; | 75 | u16 yskip; |
76 | unsigned char autoexposure; | ||
76 | }; | 77 | }; |
77 | 78 | ||
78 | static struct mt9t031 *to_mt9t031(const struct i2c_client *client) | 79 | static struct mt9t031 *to_mt9t031(const struct i2c_client *client) |
@@ -218,56 +219,68 @@ static unsigned long mt9t031_query_bus_param(struct soc_camera_device *icd) | |||
218 | return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM); | 219 | return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM); |
219 | } | 220 | } |
220 | 221 | ||
221 | /* Round up minima and round down maxima */ | 222 | /* target must be _even_ */ |
222 | static void recalculate_limits(struct soc_camera_device *icd, | 223 | static u16 mt9t031_skip(s32 *source, s32 target, s32 max) |
223 | u16 xskip, u16 yskip) | ||
224 | { | 224 | { |
225 | icd->rect_max.left = (MT9T031_COLUMN_SKIP + xskip - 1) / xskip; | 225 | unsigned int skip; |
226 | icd->rect_max.top = (MT9T031_ROW_SKIP + yskip - 1) / yskip; | 226 | |
227 | icd->width_min = (MT9T031_MIN_WIDTH + xskip - 1) / xskip; | 227 | if (*source < target + target / 2) { |
228 | icd->height_min = (MT9T031_MIN_HEIGHT + yskip - 1) / yskip; | 228 | *source = target; |
229 | icd->rect_max.width = MT9T031_MAX_WIDTH / xskip; | 229 | return 1; |
230 | icd->rect_max.height = MT9T031_MAX_HEIGHT / yskip; | 230 | } |
231 | |||
232 | skip = min(max, *source + target / 2) / target; | ||
233 | if (skip > 8) | ||
234 | skip = 8; | ||
235 | *source = target * skip; | ||
236 | |||
237 | return skip; | ||
231 | } | 238 | } |
232 | 239 | ||
240 | /* rect is the sensor rectangle, the caller guarantees parameter validity */ | ||
233 | static int mt9t031_set_params(struct soc_camera_device *icd, | 241 | static int mt9t031_set_params(struct soc_camera_device *icd, |
234 | struct v4l2_rect *rect, u16 xskip, u16 yskip) | 242 | struct v4l2_rect *rect, u16 xskip, u16 yskip) |
235 | { | 243 | { |
236 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | 244 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); |
237 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 245 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
238 | int ret; | 246 | int ret; |
239 | u16 xbin, ybin, width, height, left, top; | 247 | u16 xbin, ybin; |
240 | const u16 hblank = MT9T031_HORIZONTAL_BLANK, | 248 | const u16 hblank = MT9T031_HORIZONTAL_BLANK, |
241 | vblank = MT9T031_VERTICAL_BLANK; | 249 | vblank = MT9T031_VERTICAL_BLANK; |
242 | 250 | ||
243 | width = rect->width * xskip; | ||
244 | height = rect->height * yskip; | ||
245 | left = rect->left * xskip; | ||
246 | top = rect->top * yskip; | ||
247 | |||
248 | xbin = min(xskip, (u16)3); | 251 | xbin = min(xskip, (u16)3); |
249 | ybin = min(yskip, (u16)3); | 252 | ybin = min(yskip, (u16)3); |
250 | 253 | ||
251 | dev_dbg(&client->dev, "xskip %u, width %u/%u, yskip %u, height %u/%u\n", | 254 | /* |
252 | xskip, width, rect->width, yskip, height, rect->height); | 255 | * Could just do roundup(rect->left, [xy]bin * 2); but this is cheaper. |
253 | 256 | * There is always a valid suitably aligned value. The worst case is | |
254 | /* Could just do roundup(rect->left, [xy]bin * 2); but this is cheaper */ | 257 | * xbin = 3, width = 2048. Then we will start at 36, the last read out |
258 | * pixel will be 2083, which is < 2085 - first black pixel. | ||
259 | * | ||
260 | * MT9T031 datasheet imposes window left border alignment, depending on | ||
261 | * the selected xskip. Failing to conform to this requirement produces | ||
262 | * dark horizontal stripes in the image. However, even obeying to this | ||
263 | * requirement doesn't eliminate the stripes in all configurations. They | ||
264 | * appear "locally reproducibly," but can differ between tests under | ||
265 | * different lighting conditions. | ||
266 | */ | ||
255 | switch (xbin) { | 267 | switch (xbin) { |
256 | case 2: | 268 | case 1: |
257 | left = (left + 3) & ~3; | 269 | rect->left &= ~1; |
258 | break; | 270 | break; |
259 | case 3: | ||
260 | left = roundup(left, 6); | ||
261 | } | ||
262 | |||
263 | switch (ybin) { | ||
264 | case 2: | 271 | case 2: |
265 | top = (top + 3) & ~3; | 272 | rect->left &= ~3; |
266 | break; | 273 | break; |
267 | case 3: | 274 | case 3: |
268 | top = roundup(top, 6); | 275 | rect->left = rect->left > roundup(MT9T031_COLUMN_SKIP, 6) ? |
276 | (rect->left / 6) * 6 : roundup(MT9T031_COLUMN_SKIP, 6); | ||
269 | } | 277 | } |
270 | 278 | ||
279 | rect->top &= ~1; | ||
280 | |||
281 | dev_dbg(&client->dev, "skip %u:%u, rect %ux%u@%u:%u\n", | ||
282 | xskip, yskip, rect->width, rect->height, rect->left, rect->top); | ||
283 | |||
271 | /* Disable register update, reconfigure atomically */ | 284 | /* Disable register update, reconfigure atomically */ |
272 | ret = reg_set(client, MT9T031_OUTPUT_CONTROL, 1); | 285 | ret = reg_set(client, MT9T031_OUTPUT_CONTROL, 1); |
273 | if (ret < 0) | 286 | if (ret < 0) |
@@ -287,27 +300,29 @@ static int mt9t031_set_params(struct soc_camera_device *icd, | |||
287 | ret = reg_write(client, MT9T031_ROW_ADDRESS_MODE, | 300 | ret = reg_write(client, MT9T031_ROW_ADDRESS_MODE, |
288 | ((ybin - 1) << 4) | (yskip - 1)); | 301 | ((ybin - 1) << 4) | (yskip - 1)); |
289 | } | 302 | } |
290 | dev_dbg(&client->dev, "new physical left %u, top %u\n", left, top); | 303 | dev_dbg(&client->dev, "new physical left %u, top %u\n", |
304 | rect->left, rect->top); | ||
291 | 305 | ||
292 | /* The caller provides a supported format, as guaranteed by | 306 | /* The caller provides a supported format, as guaranteed by |
293 | * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */ | 307 | * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */ |
294 | if (ret >= 0) | 308 | if (ret >= 0) |
295 | ret = reg_write(client, MT9T031_COLUMN_START, left); | 309 | ret = reg_write(client, MT9T031_COLUMN_START, rect->left); |
296 | if (ret >= 0) | 310 | if (ret >= 0) |
297 | ret = reg_write(client, MT9T031_ROW_START, top); | 311 | ret = reg_write(client, MT9T031_ROW_START, rect->top); |
298 | if (ret >= 0) | 312 | if (ret >= 0) |
299 | ret = reg_write(client, MT9T031_WINDOW_WIDTH, width - 1); | 313 | ret = reg_write(client, MT9T031_WINDOW_WIDTH, rect->width - 1); |
300 | if (ret >= 0) | 314 | if (ret >= 0) |
301 | ret = reg_write(client, MT9T031_WINDOW_HEIGHT, | 315 | ret = reg_write(client, MT9T031_WINDOW_HEIGHT, |
302 | height + icd->y_skip_top - 1); | 316 | rect->height + icd->y_skip_top - 1); |
303 | if (ret >= 0 && mt9t031->autoexposure) { | 317 | if (ret >= 0 && mt9t031->autoexposure) { |
304 | ret = set_shutter(client, height + icd->y_skip_top + vblank); | 318 | ret = set_shutter(client, |
319 | rect->height + icd->y_skip_top + vblank); | ||
305 | if (ret >= 0) { | 320 | if (ret >= 0) { |
306 | const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; | 321 | const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; |
307 | const struct v4l2_queryctrl *qctrl = | 322 | const struct v4l2_queryctrl *qctrl = |
308 | soc_camera_find_qctrl(icd->ops, | 323 | soc_camera_find_qctrl(icd->ops, |
309 | V4L2_CID_EXPOSURE); | 324 | V4L2_CID_EXPOSURE); |
310 | icd->exposure = (shutter_max / 2 + (height + | 325 | icd->exposure = (shutter_max / 2 + (rect->height + |
311 | icd->y_skip_top + vblank - 1) * | 326 | icd->y_skip_top + vblank - 1) * |
312 | (qctrl->maximum - qctrl->minimum)) / | 327 | (qctrl->maximum - qctrl->minimum)) / |
313 | shutter_max + qctrl->minimum; | 328 | shutter_max + qctrl->minimum; |
@@ -318,27 +333,72 @@ static int mt9t031_set_params(struct soc_camera_device *icd, | |||
318 | if (ret >= 0) | 333 | if (ret >= 0) |
319 | ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 1); | 334 | ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 1); |
320 | 335 | ||
336 | if (ret >= 0) { | ||
337 | mt9t031->rect = *rect; | ||
338 | mt9t031->xskip = xskip; | ||
339 | mt9t031->yskip = yskip; | ||
340 | } | ||
341 | |||
321 | return ret < 0 ? ret : 0; | 342 | return ret < 0 ? ret : 0; |
322 | } | 343 | } |
323 | 344 | ||
324 | static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | 345 | static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) |
325 | { | 346 | { |
326 | struct v4l2_rect *rect = &a->c; | 347 | struct v4l2_rect rect = a->c; |
327 | struct i2c_client *client = sd->priv; | 348 | struct i2c_client *client = sd->priv; |
328 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 349 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
329 | struct soc_camera_device *icd = client->dev.platform_data; | 350 | struct soc_camera_device *icd = client->dev.platform_data; |
330 | 351 | ||
331 | /* Make sure we don't exceed sensor limits */ | 352 | rect.width = ALIGN(rect.width, 2); |
332 | if (rect->left + rect->width > icd->rect_max.left + icd->rect_max.width) | 353 | rect.height = ALIGN(rect.height, 2); |
333 | rect->left = icd->rect_max.width + icd->rect_max.left - | 354 | |
334 | rect->width; | 355 | soc_camera_limit_side(&rect.left, &rect.width, |
356 | MT9T031_COLUMN_SKIP, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH); | ||
357 | |||
358 | soc_camera_limit_side(&rect.top, &rect.height, | ||
359 | MT9T031_ROW_SKIP, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT); | ||
360 | |||
361 | return mt9t031_set_params(icd, &rect, mt9t031->xskip, mt9t031->yskip); | ||
362 | } | ||
363 | |||
364 | static int mt9t031_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | ||
365 | { | ||
366 | struct i2c_client *client = sd->priv; | ||
367 | struct mt9t031 *mt9t031 = to_mt9t031(client); | ||
368 | |||
369 | a->c = mt9t031->rect; | ||
370 | a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
335 | 371 | ||
336 | if (rect->top + rect->height > icd->rect_max.height + icd->rect_max.top) | 372 | return 0; |
337 | rect->top = icd->rect_max.height + icd->rect_max.top - | 373 | } |
338 | rect->height; | 374 | |
375 | static int mt9t031_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | ||
376 | { | ||
377 | a->bounds.left = MT9T031_COLUMN_SKIP; | ||
378 | a->bounds.top = MT9T031_ROW_SKIP; | ||
379 | a->bounds.width = MT9T031_MAX_WIDTH; | ||
380 | a->bounds.height = MT9T031_MAX_HEIGHT; | ||
381 | a->defrect = a->bounds; | ||
382 | a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
383 | a->pixelaspect.numerator = 1; | ||
384 | a->pixelaspect.denominator = 1; | ||
339 | 385 | ||
340 | /* CROP - no change in scaling, or in limits */ | 386 | return 0; |
341 | return mt9t031_set_params(icd, rect, mt9t031->xskip, mt9t031->yskip); | 387 | } |
388 | |||
389 | static int mt9t031_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | ||
390 | { | ||
391 | struct i2c_client *client = sd->priv; | ||
392 | struct mt9t031 *mt9t031 = to_mt9t031(client); | ||
393 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
394 | |||
395 | pix->width = mt9t031->rect.width / mt9t031->xskip; | ||
396 | pix->height = mt9t031->rect.height / mt9t031->yskip; | ||
397 | pix->pixelformat = V4L2_PIX_FMT_SGRBG10; | ||
398 | pix->field = V4L2_FIELD_NONE; | ||
399 | pix->colorspace = V4L2_COLORSPACE_SRGB; | ||
400 | |||
401 | return 0; | ||
342 | } | 402 | } |
343 | 403 | ||
344 | static int mt9t031_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 404 | static int mt9t031_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) |
@@ -346,40 +406,25 @@ static int mt9t031_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | |||
346 | struct i2c_client *client = sd->priv; | 406 | struct i2c_client *client = sd->priv; |
347 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 407 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
348 | struct soc_camera_device *icd = client->dev.platform_data; | 408 | struct soc_camera_device *icd = client->dev.platform_data; |
349 | int ret; | 409 | struct v4l2_pix_format *pix = &f->fmt.pix; |
350 | u16 xskip, yskip; | 410 | u16 xskip, yskip; |
351 | struct v4l2_rect rect = { | 411 | struct v4l2_rect rect = mt9t031->rect; |
352 | .left = icd->rect_current.left, | ||
353 | .top = icd->rect_current.top, | ||
354 | .width = f->fmt.pix.width, | ||
355 | .height = f->fmt.pix.height, | ||
356 | }; | ||
357 | 412 | ||
358 | /* | 413 | /* |
359 | * try_fmt has put rectangle within limits. | 414 | * try_fmt has put width and height within limits. |
360 | * S_FMT - use binning and skipping for scaling, recalculate | 415 | * S_FMT: use binning and skipping for scaling |
361 | * limits, used for cropping | ||
362 | */ | 416 | */ |
363 | /* Is this more optimal than just a division? */ | 417 | xskip = mt9t031_skip(&rect.width, pix->width, MT9T031_MAX_WIDTH); |
364 | for (xskip = 8; xskip > 1; xskip--) | 418 | yskip = mt9t031_skip(&rect.height, pix->height, MT9T031_MAX_HEIGHT); |
365 | if (rect.width * xskip <= MT9T031_MAX_WIDTH) | ||
366 | break; | ||
367 | |||
368 | for (yskip = 8; yskip > 1; yskip--) | ||
369 | if (rect.height * yskip <= MT9T031_MAX_HEIGHT) | ||
370 | break; | ||
371 | |||
372 | recalculate_limits(icd, xskip, yskip); | ||
373 | |||
374 | ret = mt9t031_set_params(icd, &rect, xskip, yskip); | ||
375 | if (!ret) { | ||
376 | mt9t031->xskip = xskip; | ||
377 | mt9t031->yskip = yskip; | ||
378 | } | ||
379 | 419 | ||
380 | return ret; | 420 | /* mt9t031_set_params() doesn't change width and height */ |
421 | return mt9t031_set_params(icd, &rect, xskip, yskip); | ||
381 | } | 422 | } |
382 | 423 | ||
424 | /* | ||
425 | * If a user window larger than sensor window is requested, we'll increase the | ||
426 | * sensor window. | ||
427 | */ | ||
383 | static int mt9t031_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 428 | static int mt9t031_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) |
384 | { | 429 | { |
385 | struct v4l2_pix_format *pix = &f->fmt.pix; | 430 | struct v4l2_pix_format *pix = &f->fmt.pix; |
@@ -620,12 +665,12 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
620 | if (ctrl->value) { | 665 | if (ctrl->value) { |
621 | const u16 vblank = MT9T031_VERTICAL_BLANK; | 666 | const u16 vblank = MT9T031_VERTICAL_BLANK; |
622 | const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; | 667 | const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; |
623 | if (set_shutter(client, icd->rect_current.height + | 668 | if (set_shutter(client, mt9t031->rect.height + |
624 | icd->y_skip_top + vblank) < 0) | 669 | icd->y_skip_top + vblank) < 0) |
625 | return -EIO; | 670 | return -EIO; |
626 | qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); | 671 | qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); |
627 | icd->exposure = (shutter_max / 2 + | 672 | icd->exposure = (shutter_max / 2 + |
628 | (icd->rect_current.height + | 673 | (mt9t031->rect.height + |
629 | icd->y_skip_top + vblank - 1) * | 674 | icd->y_skip_top + vblank - 1) * |
630 | (qctrl->maximum - qctrl->minimum)) / | 675 | (qctrl->maximum - qctrl->minimum)) / |
631 | shutter_max + qctrl->minimum; | 676 | shutter_max + qctrl->minimum; |
@@ -645,12 +690,6 @@ static int mt9t031_video_probe(struct i2c_client *client) | |||
645 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 690 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
646 | s32 data; | 691 | s32 data; |
647 | 692 | ||
648 | /* We must have a parent by now. And it cannot be a wrong one. | ||
649 | * So this entire test is completely redundant. */ | ||
650 | if (!icd->dev.parent || | ||
651 | to_soc_camera_host(icd->dev.parent)->nr != icd->iface) | ||
652 | return -ENODEV; | ||
653 | |||
654 | /* Enable the chip */ | 693 | /* Enable the chip */ |
655 | data = reg_write(client, MT9T031_CHIP_ENABLE, 1); | 694 | data = reg_write(client, MT9T031_CHIP_ENABLE, 1); |
656 | dev_dbg(&client->dev, "write: %d\n", data); | 695 | dev_dbg(&client->dev, "write: %d\n", data); |
@@ -688,8 +727,11 @@ static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = { | |||
688 | static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = { | 727 | static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = { |
689 | .s_stream = mt9t031_s_stream, | 728 | .s_stream = mt9t031_s_stream, |
690 | .s_fmt = mt9t031_s_fmt, | 729 | .s_fmt = mt9t031_s_fmt, |
730 | .g_fmt = mt9t031_g_fmt, | ||
691 | .try_fmt = mt9t031_try_fmt, | 731 | .try_fmt = mt9t031_try_fmt, |
692 | .s_crop = mt9t031_s_crop, | 732 | .s_crop = mt9t031_s_crop, |
733 | .g_crop = mt9t031_g_crop, | ||
734 | .cropcap = mt9t031_cropcap, | ||
693 | }; | 735 | }; |
694 | 736 | ||
695 | static struct v4l2_subdev_ops mt9t031_subdev_ops = { | 737 | static struct v4l2_subdev_ops mt9t031_subdev_ops = { |
@@ -731,15 +773,13 @@ static int mt9t031_probe(struct i2c_client *client, | |||
731 | 773 | ||
732 | /* Second stage probe - when a capture adapter is there */ | 774 | /* Second stage probe - when a capture adapter is there */ |
733 | icd->ops = &mt9t031_ops; | 775 | icd->ops = &mt9t031_ops; |
734 | icd->rect_max.left = MT9T031_COLUMN_SKIP; | ||
735 | icd->rect_max.top = MT9T031_ROW_SKIP; | ||
736 | icd->rect_current.left = icd->rect_max.left; | ||
737 | icd->rect_current.top = icd->rect_max.top; | ||
738 | icd->width_min = MT9T031_MIN_WIDTH; | ||
739 | icd->rect_max.width = MT9T031_MAX_WIDTH; | ||
740 | icd->height_min = MT9T031_MIN_HEIGHT; | ||
741 | icd->rect_max.height = MT9T031_MAX_HEIGHT; | ||
742 | icd->y_skip_top = 0; | 776 | icd->y_skip_top = 0; |
777 | |||
778 | mt9t031->rect.left = MT9T031_COLUMN_SKIP; | ||
779 | mt9t031->rect.top = MT9T031_ROW_SKIP; | ||
780 | mt9t031->rect.width = MT9T031_MAX_WIDTH; | ||
781 | mt9t031->rect.height = MT9T031_MAX_HEIGHT; | ||
782 | |||
743 | /* Simulated autoexposure. If enabled, we calculate shutter width | 783 | /* Simulated autoexposure. If enabled, we calculate shutter width |
744 | * ourselves in the driver based on vertical blanking and frame width */ | 784 | * ourselves in the driver based on vertical blanking and frame width */ |
745 | mt9t031->autoexposure = 1; | 785 | mt9t031->autoexposure = 1; |