aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ov772x.c
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2009-12-11 09:46:49 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-16 06:27:29 -0500
commit760697beca338599a65484389c7abbe54aedb664 (patch)
tree515735429d2240629a6f048ab1a7fefaf5299e46 /drivers/media/video/ov772x.c
parent9a74251d8bee7a25fee89a0be3ccea73e01c1a05 (diff)
V4L/DVB (13659): soc-camera: convert to the new mediabus API
Convert soc-camera core and all soc-camera drivers to the new mediabus API. This also takes soc-camera client drivers one step closer to also be usable with generic v4l2-subdev host drivers. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Acked-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/ov772x.c')
-rw-r--r--drivers/media/video/ov772x.c229
1 files changed, 114 insertions, 115 deletions
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index dcb690cb5ae7..3a45e945a528 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -24,6 +24,7 @@
24#include <media/v4l2-chip-ident.h> 24#include <media/v4l2-chip-ident.h>
25#include <media/v4l2-subdev.h> 25#include <media/v4l2-subdev.h>
26#include <media/soc_camera.h> 26#include <media/soc_camera.h>
27#include <media/soc_mediabus.h>
27#include <media/ov772x.h> 28#include <media/ov772x.h>
28 29
29/* 30/*
@@ -382,7 +383,8 @@ struct regval_list {
382}; 383};
383 384
384struct ov772x_color_format { 385struct ov772x_color_format {
385 const struct soc_camera_data_format *format; 386 enum v4l2_mbus_pixelcode code;
387 enum v4l2_colorspace colorspace;
386 u8 dsp3; 388 u8 dsp3;
387 u8 com3; 389 u8 com3;
388 u8 com7; 390 u8 com7;
@@ -399,7 +401,7 @@ struct ov772x_win_size {
399struct ov772x_priv { 401struct ov772x_priv {
400 struct v4l2_subdev subdev; 402 struct v4l2_subdev subdev;
401 struct ov772x_camera_info *info; 403 struct ov772x_camera_info *info;
402 const struct ov772x_color_format *fmt; 404 const struct ov772x_color_format *cfmt;
403 const struct ov772x_win_size *win; 405 const struct ov772x_win_size *win;
404 int model; 406 int model;
405 unsigned short flag_vflip:1; 407 unsigned short flag_vflip:1;
@@ -434,93 +436,57 @@ static const struct regval_list ov772x_vga_regs[] = {
434}; 436};
435 437
436/* 438/*
437 * supported format list 439 * supported color format list
438 */
439
440#define SETFOURCC(type) .name = (#type), .fourcc = (V4L2_PIX_FMT_ ## type)
441static const struct soc_camera_data_format ov772x_fmt_lists[] = {
442 {
443 SETFOURCC(YUYV),
444 .depth = 16,
445 .colorspace = V4L2_COLORSPACE_JPEG,
446 },
447 {
448 SETFOURCC(YVYU),
449 .depth = 16,
450 .colorspace = V4L2_COLORSPACE_JPEG,
451 },
452 {
453 SETFOURCC(UYVY),
454 .depth = 16,
455 .colorspace = V4L2_COLORSPACE_JPEG,
456 },
457 {
458 SETFOURCC(RGB555),
459 .depth = 16,
460 .colorspace = V4L2_COLORSPACE_SRGB,
461 },
462 {
463 SETFOURCC(RGB555X),
464 .depth = 16,
465 .colorspace = V4L2_COLORSPACE_SRGB,
466 },
467 {
468 SETFOURCC(RGB565),
469 .depth = 16,
470 .colorspace = V4L2_COLORSPACE_SRGB,
471 },
472 {
473 SETFOURCC(RGB565X),
474 .depth = 16,
475 .colorspace = V4L2_COLORSPACE_SRGB,
476 },
477};
478
479/*
480 * color format list
481 */ 440 */
482static const struct ov772x_color_format ov772x_cfmts[] = { 441static const struct ov772x_color_format ov772x_cfmts[] = {
483 { 442 {
484 .format = &ov772x_fmt_lists[0], 443 .code = V4L2_MBUS_FMT_YUYV8_2X8_LE,
485 .dsp3 = 0x0, 444 .colorspace = V4L2_COLORSPACE_JPEG,
486 .com3 = SWAP_YUV, 445 .dsp3 = 0x0,
487 .com7 = OFMT_YUV, 446 .com3 = SWAP_YUV,
447 .com7 = OFMT_YUV,
488 }, 448 },
489 { 449 {
490 .format = &ov772x_fmt_lists[1], 450 .code = V4L2_MBUS_FMT_YVYU8_2X8_LE,
491 .dsp3 = UV_ON, 451 .colorspace = V4L2_COLORSPACE_JPEG,
492 .com3 = SWAP_YUV, 452 .dsp3 = UV_ON,
493 .com7 = OFMT_YUV, 453 .com3 = SWAP_YUV,
454 .com7 = OFMT_YUV,
494 }, 455 },
495 { 456 {
496 .format = &ov772x_fmt_lists[2], 457 .code = V4L2_MBUS_FMT_YUYV8_2X8_BE,
497 .dsp3 = 0x0, 458 .colorspace = V4L2_COLORSPACE_JPEG,
498 .com3 = 0x0, 459 .dsp3 = 0x0,
499 .com7 = OFMT_YUV, 460 .com3 = 0x0,
461 .com7 = OFMT_YUV,
500 }, 462 },
501 { 463 {
502 .format = &ov772x_fmt_lists[3], 464 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
503 .dsp3 = 0x0, 465 .colorspace = V4L2_COLORSPACE_SRGB,
504 .com3 = SWAP_RGB, 466 .dsp3 = 0x0,
505 .com7 = FMT_RGB555 | OFMT_RGB, 467 .com3 = SWAP_RGB,
468 .com7 = FMT_RGB555 | OFMT_RGB,
506 }, 469 },
507 { 470 {
508 .format = &ov772x_fmt_lists[4], 471 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE,
509 .dsp3 = 0x0, 472 .colorspace = V4L2_COLORSPACE_SRGB,
510 .com3 = 0x0, 473 .dsp3 = 0x0,
511 .com7 = FMT_RGB555 | OFMT_RGB, 474 .com3 = 0x0,
475 .com7 = FMT_RGB555 | OFMT_RGB,
512 }, 476 },
513 { 477 {
514 .format = &ov772x_fmt_lists[5], 478 .code = V4L2_MBUS_FMT_RGB565_2X8_LE,
515 .dsp3 = 0x0, 479 .colorspace = V4L2_COLORSPACE_SRGB,
516 .com3 = SWAP_RGB, 480 .dsp3 = 0x0,
517 .com7 = FMT_RGB565 | OFMT_RGB, 481 .com3 = SWAP_RGB,
482 .com7 = FMT_RGB565 | OFMT_RGB,
518 }, 483 },
519 { 484 {
520 .format = &ov772x_fmt_lists[6], 485 .code = V4L2_MBUS_FMT_RGB565_2X8_BE,
521 .dsp3 = 0x0, 486 .colorspace = V4L2_COLORSPACE_SRGB,
522 .com3 = 0x0, 487 .dsp3 = 0x0,
523 .com7 = FMT_RGB565 | OFMT_RGB, 488 .com3 = 0x0,
489 .com7 = FMT_RGB565 | OFMT_RGB,
524 }, 490 },
525}; 491};
526 492
@@ -642,15 +608,15 @@ static int ov772x_s_stream(struct v4l2_subdev *sd, int enable)
642 return 0; 608 return 0;
643 } 609 }
644 610
645 if (!priv->win || !priv->fmt) { 611 if (!priv->win || !priv->cfmt) {
646 dev_err(&client->dev, "norm or win select error\n"); 612 dev_err(&client->dev, "norm or win select error\n");
647 return -EPERM; 613 return -EPERM;
648 } 614 }
649 615
650 ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0); 616 ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0);
651 617
652 dev_dbg(&client->dev, "format %s, win %s\n", 618 dev_dbg(&client->dev, "format %d, win %s\n",
653 priv->fmt->format->name, priv->win->name); 619 priv->cfmt->code, priv->win->name);
654 620
655 return 0; 621 return 0;
656} 622}
@@ -806,8 +772,8 @@ static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height)
806 return win; 772 return win;
807} 773}
808 774
809static int ov772x_set_params(struct i2c_client *client, 775static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
810 u32 *width, u32 *height, u32 pixfmt) 776 enum v4l2_mbus_pixelcode code)
811{ 777{
812 struct ov772x_priv *priv = to_ov772x(client); 778 struct ov772x_priv *priv = to_ov772x(client);
813 int ret = -EINVAL; 779 int ret = -EINVAL;
@@ -817,14 +783,14 @@ static int ov772x_set_params(struct i2c_client *client,
817 /* 783 /*
818 * select format 784 * select format
819 */ 785 */
820 priv->fmt = NULL; 786 priv->cfmt = NULL;
821 for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) { 787 for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) {
822 if (pixfmt == ov772x_cfmts[i].format->fourcc) { 788 if (code == ov772x_cfmts[i].code) {
823 priv->fmt = ov772x_cfmts + i; 789 priv->cfmt = ov772x_cfmts + i;
824 break; 790 break;
825 } 791 }
826 } 792 }
827 if (!priv->fmt) 793 if (!priv->cfmt)
828 goto ov772x_set_fmt_error; 794 goto ov772x_set_fmt_error;
829 795
830 /* 796 /*
@@ -894,7 +860,7 @@ static int ov772x_set_params(struct i2c_client *client,
894 /* 860 /*
895 * set DSP_CTRL3 861 * set DSP_CTRL3
896 */ 862 */
897 val = priv->fmt->dsp3; 863 val = priv->cfmt->dsp3;
898 if (val) { 864 if (val) {
899 ret = ov772x_mask_set(client, 865 ret = ov772x_mask_set(client,
900 DSP_CTRL3, UV_MASK, val); 866 DSP_CTRL3, UV_MASK, val);
@@ -905,7 +871,7 @@ static int ov772x_set_params(struct i2c_client *client,
905 /* 871 /*
906 * set COM3 872 * set COM3
907 */ 873 */
908 val = priv->fmt->com3; 874 val = priv->cfmt->com3;
909 if (priv->info->flags & OV772X_FLAG_VFLIP) 875 if (priv->info->flags & OV772X_FLAG_VFLIP)
910 val |= VFLIP_IMG; 876 val |= VFLIP_IMG;
911 if (priv->info->flags & OV772X_FLAG_HFLIP) 877 if (priv->info->flags & OV772X_FLAG_HFLIP)
@@ -923,9 +889,9 @@ static int ov772x_set_params(struct i2c_client *client,
923 /* 889 /*
924 * set COM7 890 * set COM7
925 */ 891 */
926 val = priv->win->com7_bit | priv->fmt->com7; 892 val = priv->win->com7_bit | priv->cfmt->com7;
927 ret = ov772x_mask_set(client, 893 ret = ov772x_mask_set(client,
928 COM7, (SLCT_MASK | FMT_MASK | OFMT_MASK), 894 COM7, SLCT_MASK | FMT_MASK | OFMT_MASK,
929 val); 895 val);
930 if (ret < 0) 896 if (ret < 0)
931 goto ov772x_set_fmt_error; 897 goto ov772x_set_fmt_error;
@@ -951,7 +917,7 @@ ov772x_set_fmt_error:
951 917
952 ov772x_reset(client); 918 ov772x_reset(client);
953 priv->win = NULL; 919 priv->win = NULL;
954 priv->fmt = NULL; 920 priv->cfmt = NULL;
955 921
956 return ret; 922 return ret;
957} 923}
@@ -981,54 +947,79 @@ static int ov772x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
981 return 0; 947 return 0;
982} 948}
983 949
984static int ov772x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 950static int ov772x_g_fmt(struct v4l2_subdev *sd,
951 struct v4l2_mbus_framefmt *mf)
985{ 952{
986 struct i2c_client *client = sd->priv; 953 struct i2c_client *client = sd->priv;
987 struct ov772x_priv *priv = to_ov772x(client); 954 struct ov772x_priv *priv = to_ov772x(client);
988 struct v4l2_pix_format *pix = &f->fmt.pix;
989 955
990 if (!priv->win || !priv->fmt) { 956 if (!priv->win || !priv->cfmt) {
991 u32 width = VGA_WIDTH, height = VGA_HEIGHT; 957 u32 width = VGA_WIDTH, height = VGA_HEIGHT;
992 int ret = ov772x_set_params(client, &width, &height, 958 int ret = ov772x_set_params(client, &width, &height,
993 V4L2_PIX_FMT_YUYV); 959 V4L2_MBUS_FMT_YUYV8_2X8_LE);
994 if (ret < 0) 960 if (ret < 0)
995 return ret; 961 return ret;
996 } 962 }
997 963
998 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 964 mf->width = priv->win->width;
999 965 mf->height = priv->win->height;
1000 pix->width = priv->win->width; 966 mf->code = priv->cfmt->code;
1001 pix->height = priv->win->height; 967 mf->colorspace = priv->cfmt->colorspace;
1002 pix->pixelformat = priv->fmt->format->fourcc; 968 mf->field = V4L2_FIELD_NONE;
1003 pix->colorspace = priv->fmt->format->colorspace;
1004 pix->field = V4L2_FIELD_NONE;
1005 969
1006 return 0; 970 return 0;
1007} 971}
1008 972
1009static int ov772x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 973static int ov772x_s_fmt(struct v4l2_subdev *sd,
974 struct v4l2_mbus_framefmt *mf)
1010{ 975{
1011 struct i2c_client *client = sd->priv; 976 struct i2c_client *client = sd->priv;
1012 struct v4l2_pix_format *pix = &f->fmt.pix; 977 struct ov772x_priv *priv = to_ov772x(client);
978 int ret = ov772x_set_params(client, &mf->width, &mf->height,
979 mf->code);
980
981 if (!ret)
982 mf->colorspace = priv->cfmt->colorspace;
1013 983
1014 return ov772x_set_params(client, &pix->width, &pix->height, 984 return ret;
1015 pix->pixelformat);
1016} 985}
1017 986
1018static int ov772x_try_fmt(struct v4l2_subdev *sd, 987static int ov772x_try_fmt(struct v4l2_subdev *sd,
1019 struct v4l2_format *f) 988 struct v4l2_mbus_framefmt *mf)
1020{ 989{
1021 struct v4l2_pix_format *pix = &f->fmt.pix; 990 struct i2c_client *client = sd->priv;
991 struct ov772x_priv *priv = to_ov772x(client);
1022 const struct ov772x_win_size *win; 992 const struct ov772x_win_size *win;
993 int i;
1023 994
1024 /* 995 /*
1025 * select suitable win 996 * select suitable win
1026 */ 997 */
1027 win = ov772x_select_win(pix->width, pix->height); 998 win = ov772x_select_win(mf->width, mf->height);
999
1000 mf->width = win->width;
1001 mf->height = win->height;
1002 mf->field = V4L2_FIELD_NONE;
1028 1003
1029 pix->width = win->width; 1004 for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++)
1030 pix->height = win->height; 1005 if (mf->code == ov772x_cfmts[i].code)
1031 pix->field = V4L2_FIELD_NONE; 1006 break;
1007
1008 if (i == ARRAY_SIZE(ov772x_cfmts)) {
1009 /* Unsupported format requested. Propose either */
1010 if (priv->cfmt) {
1011 /* the current one or */
1012 mf->colorspace = priv->cfmt->colorspace;
1013 mf->code = priv->cfmt->code;
1014 } else {
1015 /* the default one */
1016 mf->colorspace = ov772x_cfmts[0].colorspace;
1017 mf->code = ov772x_cfmts[0].code;
1018 }
1019 } else {
1020 /* Also return the colorspace */
1021 mf->colorspace = ov772x_cfmts[i].colorspace;
1022 }
1032 1023
1033 return 0; 1024 return 0;
1034} 1025}
@@ -1057,9 +1048,6 @@ static int ov772x_video_probe(struct soc_camera_device *icd,
1057 return -ENODEV; 1048 return -ENODEV;
1058 } 1049 }
1059 1050
1060 icd->formats = ov772x_fmt_lists;
1061 icd->num_formats = ARRAY_SIZE(ov772x_fmt_lists);
1062
1063 /* 1051 /*
1064 * check and show product ID and manufacturer ID 1052 * check and show product ID and manufacturer ID
1065 */ 1053 */
@@ -1109,13 +1097,24 @@ static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = {
1109#endif 1097#endif
1110}; 1098};
1111 1099
1100static int ov772x_enum_fmt(struct v4l2_subdev *sd, int index,
1101 enum v4l2_mbus_pixelcode *code)
1102{
1103 if ((unsigned int)index >= ARRAY_SIZE(ov772x_cfmts))
1104 return -EINVAL;
1105
1106 *code = ov772x_cfmts[index].code;
1107 return 0;
1108}
1109
1112static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = { 1110static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = {
1113 .s_stream = ov772x_s_stream, 1111 .s_stream = ov772x_s_stream,
1114 .g_fmt = ov772x_g_fmt, 1112 .g_mbus_fmt = ov772x_g_fmt,
1115 .s_fmt = ov772x_s_fmt, 1113 .s_mbus_fmt = ov772x_s_fmt,
1116 .try_fmt = ov772x_try_fmt, 1114 .try_mbus_fmt = ov772x_try_fmt,
1117 .cropcap = ov772x_cropcap, 1115 .cropcap = ov772x_cropcap,
1118 .g_crop = ov772x_g_crop, 1116 .g_crop = ov772x_g_crop,
1117 .enum_mbus_fmt = ov772x_enum_fmt,
1119}; 1118};
1120 1119
1121static struct v4l2_subdev_ops ov772x_subdev_ops = { 1120static struct v4l2_subdev_ops ov772x_subdev_ops = {