aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/mt9t112.c119
1 files changed, 70 insertions, 49 deletions
diff --git a/drivers/media/video/mt9t112.c b/drivers/media/video/mt9t112.c
index 608a3b6a8e99..25cdcb90768a 100644
--- a/drivers/media/video/mt9t112.c
+++ b/drivers/media/video/mt9t112.c
@@ -78,11 +78,6 @@
78/************************************************************************ 78/************************************************************************
79 struct 79 struct
80************************************************************************/ 80************************************************************************/
81struct mt9t112_frame_size {
82 u16 width;
83 u16 height;
84};
85
86struct mt9t112_format { 81struct mt9t112_format {
87 enum v4l2_mbus_pixelcode code; 82 enum v4l2_mbus_pixelcode code;
88 enum v4l2_colorspace colorspace; 83 enum v4l2_colorspace colorspace;
@@ -95,7 +90,7 @@ struct mt9t112_priv {
95 struct mt9t112_camera_info *info; 90 struct mt9t112_camera_info *info;
96 struct i2c_client *client; 91 struct i2c_client *client;
97 struct soc_camera_device icd; 92 struct soc_camera_device icd;
98 struct mt9t112_frame_size frame; 93 struct v4l2_rect frame;
99 const struct mt9t112_format *format; 94 const struct mt9t112_format *format;
100 int model; 95 int model;
101 u32 flags; 96 u32 flags;
@@ -348,13 +343,10 @@ static int mt9t112_clock_info(const struct i2c_client *client, u32 ext)
348} 343}
349#endif 344#endif
350 345
351static void mt9t112_frame_check(u32 *width, u32 *height) 346static void mt9t112_frame_check(u32 *width, u32 *height, u32 *left, u32 *top)
352{ 347{
353 if (*width > MAX_WIDTH) 348 soc_camera_limit_side(left, width, 0, 0, MAX_WIDTH);
354 *width = MAX_WIDTH; 349 soc_camera_limit_side(top, height, 0, 0, MAX_HEIGHT);
355
356 if (*height > MAX_HEIGHT)
357 *height = MAX_HEIGHT;
358} 350}
359 351
360static int mt9t112_set_a_frame_size(const struct i2c_client *client, 352static int mt9t112_set_a_frame_size(const struct i2c_client *client,
@@ -849,19 +841,12 @@ static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable)
849 return ret; 841 return ret;
850} 842}
851 843
852static int mt9t112_set_params(struct i2c_client *client, u32 width, u32 height, 844static int mt9t112_set_params(struct mt9t112_priv *priv,
845 const struct v4l2_rect *rect,
853 enum v4l2_mbus_pixelcode code) 846 enum v4l2_mbus_pixelcode code)
854{ 847{
855 struct mt9t112_priv *priv = to_mt9t112(client);
856 int i; 848 int i;
857 849
858 priv->format = NULL;
859
860 /*
861 * frame size check
862 */
863 mt9t112_frame_check(&width, &height);
864
865 /* 850 /*
866 * get color format 851 * get color format
867 */ 852 */
@@ -872,8 +857,13 @@ static int mt9t112_set_params(struct i2c_client *client, u32 width, u32 height,
872 if (i == ARRAY_SIZE(mt9t112_cfmts)) 857 if (i == ARRAY_SIZE(mt9t112_cfmts))
873 return -EINVAL; 858 return -EINVAL;
874 859
875 priv->frame.width = (u16)width; 860 priv->frame = *rect;
876 priv->frame.height = (u16)height; 861
862 /*
863 * frame size check
864 */
865 mt9t112_frame_check(&priv->frame.width, &priv->frame.height,
866 &priv->frame.left, &priv->frame.top);
877 867
878 priv->format = mt9t112_cfmts + i; 868 priv->format = mt9t112_cfmts + i;
879 869
@@ -884,9 +874,12 @@ static int mt9t112_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
884{ 874{
885 a->bounds.left = 0; 875 a->bounds.left = 0;
886 a->bounds.top = 0; 876 a->bounds.top = 0;
887 a->bounds.width = VGA_WIDTH; 877 a->bounds.width = MAX_WIDTH;
888 a->bounds.height = VGA_HEIGHT; 878 a->bounds.height = MAX_HEIGHT;
889 a->defrect = a->bounds; 879 a->defrect.left = 0;
880 a->defrect.top = 0;
881 a->defrect.width = VGA_WIDTH;
882 a->defrect.height = VGA_HEIGHT;
890 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 883 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
891 a->pixelaspect.numerator = 1; 884 a->pixelaspect.numerator = 1;
892 a->pixelaspect.denominator = 1; 885 a->pixelaspect.denominator = 1;
@@ -896,11 +889,11 @@ static int mt9t112_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
896 889
897static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 890static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
898{ 891{
899 a->c.left = 0; 892 struct i2c_client *client = v4l2_get_subdevdata(sd);
900 a->c.top = 0; 893 struct mt9t112_priv *priv = to_mt9t112(client);
901 a->c.width = VGA_WIDTH; 894
902 a->c.height = VGA_HEIGHT; 895 a->c = priv->frame;
903 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 896 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
904 897
905 return 0; 898 return 0;
906} 899}
@@ -908,10 +901,10 @@ static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
908static int mt9t112_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 901static int mt9t112_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
909{ 902{
910 struct i2c_client *client = v4l2_get_subdevdata(sd); 903 struct i2c_client *client = v4l2_get_subdevdata(sd);
904 struct mt9t112_priv *priv = to_mt9t112(client);
911 struct v4l2_rect *rect = &a->c; 905 struct v4l2_rect *rect = &a->c;
912 906
913 return mt9t112_set_params(client, rect->width, rect->height, 907 return mt9t112_set_params(priv, rect, priv->format->code);
914 V4L2_MBUS_FMT_UYVY8_2X8);
915} 908}
916 909
917static int mt9t112_g_fmt(struct v4l2_subdev *sd, 910static int mt9t112_g_fmt(struct v4l2_subdev *sd,
@@ -920,16 +913,9 @@ static int mt9t112_g_fmt(struct v4l2_subdev *sd,
920 struct i2c_client *client = v4l2_get_subdevdata(sd); 913 struct i2c_client *client = v4l2_get_subdevdata(sd);
921 struct mt9t112_priv *priv = to_mt9t112(client); 914 struct mt9t112_priv *priv = to_mt9t112(client);
922 915
923 if (!priv->format) {
924 int ret = mt9t112_set_params(client, VGA_WIDTH, VGA_HEIGHT,
925 V4L2_MBUS_FMT_UYVY8_2X8);
926 if (ret < 0)
927 return ret;
928 }
929
930 mf->width = priv->frame.width; 916 mf->width = priv->frame.width;
931 mf->height = priv->frame.height; 917 mf->height = priv->frame.height;
932 /* TODO: set colorspace */ 918 mf->colorspace = priv->format->colorspace;
933 mf->code = priv->format->code; 919 mf->code = priv->format->code;
934 mf->field = V4L2_FIELD_NONE; 920 mf->field = V4L2_FIELD_NONE;
935 921
@@ -940,17 +926,42 @@ static int mt9t112_s_fmt(struct v4l2_subdev *sd,
940 struct v4l2_mbus_framefmt *mf) 926 struct v4l2_mbus_framefmt *mf)
941{ 927{
942 struct i2c_client *client = v4l2_get_subdevdata(sd); 928 struct i2c_client *client = v4l2_get_subdevdata(sd);
929 struct mt9t112_priv *priv = to_mt9t112(client);
930 struct v4l2_rect rect = {
931 .width = mf->width,
932 .height = mf->height,
933 .left = priv->frame.left,
934 .top = priv->frame.top,
935 };
936 int ret;
937
938 ret = mt9t112_set_params(priv, &rect, mf->code);
939
940 if (!ret)
941 mf->colorspace = priv->format->colorspace;
943 942
944 /* TODO: set colorspace */ 943 return ret;
945 return mt9t112_set_params(client, mf->width, mf->height, mf->code);
946} 944}
947 945
948static int mt9t112_try_fmt(struct v4l2_subdev *sd, 946static int mt9t112_try_fmt(struct v4l2_subdev *sd,
949 struct v4l2_mbus_framefmt *mf) 947 struct v4l2_mbus_framefmt *mf)
950{ 948{
951 mt9t112_frame_check(&mf->width, &mf->height); 949 unsigned int top, left;
950 int i;
951
952 for (i = 0; i < ARRAY_SIZE(mt9t112_cfmts); i++)
953 if (mt9t112_cfmts[i].code == mf->code)
954 break;
955
956 if (i == ARRAY_SIZE(mt9t112_cfmts)) {
957 mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
958 mf->colorspace = V4L2_COLORSPACE_JPEG;
959 } else {
960 mf->colorspace = mt9t112_cfmts[i].colorspace;
961 }
962
963 mt9t112_frame_check(&mf->width, &mf->height, &left, &top);
952 964
953 /* TODO: set colorspace */
954 mf->field = V4L2_FIELD_NONE; 965 mf->field = V4L2_FIELD_NONE;
955 966
956 return 0; 967 return 0;
@@ -963,6 +974,7 @@ static int mt9t112_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
963 return -EINVAL; 974 return -EINVAL;
964 975
965 *code = mt9t112_cfmts[index].code; 976 *code = mt9t112_cfmts[index].code;
977
966 return 0; 978 return 0;
967} 979}
968 980
@@ -1055,10 +1067,16 @@ static int mt9t112_camera_probe(struct soc_camera_device *icd,
1055static int mt9t112_probe(struct i2c_client *client, 1067static int mt9t112_probe(struct i2c_client *client,
1056 const struct i2c_device_id *did) 1068 const struct i2c_device_id *did)
1057{ 1069{
1058 struct mt9t112_priv *priv; 1070 struct mt9t112_priv *priv;
1059 struct soc_camera_device *icd = client->dev.platform_data; 1071 struct soc_camera_device *icd = client->dev.platform_data;
1060 struct soc_camera_link *icl; 1072 struct soc_camera_link *icl;
1061 int ret; 1073 struct v4l2_rect rect = {
1074 .width = VGA_WIDTH,
1075 .height = VGA_HEIGHT,
1076 .left = (MAX_WIDTH - VGA_WIDTH) / 2,
1077 .top = (MAX_HEIGHT - VGA_HEIGHT) / 2,
1078 };
1079 int ret;
1062 1080
1063 if (!icd) { 1081 if (!icd) {
1064 dev_err(&client->dev, "mt9t112: missing soc-camera data!\n"); 1082 dev_err(&client->dev, "mt9t112: missing soc-camera data!\n");
@@ -1083,6 +1101,9 @@ static int mt9t112_probe(struct i2c_client *client,
1083 if (ret) 1101 if (ret)
1084 kfree(priv); 1102 kfree(priv);
1085 1103
1104 /* Cannot fail: using the default supported pixel code */
1105 mt9t112_set_params(priv, &rect, V4L2_MBUS_FMT_UYVY8_2X8);
1106
1086 return ret; 1107 return ret;
1087} 1108}
1088 1109