aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/mt9m111.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/mt9m111.c')
-rw-r--r--drivers/media/video/mt9m111.c64
1 files changed, 46 insertions, 18 deletions
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index 5b8e20979cce..cdd1ddb51388 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -152,7 +152,7 @@ struct mt9m111 {
152 struct soc_camera_device icd; 152 struct soc_camera_device icd;
153 int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */ 153 int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */
154 enum mt9m111_context context; 154 enum mt9m111_context context;
155 unsigned int left, top, width, height; 155 struct v4l2_rect rect;
156 u32 pixfmt; 156 u32 pixfmt;
157 unsigned char autoexposure; 157 unsigned char autoexposure;
158 unsigned char datawidth; 158 unsigned char datawidth;
@@ -249,12 +249,13 @@ static int mt9m111_set_context(struct soc_camera_device *icd,
249 return reg_write(CONTEXT_CONTROL, valA); 249 return reg_write(CONTEXT_CONTROL, valA);
250} 250}
251 251
252static int mt9m111_setup_rect(struct soc_camera_device *icd) 252static int mt9m111_setup_rect(struct soc_camera_device *icd,
253 struct v4l2_rect *rect)
253{ 254{
254 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 255 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
255 int ret, is_raw_format; 256 int ret, is_raw_format;
256 int width = mt9m111->width; 257 int width = rect->width;
257 int height = mt9m111->height; 258 int height = rect->height;
258 259
259 if ((mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8) 260 if ((mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8)
260 || (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16)) 261 || (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16))
@@ -262,9 +263,9 @@ static int mt9m111_setup_rect(struct soc_camera_device *icd)
262 else 263 else
263 is_raw_format = 0; 264 is_raw_format = 0;
264 265
265 ret = reg_write(COLUMN_START, mt9m111->left); 266 ret = reg_write(COLUMN_START, rect->left);
266 if (!ret) 267 if (!ret)
267 ret = reg_write(ROW_START, mt9m111->top); 268 ret = reg_write(ROW_START, rect->top);
268 269
269 if (is_raw_format) { 270 if (is_raw_format) {
270 if (!ret) 271 if (!ret)
@@ -393,6 +394,8 @@ static int mt9m111_disable(struct soc_camera_device *icd)
393 394
394static int mt9m111_reset(struct soc_camera_device *icd) 395static int mt9m111_reset(struct soc_camera_device *icd)
395{ 396{
397 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
398 struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
396 int ret; 399 int ret;
397 400
398 ret = reg_set(RESET, MT9M111_RESET_RESET_MODE); 401 ret = reg_set(RESET, MT9M111_RESET_RESET_MODE);
@@ -401,6 +404,10 @@ static int mt9m111_reset(struct soc_camera_device *icd)
401 if (!ret) 404 if (!ret)
402 ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE 405 ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE
403 | MT9M111_RESET_RESET_SOC); 406 | MT9M111_RESET_RESET_SOC);
407
408 if (icl->reset)
409 icl->reset(&mt9m111->client->dev);
410
404 return ret; 411 return ret;
405} 412}
406 413
@@ -420,7 +427,7 @@ static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd)
420 struct soc_camera_link *icl = mt9m111->client->dev.platform_data; 427 struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
421 unsigned long flags = SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING | 428 unsigned long flags = SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |
422 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | 429 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
423 SOCAM_DATAWIDTH_8; 430 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
424 431
425 return soc_camera_apply_sensor_flags(icl, flags); 432 return soc_camera_apply_sensor_flags(icl, flags);
426} 433}
@@ -430,6 +437,22 @@ static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f)
430 return 0; 437 return 0;
431} 438}
432 439
440static int mt9m111_set_crop(struct soc_camera_device *icd,
441 struct v4l2_rect *rect)
442{
443 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
444 int ret;
445
446 dev_dbg(&icd->dev, "%s left=%d, top=%d, width=%d, height=%d\n",
447 __func__, rect->left, rect->top, rect->width,
448 rect->height);
449
450 ret = mt9m111_setup_rect(icd, rect);
451 if (!ret)
452 mt9m111->rect = *rect;
453 return ret;
454}
455
433static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt) 456static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt)
434{ 457{
435 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 458 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
@@ -480,23 +503,27 @@ static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt)
480} 503}
481 504
482static int mt9m111_set_fmt(struct soc_camera_device *icd, 505static int mt9m111_set_fmt(struct soc_camera_device *icd,
483 __u32 pixfmt, struct v4l2_rect *rect) 506 struct v4l2_format *f)
484{ 507{
485 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 508 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
509 struct v4l2_pix_format *pix = &f->fmt.pix;
510 struct v4l2_rect rect = {
511 .left = mt9m111->rect.left,
512 .top = mt9m111->rect.top,
513 .width = pix->width,
514 .height = pix->height,
515 };
486 int ret; 516 int ret;
487 517
488 mt9m111->left = rect->left;
489 mt9m111->top = rect->top;
490 mt9m111->width = rect->width;
491 mt9m111->height = rect->height;
492
493 dev_dbg(&icd->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", 518 dev_dbg(&icd->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n",
494 __func__, pixfmt, mt9m111->left, mt9m111->top, mt9m111->width, 519 __func__, pix->pixelformat, rect.left, rect.top, rect.width,
495 mt9m111->height); 520 rect.height);
496 521
497 ret = mt9m111_setup_rect(icd); 522 ret = mt9m111_setup_rect(icd, &rect);
523 if (!ret)
524 ret = mt9m111_set_pixfmt(icd, pix->pixelformat);
498 if (!ret) 525 if (!ret)
499 ret = mt9m111_set_pixfmt(icd, pixfmt); 526 mt9m111->rect = rect;
500 return ret; 527 return ret;
501} 528}
502 529
@@ -627,6 +654,7 @@ static struct soc_camera_ops mt9m111_ops = {
627 .release = mt9m111_release, 654 .release = mt9m111_release,
628 .start_capture = mt9m111_start_capture, 655 .start_capture = mt9m111_start_capture,
629 .stop_capture = mt9m111_stop_capture, 656 .stop_capture = mt9m111_stop_capture,
657 .set_crop = mt9m111_set_crop,
630 .set_fmt = mt9m111_set_fmt, 658 .set_fmt = mt9m111_set_fmt,
631 .try_fmt = mt9m111_try_fmt, 659 .try_fmt = mt9m111_try_fmt,
632 .query_bus_param = mt9m111_query_bus_param, 660 .query_bus_param = mt9m111_query_bus_param,
@@ -811,7 +839,7 @@ static int mt9m111_restore_state(struct soc_camera_device *icd)
811 839
812 mt9m111_set_context(icd, mt9m111->context); 840 mt9m111_set_context(icd, mt9m111->context);
813 mt9m111_set_pixfmt(icd, mt9m111->pixfmt); 841 mt9m111_set_pixfmt(icd, mt9m111->pixfmt);
814 mt9m111_setup_rect(icd); 842 mt9m111_setup_rect(icd, &mt9m111->rect);
815 mt9m111_set_flip(icd, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS); 843 mt9m111_set_flip(icd, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS);
816 mt9m111_set_flip(icd, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS); 844 mt9m111_set_flip(icd, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS);
817 mt9m111_set_global_gain(icd, icd->gain); 845 mt9m111_set_global_gain(icd, icd->gain);