diff options
Diffstat (limited to 'drivers/media/video/mt9t112.c')
-rw-r--r-- | drivers/media/video/mt9t112.c | 269 |
1 files changed, 117 insertions, 152 deletions
diff --git a/drivers/media/video/mt9t112.c b/drivers/media/video/mt9t112.c index d2e0a50063a..32114a3c0ca 100644 --- a/drivers/media/video/mt9t112.c +++ b/drivers/media/video/mt9t112.c | |||
@@ -22,11 +22,11 @@ | |||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/v4l2-mediabus.h> | ||
25 | #include <linux/videodev2.h> | 26 | #include <linux/videodev2.h> |
26 | 27 | ||
27 | #include <media/mt9t112.h> | 28 | #include <media/mt9t112.h> |
28 | #include <media/soc_camera.h> | 29 | #include <media/soc_camera.h> |
29 | #include <media/soc_mediabus.h> | ||
30 | #include <media/v4l2-chip-ident.h> | 30 | #include <media/v4l2-chip-ident.h> |
31 | #include <media/v4l2-common.h> | 31 | #include <media/v4l2-common.h> |
32 | 32 | ||
@@ -34,11 +34,7 @@ | |||
34 | /* #define EXT_CLOCK 24000000 */ | 34 | /* #define EXT_CLOCK 24000000 */ |
35 | 35 | ||
36 | /************************************************************************ | 36 | /************************************************************************ |
37 | |||
38 | |||
39 | macro | 37 | macro |
40 | |||
41 | |||
42 | ************************************************************************/ | 38 | ************************************************************************/ |
43 | /* | 39 | /* |
44 | * frame size | 40 | * frame size |
@@ -80,17 +76,8 @@ | |||
80 | #define VAR8(id, offset) _VAR(id, offset, 0x8000) | 76 | #define VAR8(id, offset) _VAR(id, offset, 0x8000) |
81 | 77 | ||
82 | /************************************************************************ | 78 | /************************************************************************ |
83 | |||
84 | |||
85 | struct | 79 | struct |
86 | |||
87 | |||
88 | ************************************************************************/ | 80 | ************************************************************************/ |
89 | struct mt9t112_frame_size { | ||
90 | u16 width; | ||
91 | u16 height; | ||
92 | }; | ||
93 | |||
94 | struct mt9t112_format { | 81 | struct mt9t112_format { |
95 | enum v4l2_mbus_pixelcode code; | 82 | enum v4l2_mbus_pixelcode code; |
96 | enum v4l2_colorspace colorspace; | 83 | enum v4l2_colorspace colorspace; |
@@ -102,21 +89,17 @@ struct mt9t112_priv { | |||
102 | struct v4l2_subdev subdev; | 89 | struct v4l2_subdev subdev; |
103 | struct mt9t112_camera_info *info; | 90 | struct mt9t112_camera_info *info; |
104 | struct i2c_client *client; | 91 | struct i2c_client *client; |
105 | struct soc_camera_device icd; | 92 | struct v4l2_rect frame; |
106 | struct mt9t112_frame_size frame; | ||
107 | const struct mt9t112_format *format; | 93 | const struct mt9t112_format *format; |
108 | int model; | 94 | int model; |
109 | u32 flags; | 95 | u32 flags; |
110 | /* for flags */ | 96 | /* for flags */ |
111 | #define INIT_DONE (1<<0) | 97 | #define INIT_DONE (1 << 0) |
98 | #define PCLK_RISING (1 << 1) | ||
112 | }; | 99 | }; |
113 | 100 | ||
114 | /************************************************************************ | 101 | /************************************************************************ |
115 | |||
116 | |||
117 | supported format | 102 | supported format |
118 | |||
119 | |||
120 | ************************************************************************/ | 103 | ************************************************************************/ |
121 | 104 | ||
122 | static const struct mt9t112_format mt9t112_cfmts[] = { | 105 | static const struct mt9t112_format mt9t112_cfmts[] = { |
@@ -154,11 +137,7 @@ static const struct mt9t112_format mt9t112_cfmts[] = { | |||
154 | }; | 137 | }; |
155 | 138 | ||
156 | /************************************************************************ | 139 | /************************************************************************ |
157 | |||
158 | |||
159 | general function | 140 | general function |
160 | |||
161 | |||
162 | ************************************************************************/ | 141 | ************************************************************************/ |
163 | static struct mt9t112_priv *to_mt9t112(const struct i2c_client *client) | 142 | static struct mt9t112_priv *to_mt9t112(const struct i2c_client *client) |
164 | { | 143 | { |
@@ -326,50 +305,47 @@ static int mt9t112_clock_info(const struct i2c_client *client, u32 ext) | |||
326 | n = (n >> 8) & 0x003f; | 305 | n = (n >> 8) & 0x003f; |
327 | 306 | ||
328 | enable = ((6000 > ext) || (54000 < ext)) ? "X" : ""; | 307 | enable = ((6000 > ext) || (54000 < ext)) ? "X" : ""; |
329 | dev_info(&client->dev, "EXTCLK : %10u K %s\n", ext, enable); | 308 | dev_dbg(&client->dev, "EXTCLK : %10u K %s\n", ext, enable); |
330 | 309 | ||
331 | vco = 2 * m * ext / (n+1); | 310 | vco = 2 * m * ext / (n+1); |
332 | enable = ((384000 > vco) || (768000 < vco)) ? "X" : ""; | 311 | enable = ((384000 > vco) || (768000 < vco)) ? "X" : ""; |
333 | dev_info(&client->dev, "VCO : %10u K %s\n", vco, enable); | 312 | dev_dbg(&client->dev, "VCO : %10u K %s\n", vco, enable); |
334 | 313 | ||
335 | clk = vco / (p1+1) / (p2+1); | 314 | clk = vco / (p1+1) / (p2+1); |
336 | enable = (96000 < clk) ? "X" : ""; | 315 | enable = (96000 < clk) ? "X" : ""; |
337 | dev_info(&client->dev, "PIXCLK : %10u K %s\n", clk, enable); | 316 | dev_dbg(&client->dev, "PIXCLK : %10u K %s\n", clk, enable); |
338 | 317 | ||
339 | clk = vco / (p3+1); | 318 | clk = vco / (p3+1); |
340 | enable = (768000 < clk) ? "X" : ""; | 319 | enable = (768000 < clk) ? "X" : ""; |
341 | dev_info(&client->dev, "MIPICLK : %10u K %s\n", clk, enable); | 320 | dev_dbg(&client->dev, "MIPICLK : %10u K %s\n", clk, enable); |
342 | 321 | ||
343 | clk = vco / (p6+1); | 322 | clk = vco / (p6+1); |
344 | enable = (96000 < clk) ? "X" : ""; | 323 | enable = (96000 < clk) ? "X" : ""; |
345 | dev_info(&client->dev, "MCU CLK : %10u K %s\n", clk, enable); | 324 | dev_dbg(&client->dev, "MCU CLK : %10u K %s\n", clk, enable); |
346 | 325 | ||
347 | clk = vco / (p5+1); | 326 | clk = vco / (p5+1); |
348 | enable = (54000 < clk) ? "X" : ""; | 327 | enable = (54000 < clk) ? "X" : ""; |
349 | dev_info(&client->dev, "SOC CLK : %10u K %s\n", clk, enable); | 328 | dev_dbg(&client->dev, "SOC CLK : %10u K %s\n", clk, enable); |
350 | 329 | ||
351 | clk = vco / (p4+1); | 330 | clk = vco / (p4+1); |
352 | enable = (70000 < clk) ? "X" : ""; | 331 | enable = (70000 < clk) ? "X" : ""; |
353 | dev_info(&client->dev, "Sensor CLK : %10u K %s\n", clk, enable); | 332 | dev_dbg(&client->dev, "Sensor CLK : %10u K %s\n", clk, enable); |
354 | 333 | ||
355 | clk = vco / (p7+1); | 334 | clk = vco / (p7+1); |
356 | dev_info(&client->dev, "External sensor : %10u K\n", clk); | 335 | dev_dbg(&client->dev, "External sensor : %10u K\n", clk); |
357 | 336 | ||
358 | clk = ext / (n+1); | 337 | clk = ext / (n+1); |
359 | enable = ((2000 > clk) || (24000 < clk)) ? "X" : ""; | 338 | enable = ((2000 > clk) || (24000 < clk)) ? "X" : ""; |
360 | dev_info(&client->dev, "PFD : %10u K %s\n", clk, enable); | 339 | dev_dbg(&client->dev, "PFD : %10u K %s\n", clk, enable); |
361 | 340 | ||
362 | return 0; | 341 | return 0; |
363 | } | 342 | } |
364 | #endif | 343 | #endif |
365 | 344 | ||
366 | static void mt9t112_frame_check(u32 *width, u32 *height) | 345 | static void mt9t112_frame_check(u32 *width, u32 *height, u32 *left, u32 *top) |
367 | { | 346 | { |
368 | if (*width > MAX_WIDTH) | 347 | soc_camera_limit_side(left, width, 0, 0, MAX_WIDTH); |
369 | *width = MAX_WIDTH; | 348 | soc_camera_limit_side(top, height, 0, 0, MAX_HEIGHT); |
370 | |||
371 | if (*height > MAX_HEIGHT) | ||
372 | *height = MAX_HEIGHT; | ||
373 | } | 349 | } |
374 | 350 | ||
375 | static int mt9t112_set_a_frame_size(const struct i2c_client *client, | 351 | static int mt9t112_set_a_frame_size(const struct i2c_client *client, |
@@ -758,48 +734,7 @@ static int mt9t112_init_camera(const struct i2c_client *client) | |||
758 | } | 734 | } |
759 | 735 | ||
760 | /************************************************************************ | 736 | /************************************************************************ |
761 | |||
762 | |||
763 | soc_camera_ops | ||
764 | |||
765 | |||
766 | ************************************************************************/ | ||
767 | static int mt9t112_set_bus_param(struct soc_camera_device *icd, | ||
768 | unsigned long flags) | ||
769 | { | ||
770 | return 0; | ||
771 | } | ||
772 | |||
773 | static unsigned long mt9t112_query_bus_param(struct soc_camera_device *icd) | ||
774 | { | ||
775 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | ||
776 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
777 | struct soc_camera_link *icl = to_soc_camera_link(icd); | ||
778 | unsigned long flags = SOCAM_MASTER | SOCAM_VSYNC_ACTIVE_HIGH | | ||
779 | SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH; | ||
780 | |||
781 | flags |= (priv->info->flags & MT9T112_FLAG_PCLK_RISING_EDGE) ? | ||
782 | SOCAM_PCLK_SAMPLE_RISING : SOCAM_PCLK_SAMPLE_FALLING; | ||
783 | |||
784 | if (priv->info->flags & MT9T112_FLAG_DATAWIDTH_8) | ||
785 | flags |= SOCAM_DATAWIDTH_8; | ||
786 | else | ||
787 | flags |= SOCAM_DATAWIDTH_10; | ||
788 | |||
789 | return soc_camera_apply_sensor_flags(icl, flags); | ||
790 | } | ||
791 | |||
792 | static struct soc_camera_ops mt9t112_ops = { | ||
793 | .set_bus_param = mt9t112_set_bus_param, | ||
794 | .query_bus_param = mt9t112_query_bus_param, | ||
795 | }; | ||
796 | |||
797 | /************************************************************************ | ||
798 | |||
799 | |||
800 | v4l2_subdev_core_ops | 737 | v4l2_subdev_core_ops |
801 | |||
802 | |||
803 | ************************************************************************/ | 738 | ************************************************************************/ |
804 | static int mt9t112_g_chip_ident(struct v4l2_subdev *sd, | 739 | static int mt9t112_g_chip_ident(struct v4l2_subdev *sd, |
805 | struct v4l2_dbg_chip_ident *id) | 740 | struct v4l2_dbg_chip_ident *id) |
@@ -850,11 +785,7 @@ static struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = { | |||
850 | 785 | ||
851 | 786 | ||
852 | /************************************************************************ | 787 | /************************************************************************ |
853 | |||
854 | |||
855 | v4l2_subdev_video_ops | 788 | v4l2_subdev_video_ops |
856 | |||
857 | |||
858 | ************************************************************************/ | 789 | ************************************************************************/ |
859 | static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable) | 790 | static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable) |
860 | { | 791 | { |
@@ -877,8 +808,7 @@ static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable) | |||
877 | } | 808 | } |
878 | 809 | ||
879 | if (!(priv->flags & INIT_DONE)) { | 810 | if (!(priv->flags & INIT_DONE)) { |
880 | u16 param = (MT9T112_FLAG_PCLK_RISING_EDGE & | 811 | u16 param = PCLK_RISING & priv->flags ? 0x0001 : 0x0000; |
881 | priv->info->flags) ? 0x0001 : 0x0000; | ||
882 | 812 | ||
883 | ECHECKER(ret, mt9t112_init_camera(client)); | 813 | ECHECKER(ret, mt9t112_init_camera(client)); |
884 | 814 | ||
@@ -910,19 +840,12 @@ static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable) | |||
910 | return ret; | 840 | return ret; |
911 | } | 841 | } |
912 | 842 | ||
913 | static int mt9t112_set_params(struct i2c_client *client, u32 width, u32 height, | 843 | static int mt9t112_set_params(struct mt9t112_priv *priv, |
844 | const struct v4l2_rect *rect, | ||
914 | enum v4l2_mbus_pixelcode code) | 845 | enum v4l2_mbus_pixelcode code) |
915 | { | 846 | { |
916 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
917 | int i; | 847 | int i; |
918 | 848 | ||
919 | priv->format = NULL; | ||
920 | |||
921 | /* | ||
922 | * frame size check | ||
923 | */ | ||
924 | mt9t112_frame_check(&width, &height); | ||
925 | |||
926 | /* | 849 | /* |
927 | * get color format | 850 | * get color format |
928 | */ | 851 | */ |
@@ -933,8 +856,13 @@ static int mt9t112_set_params(struct i2c_client *client, u32 width, u32 height, | |||
933 | if (i == ARRAY_SIZE(mt9t112_cfmts)) | 856 | if (i == ARRAY_SIZE(mt9t112_cfmts)) |
934 | return -EINVAL; | 857 | return -EINVAL; |
935 | 858 | ||
936 | priv->frame.width = (u16)width; | 859 | priv->frame = *rect; |
937 | priv->frame.height = (u16)height; | 860 | |
861 | /* | ||
862 | * frame size check | ||
863 | */ | ||
864 | mt9t112_frame_check(&priv->frame.width, &priv->frame.height, | ||
865 | &priv->frame.left, &priv->frame.top); | ||
938 | 866 | ||
939 | priv->format = mt9t112_cfmts + i; | 867 | priv->format = mt9t112_cfmts + i; |
940 | 868 | ||
@@ -945,9 +873,12 @@ static int mt9t112_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | |||
945 | { | 873 | { |
946 | a->bounds.left = 0; | 874 | a->bounds.left = 0; |
947 | a->bounds.top = 0; | 875 | a->bounds.top = 0; |
948 | a->bounds.width = VGA_WIDTH; | 876 | a->bounds.width = MAX_WIDTH; |
949 | a->bounds.height = VGA_HEIGHT; | 877 | a->bounds.height = MAX_HEIGHT; |
950 | a->defrect = a->bounds; | 878 | a->defrect.left = 0; |
879 | a->defrect.top = 0; | ||
880 | a->defrect.width = VGA_WIDTH; | ||
881 | a->defrect.height = VGA_HEIGHT; | ||
951 | a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 882 | a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
952 | a->pixelaspect.numerator = 1; | 883 | a->pixelaspect.numerator = 1; |
953 | a->pixelaspect.denominator = 1; | 884 | a->pixelaspect.denominator = 1; |
@@ -957,11 +888,11 @@ static int mt9t112_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | |||
957 | 888 | ||
958 | static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | 889 | static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) |
959 | { | 890 | { |
960 | a->c.left = 0; | 891 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
961 | a->c.top = 0; | 892 | struct mt9t112_priv *priv = to_mt9t112(client); |
962 | a->c.width = VGA_WIDTH; | 893 | |
963 | a->c.height = VGA_HEIGHT; | 894 | a->c = priv->frame; |
964 | a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 895 | a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
965 | 896 | ||
966 | return 0; | 897 | return 0; |
967 | } | 898 | } |
@@ -969,10 +900,10 @@ static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
969 | static int mt9t112_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | 900 | static int mt9t112_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) |
970 | { | 901 | { |
971 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 902 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
903 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
972 | struct v4l2_rect *rect = &a->c; | 904 | struct v4l2_rect *rect = &a->c; |
973 | 905 | ||
974 | return mt9t112_set_params(client, rect->width, rect->height, | 906 | return mt9t112_set_params(priv, rect, priv->format->code); |
975 | V4L2_MBUS_FMT_UYVY8_2X8); | ||
976 | } | 907 | } |
977 | 908 | ||
978 | static int mt9t112_g_fmt(struct v4l2_subdev *sd, | 909 | static int mt9t112_g_fmt(struct v4l2_subdev *sd, |
@@ -981,16 +912,9 @@ static int mt9t112_g_fmt(struct v4l2_subdev *sd, | |||
981 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 912 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
982 | struct mt9t112_priv *priv = to_mt9t112(client); | 913 | struct mt9t112_priv *priv = to_mt9t112(client); |
983 | 914 | ||
984 | if (!priv->format) { | ||
985 | int ret = mt9t112_set_params(client, VGA_WIDTH, VGA_HEIGHT, | ||
986 | V4L2_MBUS_FMT_UYVY8_2X8); | ||
987 | if (ret < 0) | ||
988 | return ret; | ||
989 | } | ||
990 | |||
991 | mf->width = priv->frame.width; | 915 | mf->width = priv->frame.width; |
992 | mf->height = priv->frame.height; | 916 | mf->height = priv->frame.height; |
993 | /* TODO: set colorspace */ | 917 | mf->colorspace = priv->format->colorspace; |
994 | mf->code = priv->format->code; | 918 | mf->code = priv->format->code; |
995 | mf->field = V4L2_FIELD_NONE; | 919 | mf->field = V4L2_FIELD_NONE; |
996 | 920 | ||
@@ -1001,17 +925,42 @@ static int mt9t112_s_fmt(struct v4l2_subdev *sd, | |||
1001 | struct v4l2_mbus_framefmt *mf) | 925 | struct v4l2_mbus_framefmt *mf) |
1002 | { | 926 | { |
1003 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 927 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
928 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
929 | struct v4l2_rect rect = { | ||
930 | .width = mf->width, | ||
931 | .height = mf->height, | ||
932 | .left = priv->frame.left, | ||
933 | .top = priv->frame.top, | ||
934 | }; | ||
935 | int ret; | ||
936 | |||
937 | ret = mt9t112_set_params(priv, &rect, mf->code); | ||
938 | |||
939 | if (!ret) | ||
940 | mf->colorspace = priv->format->colorspace; | ||
1004 | 941 | ||
1005 | /* TODO: set colorspace */ | 942 | return ret; |
1006 | return mt9t112_set_params(client, mf->width, mf->height, mf->code); | ||
1007 | } | 943 | } |
1008 | 944 | ||
1009 | static int mt9t112_try_fmt(struct v4l2_subdev *sd, | 945 | static int mt9t112_try_fmt(struct v4l2_subdev *sd, |
1010 | struct v4l2_mbus_framefmt *mf) | 946 | struct v4l2_mbus_framefmt *mf) |
1011 | { | 947 | { |
1012 | mt9t112_frame_check(&mf->width, &mf->height); | 948 | unsigned int top, left; |
949 | int i; | ||
950 | |||
951 | for (i = 0; i < ARRAY_SIZE(mt9t112_cfmts); i++) | ||
952 | if (mt9t112_cfmts[i].code == mf->code) | ||
953 | break; | ||
954 | |||
955 | if (i == ARRAY_SIZE(mt9t112_cfmts)) { | ||
956 | mf->code = V4L2_MBUS_FMT_UYVY8_2X8; | ||
957 | mf->colorspace = V4L2_COLORSPACE_JPEG; | ||
958 | } else { | ||
959 | mf->colorspace = mt9t112_cfmts[i].colorspace; | ||
960 | } | ||
961 | |||
962 | mt9t112_frame_check(&mf->width, &mf->height, &left, &top); | ||
1013 | 963 | ||
1014 | /* TODO: set colorspace */ | ||
1015 | mf->field = V4L2_FIELD_NONE; | 964 | mf->field = V4L2_FIELD_NONE; |
1016 | 965 | ||
1017 | return 0; | 966 | return 0; |
@@ -1024,6 +973,35 @@ static int mt9t112_enum_fmt(struct v4l2_subdev *sd, unsigned int index, | |||
1024 | return -EINVAL; | 973 | return -EINVAL; |
1025 | 974 | ||
1026 | *code = mt9t112_cfmts[index].code; | 975 | *code = mt9t112_cfmts[index].code; |
976 | |||
977 | return 0; | ||
978 | } | ||
979 | |||
980 | static int mt9t112_g_mbus_config(struct v4l2_subdev *sd, | ||
981 | struct v4l2_mbus_config *cfg) | ||
982 | { | ||
983 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
984 | struct soc_camera_link *icl = soc_camera_i2c_to_link(client); | ||
985 | |||
986 | cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_VSYNC_ACTIVE_HIGH | | ||
987 | V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_HIGH | | ||
988 | V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING; | ||
989 | cfg->type = V4L2_MBUS_PARALLEL; | ||
990 | cfg->flags = soc_camera_apply_board_flags(icl, cfg); | ||
991 | |||
992 | return 0; | ||
993 | } | ||
994 | |||
995 | static int mt9t112_s_mbus_config(struct v4l2_subdev *sd, | ||
996 | const struct v4l2_mbus_config *cfg) | ||
997 | { | ||
998 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
999 | struct soc_camera_link *icl = soc_camera_i2c_to_link(client); | ||
1000 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
1001 | |||
1002 | if (soc_camera_apply_board_flags(icl, cfg) & V4L2_MBUS_PCLK_SAMPLE_RISING) | ||
1003 | priv->flags |= PCLK_RISING; | ||
1004 | |||
1027 | return 0; | 1005 | return 0; |
1028 | } | 1006 | } |
1029 | 1007 | ||
@@ -1036,31 +1014,24 @@ static struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = { | |||
1036 | .g_crop = mt9t112_g_crop, | 1014 | .g_crop = mt9t112_g_crop, |
1037 | .s_crop = mt9t112_s_crop, | 1015 | .s_crop = mt9t112_s_crop, |
1038 | .enum_mbus_fmt = mt9t112_enum_fmt, | 1016 | .enum_mbus_fmt = mt9t112_enum_fmt, |
1017 | .g_mbus_config = mt9t112_g_mbus_config, | ||
1018 | .s_mbus_config = mt9t112_s_mbus_config, | ||
1039 | }; | 1019 | }; |
1040 | 1020 | ||
1041 | /************************************************************************ | 1021 | /************************************************************************ |
1042 | |||
1043 | |||
1044 | i2c driver | 1022 | i2c driver |
1045 | |||
1046 | |||
1047 | ************************************************************************/ | 1023 | ************************************************************************/ |
1048 | static struct v4l2_subdev_ops mt9t112_subdev_ops = { | 1024 | static struct v4l2_subdev_ops mt9t112_subdev_ops = { |
1049 | .core = &mt9t112_subdev_core_ops, | 1025 | .core = &mt9t112_subdev_core_ops, |
1050 | .video = &mt9t112_subdev_video_ops, | 1026 | .video = &mt9t112_subdev_video_ops, |
1051 | }; | 1027 | }; |
1052 | 1028 | ||
1053 | static int mt9t112_camera_probe(struct soc_camera_device *icd, | 1029 | static int mt9t112_camera_probe(struct i2c_client *client) |
1054 | struct i2c_client *client) | ||
1055 | { | 1030 | { |
1056 | struct mt9t112_priv *priv = to_mt9t112(client); | 1031 | struct mt9t112_priv *priv = to_mt9t112(client); |
1057 | const char *devname; | 1032 | const char *devname; |
1058 | int chipid; | 1033 | int chipid; |
1059 | 1034 | ||
1060 | /* We must have a parent by now. And it cannot be a wrong one. */ | ||
1061 | BUG_ON(!icd->parent || | ||
1062 | to_soc_camera_host(icd->parent)->nr != icd->iface); | ||
1063 | |||
1064 | /* | 1035 | /* |
1065 | * check and show chip ID | 1036 | * check and show chip ID |
1066 | */ | 1037 | */ |
@@ -1088,20 +1059,21 @@ static int mt9t112_camera_probe(struct soc_camera_device *icd, | |||
1088 | static int mt9t112_probe(struct i2c_client *client, | 1059 | static int mt9t112_probe(struct i2c_client *client, |
1089 | const struct i2c_device_id *did) | 1060 | const struct i2c_device_id *did) |
1090 | { | 1061 | { |
1091 | struct mt9t112_priv *priv; | 1062 | struct mt9t112_priv *priv; |
1092 | struct soc_camera_device *icd = client->dev.platform_data; | 1063 | struct soc_camera_link *icl = soc_camera_i2c_to_link(client); |
1093 | struct soc_camera_link *icl; | 1064 | struct v4l2_rect rect = { |
1094 | int ret; | 1065 | .width = VGA_WIDTH, |
1066 | .height = VGA_HEIGHT, | ||
1067 | .left = (MAX_WIDTH - VGA_WIDTH) / 2, | ||
1068 | .top = (MAX_HEIGHT - VGA_HEIGHT) / 2, | ||
1069 | }; | ||
1070 | int ret; | ||
1095 | 1071 | ||
1096 | if (!icd) { | 1072 | if (!icl || !icl->priv) { |
1097 | dev_err(&client->dev, "mt9t112: missing soc-camera data!\n"); | 1073 | dev_err(&client->dev, "mt9t112: missing platform data!\n"); |
1098 | return -EINVAL; | 1074 | return -EINVAL; |
1099 | } | 1075 | } |
1100 | 1076 | ||
1101 | icl = to_soc_camera_link(icd); | ||
1102 | if (!icl || !icl->priv) | ||
1103 | return -EINVAL; | ||
1104 | |||
1105 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 1077 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
1106 | if (!priv) | 1078 | if (!priv) |
1107 | return -ENOMEM; | 1079 | return -ENOMEM; |
@@ -1110,13 +1082,12 @@ static int mt9t112_probe(struct i2c_client *client, | |||
1110 | 1082 | ||
1111 | v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops); | 1083 | v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops); |
1112 | 1084 | ||
1113 | icd->ops = &mt9t112_ops; | 1085 | ret = mt9t112_camera_probe(client); |
1114 | 1086 | if (ret) | |
1115 | ret = mt9t112_camera_probe(icd, client); | ||
1116 | if (ret) { | ||
1117 | icd->ops = NULL; | ||
1118 | kfree(priv); | 1087 | kfree(priv); |
1119 | } | 1088 | |
1089 | /* Cannot fail: using the default supported pixel code */ | ||
1090 | mt9t112_set_params(priv, &rect, V4L2_MBUS_FMT_UYVY8_2X8); | ||
1120 | 1091 | ||
1121 | return ret; | 1092 | return ret; |
1122 | } | 1093 | } |
@@ -1124,9 +1095,7 @@ static int mt9t112_probe(struct i2c_client *client, | |||
1124 | static int mt9t112_remove(struct i2c_client *client) | 1095 | static int mt9t112_remove(struct i2c_client *client) |
1125 | { | 1096 | { |
1126 | struct mt9t112_priv *priv = to_mt9t112(client); | 1097 | struct mt9t112_priv *priv = to_mt9t112(client); |
1127 | struct soc_camera_device *icd = client->dev.platform_data; | ||
1128 | 1098 | ||
1129 | icd->ops = NULL; | ||
1130 | kfree(priv); | 1099 | kfree(priv); |
1131 | return 0; | 1100 | return 0; |
1132 | } | 1101 | } |
@@ -1147,11 +1116,7 @@ static struct i2c_driver mt9t112_i2c_driver = { | |||
1147 | }; | 1116 | }; |
1148 | 1117 | ||
1149 | /************************************************************************ | 1118 | /************************************************************************ |
1150 | |||
1151 | |||
1152 | module function | 1119 | module function |
1153 | |||
1154 | |||
1155 | ************************************************************************/ | 1120 | ************************************************************************/ |
1156 | static int __init mt9t112_module_init(void) | 1121 | static int __init mt9t112_module_init(void) |
1157 | { | 1122 | { |