aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/sh_mobile_ceu_camera.c
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <lyakh@axis700.grange>2008-12-01 07:44:59 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-30 06:38:22 -0500
commit25c4d74ea6f07f2aaa3df537619680ba967043f5 (patch)
tree58a33458a15e9720adc027ef443828550ba1f0eb /drivers/media/video/sh_mobile_ceu_camera.c
parentabe4c4710386a4859dae9193bfc9a1f0e3c60db4 (diff)
V4L/DVB (9787): soc-camera: let camera host drivers decide upon pixel format
Pixel format requested by the user is not necessarily the same, as what a sensor driver provides. There are situations, when a camera host driver provides the required format, but requires a different format from the sensor. Further, the list of formats, supported by sensors is pretty static and can be pretty good described with a constant list of structures. Whereas decisions, made by camera host drivers to support requested formats can be quite complex, therefore it is better to let the host driver do the work. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/sh_mobile_ceu_camera.c')
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 87d0f307581..02f846d1908 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -453,17 +453,43 @@ static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd,
453static int sh_mobile_ceu_set_fmt_cap(struct soc_camera_device *icd, 453static int sh_mobile_ceu_set_fmt_cap(struct soc_camera_device *icd,
454 __u32 pixfmt, struct v4l2_rect *rect) 454 __u32 pixfmt, struct v4l2_rect *rect)
455{ 455{
456 return icd->ops->set_fmt_cap(icd, pixfmt, rect); 456 const struct soc_camera_data_format *cam_fmt;
457 int ret;
458
459 /*
460 * TODO: find a suitable supported by the SoC output format, check
461 * whether the sensor supports one of acceptable input formats.
462 */
463 if (pixfmt) {
464 cam_fmt = soc_camera_format_by_fourcc(icd, pixfmt);
465 if (!cam_fmt)
466 return -EINVAL;
467 }
468
469 ret = icd->ops->set_fmt_cap(icd, pixfmt, rect);
470 if (pixfmt && !ret)
471 icd->current_fmt = cam_fmt;
472
473 return ret;
457} 474}
458 475
459static int sh_mobile_ceu_try_fmt_cap(struct soc_camera_device *icd, 476static int sh_mobile_ceu_try_fmt_cap(struct soc_camera_device *icd,
460 struct v4l2_format *f) 477 struct v4l2_format *f)
461{ 478{
479 const struct soc_camera_data_format *cam_fmt;
462 int ret = sh_mobile_ceu_try_bus_param(icd, f->fmt.pix.pixelformat); 480 int ret = sh_mobile_ceu_try_bus_param(icd, f->fmt.pix.pixelformat);
463 481
464 if (ret < 0) 482 if (ret < 0)
465 return ret; 483 return ret;
466 484
485 /*
486 * TODO: find a suitable supported by the SoC output format, check
487 * whether the sensor supports one of acceptable input formats.
488 */
489 cam_fmt = soc_camera_format_by_fourcc(icd, f->fmt.pix.pixelformat);
490 if (!cam_fmt)
491 return -EINVAL;
492
467 /* FIXME: calculate using depth and bus width */ 493 /* FIXME: calculate using depth and bus width */
468 494
469 if (f->fmt.pix.height < 4) 495 if (f->fmt.pix.height < 4)
@@ -477,6 +503,10 @@ static int sh_mobile_ceu_try_fmt_cap(struct soc_camera_device *icd,
477 f->fmt.pix.width &= ~0x01; 503 f->fmt.pix.width &= ~0x01;
478 f->fmt.pix.height &= ~0x03; 504 f->fmt.pix.height &= ~0x03;
479 505
506 f->fmt.pix.bytesperline = f->fmt.pix.width *
507 DIV_ROUND_UP(cam_fmt->depth, 8);
508 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
509
480 /* limit to sensor capabilities */ 510 /* limit to sensor capabilities */
481 return icd->ops->try_fmt_cap(icd, f); 511 return icd->ops->try_fmt_cap(icd, f);
482} 512}