diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2011-07-26 12:13:47 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-11-03 16:27:30 -0400 |
commit | f836c6289b0cfbfaf2f90202d0edcb45f957f7cd (patch) | |
tree | 44c5b8b6733f55ab9176653f400761d6bd5ace95 | |
parent | 19a1780b628ecbc943465fa4d53b69e94c279f23 (diff) |
[media] V4L: sh_mobile_csi2: verify client compatibility
Switch the meaning of the .lanes platform data parameter to specify
the number of used lanes instead of a bitmask. Verify bus configuration
compatibility with client's capabilities.
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_csi2.c | 58 |
1 files changed, 52 insertions, 6 deletions
diff --git a/drivers/media/video/sh_mobile_csi2.c b/drivers/media/video/sh_mobile_csi2.c index 2893a0134c7e..09ef63d912e3 100644 --- a/drivers/media/video/sh_mobile_csi2.c +++ b/drivers/media/video/sh_mobile_csi2.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <media/sh_mobile_ceu.h> | 19 | #include <media/sh_mobile_ceu.h> |
20 | #include <media/sh_mobile_csi2.h> | 20 | #include <media/sh_mobile_csi2.h> |
21 | #include <media/soc_camera.h> | 21 | #include <media/soc_camera.h> |
22 | #include <media/soc_mediabus.h> | ||
22 | #include <media/v4l2-common.h> | 23 | #include <media/v4l2-common.h> |
23 | #include <media/v4l2-dev.h> | 24 | #include <media/v4l2-dev.h> |
24 | #include <media/v4l2-device.h> | 25 | #include <media/v4l2-device.h> |
@@ -144,11 +145,21 @@ static void sh_csi2_hwinit(struct sh_csi2 *priv) | |||
144 | udelay(5); | 145 | udelay(5); |
145 | iowrite32(0x00000000, priv->base + SH_CSI2_SRST); | 146 | iowrite32(0x00000000, priv->base + SH_CSI2_SRST); |
146 | 147 | ||
147 | if (priv->client->lanes & 3) | 148 | switch (pdata->type) { |
148 | tmp |= priv->client->lanes & 3; | 149 | case SH_CSI2C: |
149 | else | 150 | if (priv->client->lanes == 1) |
150 | /* Default - both lanes */ | 151 | tmp |= 1; |
151 | tmp |= 3; | 152 | else |
153 | /* Default - both lanes */ | ||
154 | tmp |= 3; | ||
155 | break; | ||
156 | case SH_CSI2I: | ||
157 | if (!priv->client->lanes || priv->client->lanes > 4) | ||
158 | /* Default - all 4 lanes */ | ||
159 | tmp |= 0xf; | ||
160 | else | ||
161 | tmp |= (1 << priv->client->lanes) - 1; | ||
162 | } | ||
152 | 163 | ||
153 | if (priv->client->phy == SH_CSI2_PHY_MAIN) | 164 | if (priv->client->phy == SH_CSI2_PHY_MAIN) |
154 | tmp |= 0x8000; | 165 | tmp |= 0x8000; |
@@ -185,7 +196,9 @@ static int sh_csi2_client_connect(struct sh_csi2 *priv) | |||
185 | struct v4l2_subdev *sd, *csi2_sd = &priv->subdev; | 196 | struct v4l2_subdev *sd, *csi2_sd = &priv->subdev; |
186 | struct soc_camera_device *icd = NULL; | 197 | struct soc_camera_device *icd = NULL; |
187 | struct device *dev = v4l2_get_subdevdata(&priv->subdev); | 198 | struct device *dev = v4l2_get_subdevdata(&priv->subdev); |
188 | int i; | 199 | struct v4l2_mbus_config cfg; |
200 | unsigned long common_flags, csi2_flags; | ||
201 | int i, ret; | ||
189 | 202 | ||
190 | v4l2_device_for_each_subdev(sd, csi2_sd->v4l2_dev) | 203 | v4l2_device_for_each_subdev(sd, csi2_sd->v4l2_dev) |
191 | if (sd->grp_id) { | 204 | if (sd->grp_id) { |
@@ -205,6 +218,39 @@ static int sh_csi2_client_connect(struct sh_csi2 *priv) | |||
205 | if (i == pdata->num_clients) | 218 | if (i == pdata->num_clients) |
206 | return -ENODEV; | 219 | return -ENODEV; |
207 | 220 | ||
221 | /* Check if we can support this camera */ | ||
222 | csi2_flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK | V4L2_MBUS_CSI2_1_LANE; | ||
223 | |||
224 | switch (pdata->type) { | ||
225 | case SH_CSI2C: | ||
226 | if (pdata->clients[i].lanes != 1) | ||
227 | csi2_flags |= V4L2_MBUS_CSI2_2_LANE; | ||
228 | break; | ||
229 | case SH_CSI2I: | ||
230 | switch (pdata->clients[i].lanes) { | ||
231 | default: | ||
232 | csi2_flags |= V4L2_MBUS_CSI2_4_LANE; | ||
233 | case 3: | ||
234 | csi2_flags |= V4L2_MBUS_CSI2_3_LANE; | ||
235 | case 2: | ||
236 | csi2_flags |= V4L2_MBUS_CSI2_2_LANE; | ||
237 | } | ||
238 | } | ||
239 | |||
240 | cfg.type = V4L2_MBUS_CSI2; | ||
241 | ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg); | ||
242 | if (ret == -ENOIOCTLCMD) | ||
243 | common_flags = csi2_flags; | ||
244 | else if (!ret) | ||
245 | common_flags = soc_mbus_config_compatible(&cfg, | ||
246 | csi2_flags); | ||
247 | else | ||
248 | common_flags = 0; | ||
249 | |||
250 | if (!common_flags) | ||
251 | return -EINVAL; | ||
252 | |||
253 | /* All good: camera MIPI configuration supported */ | ||
208 | priv->client = pdata->clients + i; | 254 | priv->client = pdata->clients + i; |
209 | 255 | ||
210 | priv->set_bus_param = icd->ops->set_bus_param; | 256 | priv->set_bus_param = icd->ops->set_bus_param; |