aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMagnus Damm <damm@igel.co.jp>2008-12-18 09:49:06 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-30 06:40:21 -0500
commit9414de39e8e07d90bdb6524be501fae0e013d37b (patch)
treefdbae3246217cd7e209d3195758b8a2afc449b2b
parent91962fa713bd8bf47434b02ac661fdc201365fa5 (diff)
V4L/DVB (10079): sh_mobile_ceu: use new pixel format translation code
This patch converts the sh_mobile_ceu driver to make use of the new pixel format translation code. Only pass-though mode at this point. Signed-off-by: Magnus Damm <damm@igel.co.jp> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c83
1 files changed, 57 insertions, 26 deletions
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index c25ea0047e04..a49bec1509f4 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -434,8 +434,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
434 return 0; 434 return 0;
435} 435}
436 436
437static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd, 437static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd)
438 __u32 pixfmt)
439{ 438{
440 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 439 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
441 struct sh_mobile_ceu_dev *pcdev = ici->priv; 440 struct sh_mobile_ceu_dev *pcdev = ici->priv;
@@ -450,25 +449,60 @@ static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd,
450 return 0; 449 return 0;
451} 450}
452 451
452static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
453 struct soc_camera_format_xlate *xlate)
454{
455 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
456 int ret;
457 int formats = 0;
458
459 ret = sh_mobile_ceu_try_bus_param(icd);
460 if (ret < 0)
461 return 0;
462
463 switch (icd->formats[idx].fourcc) {
464 default:
465 /* Generic pass-through */
466 formats++;
467 if (xlate) {
468 xlate->host_fmt = icd->formats + idx;
469 xlate->cam_fmt = icd->formats + idx;
470 xlate->buswidth = icd->formats[idx].depth;
471 xlate++;
472 dev_dbg(&ici->dev,
473 "Providing format %s in pass-through mode\n",
474 icd->formats[idx].name);
475 }
476 }
477
478 return formats;
479}
480
453static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, 481static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
454 __u32 pixfmt, struct v4l2_rect *rect) 482 __u32 pixfmt, struct v4l2_rect *rect)
455{ 483{
456 const struct soc_camera_data_format *cam_fmt = NULL; 484 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
485 const struct soc_camera_format_xlate *xlate;
457 int ret; 486 int ret;
458 487
459 /* 488 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
460 * TODO: find a suitable supported by the SoC output format, check 489 if (!xlate) {
461 * whether the sensor supports one of acceptable input formats. 490 dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
462 */ 491 return -EINVAL;
463 if (pixfmt) {
464 cam_fmt = soc_camera_format_by_fourcc(icd, pixfmt);
465 if (!cam_fmt)
466 return -EINVAL;
467 } 492 }
468 493
469 ret = icd->ops->set_fmt(icd, pixfmt, rect); 494 switch (pixfmt) {
470 if (pixfmt && !ret) 495 case 0: /* Only geometry change */
471 icd->current_fmt = cam_fmt; 496 ret = icd->ops->set_fmt(icd, pixfmt, rect);
497 break;
498 default:
499 ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect);
500 }
501
502 if (pixfmt && !ret) {
503 icd->buswidth = xlate->buswidth;
504 icd->current_fmt = xlate->host_fmt;
505 }
472 506
473 return ret; 507 return ret;
474} 508}
@@ -476,19 +510,15 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
476static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, 510static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
477 struct v4l2_format *f) 511 struct v4l2_format *f)
478{ 512{
479 const struct soc_camera_data_format *cam_fmt; 513 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
480 int ret = sh_mobile_ceu_try_bus_param(icd, f->fmt.pix.pixelformat); 514 const struct soc_camera_format_xlate *xlate;
481 515 __u32 pixfmt = f->fmt.pix.pixelformat;
482 if (ret < 0)
483 return ret;
484 516
485 /* 517 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
486 * TODO: find a suitable supported by the SoC output format, check 518 if (!xlate) {
487 * whether the sensor supports one of acceptable input formats. 519 dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
488 */
489 cam_fmt = soc_camera_format_by_fourcc(icd, f->fmt.pix.pixelformat);
490 if (!cam_fmt)
491 return -EINVAL; 520 return -EINVAL;
521 }
492 522
493 /* FIXME: calculate using depth and bus width */ 523 /* FIXME: calculate using depth and bus width */
494 524
@@ -504,7 +534,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
504 f->fmt.pix.height &= ~0x03; 534 f->fmt.pix.height &= ~0x03;
505 535
506 f->fmt.pix.bytesperline = f->fmt.pix.width * 536 f->fmt.pix.bytesperline = f->fmt.pix.width *
507 DIV_ROUND_UP(cam_fmt->depth, 8); 537 DIV_ROUND_UP(xlate->host_fmt->depth, 8);
508 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; 538 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
509 539
510 /* limit to sensor capabilities */ 540 /* limit to sensor capabilities */
@@ -576,6 +606,7 @@ static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
576 .owner = THIS_MODULE, 606 .owner = THIS_MODULE,
577 .add = sh_mobile_ceu_add_device, 607 .add = sh_mobile_ceu_add_device,
578 .remove = sh_mobile_ceu_remove_device, 608 .remove = sh_mobile_ceu_remove_device,
609 .get_formats = sh_mobile_ceu_get_formats,
579 .set_fmt = sh_mobile_ceu_set_fmt, 610 .set_fmt = sh_mobile_ceu_set_fmt,
580 .try_fmt = sh_mobile_ceu_try_fmt, 611 .try_fmt = sh_mobile_ceu_try_fmt,
581 .reqbufs = sh_mobile_ceu_reqbufs, 612 .reqbufs = sh_mobile_ceu_reqbufs,