| From ebe5f6eafcfdc6e8af99577a4ce98356e751662e Mon Sep 17 00:00:00 2001 |
| From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> |
| Date: Mon, 17 Sep 2012 07:42:55 -0300 |
| Subject: [media] sh-mobile-ceu-camera: add primitive OF support |
| |
| Add an OF hook to sh_mobile_ceu_camera.c, no properties so far. Booting |
| with DT also requires platform data to be optional. |
| |
| Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> |
| Acked-by: Hans Verkuil <hans.verkuil@cisco.com> |
| Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> |
| Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com> |
| (cherry picked from commit f146e4e79a6f5d457553dfe2ac66b93c7a39f676) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| .../platform/soc_camera/sh_mobile_ceu_camera.c | 33 +++++++++++++++------- |
| 1 file changed, 23 insertions(+), 10 deletions(-) |
| |
| diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c |
| index 9037472e..fcc13d8e 100644 |
| --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c |
| +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c |
| @@ -27,6 +27,7 @@ |
| #include <linux/kernel.h> |
| #include <linux/mm.h> |
| #include <linux/moduleparam.h> |
| +#include <linux/of.h> |
| #include <linux/time.h> |
| #include <linux/slab.h> |
| #include <linux/device.h> |
| @@ -118,6 +119,7 @@ struct sh_mobile_ceu_dev { |
| |
| enum v4l2_field field; |
| int sequence; |
| + unsigned long flags; |
| |
| unsigned int image_mode:1; |
| unsigned int is_16bit:1; |
| @@ -706,7 +708,7 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd) |
| } |
| |
| /* CSI2 special configuration */ |
| - if (pcdev->pdata->csi2) { |
| + if (pcdev->csi2_pdev) { |
| in_width = ((in_width - 2) * 2); |
| left_offset *= 2; |
| } |
| @@ -810,7 +812,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) |
| /* Make choises, based on platform preferences */ |
| if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) && |
| (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) { |
| - if (pcdev->pdata->flags & SH_CEU_FLAG_HSYNC_LOW) |
| + if (pcdev->flags & SH_CEU_FLAG_HSYNC_LOW) |
| common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH; |
| else |
| common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW; |
| @@ -818,7 +820,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) |
| |
| if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) && |
| (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) { |
| - if (pcdev->pdata->flags & SH_CEU_FLAG_VSYNC_LOW) |
| + if (pcdev->flags & SH_CEU_FLAG_VSYNC_LOW) |
| common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH; |
| else |
| common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW; |
| @@ -873,11 +875,11 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) |
| value |= common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0; |
| value |= common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0; |
| |
| - if (pcdev->pdata->csi2) /* CSI2 mode */ |
| + if (pcdev->csi2_pdev) /* CSI2 mode */ |
| value |= 3 << 12; |
| else if (pcdev->is_16bit) |
| value |= 1 << 12; |
| - else if (pcdev->pdata->flags & SH_CEU_FLAG_LOWER_8BIT) |
| + else if (pcdev->flags & SH_CEU_FLAG_LOWER_8BIT) |
| value |= 2 << 12; |
| |
| ceu_write(pcdev, CAMCR, value); |
| @@ -1052,7 +1054,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int |
| return 0; |
| } |
| |
| - if (!pcdev->pdata->csi2) { |
| + if (!pcdev->pdata || !pcdev->pdata->csi2) { |
| /* Are there any restrictions in the CSI-2 case? */ |
| ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample); |
| if (ret < 0) |
| @@ -2107,13 +2109,17 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) |
| init_completion(&pcdev->complete); |
| |
| pcdev->pdata = pdev->dev.platform_data; |
| - if (!pcdev->pdata) { |
| + if (!pcdev->pdata && !pdev->dev.of_node) { |
| dev_err(&pdev->dev, "CEU platform data not set.\n"); |
| return -EINVAL; |
| } |
| |
| - pcdev->max_width = pcdev->pdata->max_width ? : 2560; |
| - pcdev->max_height = pcdev->pdata->max_height ? : 1920; |
| + /* TODO: implement per-device bus flags */ |
| + if (pcdev->pdata) { |
| + pcdev->max_width = pcdev->pdata->max_width ? : 2560; |
| + pcdev->max_height = pcdev->pdata->max_height ? : 1920; |
| + pcdev->flags = pcdev->pdata->flags; |
| + } |
| |
| base = devm_ioremap_resource(&pdev->dev, res); |
| if (IS_ERR(base)) |
| @@ -2168,7 +2174,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) |
| goto exit_free_ctx; |
| |
| /* CSI2 interfacing */ |
| - csi2 = pcdev->pdata->csi2; |
| + csi2 = pcdev->pdata ? pcdev->pdata->csi2 : NULL; |
| if (csi2) { |
| struct platform_device *csi2_pdev = |
| platform_device_alloc("sh-mobile-csi2", csi2->id); |
| @@ -2290,10 +2296,17 @@ static const struct dev_pm_ops sh_mobile_ceu_dev_pm_ops = { |
| .runtime_resume = sh_mobile_ceu_runtime_nop, |
| }; |
| |
| +static const struct of_device_id sh_mobile_ceu_of_match[] = { |
| + { .compatible = "renesas,sh-mobile-ceu" }, |
| + { } |
| +}; |
| +MODULE_DEVICE_TABLE(of, sh_mobile_ceu_of_match); |
| + |
| static struct platform_driver sh_mobile_ceu_driver = { |
| .driver = { |
| .name = "sh_mobile_ceu", |
| .pm = &sh_mobile_ceu_dev_pm_ops, |
| + .of_match_table = sh_mobile_ceu_of_match, |
| }, |
| .probe = sh_mobile_ceu_probe, |
| .remove = sh_mobile_ceu_remove, |
| -- |
| 1.8.4.3.gca3854a |
| |