aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ov772x.c
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2009-08-25 10:50:46 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-18 23:19:17 -0400
commit6a6c8786725c0b3d143674effa8b772f47b1c189 (patch)
tree8bb76c5dcbd579f13e876bd1a0bb56bee4bcebdd /drivers/media/video/ov772x.c
parent0166b74374cae3fa8bff0caef726a3d960a9a50a (diff)
V4L/DVB (12534): soc-camera: V4L2 API compliant scaling (S_FMT) and cropping (S_CROP)
The initial soc-camera scaling and cropping implementation turned out to be incompliant with the V4L2 API, e.g., it expected the user to specify cropping in output window pixels, instead of input window pixels. This patch converts the soc-camera core and all drivers to comply with the standard. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/ov772x.c')
-rw-r--r--drivers/media/video/ov772x.c84
1 files changed, 67 insertions, 17 deletions
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index bbf5331a2eae..776a91dcfbe6 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -382,11 +382,10 @@ struct regval_list {
382}; 382};
383 383
384struct ov772x_color_format { 384struct ov772x_color_format {
385 char *name; 385 const struct soc_camera_data_format *format;
386 __u32 fourcc; 386 u8 dsp3;
387 u8 dsp3; 387 u8 com3;
388 u8 com3; 388 u8 com7;
389 u8 com7;
390}; 389};
391 390
392struct ov772x_win_size { 391struct ov772x_win_size {
@@ -481,43 +480,43 @@ static const struct soc_camera_data_format ov772x_fmt_lists[] = {
481 */ 480 */
482static const struct ov772x_color_format ov772x_cfmts[] = { 481static const struct ov772x_color_format ov772x_cfmts[] = {
483 { 482 {
484 SETFOURCC(YUYV), 483 .format = &ov772x_fmt_lists[0],
485 .dsp3 = 0x0, 484 .dsp3 = 0x0,
486 .com3 = SWAP_YUV, 485 .com3 = SWAP_YUV,
487 .com7 = OFMT_YUV, 486 .com7 = OFMT_YUV,
488 }, 487 },
489 { 488 {
490 SETFOURCC(YVYU), 489 .format = &ov772x_fmt_lists[1],
491 .dsp3 = UV_ON, 490 .dsp3 = UV_ON,
492 .com3 = SWAP_YUV, 491 .com3 = SWAP_YUV,
493 .com7 = OFMT_YUV, 492 .com7 = OFMT_YUV,
494 }, 493 },
495 { 494 {
496 SETFOURCC(UYVY), 495 .format = &ov772x_fmt_lists[2],
497 .dsp3 = 0x0, 496 .dsp3 = 0x0,
498 .com3 = 0x0, 497 .com3 = 0x0,
499 .com7 = OFMT_YUV, 498 .com7 = OFMT_YUV,
500 }, 499 },
501 { 500 {
502 SETFOURCC(RGB555), 501 .format = &ov772x_fmt_lists[3],
503 .dsp3 = 0x0, 502 .dsp3 = 0x0,
504 .com3 = SWAP_RGB, 503 .com3 = SWAP_RGB,
505 .com7 = FMT_RGB555 | OFMT_RGB, 504 .com7 = FMT_RGB555 | OFMT_RGB,
506 }, 505 },
507 { 506 {
508 SETFOURCC(RGB555X), 507 .format = &ov772x_fmt_lists[4],
509 .dsp3 = 0x0, 508 .dsp3 = 0x0,
510 .com3 = 0x0, 509 .com3 = 0x0,
511 .com7 = FMT_RGB555 | OFMT_RGB, 510 .com7 = FMT_RGB555 | OFMT_RGB,
512 }, 511 },
513 { 512 {
514 SETFOURCC(RGB565), 513 .format = &ov772x_fmt_lists[5],
515 .dsp3 = 0x0, 514 .dsp3 = 0x0,
516 .com3 = SWAP_RGB, 515 .com3 = SWAP_RGB,
517 .com7 = FMT_RGB565 | OFMT_RGB, 516 .com7 = FMT_RGB565 | OFMT_RGB,
518 }, 517 },
519 { 518 {
520 SETFOURCC(RGB565X), 519 .format = &ov772x_fmt_lists[6],
521 .dsp3 = 0x0, 520 .dsp3 = 0x0,
522 .com3 = 0x0, 521 .com3 = 0x0,
523 .com7 = FMT_RGB565 | OFMT_RGB, 522 .com7 = FMT_RGB565 | OFMT_RGB,
@@ -648,8 +647,8 @@ static int ov772x_s_stream(struct v4l2_subdev *sd, int enable)
648 647
649 ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0); 648 ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0);
650 649
651 dev_dbg(&client->dev, 650 dev_dbg(&client->dev, "format %s, win %s\n",
652 "format %s, win %s\n", priv->fmt->name, priv->win->name); 651 priv->fmt->format->name, priv->win->name);
653 652
654 return 0; 653 return 0;
655} 654}
@@ -818,7 +817,7 @@ static int ov772x_set_params(struct i2c_client *client,
818 */ 817 */
819 priv->fmt = NULL; 818 priv->fmt = NULL;
820 for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) { 819 for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) {
821 if (pixfmt == ov772x_cfmts[i].fourcc) { 820 if (pixfmt == ov772x_cfmts[i].format->fourcc) {
822 priv->fmt = ov772x_cfmts + i; 821 priv->fmt = ov772x_cfmts + i;
823 break; 822 break;
824 } 823 }
@@ -955,6 +954,56 @@ ov772x_set_fmt_error:
955 return ret; 954 return ret;
956} 955}
957 956
957static int ov772x_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
958{
959 a->c.left = 0;
960 a->c.top = 0;
961 a->c.width = VGA_WIDTH;
962 a->c.height = VGA_HEIGHT;
963 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
964
965 return 0;
966}
967
968static int ov772x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
969{
970 a->bounds.left = 0;
971 a->bounds.top = 0;
972 a->bounds.width = VGA_WIDTH;
973 a->bounds.height = VGA_HEIGHT;
974 a->defrect = a->bounds;
975 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
976 a->pixelaspect.numerator = 1;
977 a->pixelaspect.denominator = 1;
978
979 return 0;
980}
981
982static int ov772x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
983{
984 struct i2c_client *client = sd->priv;
985 struct ov772x_priv *priv = to_ov772x(client);
986 struct v4l2_pix_format *pix = &f->fmt.pix;
987
988 if (!priv->win || !priv->fmt) {
989 u32 width = VGA_WIDTH, height = VGA_HEIGHT;
990 int ret = ov772x_set_params(client, &width, &height,
991 V4L2_PIX_FMT_YUYV);
992 if (ret < 0)
993 return ret;
994 }
995
996 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
997
998 pix->width = priv->win->width;
999 pix->height = priv->win->height;
1000 pix->pixelformat = priv->fmt->format->fourcc;
1001 pix->colorspace = priv->fmt->format->colorspace;
1002 pix->field = V4L2_FIELD_NONE;
1003
1004 return 0;
1005}
1006
958static int ov772x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 1007static int ov772x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
959{ 1008{
960 struct i2c_client *client = sd->priv; 1009 struct i2c_client *client = sd->priv;
@@ -1060,8 +1109,11 @@ static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = {
1060 1109
1061static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = { 1110static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = {
1062 .s_stream = ov772x_s_stream, 1111 .s_stream = ov772x_s_stream,
1112 .g_fmt = ov772x_g_fmt,
1063 .s_fmt = ov772x_s_fmt, 1113 .s_fmt = ov772x_s_fmt,
1064 .try_fmt = ov772x_try_fmt, 1114 .try_fmt = ov772x_try_fmt,
1115 .cropcap = ov772x_cropcap,
1116 .g_crop = ov772x_g_crop,
1065}; 1117};
1066 1118
1067static struct v4l2_subdev_ops ov772x_subdev_ops = { 1119static struct v4l2_subdev_ops ov772x_subdev_ops = {
@@ -1110,8 +1162,6 @@ static int ov772x_probe(struct i2c_client *client,
1110 v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops); 1162 v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops);
1111 1163
1112 icd->ops = &ov772x_ops; 1164 icd->ops = &ov772x_ops;
1113 icd->rect_max.width = MAX_WIDTH;
1114 icd->rect_max.height = MAX_HEIGHT;
1115 1165
1116 ret = ov772x_video_probe(icd, client); 1166 ret = ov772x_video_probe(icd, client);
1117 if (ret) { 1167 if (ret) {