diff options
Diffstat (limited to 'drivers/media/video/mt9m111.c')
-rw-r--r-- | drivers/media/video/mt9m111.c | 64 |
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 | ||
252 | static int mt9m111_setup_rect(struct soc_camera_device *icd) | 252 | static 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 | ||
394 | static int mt9m111_reset(struct soc_camera_device *icd) | 395 | static 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 | ||
440 | static 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 | |||
433 | static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt) | 456 | static 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 | ||
482 | static int mt9m111_set_fmt(struct soc_camera_device *icd, | 505 | static 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); |